#!/usr/bin/env python
#
# Copyright 2001 Google Inc. 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.

"""Script that generates the build.ninja for ninja itself.

Projects that use ninja themselves should either write a similar script
or use a meta-build system that supports Ninja output."""

from __future__ import print_function

from optparse import OptionParser
import os
import pipes
import string
import subprocess
import sys

sourcedir = os.path.dirname(os.path.realpath(__file__))
sys.path.insert(0, os.path.join(sourcedir, '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'
        elif self._platform.startswith('aix'):
            self._platform = 'aix'

    @staticmethod
    def known_platforms():
      return ['linux', 'darwin', 'freebsd', 'openbsd', 'solaris', 'sunos5',
              'mingw', 'msvc', 'gnukfreebsd', 'bitrig', 'netbsd', 'aix']

    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 b'/FS' in out

    def is_windows(self):
        return self.is_mingw() or self.is_msvc()

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

    def is_aix(self):
        return self._platform == 'aix'

    def uses_usr_local(self):
        return self._platform in ('freebsd', 'openbsd', 'bitrig')

    def supports_ppoll(self):
        return self._platform in ('freebsd', 'linux', 'openbsd', 'bitrig')

    def supports_ninja_browse(self):
        return (not self.is_windows()
                and not self.is_solaris()
                and not self.is_aix())

    def can_rebuild_in_place(self):
        return not (self.is_windows() or self.is_aix())

class Bootstrap:
    """API shim for ninja_syntax.Writer that instead runs the commands.

    Used to bootstrap Ninja from scratch.  In --bootstrap mode this
    class is used to execute all the commands to build an executable.
    It also proxies all calls to an underlying ninja_syntax.Writer, to
    behave like non-bootstrap mode.
    """
    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.
        self.rules = {
            'phony': {}
        }

    def comment(self, text):
        return self.writer.comment(text)

    def newline(self):
        return self.writer.newline()

    def variable(self, key, val):
        # In bootstrap mode, we have no ninja process to catch /showIncludes
        # output.
        self.vars[key] = self._expand(val).replace('/showIncludes', '')
        return self.writer.variable(key, val)

    def rule(self, name, **kwargs):
        self.rules[name] = kwargs
        return self.writer.rule(name, **kwargs)

    def build(self, outputs, rule, inputs=None, **kwargs):
        ruleattr = self.rules[rule]
        cmd = ruleattr.get('command')
        if cmd is None:  # A phony rule, for example.
            return

        # Implement just enough of Ninja variable expansion etc. to
        # make the bootstrap build work.
        local_vars = {
            'in': self._expand_paths(inputs),
            'out': self._expand_paths(outputs)
        }
        for key, val in kwargs.get('variables', []):
            local_vars[key] = ' '.join(ninja_syntax.as_list(val))

        self._run_command(self._expand(cmd, local_vars))

        return self.writer.build(outputs, rule, inputs, **kwargs)

    def default(self, paths):
        return self.writer.default(paths)

    def _expand_paths(self, paths):
        """Expand $vars in an array of paths, e.g. from a 'build' block."""
        paths = ninja_syntax.as_list(paths)
        return ' '.join(map(self._shell_escape, (map(self._expand, paths))))

    def _expand(self, str, local_vars={}):
        """Expand $vars in a string."""
        return ninja_syntax.expand(str, self.vars, local_vars)

    def _shell_escape(self, path):
        """Quote paths containing spaces."""
        return '"%s"' % path if ' ' in path else path

    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:
            print('when running: ', cmdline)
            raise


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.known_platforms()) + ')',
                  choices=Platform.known_platforms())
parser.add_option('--host',
                  help='host platform (' +
                       '/'.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',
                  choices=profilers,
                  help='enable profiling (' + '/'.join(profilers) + ')',)
parser.add_option('--with-gtest', metavar='PATH', help='ignored')
parser.add_option('--with-python', metavar='EXE',
                  help='use EXE as the Python interpreter',
                  default=os.path.basename(sys.executable))
parser.add_option('--force-pselect', action='store_true',
                  help='ppoll() is used by default where available, '
                       'but some platforms may need to use pselect instead',)
(options, args) = parser.parse_args()
if args:
    print('ERROR: extra unparsed command-line arguments:', args)
    sys.exit(1)

