Bug 1257049 - Stop spawning a separate process for config.status from configure.py. r?gps
--- a/configure.py
+++ b/configure.py
@@ -5,16 +5,18 @@
from __future__ import print_function, unicode_literals
import codecs
import json
import os
import subprocess
import sys
+from collections import Iterable
+
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
def main(argv):
config = {}
@@ -74,21 +76,43 @@ def config_status(config):
if config.get('MOZ_BUILD_APP') != 'js' or config.get('JS_STANDALONE'):
fh.write('''
if __name__ == '__main__':
args = dict([(name, globals()[name]) for name in __all__])
from mozbuild.config_status import config_status
config_status(**args)
''')
+ # Running config.status standalone uses byte literals for all the config,
+ # instead of the unicode literals we have in sanitized_config right now.
+ # 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.
+ # Moreover, a lot of the build backend code is currently expecting byte
+ # strings and breaks in subtle ways with unicode strings.
+ def encode(v):
+ if isinstance(v, dict):
+ return {
+ encode(k): encode(val)
+ for k, val in v.iteritems()
+ }
+ if isinstance(v, str):
+ return v
+ if isinstance(v, unicode):
+ return v.encode(encoding)
+ if isinstance(v, Iterable):
+ return [encode(i) for i in v]
+ return v
+
# 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'):
- os.environ['WRITE_MOZINFO'] = '1'
- # Until we have access to the virtualenv from this script, execute
- # config.status externally, with the virtualenv python.
- return subprocess.call([config['PYTHON'], 'config.status'])
+ os.environ[b'WRITE_MOZINFO'] = b'1'
+ from mozbuild.config_status import config_status
+ return config_status(args=[], **encode(sanitized_config))
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv))
--- a/python/mozbuild/mozbuild/config_status.py
+++ b/python/mozbuild/mozbuild/config_status.py
@@ -58,17 +58,17 @@ files by running:
mach build-backend --backend=VisualStudio
===============================
'''.strip()
def config_status(topobjdir='.', topsrcdir='.', defines=None,
non_global_defines=None, substs=None, source=None,
- mozconfig=None):
+ mozconfig=None, args=sys.argv[1:]):
'''Main function, providing config.status functionality.
Contrary to config.status, it doesn't use CONFIG_FILES or CONFIG_HEADERS
variables.
Without the -n option, this program acts as config.status and considers
the current directory as the top object directory, even when config.status
is in a different directory. It will, however, treat the directory
@@ -102,17 +102,17 @@ def config_status(topobjdir='.', topsrcd
parser.add_argument('-d', '--diff', action='store_true',
help='print diffs of changed files.')
parser.add_argument('-b', '--backend', nargs='+', choices=sorted(backends),
default=default_backends,
help='what backend to build (default: %s).' %
' '.join(default_backends))
parser.add_argument('--dry-run', action='store_true',
help='do everything except writing files out.')
- options = parser.parse_args()
+ options = parser.parse_args(args)
# Without -n, the current directory is meant to be the top object directory
if not options.not_topobjdir:
topobjdir = os.path.abspath('.')
env = ConfigEnvironment(topsrcdir, topobjdir, defines=defines,
non_global_defines=non_global_defines, substs=substs,
source=source, mozconfig=mozconfig)