Merge pull request #917 from pinotree/rlimit
[platform/upstream/ninja.git] / configure.py
index b818bfc..661662f 100755 (executable)
@@ -27,12 +27,77 @@ import pipes
 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.
 
@@ -41,8 +106,9 @@ class Bootstrap:
     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.
@@ -98,8 +164,10 @@ class Bootstrap:
     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
 
@@ -108,14 +176,16 @@ parser = OptionParser()
 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',
@@ -133,9 +203,9 @@ if args:
     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
 
@@ -152,7 +222,7 @@ if options.bootstrap:
     # 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__) + '.')
@@ -214,6 +284,8 @@ if platform.is_msvc():
               '/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.
@@ -245,11 +317,22 @@ else:
         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():
@@ -267,12 +350,9 @@ else:
         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):
@@ -334,7 +414,7 @@ n.newline()
 
 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',
@@ -425,7 +505,6 @@ if options.bootstrap:
 
 n.comment('Tests all build into ninja_test executable.')
 
-test_libs = libs
 objs = []
 
 for name in ['build_log_test',
@@ -448,10 +527,8 @@ if platform.is_windows():
     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
 
@@ -539,6 +616,10 @@ n.build('all', 'phony', all_targets)
 n.close()
 print('wrote %s.' % BUILD_FILENAME)
 
+verbose = ''
+if options.verbose:
+    verbose = ' -v'
+
 if options.bootstrap:
     print('bootstrap complete.  rebuilding...')
     if platform.is_windows():
@@ -546,6 +627,6 @@ if options.bootstrap:
         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)