platform = Platform(options.platform)
if options.host:
    host = Platform(options.host)
else:
    host = platform

BUILD_FILENAME = 'build.ninja'
ninja_writer = ninja_syntax.Writer(open(BUILD_FILENAME, 'w'))
n = ninja_writer

if options.bootstrap:
    # Make the build directory.
    try:
        os.mkdir('build')
    except OSError:
        pass
    # Wrap ninja_writer with the Bootstrapper, which also executes the
    # commands.
    print('bootstrapping ninja...')
    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__) + '.')
n.newline()

n.variable('ninja_required_version', '1.3')
n.newline()

n.comment('The arguments passed to configure.py, for rerunning it.')
configure_args = sys.argv[1:]
if '--bootstrap' in configure_args:
    configure_args.remove('--bootstrap')
n.variable('configure_args', ' '.join(configure_args))
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 + '=' + pipes.quote(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.is_msvc():
    CXX = 'cl'
    objext = '.obj'

def src(filename):
    return os.path.join('$root', 'src', filename)
def built(filename):
    return os.path.join('$builddir', filename)
def doc(filename):
    return os.path.join('$root', 'doc', filename)
def cc(name, **kwargs):
    return n.build(built(name + objext), 'cxx', src(name + '.c'), **kwargs)
def cxx(name, **kwargs):
    return n.build(built(name + objext), 'cxx', src(name + '.cc'), **kwargs)
def binary(name):
    if platform.is_windows():
        exe = name + '.exe'
        n.build(name, 'phony', exe)
        return exe
    return name

root = sourcedir
if root == os.getcwd():
    # In the common case where we're building directly in the source
    # tree, simplify all the paths to just be cwd-relative.
    root = '.'
n.variable('root', root)
n.variable('builddir', 'build')
n.variable('cxx', CXX)
if platform.is_msvc():
    n.variable('ar', 'link')
else:
    n.variable('ar', configure_env.get('AR', 'ar'))

if platform.is_msvc():
    cflags = ['/showIncludes',
              '/nologo',  # Don't print startup banner.
              '/Zi',  # Create pdb with debug info.
              '/W4',  # Highest warning level.
              '/WX',  # Warnings as errors.
              '/wd4530', '/wd4100', '/wd4706',
              '/wd4512', '/wd4800', '/wd4702', '/wd4819',
              # Disable warnings about constant conditional expressions.
              '/wd4127',
              # 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.
              '/wd4267',
              '/DNOMINMAX', '/D_CRT_SECURE_NO_WARNINGS',
              '/D_HAS_EXCEPTIONS=0',
              '/DNINJA_PYTHON="%s"' % options.with_python]
    if platform.msvc_needs_fs():
        cflags.append('/FS')
    ldflags = ['/DEBUG', '/libpath:$builddir']
    if not options.debug:
        cflags += ['/Ox', '/DNDEBUG', '/GL']
        ldflags += ['/LTCG', '/OPT:REF', '/OPT:ICF']
else:
    cflags = ['-g', '-Wall', '-Wextra',
              '-Wno-deprecated',
              '-Wno-missing-field-initializers',
              '-Wno-unused-parameter',
              '-fno-rtti',
              '-fno-exceptions',
              '-fvisibility=hidden', '-pipe',
              '-DNINJA_PYTHON="%s"' % options.with_python]
    if options.debug:
        cflags += ['-D_GLIBCXX_DEBUG', '-D_GLIBCXX_DEBUG_PEDANTIC']
        cflags.remove('-fno-rtti')  # Needed for above pedanticness.
    else:
        cflags += ['-O2', '-DNDEBUG']
    try:
        proc = subprocess.Popen(
            [CXX, '-fdiagnostics-color', '-c', '-x', 'c++', '/dev/null',
             '-o', '/dev/null'],
            stdout=open(os.devnull, 'wb'), stderr=subprocess.STDOUT)
        if proc.wait() == 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.remove('-fvisibility=hidden');
    ldflags.append('-static')
elif platform.is_solaris():
    cflags.remove('-fvisibility=hidden')
elif platform.is_aix():
    cflags.remove('-fvisibility=hidden')
elif platform.is_msvc():
    pass
else:
    if options.profile == 'gmon':
        cflags.append('-pg')
        ldflags.append('-pg')
    elif options.profile == 'pprof':
        cflags.append('-fno-omit-frame-pointer')
        libs.extend(['-Wl,--no-as-needed', '-lprofiler'])

if platform.supports_ppoll() and not options.force_pselect:
    cflags.append('-DUSE_PPOLL')
if platform.supports_ninja_browse():
    cflags.append('-DNINJA_HAVE_BROWSE')

# Search for generated headers relative to build dir.
cflags.append('-I.')

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.is_windows():
      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.is_msvc():
    n.rule('cxx',
        command='$cxx $cflags -c $in /Fo$out',
        description='CXX $out',
        deps='msvc'  # /showIncludes is included in $cflags.
    )
else:
    n.rule('cxx',
        command='$cxx -MMD -MT $out -MF $out.d $cflags -c $in -o $out',
        depfile='$out.d',
        deps='gcc',
        description='CXX $out')
n.newline()

if host.is_msvc():
    n.rule('ar',
           command='lib /nologo /ltcg /out:$out $in',
           description='LIB $out')
elif host.is_mingw():
    n.rule('ar',
           command='cmd /c $ar cqs $out.tmp $in && move /Y $out.tmp $out',
           description='AR $out')
else:
    n.rule('ar',
           command='rm -f $out && $ar crs $out $in',
           description='AR $out')
n.newline()

if platform.is_msvc():
    n.rule('link',
        command='$cxx $in $libs /nologo /link $ldflags /out:$out',
        description='LINK $out')
else:
    n.rule('link',
        command='$cxx $ldflags -o $out $in $libs',
        description='LINK $out')
n.newline()

objs = []

if platform.supports_ninja_browse():
    n.comment('browse_py.h is used to inline browse.py.')
    n.rule('inline',
           command='"%s"' % src('inline.sh') + ' $varname < $in > $out',
           description='INLINE $out')
    n.build(built('browse_py.h'), 'inline', src('browse.py'),
            implicit=src('inline.sh'),
            variables=[('varname', 'kBrowsePy')])
    n.newline()

    objs += cxx('browse', order_only=built('browse_py.h'))
    n.newline()

n.comment('the depfile parser and ninja lexers are generated using re2c.')
def has_re2c():
    try:
        proc = subprocess.Popen(['re2c', '-V'], stdout=subprocess.PIPE)
        return int(proc.communicate()[0], 10) >= 1103
    except OSError:
        return False
if has_re2c():
    n.rule('re2c',
           command='re2c -b -i --no-generation-date -o $out $in',
           description='RE2C $out')
    # Generate the .cc files in the source directory so we can check them in.
    n.build(src('depfile_parser.cc'), 're2c', src('depfile_parser.in.cc'))
    n.build(src('lexer.cc'), 're2c', src('lexer.in.cc'))
else:
    print("warning: A compatible version of re2c (>= 0.11.3) was not found; "
           "changes to src/*.in.cc will not affect your build.")
n.newline()

n.comment('Core source files all build into ninja library.')
for name in ['build',
             'build_log',
             'clean',
             'clparser',
             'debug_flags',
             'depfile_parser',
             'deps_log',
             'disk_interface',
             'edit_distance',
             'eval_env',
             'graph',
             'graphviz',
             'lexer',
             'line_printer',
             'manifest_parser',
             'metrics',
             'state',
             'util',
             'version']:
    objs += cxx(name)
if platform.is_windows():
    for name in ['subprocess-win32',
                 'includes_normalize-win32',
                 'msvc_helper-win32',
                 'msvc_helper_main-win32']:
        objs += cxx(name)
    if platform.is_msvc():
        objs += cxx('minidump-win32')
    objs += cc('getopt')
else:
    objs += cxx('subprocess-posix')
if platform.is_aix():
    objs += cc('getopt')
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.is_msvc():
    libs.append('ninja.lib')
else:
    libs.append('-lninja')

if platform.is_aix():
    libs.append('-lperfstat')

all_targets = []

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)])
n.newline()
all_targets += ninja

