2 # Copyright 2011 Google Inc. All Rights Reserved.
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
16 from __future__ import print_function
18 from optparse import OptionParser
26 import platform_helper
28 os.chdir(os.path.dirname(os.path.abspath(__file__)))
30 parser = OptionParser()
32 parser.add_option('--verbose', action='store_true',
33 help='enable verbose build',)
34 parser.add_option('--x64', action='store_true',
35 help='force 64-bit build (Windows)',)
36 parser.add_option('--platform',
37 help='target platform (' +
38 '/'.join(platform_helper.platforms()) + ')',
39 choices=platform_helper.platforms())
40 parser.add_option('--force-pselect', action='store_true',
41 help='ppoll() is used by default where available, '
42 'but some platforms might need to use pselect instead',)
43 (options, conf_args) = parser.parse_args()
46 platform = platform_helper.Platform(options.platform)
47 conf_args.append("--platform=" + platform.platform())
49 def run(*args, **kwargs):
50 returncode = subprocess.call(*args, **kwargs)
54 # Compute system-specific CFLAGS/LDFLAGS as used in both in the below
55 # g++ call as well as in the later configure.py.
56 cflags = os.environ.get('CFLAGS', '').split()
57 ldflags = os.environ.get('LDFLAGS', '').split()
58 if platform.is_freebsd() or platform.is_openbsd() or platform.is_bitrig():
59 cflags.append('-I/usr/local/include')
60 ldflags.append('-L/usr/local/lib')
62 print('Building ninja manually...')
68 if e.errno != errno.EEXIST:
72 for src in glob.glob('src/*.cc'):
73 if src.endswith('test.cc') or src.endswith('.in.cc'):
75 if src.endswith('bench.cc'):
78 filename = os.path.basename(src)
79 if filename == 'browse.cc': # Depends on generated header.
82 if platform.is_windows():
83 if src.endswith('-posix.cc'):
86 if src.endswith('-win32.cc'):
91 if platform.is_windows():
92 sources.append('src/getopt.c')
94 if platform.is_msvc():
96 vcdir = os.environ.get('VCINSTALLDIR')
99 cl = os.path.join(vcdir, 'bin', 'x86_amd64', 'cl.exe')
100 if not os.path.exists(cl):
101 cl = os.path.join(vcdir, 'bin', 'amd64', 'cl.exe')
103 cl = os.path.join(vcdir, 'bin', 'cl.exe')
104 args = [cl, '/nologo', '/EHsc', '/DNOMINMAX']
106 args = shlex.split(os.environ.get('CXX', 'g++'))
107 cflags.extend(['-Wno-deprecated',
108 '-DNINJA_PYTHON="' + sys.executable + '"',
109 '-DNINJA_BOOTSTRAP'])
110 if platform.is_windows():
111 cflags.append('-D_WIN32_WINNT=0x0501')
113 cflags.append('-m64')
114 if (platform.is_linux() or platform.is_openbsd() or platform.is_bitrig()) and \
115 not options.force_pselect:
116 cflags.append('-DUSE_PPOLL')
117 if options.force_pselect:
118 conf_args.append("--force-pselect")
121 binary = 'ninja.bootstrap'
122 if platform.is_windows():
123 binary = 'ninja.bootstrap.exe'
125 if platform.is_msvc():
126 args.extend(['/link', '/out:' + binary])
128 args.extend(['-o', binary])
131 print(' '.join(args))
136 print('Failure running:', args)
143 if platform.is_windows():
144 print('Building ninja using itself...')
145 run([sys.executable, 'configure.py'] + conf_args)
146 run(['./' + binary] + verbose)
148 # Copy the new executable over the bootstrap one.
149 shutil.copyfile('ninja.exe', binary)
152 for obj in glob.glob('*.obj'):
158 Note: to work around Windows file locking, where you can't rebuild an
159 in-use binary, to run ninja after making any changes to build ninja
160 itself you should run ninja.bootstrap instead.""")
162 print('Building ninja using itself...')
163 run([sys.executable, 'configure.py'] + conf_args)
164 run(['./' + binary] + verbose)