Skip to content

Commit

Permalink
share platform support between configure/bootstrap
Browse files Browse the repository at this point in the history
  • Loading branch information
TheOneRing authored and evmar committed Apr 30, 2013
1 parent c0d2118 commit 4c552c2
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 55 deletions.
29 changes: 17 additions & 12 deletions bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,26 @@
import shlex
import shutil
import subprocess
import platform_helper

os.chdir(os.path.dirname(os.path.abspath(__file__)))

parser = OptionParser()

parser.add_option('--verbose', action='store_true',
help='enable verbose build',)
parser.add_option('--x64', action='store_true',
help='force 64-bit build (Windows)',)
# TODO: make this --platform to match configure.py.
parser.add_option('--windows', action='store_true',
help='force native Windows build',
default=sys.platform.startswith('win32'))
parser.add_option('--platform',
help='target platform (' + '/'.join(platform_helper.platforms()) + ')',
choices=platform_helper.platforms())
(options, conf_args) = parser.parse_args()


platform = platform_helper.Platform(options.platform)
conf_args.append("--platform=" + platform.platform())

def run(*args, **kwargs):
returncode = subprocess.call(*args, **kwargs)
if returncode != 0:
Expand All @@ -46,7 +52,7 @@ def run(*args, **kwargs):
# g++ call as well as in the later configure.py.
cflags = os.environ.get('CFLAGS', '').split()
ldflags = os.environ.get('LDFLAGS', '').split()
if sys.platform.startswith('freebsd'):
if platform.is_freebsd():
cflags.append('-I/usr/local/include')
ldflags.append('-L/usr/local/lib')

Expand All @@ -70,7 +76,7 @@ def run(*args, **kwargs):
if filename == 'browse.cc': # Depends on generated header.
continue

if options.windows:
if platform.is_windows():
if src.endswith('-posix.cc'):
continue
else:
Expand All @@ -79,10 +85,10 @@ def run(*args, **kwargs):

sources.append(src)

if options.windows:
if platform.is_windows():
sources.append('src/getopt.c')

if options.windows:
if platform.is_msvc():
cl = 'cl'
vcdir = os.environ.get('VCINSTALLDIR')
if vcdir:
Expand All @@ -98,18 +104,17 @@ def run(*args, **kwargs):
cflags.extend(['-Wno-deprecated',
'-DNINJA_PYTHON="' + sys.executable + '"',
'-DNINJA_BOOTSTRAP'])
if options.windows:
if platform.is_windows():
cflags.append('-D_WIN32_WINNT=0x0501')
conf_args.append("--platform=mingw")
if options.x64:
cflags.append('-m64')
args.extend(cflags)
args.extend(ldflags)
binary = 'ninja.bootstrap'
if options.windows:
if platform.is_windows():
binary = 'ninja.bootstrap.exe'
args.extend(sources)
if options.windows:
if platform.is_msvc():
args.extend(['/link', '/out:' + binary])
else:
args.extend(['-o', binary])
Expand All @@ -127,7 +132,7 @@ def run(*args, **kwargs):
if options.verbose:
verbose = ['-v']

if options.windows:
if platform.is_windows():
print('Building ninja using itself...')
run([sys.executable, 'configure.py'] + conf_args)
run(['./' + binary] + verbose)
Expand Down
77 changes: 34 additions & 43 deletions configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,19 @@
from optparse import OptionParser
import os
import sys
import platform_helper
sys.path.insert(0, 'misc')

import ninja_syntax

