blob: 733e958a27225461ab280fae3e65e47e6ceb1abe [file] [log] [blame]
#!/usr/bin/env python
# Copyright 2016 The Shaderc Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Builds the Shaderc project, on Linux, Mac, or Windows.
"""
from __future__ import print_function
import argparse
import os
import platform
import subprocess
import sys
OS = platform.system()
def run(cmd, cwd, env, justprint):
"""Prints a command to run, and optionally runs it.
Raises a RuntimeError if the command does not launch or otherwise fails.
Args:
justprint: If true, then only print the command. Otherwise run the
command after printing it.
cmd: List of words in the command.
cwd: Working directory for the command.
env: Environment to pass to subprocess.
"""
print(cmd)
if justprint:
return
p = subprocess.Popen(cmd, cwd=cwd, env=env)
(_, _) = p.communicate()
if p.returncode != 0:
raise RuntimeError('Failed to run %s in %s' % (cmd, cwd))
def build(args):
""" Builds Shaderc under specified conditions.
Args:
args: An object with attributes:
srcdir: where Shaderc source can be found
builddir: build working directory
installdir: install directory
"""
if not os.path.isdir(args.srcdir):
raise RuntimeError('Soure directory %s does not exist' % (args.srcdir))
# Make paths absolute, and ensure directories exist.
for d in [args.builddir, args.installdir]:
if not os.path.isdir(d):
os.makedirs(d)
args.srcdir = os.path.abspath(args.srcdir)
args.builddir = os.path.abspath(args.builddir)
args.installdir = os.path.abspath(args.installdir)
print('Building Shaderc:')
print(' Source : ', args.srcdir)
print(' Build dir : ', args.builddir)
print(' Install dir: ', args.installdir)
cmake_command = ['cmake', args.srcdir, '-GNinja',
'-DCMAKE_BUILD_TYPE=%s' % args.buildtype,
'-DCMAKE_INSTALL_PREFIX=%s' % args.installdir]
env = None
if OS == 'Windows':
p = subprocess.Popen(
'"%VS140COMNTOOLS%..\\..\\VC\\vcvarsall.bat" & set',
stdout=subprocess.PIPE, cwd=args.builddir, shell=True)
env = dict([tuple(line.split('=', 1))
for line in p.communicate()[0].splitlines()])
run(cmake_command, args.builddir, env, args.dry_run)
run(['ninja', 'install'], args.builddir, env, args.dry_run)
run(['ctest', '--output-on-failure'], args.builddir, env, args.dry_run)
def cygpath(f):
p = subprocess.Popen(['cygpath', '-w', f], stdout=subprocess.PIPE)
return p.communicate()[0].rstrip()
def main():
"""Builds Shaderc after parsing argument specifying locations of
files, level of parallelism, and whether it's a dry run that should
skip actual compilation and installation."""
parser = argparse.ArgumentParser(description='Build Shaderc simply')
parser.add_argument('-n', '--dry_run', dest='dry_run', default=False,
action='store_true',
help='Dry run: Make dirs and only print commands '
'to be run')
parser.add_argument('--srcdir', dest='srcdir', default='src/shaderc',
help='Shaderc source directory. Default "src/shaderc".')
parser.add_argument('--builddir', dest='builddir', default='out',
help='Build directory. Default is "out".')
parser.add_argument('--installdir', dest='installdir', required=True,
help='Installation directory. Required.')
parser.add_argument('--type', dest='buildtype', default='RelWithDebInfo',
help='Build type. Default is RelWithDebInfo')
arch = None
if (OS == 'Windows' or OS.startswith('CYGWIN')):
arch = 'windows-x86'
if OS == 'Linux':
arch = 'linux-x86'
if OS == 'Darwin':
arch = 'darwin-x86'
if arch is None:
raise RuntimeError('Unknown OS: %s' % OS)
path_default = os.pathsep.join([
os.path.join(os.getcwd(), 'prebuilts', 'cmake', arch, 'bin'),
os.path.join(os.getcwd(), 'prebuilts', 'ninja', arch),
os.path.join(os.getcwd(), 'prebuilts', 'python', arch, 'x64')])
parser.add_argument('--path', dest='path',
default=path_default,
help='Extra directories to prepend to the system path, '
'separated by your system\'s path delimiter (typically '
'":" or ";"). After prepending, path must contain '
'cmake, ninja, and python. On Cygwin, the native '
'Windows Python must come first. Default is %s.'
% path_default)
args = parser.parse_args()
if args.path:
os.environ['PATH'] = os.pathsep.join([args.path, os.getenv('PATH')])
if OS.startswith('CYGWIN'):
# Escape to Windows.
winargv = []
args_dict = vars(args)
for k in args_dict:
if k=='path' or k.endswith('dir'):
winargv.extend(['--%s' % k, cygpath(args_dict[k])])
elif k=='buildtype':
winargv.extend(['--type', args.buildtype])
elif k=='dry_run':
if args.dry_run:
winargv.append('-n')
else:
winargv.extend(['--%s' % k, args_dict[k]])
os.execlp('python', 'python', sys.argv[0], *winargv)
build(args)
if __name__ == '__main__':
main()