version 1.0.0
[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 optparse import OptionParser
17 import sys
18 import os
19 import glob
20 import errno
21 import shlex
22 import shutil
23 import subprocess
24
25 os.chdir(os.path.dirname(os.path.abspath(__file__)))
26
27 parser = OptionParser()
28 parser.add_option('--verbose', action='store_true',
29                   help='enable verbose build',)
30 parser.add_option('--x64', action='store_true',
31                   help='force 64-bit build (Windows)',)
32 (options, conf_args) = parser.parse_args()
33
34 def run(*args, **kwargs):
35     returncode = subprocess.call(*args, **kwargs)
36     if returncode != 0:
37         sys.exit(returncode)
38
39 # Compute system-specific CFLAGS/LDFLAGS as used in both in the below
40 # g++ call as well as in the later configure.py.
41 cflags = os.environ.get('CFLAGS', '').split()
42 ldflags = os.environ.get('LDFLAGS', '').split()
43 if sys.platform.startswith('freebsd'):
44     cflags.append('-I/usr/local/include')
45     ldflags.append('-L/usr/local/lib')
46
47 print 'Building ninja manually...'
48
49 try:
50     os.mkdir('build')
51 except OSError, e:
52     if e.errno != errno.EEXIST:
53         raise
54
55 sources = []
56 for src in glob.glob('src/*.cc'):
57     if src.endswith('test.cc') or src.endswith('.in.cc'):
58         continue
59     if src.endswith('bench.cc'):
60         continue
61
62     filename = os.path.basename(src)
63     if filename == 'browse.cc':  # Depends on generated header.
64         continue
65
66     if sys.platform.startswith('win32'):
67         if src.endswith('-posix.cc'):
68             continue
69     else:
70         if src.endswith('-win32.cc'):
71             continue
72
73     sources.append(src)
74
75 if sys.platform.startswith('win32'):
76     sources.append('src/getopt.c')
77
78 vcdir = os.environ.get('VCINSTALLDIR')
79 if vcdir:
80     if options.x64:
81         cl = [os.path.join(vcdir, 'bin', 'amd64', 'cl.exe')]
82     else:
83         cl = [os.path.join(vcdir, 'bin', 'cl.exe')]
84     args = cl + ['/nologo', '/EHsc', '/DNOMINMAX']
85 else:
86     args = shlex.split(os.environ.get('CXX', 'g++'))
87     cflags.extend(['-Wno-deprecated',
88                    '-DNINJA_PYTHON="' + sys.executable + '"',
89                    '-DNINJA_BOOTSTRAP'])
90     if sys.platform.startswith('win32'):
91         cflags.append('-D_WIN32_WINNT=0x0501')
92     if options.x64:
93         cflags.append('-m64')
94 args.extend(cflags)
95 args.extend(ldflags)
96 binary = 'ninja.bootstrap'
97 if sys.platform.startswith('win32'):
98     binary = 'ninja.bootstrap.exe'
99 args.extend(sources)
100 if vcdir:
101     args.extend(['/link', '/out:' + binary])
102 else:
103     args.extend(['-o', binary])
104
105 if options.verbose:
106     print ' '.join(args)
107
108 run(args)
109
110 verbose = []
111 if options.verbose:
112     verbose = ['-v']
113
114 if sys.platform.startswith('win32'):
115     print 'Building ninja using itself...'
116     run([sys.executable, 'configure.py', '--with-ninja=%s' % binary] +
117         conf_args)
118     run(['./' + binary] + verbose)
119
120     # Copy the new executable over the bootstrap one.
121     shutil.copyfile('ninja.exe', binary)
122
123     # Clean up.
124     for obj in glob.glob('*.obj'):
125         os.unlink(obj)
126
127     print """
128 Done!
129
130 Note: to work around Windows file locking, where you can't rebuild an
131 in-use binary, to run ninja after making any changes to build ninja itself
132 you should run ninja.bootstrap instead.  Your build is also configured to
133 use ninja.bootstrap.exe as the MSVC helper; see the --with-ninja flag of
134 the --help output of configure.py."""
135 else:
136     print 'Building ninja using itself...'
137     run([sys.executable, 'configure.py'] + conf_args)
138     run(['./' + binary] + verbose)
139     os.unlink(binary)
140     print 'Done!'