configure.py
author dvarga <dvarga@mozilla.com>
Wed, 08 Aug 2018 22:39:03 +0300
changeset 430585 b7cd9638d4a4c7d2f9df0cf7dbcb2a85bbafa7b7
parent 419187 ec5cda49535fddf8860091ff4bd37155d90b248d
child 454212 ab27c46876ddb7ef3a1c99d8c2297fa7d0039e2d
permissions -rw-r--r--
Backed out 6 changesets (bug 1476106) for failure at bf1f28e2b46d for failure at testing/marionette/harness/marionette_harness/tests/unit/test_screen_orientation.py Backed out changeset bf1f28e2b46d (bug 1476106) Backed out changeset ab38b11f85dd (bug 1476106) Backed out changeset b1a3ff0760bf (bug 1476106) Backed out changeset deb22f602d59 (bug 1476106) Backed out changeset 3b1084efc943 (bug 1476106) Backed out changeset 6d885f08136b (bug 1476106)

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

from __future__ import print_function, unicode_literals

import codecs
import itertools
import os
import sys
import textwrap


base_dir = os.path.abspath(os.path.dirname(__file__))
sys.path.insert(0, os.path.join(base_dir, 'python', 'mozbuild'))
from mozbuild.configure import ConfigureSandbox
from mozbuild.pythonutil import iter_modules_in_path
from mozbuild.backend.configenvironment import PartialConfigEnvironment
from mozbuild.util import (
    indented_repr,
    encode,
)
import mozpack.path as mozpath


def main(argv):
    config = {}
    sandbox = ConfigureSandbox(config, os.environ, argv)
    sandbox.run(os.path.join(os.path.dirname(__file__), 'moz.configure'))

    if sandbox._help:
        return 0

    return config_status(config)


def config_status(config):
    # Sanitize config data to feed config.status
    # Ideally, all the backend and frontend code would handle the booleans, but
    # there are so many things involved, that it's easier to keep config.status
    # untouched for now.
    def sanitized_bools(v):
        if v is True:
            return '1'
        if v is False:
            return ''
        return v

    sanitized_config = {}
    sanitized_config['substs'] = {
        k: sanitized_bools(v) for k, v in config.iteritems()
        if k not in ('DEFINES', 'non_global_defines', 'TOPSRCDIR', 'TOPOBJDIR',
                     'CONFIG_STATUS_DEPS')
    }
    sanitized_config['defines'] = {
        k: sanitized_bools(v) for k, v in config['DEFINES'].iteritems()
    }
    sanitized_config['non_global_defines'] = config['non_global_defines']
    sanitized_config['topsrcdir'] = config['TOPSRCDIR']
    sanitized_config['topobjdir'] = config['TOPOBJDIR']
    sanitized_config['mozconfig'] = config.get('MOZCONFIG')

    # Create config.status. Eventually, we'll want to just do the work it does
    # here, when we're able to skip configure tests/use cached results/not rely
    # on autoconf.
    print("Creating config.status", file=sys.stderr)
    encoding = 'mbcs' if sys.platform == 'win32' else 'utf-8'
    with codecs.open('config.status', 'w', encoding) as fh:
        fh.write(textwrap.dedent('''\
            #!%(python)s
            # coding=%(encoding)s
            from __future__ import unicode_literals
            from mozbuild.util import encode
            encoding = '%(encoding)s'
        ''') % {'python': config['PYTHON'], 'encoding': encoding})
        # A lot of the build backend code is currently expecting byte
        # strings and breaks in subtle ways with unicode strings. (bug 1296508)
        for k, v in sanitized_config.iteritems():
            fh.write('%s = encode(%s, encoding)\n' % (k, indented_repr(v)))
        fh.write("__all__ = ['topobjdir', 'topsrcdir', 'defines', "
                 "'non_global_defines', 'substs', 'mozconfig']")

        if config.get('MOZ_BUILD_APP') != 'js' or config.get('JS_STANDALONE'):
            fh.write(textwrap.dedent('''
                if __name__ == '__main__':
                    from mozbuild.util import patch_main
                    patch_main()
                    from mozbuild.config_status import config_status
                    args = dict([(name, globals()[name]) for name in __all__])
                    config_status(**args)
            '''))

    partial_config = PartialConfigEnvironment(config['TOPOBJDIR'])
    partial_config.write_vars(sanitized_config)

    # Write out a file so the build backend knows to re-run configure when
    # relevant Python changes.
    with open('config_status_deps.in', 'w') as fh:
        for f in itertools.chain(config['CONFIG_STATUS_DEPS'],
                                 iter_modules_in_path(config['TOPOBJDIR'],
                                                      config['TOPSRCDIR'])):
            fh.write('%s\n' % mozpath.normpath(f))

    # Other things than us are going to run this file, so we need to give it
    # executable permissions.
    os.chmod('config.status', 0o755)
    if config.get('MOZ_BUILD_APP') != 'js' or config.get('JS_STANDALONE'):
        from mozbuild.config_status import config_status

        # Some values in sanitized_config also have more complex types, such as
        # EnumString, which using when calling config_status would currently
        # break the build, as well as making it inconsistent with re-running
        # config.status. Fortunately, EnumString derives from unicode, so it's
        # covered by converting unicode strings.

        # A lot of the build backend code is currently expecting byte strings
        # and breaks in subtle ways with unicode strings.
        return config_status(args=[], **encode(sanitized_config, encoding))
    return 0


if __name__ == '__main__':
    sys.exit(main(sys.argv))