Wrap to 79 colums. No functionality change.
[platform/upstream/ninja.git] / bootstrap.py
1 #!/usr/bin/env python
2 # Copyright 2011 Google Inc. All Rights Reserved.
3 #
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
7 #
8 #     http://www.apache.org/licenses/LICENSE-2.0
9 #
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.
15
16 from __future__ import print_function
17
18 from optparse import OptionParser
19 import sys
20 import os
21 import glob
22 import errno
23 import shlex
24 import shutil
25 import subprocess
26 import platform_helper
27
28 os.chdir(os.path.dirname(os.path.abspath(__file__)))
29
30 parser = OptionParser()
31
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()
44
45
46 platform = platform_helper.Platform(options.platform)
47 conf_args.append("--platform=" + platform.platform())
48
49 def run(*args, **kwargs):
50     returncode = subprocess.call(*args, **kwargs)
51     if returncode != 0:
52         sys.exit(returncode)
53
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')
61
62 print('Building ninja manually...')
63
64 try:
65     os.mkdir('build')
66 except OSError:
67     e = sys.exc_info()[1]
68     if e.errno != errno.EEXIST:
69         raise
70
71 sources = []
72 for src in glob.glob('src/*.cc'):
73     if src.endswith('test.cc') or src.endswith('.in.cc'):
74         continue
75     if src.endswith('bench.cc'):
76         continue
77
78     filename = os.path.basename(src)
79     if filename == 'browse.cc':  # Depends on generated header.
80         continue
81
82     if platform.is_windows():
83         if src.endswith('-posix.cc'):
84             continue
85     else:
86         if src.endswith('-win32.cc'):
87             continue
88
89     sources.append(src)
90
91 if platform.is_windows():
92     sources.append('src/getopt.c')
93
94 if platform.is_msvc():
95     cl = 'cl'
96     vcdir = os.environ.get('VCINSTALLDIR')
97     if vcdir:
98         if options.x64:
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')
102         else:
103             cl = os.path.join(vcdir, 'bin', 'cl.exe')
104     args = [cl, '/nologo', '/EHsc', '/DNOMINMAX']
105 else:
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')
112     if options.x64:
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")
119 args.extend(cflags)
120 args.extend(ldflags)
121 binary = 'ninja.bootstrap'
122 if platform.is_windows():
123     binary = 'ninja.bootstrap.exe'
124 args.extend(sources)
125 if platform.is_msvc():
126     args.extend(['/link', '/out:' + binary])
127 else:
128     args.extend(['-o', binary])
129
130 if options.verbose:
131     print(' '.join(args))
132
133 try:
134     run(args)
135 except:
136     print('Failure running:', args)
137     raise
138
139 verbose = []
140 if options.verbose:
141     verbose = ['-v']
142
143 if platform.is_windows():
144     print('Building ninja using itself...')
145     run([sys.executable, 'configure.py'] + conf_args)
146     run(['./' + binary] + verbose)
147
148     # Copy the new executable over the bootstrap one.
149     shutil.copyfile('ninja.exe', binary)
150
151     # Clean up.
152     for obj in glob.glob('*.obj'):
153         os.unlink(obj)
154
155     print("""
156 Done!
157
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.""")
161 else:
162     print('Building ninja using itself...')
163     run([sys.executable, 'configure.py'] + conf_args)
164     run(['./' + binary] + verbose)
165     os.unlink(binary)
166     print('Done!')