diff options
Diffstat (limited to 'configure.py')
-rwxr-xr-x | configure.py | 115 |
1 files changed, 86 insertions, 29 deletions
diff --git a/configure.py b/configure.py index 9c9d108..e52262d 100755 --- a/configure.py +++ b/configure.py @@ -36,7 +36,7 @@ parser.add_option('--host', help='host platform (' + '/'.join(platforms) + ')', choices=platforms) parser.add_option('--debug', action='store_true', - help='enable debugging flags',) + help='enable debugging extras',) parser.add_option('--profile', metavar='TYPE', choices=profilers, help='enable profiling (' + '/'.join(profilers) + ')',) @@ -72,10 +72,17 @@ n.newline() n.comment('The arguments passed to configure.py, for rerunning it.') n.variable('configure_args', ' '.join(sys.argv[1:])) +env_keys = set(['CXX', 'AR', 'CFLAGS', 'LDFLAGS']) +configure_env = dict((k, os.environ[k]) for k in os.environ if k in env_keys) +if configure_env: + config_str = ' '.join([k + '=' + configure_env[k] for k in configure_env]) + n.variable('configure_env', config_str + '$ ') n.newline() +CXX = configure_env.get('CXX', 'g++') objext = '.o' if platform == 'windows': + CXX = 'cl' objext = '.obj' def src(filename): @@ -94,18 +101,17 @@ def binary(name): return name n.variable('builddir', 'build') +n.variable('cxx', CXX) if platform == 'windows': - n.variable('cxx', 'cl') n.variable('ar', 'link') else: - n.variable('cxx', os.environ.get('CXX', 'g++')) - n.variable('ar', os.environ.get('AR', 'ar')) + n.variable('ar', configure_env.get('AR', 'ar')) if platform == 'windows': cflags = ['/nologo', '/Zi', '/W4', '/WX', '/wd4530', '/wd4100', '/wd4706', - '/wd4512', '/wd4800', '/wd4702', '/wd4819', - '/D_CRT_SECURE_NO_WARNINGS', - "/DNINJA_PYTHON=\"%s\"" % (options.with_python,)] + '/wd4512', '/wd4800', '/wd4702', '/wd4819', '/GR-', + '/DNOMINMAX', '/D_CRT_SECURE_NO_WARNINGS', + '/DNINJA_PYTHON="%s"' % options.with_python] ldflags = ['/DEBUG', '/libpath:$builddir'] if not options.debug: cflags += ['/Ox', '/DNDEBUG', '/GL'] @@ -117,11 +123,15 @@ else: '-fno-rtti', '-fno-exceptions', '-fvisibility=hidden', '-pipe', - "'-DNINJA_PYTHON=\"%s\"'" % (options.with_python,)] + '-DNINJA_PYTHON="%s"' % options.with_python] if options.debug: cflags += ['-D_GLIBCXX_DEBUG', '-D_GLIBCXX_DEBUG_PEDANTIC'] else: cflags += ['-O2', '-DNDEBUG'] + if 'clang' in os.path.basename(CXX): + cflags += ['-fcolor-diagnostics'] + if platform == 'mingw': + cflags += ['-D_WIN32_WINNT=0x0501'] ldflags = ['-L$builddir'] libs = [] @@ -139,12 +149,21 @@ else: elif options.profile == 'pprof': libs.append('-lprofiler') -if 'CFLAGS' in os.environ: - cflags.append(os.environ['CFLAGS']) -n.variable('cflags', ' '.join(cflags)) -if 'LDFLAGS' in os.environ: - ldflags.append(os.environ['LDFLAGS']) -n.variable('ldflags', ' '.join(ldflags)) +def shell_escape(str): + """Escape str such that it's interpreted as a single argument by the shell.""" + # This isn't complete, but it's just enough to make NINJA_PYTHON work. + if platform in ('windows', 'mingw'): + return str + if '"' in str: + return "'%s'" % str.replace("'", "\\'") + return str + +if 'CFLAGS' in configure_env: + cflags.append(configure_env['CFLAGS']) +n.variable('cflags', ' '.join(shell_escape(flag) for flag in cflags)) +if 'LDFLAGS' in configure_env: + ldflags.append(configure_env['LDFLAGS']) +n.variable('ldflags', ' '.join(shell_escape(flag) for flag in ldflags)) n.newline() if platform == 'windows': @@ -154,7 +173,7 @@ if platform == 'windows': description='CXX $out') else: n.rule('cxx', - command='$cxx -MMD -MF $out.d $cflags -c $in -o $out', + command='$cxx -MMD -MT $out -MF $out.d $cflags -c $in -o $out', depfile='$out.d', description='CXX $out') n.newline() @@ -215,11 +234,12 @@ for name in ['build', 'disk_interface', 'edit_distance', 'eval_env', + 'explain', 'graph', 'graphviz', 'lexer', + 'manifest_parser', 'metrics', - 'parsers', 'state', 'util']: objs += cxx(name) @@ -245,6 +265,8 @@ n.comment('Main executable is library plus main() function.') objs = cxx('ninja') ninja = n.build(binary('ninja'), 'link', objs, implicit=ninja_lib, variables=[('libs', libs)]) +if 'ninja' not in ninja: + n.build('ninja', 'phony', ninja) n.newline() all_targets += ninja @@ -259,15 +281,19 @@ if options.with_gtest: path = options.with_gtest gtest_all_incs = '-I%s -I%s' % (path, os.path.join(path, 'include')) - gtest_cflags = '-fvisibility=hidden ' + gtest_all_incs - objs += n.build(built('gtest-all.o'), 'cxx', + if platform == 'windows': + gtest_cflags = '/nologo /EHsc ' + gtest_all_incs + else: + gtest_cflags = '-fvisibility=hidden ' + gtest_all_incs + objs += n.build(built('gtest-all' + objext), 'cxx', os.path.join(path, 'src/gtest-all.cc'), variables=[('cflags', gtest_cflags)]) - objs += n.build(built('gtest_main.o'), 'cxx', + objs += n.build(built('gtest_main' + objext), 'cxx', os.path.join(path, 'src/gtest_main.cc'), variables=[('cflags', gtest_cflags)]) - test_cflags = cflags + ['-I%s' % os.path.join(path, 'include')] + test_cflags = cflags + ['-DGTEST_HAS_RTTI=0', + '-I%s' % os.path.join(path, 'include')] elif platform == 'windows': test_libs.extend(['gtest_main.lib', 'gtest.lib']) else: @@ -281,7 +307,7 @@ for name in ['build_log_test', 'edit_distance_test', 'graph_test', 'lexer_test', - 'parsers_test', + 'manifest_parser_test', 'state_test', 'subprocess_test', 'test', @@ -293,16 +319,26 @@ if platform != 'mingw' and platform != 'windows': ninja_test = n.build(binary('ninja_test'), 'link', objs, implicit=ninja_lib, variables=[('ldflags', test_ldflags), ('libs', test_libs)]) +if 'ninja_test' not in ninja_test: + n.build('ninja_test', 'phony', ninja_test) n.newline() all_targets += ninja_test -n.comment('Perftest executable.') + +n.comment('Ancilliary executables.') objs = cxx('parser_perftest') -parser_perftest = n.build(binary('parser_perftest'), 'link', objs, - implicit=ninja_lib, - variables=[('libs', '-L$builddir -lninja')]) +all_targets += n.build(binary('parser_perftest'), 'link', objs, + implicit=ninja_lib, variables=[('libs', libs)]) +objs = cxx('build_log_perftest') +all_targets += n.build(binary('build_log_perftest'), 'link', objs, + implicit=ninja_lib, variables=[('libs', libs)]) +objs = cxx('canon_perftest') +all_targets += n.build(binary('canon_perftest'), 'link', objs, + implicit=ninja_lib, variables=[('libs', libs)]) +objs = cxx('hash_collision_bench') +all_targets += n.build(binary('hash_collision_bench'), 'link', objs, + implicit=ninja_lib, variables=[('libs', libs)]) n.newline() -all_targets += parser_perftest n.comment('Generate a graph using the "graph" tool.') n.rule('gendot', @@ -315,7 +351,7 @@ n.newline() n.comment('Generate the manual using asciidoc.') n.rule('asciidoc', - command='asciidoc -a toc -o $out $in', + command='asciidoc -a toc -a max-width=45em -o $out $in', description='ASCIIDOC $in') manual = n.build(doc('manual.html'), 'asciidoc', doc('manual.asciidoc')) n.build('manual', 'phony', @@ -341,16 +377,37 @@ n.newline() if host != 'mingw': n.comment('Regenerate build files if build script changes.') n.rule('configure', - command=options.with_python + ' configure.py $configure_args', + command='${configure_env}%s configure.py $configure_args' % + options.with_python, generator=True) n.build('build.ninja', 'configure', - implicit=['configure.py', 'misc/ninja_syntax.py']) + implicit=['configure.py', os.path.normpath('misc/ninja_syntax.py')]) n.newline() n.comment('Build only the main binary by default.') n.default(ninja) n.newline() +if host == 'linux': + n.comment('Packaging') + n.rule('rpmbuild', + command="rpmbuild \ + --define 'ver git' \ + --define \"rel `git rev-parse --short HEAD`\" \ + --define '_topdir %(pwd)/rpm-build' \ + --define '_builddir %{_topdir}' \ + --define '_rpmdir %{_topdir}' \ + --define '_srcrpmdir %{_topdir}' \ + --define '_rpmfilename %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm' \ + --define '_specdir %{_topdir}' \ + --define '_sourcedir %{_topdir}' \ + --quiet \ + -bb misc/packaging/ninja.spec", + description='Building RPM..') + n.build('rpm', 'rpmbuild', + implicit=['ninja','README', 'COPYING', doc('manual.html')]) + n.newline() + n.build('all', 'phony', all_targets) print 'wrote %s.' % BUILD_FILENAME |