parser = OptionParser()
platforms = ['linux', 'freebsd', 'solaris', 'mingw', 'windows']
profilers = ['gmon', 'pprof']
parser.add_option('--platform',
help='target platform (' + '/'.join(platforms) + ')',
choices=platforms)
help='target platform (' + '/'.join(platform_helper.platforms()) + ')',
choices=platform_helper.platforms())
parser.add_option('--host',
help='host platform (' + '/'.join(platforms) + ')',
choices=platforms)
help='host platform (' + '/'.join(platform_helper.platforms()) + ')',
choices=platform_helper.platforms())
parser.add_option('--debug', action='store_true',
help='enable debugging extras',)
parser.add_option('--profile', metavar='TYPE',
Expand All @@ -52,20 +52,11 @@
print('ERROR: extra unparsed command-line arguments:', args)
sys.exit(1)

platform = options.platform
if platform is None:
platform = sys.platform
if platform.startswith('linux'):
platform = 'linux'
elif platform.startswith('freebsd'):
platform = 'freebsd'
elif platform.startswith('solaris'):
platform = 'solaris'
elif platform.startswith('mingw'):
platform = 'mingw'
elif platform.startswith('win'):
platform = 'windows'
host = options.host or platform
platform = platform_helper.Platform(options.platform)
if options.host:
host = platform_helper.Platform(options.host)
else:
host = platform

BUILD_FILENAME = 'build.ninja'
buildfile = open(BUILD_FILENAME, 'w')
Expand All @@ -85,7 +76,7 @@

CXX = configure_env.get('CXX', 'g++')
objext = '.o'
if platform == 'windows':
if platform.is_msvc():
CXX = 'cl'
objext = '.obj'

Expand All @@ -100,20 +91,20 @@ def cc(name, **kwargs):
def cxx(name, **kwargs):
return n.build(built(name + objext), 'cxx', src(name + '.cc'), **kwargs)
def binary(name):
if platform in ('mingw', 'windows'):
if platform.is_windows():
exe = name + '.exe'
n.build(name, 'phony', exe)
return exe
return name

n.variable('builddir', 'build')
n.variable('cxx', CXX)
if platform == 'windows':
if platform.is_msvc():
n.variable('ar', 'link')
else:
n.variable('ar', configure_env.get('AR', 'ar'))

if platform == 'windows':
if platform.is_msvc():
cflags = ['/nologo', # Don't print startup banner.
'/Zi', # Create pdb with debug info.
'/W4', # Highest warning level.
Expand Down Expand Up @@ -149,17 +140,17 @@ def binary(name):
cflags += ['-O2', '-DNDEBUG']
if 'clang' in os.path.basename(CXX):
cflags += ['-fcolor-diagnostics']
if platform == 'mingw':
if platform.is_mingw():
cflags += ['-D_WIN32_WINNT=0x0501']
ldflags = ['-L$builddir']
libs = []

if platform == 'mingw':
if platform.is_mingw():
cflags.remove('-fvisibility=hidden');
ldflags.append('-static')
elif platform == 'sunos5':
elif platform.is_sunos5():
cflags.remove('-fvisibility=hidden')
elif platform == 'windows':
elif platform.is_msvc():
pass
else:
if options.profile == 'gmon':
Expand All @@ -174,7 +165,7 @@ def shell_escape(str):
the shell."""

# This isn't complete, but it's just enough to make NINJA_PYTHON work.
if platform in ('windows', 'mingw'):
if platform.is_windows():
return str
if '"' in str:
return "'%s'" % str.replace("'", "\\'")
Expand All @@ -188,7 +179,7 @@ def shell_escape(str):
n.variable('ldflags', ' '.join(shell_escape(flag) for flag in ldflags))
n.newline()

if platform == 'windows':
if platform.is_msvc():
n.rule('cxx',
command='$cxx /showIncludes $cflags -c $in /Fo$out',
description='CXX $out',
Expand All @@ -201,11 +192,11 @@ def shell_escape(str):
description='CXX $out')
n.newline()

if host == 'windows':
if host.is_msvc():
n.rule('ar',
command='lib /nologo /ltcg /out:$out $in',
description='LIB $out')
elif host == 'mingw':
elif host.is_mingw():
n.rule('ar',
command='cmd /c $ar cqs $out.tmp $in && move /Y $out.tmp $out',
description='AR $out')
Expand All @@ -215,7 +206,7 @@ def shell_escape(str):
description='AR $out')
n.newline()

if platform == 'windows':
if platform.is_msvc():
n.rule('link',
command='$cxx $in $libs /nologo /link $ldflags /out:$out',
description='LINK $out')
Expand All @@ -227,7 +218,7 @@ def shell_escape(str):

objs = []

if platform not in ('solaris', 'mingw', 'windows'):
if not platform.is_windows() and not platform.is_solaris():
n.comment('browse_py.h is used to inline browse.py.')
n.rule('inline',
command='src/inline.sh $varname < $in > $out',
Expand Down Expand Up @@ -280,24 +271,24 @@ def has_re2c():
'util',
'version']:
objs += cxx(name)
if platform in ('mingw', 'windows'):
if platform.is_windows():
for name in ['subprocess-win32',
'includes_normalize-win32',
'msvc_helper-win32',
'msvc_helper_main-win32']:
objs += cxx(name)
if platform == 'windows':
if platform.is_msvc():
objs += cxx('minidump-win32')
objs += cc('getopt')
else:
objs += cxx('subprocess-posix')
if platform == 'windows':
if platform.is_msvc():
ninja_lib = n.build(built('ninja.lib'), 'ar', objs)
else:
ninja_lib = n.build(built('libninja.a'), 'ar', objs)
n.newline()

if platform == 'windows':
if platform.is_msvc():
libs.append('ninja.lib')
else:
libs.append('-lninja')
Expand All @@ -322,7 +313,7 @@ def has_re2c():
path = options.with_gtest

gtest_all_incs = '-I%s -I%s' % (path, os.path.join(path, 'include'))
if platform == 'windows':
if platform.is_msvc():
gtest_cflags = '/nologo /EHsc /Zi /D_VARIADIC_MAX=10 ' + gtest_all_incs
else:
gtest_cflags = '-fvisibility=hidden ' + gtest_all_incs
Expand All @@ -333,7 +324,7 @@ def has_re2c():
test_cflags.append('-I%s' % os.path.join(path, 'include'))
else:
# Use gtest from system.
if platform == 'windows':
if platform.is_msvc():
test_libs.extend(['gtest_main.lib', 'gtest.lib'])
else:
test_libs.extend(['-lgtest_main', '-lgtest'])
Expand All @@ -355,11 +346,11 @@ def has_re2c():
'test',
'util_test']:
objs += cxx(name, variables=[('cflags', '$test_cflags')])
if platform in ('windows', 'mingw'):
if platform.is_windows():
for name in ['includes_normalize_test', 'msvc_helper_test']:
objs += cxx(name, variables=[('cflags', test_cflags)])

if platform != 'mingw' and platform != 'windows':
if not platform.is_windows():
test_libs.append('-lpthread')
ninja_test = n.build(binary('ninja_test'), 'link', objs, implicit=ninja_lib,
variables=[('ldflags', test_ldflags),
Expand Down Expand Up @@ -422,7 +413,7 @@ def has_re2c():
implicit=mainpage)
n.newline()

if host != 'mingw':
if not host.is_mingw():
n.comment('Regenerate build files if build script changes.')
n.rule('configure',
command='${configure_env}%s configure.py $configure_args' %
Expand All @@ -435,7 +426,7 @@ def has_re2c():
n.default(ninja)
n.newline()

if host == 'linux':
if host.is_linux():
n.comment('Packaging')
n.rule('rpmbuild',
command="misc/packaging/rpmbuild.sh",
Expand Down
63 changes: 63 additions & 0 deletions platform_helper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#!/usr/bin/env python
# Copyright 2011 Google Inc.
# Copyright 2013 Patrick von Reth <[email protected]>
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import sys

def platforms():
return ['linux', 'freebsd', 'solaris', 'sunos5', 'mingw', 'msvc']

class Platform( object ):
def __init__( self, platform):
self._platform = platform
if not self._platform is 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('solaris'):
self._platform = 'solaris'
elif self._platform.startswith('mingw'):
self._platform = 'mingw'
elif self._platform.startswith('win'):
self._platform = 'msvc'


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 is_windows(self):
return self.is_mingw() or self.is_msvc()

def is_solaris(self):
return self._platform == 'solaris'

def is_freebsd(self):
return self._platform == 'freebsd'

def is_sunos5(self):
return self._platform == 'sunos5'

0 comments on commit 4c552c2

Please sign in to comment.