import string
import subprocess
import sys
-import platform_helper
-sys.path.insert(0, 'misc')
+sys.path.insert(0, 'misc')
import ninja_syntax
+class Platform(object):
+ """Represents a host/target platform and its specific build attributes."""
+ def __init__(self, platform):
+ self._platform = platform
+ if self._platform is not None:
+ return
+ self._platform = sys.platform
+ if self._platform.startswith('linux'):
+ self._platform = 'linux'
+ elif self._platform.startswith('freebsd'):
+ self._platform = 'freebsd'
+ elif self._platform.startswith('gnukfreebsd'):
+ self._platform = 'freebsd'
+ elif self._platform.startswith('openbsd'):
+ self._platform = 'openbsd'
+ elif self._platform.startswith('solaris') or self._platform == 'sunos5':
+ self._platform = 'solaris'
+ elif self._platform.startswith('mingw'):
+ self._platform = 'mingw'
+ elif self._platform.startswith('win'):
+ self._platform = 'msvc'
+ elif self._platform.startswith('bitrig'):
+ self._platform = 'bitrig'
+ elif self._platform.startswith('netbsd'):
+ self._platform = 'netbsd'
+
+ @staticmethod
+ def known_platforms():
+ return ['linux', 'darwin', 'freebsd', 'openbsd', 'solaris', 'sunos5',
+ 'mingw', 'msvc', 'gnukfreebsd', 'bitrig', 'netbsd']
+
+ def platform(self):
+ return self._platform
+
+ def is_linux(self):
+ return self._platform == 'linux'
+
+ def is_mingw(self):
+ return self._platform == 'mingw'
+
+ def is_msvc(self):
+ return self._platform == 'msvc'
+
+ def msvc_needs_fs(self):
+ popen = subprocess.Popen(['cl', '/nologo', '/?'],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ out, err = popen.communicate()
+ return '/FS ' in str(out)
+
+ def is_windows(self):
+ return self.is_mingw() or self.is_msvc()
+
+ def is_solaris(self):
+ return self._platform == 'solaris'
+
+ def uses_usr_local(self):
+ return self._platform in ('freebsd', 'openbsd', 'bitrig')
+
+ def supports_ppoll(self):
+ return self._platform in ('linux', 'openbsd', 'bitrig')
+
+ def supports_ninja_browse(self):
+ return not self.is_windows() and not self.is_solaris()
+
+
class Bootstrap:
"""API shim for ninja_syntax.Writer that instead runs the commands.
It also proxies all calls to an underlying ninja_syntax.Writer, to
behave like non-bootstrap mode.
"""
- def __init__(self, writer):
+ def __init__(self, writer, verbose=False):
self.writer = writer
+ self.verbose = verbose
# Map of variable name => expanded variable value.
self.vars = {}
# Map of rule name => dict of rule attributes.
def _run_command(self, cmdline):
"""Run a subcommand, quietly. Prints the full command on error."""
try:
+ if self.verbose:
+ print(cmdline)
subprocess.check_call(cmdline, shell=True)
- except subprocess.CalledProcessError, e:
+ except subprocess.CalledProcessError:
print('when running: ', cmdline)
raise
profilers = ['gmon', 'pprof']
parser.add_option('--bootstrap', action='store_true',
help='bootstrap a ninja binary from nothing')
+parser.add_option('--verbose', action='store_true',
+ help='enable verbose build')
parser.add_option('--platform',
help='target platform (' +
- '/'.join(platform_helper.platforms()) + ')',
- choices=platform_helper.platforms())
+ '/'.join(Platform.known_platforms()) + ')',
+ choices=Platform.known_platforms())
parser.add_option('--host',
help='host platform (' +
- '/'.join(platform_helper.platforms()) + ')',
- choices=platform_helper.platforms())
+ '/'.join(Platform.known_platforms()) + ')',
+ choices=Platform.known_platforms())
parser.add_option('--debug', action='store_true',
help='enable debugging extras',)
parser.add_option('--profile', metavar='TYPE',
print('ERROR: extra unparsed command-line arguments:', args)
sys.exit(1)
-platform = platform_helper.Platform(options.platform)
+platform = Platform(options.platform)
if options.host:
- host = platform_helper.Platform(options.host)
+ host = Platform(options.host)
else:
host = platform
# Wrap ninja_writer with the Bootstrapper, which also executes the
# commands.
print('bootstrapping ninja...')
- n = Bootstrap(n)
+ n = Bootstrap(n, verbose=options.verbose)
n.comment('This file is used to build ninja itself.')
n.comment('It is generated by ' + os.path.basename(__file__) + '.')
'/wd4512', '/wd4800', '/wd4702', '/wd4819',
# Disable warnings about passing "this" during initialization.
'/wd4355',
+ # Disable warnings about ignored typedef in DbgHelp.h
+ '/wd4091',
'/GR-', # Disable RTTI.
# Disable size_t -> int truncation warning.
# We never have strings or arrays larger than 2**31.
cflags.remove('-fno-rtti') # Needed for above pedanticness.
else:
cflags += ['-O2', '-DNDEBUG']
- if 'clang' in os.path.basename(CXX):
- cflags += ['-fcolor-diagnostics']
+ try:
+ proc = subprocess.Popen(
+ [CXX, '-fdiagnostics-color', '-c', '-x', 'c++', '/dev/null'],
+ stdout=open(os.devnull, 'wb'), stderr=subprocess.STDOUT)
+ proc.wait()
+ if proc.returncode == 0:
+ cflags += ['-fdiagnostics-color']
+ except:
+ pass
if platform.is_mingw():
cflags += ['-D_WIN32_WINNT=0x0501']
ldflags = ['-L$builddir']
+ if platform.uses_usr_local():
+ cflags.append('-I/usr/local/include')
+ ldflags.append('-L/usr/local/lib')
+
libs = []
if platform.is_mingw():
cflags.append('-fno-omit-frame-pointer')
libs.extend(['-Wl,--no-as-needed', '-lprofiler'])
-if (platform.is_linux() or platform.is_openbsd() or platform.is_bitrig()) and \
- not options.force_pselect:
+if platform.supports_ppoll() and not options.force_pselect:
cflags.append('-DUSE_PPOLL')
-
-have_browse = not platform.is_windows() and not platform.is_solaris()
-if have_browse:
+if platform.supports_ninja_browse():
cflags.append('-DNINJA_HAVE_BROWSE')
def shell_escape(str):
objs = []
-if have_browse:
+if platform.supports_ninja_browse():
n.comment('browse_py.h is used to inline browse.py.')
n.rule('inline',
command='src/inline.sh $varname < $in > $out',
n.comment('Tests all build into ninja_test executable.')
-test_libs = libs
objs = []
for name in ['build_log_test',
for name in ['includes_normalize_test', 'msvc_helper_test']:
objs += cxx(name)
-if not platform.is_windows():
- test_libs.append('-lpthread')
ninja_test = n.build(binary('ninja_test'), 'link', objs, implicit=ninja_lib,
- variables=[('libs', test_libs)])
+ variables=[('libs', libs)])
n.newline()
all_targets += ninja_test
n.close()
print('wrote %s.' % BUILD_FILENAME)
+verbose = ''
+if options.verbose:
+ verbose = ' -v'
+
if options.bootstrap:
print('bootstrap complete. rebuilding...')
if platform.is_windows():
if os.path.exists(bootstrap_exe):
os.unlink(bootstrap_exe)
os.rename('ninja.exe', bootstrap_exe)
- subprocess.check_call('ninja.bootstrap.exe', shell=True)
+ subprocess.check_call('ninja.bootstrap.exe%s' % verbose, shell=True)
else:
- subprocess.check_call('./ninja', shell=True)
+ subprocess.check_call('./ninja%s' % verbose, shell=True)