| #!/usr/bin/env python |
| # Copyright 2011 Google Inc. 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. |
| |
| from __future__ import print_function |
| |
| from optparse import OptionParser |
| import sys |
| import os |
| import glob |
| import errno |
| import shlex |
| import shutil |
| import subprocess |
| import platform_helper |
| |
| os.chdir(os.path.dirname(os.path.abspath(__file__))) |
| |
| parser = OptionParser() |
| |
| parser.add_option('--verbose', action='store_true', |
| help='enable verbose build',) |
| parser.add_option('--x64', action='store_true', |
| help='force 64-bit build (Windows)',) |
| parser.add_option('--platform', |
| help='target platform (' + '/'.join(platform_helper.platforms()) + ')', |
| choices=platform_helper.platforms()) |
| parser.add_option('--force-pselect', action='store_true', |
| help="ppoll() is used by default on Linux and OpenBSD, but older versions might need to use pselect instead",) |
| (options, conf_args) = parser.parse_args() |
| |
| |
| platform = platform_helper.Platform(options.platform) |
| conf_args.append("--platform=" + platform.platform()) |
| |
| def run(*args, **kwargs): |
| returncode = subprocess.call(*args, **kwargs) |
| if returncode != 0: |
| sys.exit(returncode) |
| |
| # Compute system-specific CFLAGS/LDFLAGS as used in both in the below |
| # g++ call as well as in the later configure.py. |
| cflags = os.environ.get('CFLAGS', '').split() |
| ldflags = os.environ.get('LDFLAGS', '').split() |
| if platform.is_freebsd() or platform.is_openbsd(): |
| cflags.append('-I/usr/local/include') |
| ldflags.append('-L/usr/local/lib') |
| |
| print('Building ninja manually...') |
| |
| try: |
| os.mkdir('build') |
| except OSError: |
| e = sys.exc_info()[1] |
| if e.errno != errno.EEXIST: |
| raise |
| |
| sources = [] |
| for src in glob.glob('src/*.cc'): |
| if src.endswith('test.cc') or src.endswith('.in.cc'): |
| continue |
| if src.endswith('bench.cc'): |
| continue |
| |
| filename = os.path.basename(src) |
| if filename == 'browse.cc': # Depends on generated header. |
| continue |
| |
| if platform.is_windows(): |
| if src.endswith('-posix.cc'): |
| continue |
| else: |
| if src.endswith('-win32.cc'): |
| continue |
| |
| sources.append(src) |
| |
| if platform.is_windows(): |
| sources.append('src/getopt.c') |
| |
| if platform.is_msvc(): |
| cl = 'cl' |
| vcdir = os.environ.get('VCINSTALLDIR') |
| if vcdir: |
| if options.x64: |
| cl = os.path.join(vcdir, 'bin', 'x86_amd64', 'cl.exe') |
| if not os.path.exists(cl): |
| cl = os.path.join(vcdir, 'bin', 'amd64', 'cl.exe') |
| else: |
| cl = os.path.join(vcdir, 'bin', 'cl.exe') |
| args = [cl, '/nologo', '/EHsc', '/DNOMINMAX'] |
| else: |
| args = shlex.split(os.environ.get('CXX', 'g++')) |
| cflags.extend(['-Wno-deprecated', |
| '-DNINJA_PYTHON="' + sys.executable + '"', |
| '-DNINJA_BOOTSTRAP']) |
| if platform.is_windows(): |
| cflags.append('-D_WIN32_WINNT=0x0501') |
| if options.x64: |
| cflags.append('-m64') |
| if (platform.is_linux() or platform.is_openbsd()) and not options.force_pselect: |
| cflags.append('-DUSE_PPOLL') |
| if options.force_pselect: |
| conf_args.append("--force-pselect") |
| args.extend(cflags) |
| args.extend(ldflags) |
| binary = 'ninja.bootstrap' |
| if platform.is_windows(): |
| binary = 'ninja.bootstrap.exe' |
| args.extend(sources) |
| if platform.is_msvc(): |
| args.extend(['/link', '/out:' + binary]) |
| else: |
| args.extend(['-o', binary]) |
| |
| if options.verbose: |
| print(' '.join(args)) |
| |
| try: |
| run(args) |
| except: |
| print('Failure running:', args) |
| raise |
| |
| verbose = [] |
| if options.verbose: |
| verbose = ['-v'] |
| |
| if platform.is_windows(): |
| print('Building ninja using itself...') |
| run([sys.executable, 'configure.py'] + conf_args) |
| run(['./' + binary] + verbose) |
| |
| # Copy the new executable over the bootstrap one. |
| shutil.copyfile('ninja.exe', binary) |
| |
| # Clean up. |
| for obj in glob.glob('*.obj'): |
| os.unlink(obj) |
| |
| print(""" |
| Done! |
| |
| Note: to work around Windows file locking, where you can't rebuild an |
| in-use binary, to run ninja after making any changes to build ninja itself |
| you should run ninja.bootstrap instead.""") |
| else: |
| print('Building ninja using itself...') |
| run([sys.executable, 'configure.py'] + conf_args) |
| run(['./' + binary] + verbose) |
| os.unlink(binary) |
| print('Done!') |