if options.bootstrap:
    # We've built the ninja binary.  Don't run any more commands
    # through the bootstrap executor, but continue writing the
    # build.ninja file.
    n = ninja_writer

n.comment('Tests all build into ninja_test executable.')

objs = []

for name in ['build_log_test',
             'build_test',
             'clean_test',
             'clparser_test',
             'depfile_parser_test',
             'deps_log_test',
             'disk_interface_test',
             'edit_distance_test',
             'graph_test',
             'lexer_test',
             'manifest_parser_test',
             'ninja_test',
             'state_test',
             'subprocess_test',
             'test',
             'util_test']:
    objs += cxx(name)
if platform.is_windows():
    for name in ['includes_normalize_test', 'msvc_helper_test']:
        objs += cxx(name)

ninja_test = n.build(binary('ninja_test'), 'link', objs, implicit=ninja_lib,
                     variables=[('libs', libs)])
n.newline()
all_targets += ninja_test


n.comment('Ancillary executables.')
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('depfile_parser_perftest')
all_targets += n.build(binary('depfile_parser_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)])
objs = cxx('manifest_parser_perftest')
all_targets += n.build(binary('manifest_parser_perftest'), 'link', objs,
                              implicit=ninja_lib, variables=[('libs', libs)])
n.newline()

n.comment('Generate a graph using the "graph" tool.')
n.rule('gendot',
       command='./ninja -t graph all > $out')
n.rule('gengraph',
       command='dot -Tpng $in > $out')
dot = n.build(built('graph.dot'), 'gendot', ['ninja', 'build.ninja'])
n.build('graph.png', 'gengraph', dot)
n.newline()

n.comment('Generate the manual using asciidoc.')
n.rule('asciidoc',
       command='asciidoc -b docbook -d book -o $out $in',
       description='ASCIIDOC $out')
n.rule('xsltproc',
       command='xsltproc --nonet doc/docbook.xsl $in > $out',
       description='XSLTPROC $out')
docbookxml = n.build(built('manual.xml'), 'asciidoc', doc('manual.asciidoc'))
manual = n.build(doc('manual.html'), 'xsltproc', docbookxml,
                 implicit=[doc('style.css'), doc('docbook.xsl')])
n.build('manual', 'phony',
        order_only=manual)
n.newline()

n.rule('dblatex',
       command='dblatex -q -o $out -p doc/dblatex.xsl $in',
       description='DBLATEX $out')
n.build(doc('manual.pdf'), 'dblatex', docbookxml,
        implicit=[doc('dblatex.xsl')])

n.comment('Generate Doxygen.')
n.rule('doxygen',
       command='doxygen $in',
       description='DOXYGEN $in')
n.variable('doxygen_mainpage_generator',
           src('gen_doxygen_mainpage.sh'))
n.rule('doxygen_mainpage',
       command='$doxygen_mainpage_generator $in > $out',
       description='DOXYGEN_MAINPAGE $out')
mainpage = n.build(built('doxygen_mainpage'), 'doxygen_mainpage',
                   ['README', 'COPYING'],
                   implicit=['$doxygen_mainpage_generator'])
n.build('doxygen', 'doxygen', doc('doxygen.config'),
        implicit=mainpage)
n.newline()

if not host.is_mingw():
    n.comment('Regenerate build files if build script changes.')
    n.rule('configure',
           command='${configure_env}%s $root/configure.py $configure_args' %
               options.with_python,
           generator=True)
    n.build('build.ninja', 'configure',
            implicit=['$root/configure.py',
                      os.path.normpath('$root/misc/ninja_syntax.py')])
    n.newline()

n.default(ninja)
n.newline()

if host.is_linux():
    n.comment('Packaging')
    n.rule('rpmbuild',
           command="misc/packaging/rpmbuild.sh",
           description='Building rpms..')
    n.build('rpm', 'rpmbuild')
    n.newline()

n.build('all', 'phony', all_targets)

n.close()
print('wrote %s.' % BUILD_FILENAME)

if options.bootstrap:
    print('bootstrap complete.  rebuilding...')

    rebuild_args = []

    if platform.can_rebuild_in_place():
        rebuild_args.append('./ninja')
    else:
        if platform.is_windows():
            bootstrap_exe = 'ninja.bootstrap.exe'
            final_exe = 'ninja.exe'
        else:
            bootstrap_exe = './ninja.bootstrap'
            final_exe = './ninja'

        if os.path.exists(bootstrap_exe):
            os.unlink(bootstrap_exe)
        os.rename(final_exe, bootstrap_exe)

        rebuild_args.append(bootstrap_exe)

    if options.verbose:
        rebuild_args.append('-v')

    subprocess.check_call(rebuild_args)
