| # 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/. |
| |
| # Combined with build/autoconf/config.status.m4, ConfigStatus is an almost |
| # drop-in replacement for autoconf 2.13's config.status, with features |
| # borrowed from autoconf > 2.5, and additional features. |
| |
| from __future__ import print_function |
| |
| import logging |
| import os |
| import sys |
| |
| from optparse import OptionParser |
| |
| from mach.logging import LoggingManager |
| from mozbuild.backend.configenvironment import ConfigEnvironment |
| from mozbuild.backend.recursivemake import RecursiveMakeBackend |
| from mozbuild.frontend.emitter import TreeMetadataEmitter |
| from mozbuild.frontend.reader import BuildReader |
| |
| from Preprocessor import Preprocessor |
| |
| |
| log_manager = LoggingManager() |
| |
| |
| def config_status(topobjdir = '.', topsrcdir = '.', |
| defines = [], non_global_defines = [], substs = [], |
| files = [], headers = []): |
| '''Main function, providing config.status functionality. |
| |
| Contrary to config.status, it doesn't use CONFIG_FILES or CONFIG_HEADERS |
| variables, but like config.status from autoconf 2.6, single files may be |
| generated with the --file and --header options. Several such options can |
| be given to generate several files at the same time. |
| |
| 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 |
| containing config.status as the top object directory with the -n option, |
| while files given to the --file and --header arguments are considered |
| relative to the current directory. |
| |
| The --recheck option, like with the original config.status, runs configure |
| again, with the options given in the "ac_configure_args" subst. |
| |
| The options to this function are passed when creating the |
| ConfigEnvironment, except for files and headers, which contain the list |
| of files and headers to be generated by default. These lists, as well as |
| the actual wrapper script around this function, are meant to be generated |
| by configure. See build/autoconf/config.status.m4. |
| |
| Unlike config.status behaviour with CONFIG_FILES and CONFIG_HEADERS, |
| but like config.status behaviour with --file and --header, providing |
| files or headers on the command line inhibits the default generation of |
| files when given headers and headers when given files. |
| |
| Unlike config.status, the FILE:TEMPLATE syntax is not supported for |
| files and headers. The template is always the filename suffixed with |
| '.in', in the corresponding directory under the top source directory. |
| ''' |
| |
| if 'CONFIG_FILES' in os.environ: |
| raise Exception, 'Using the CONFIG_FILES environment variable is not supported. Use --file instead.' |
| if 'CONFIG_HEADERS' in os.environ: |
| raise Exception, 'Using the CONFIG_HEADERS environment variable is not supported. Use --header instead.' |
| |
| parser = OptionParser() |
| parser.add_option('--recheck', dest='recheck', action='store_true', |
| help='update config.status by reconfiguring in the same conditions') |
| parser.add_option('--file', dest='files', metavar='FILE', action='append', |
| help='instantiate the configuration file FILE') |
| parser.add_option('--header', dest='headers', metavar='FILE', action='append', |
| help='instantiate the configuration header FILE') |
| parser.add_option('-v', '--verbose', dest='verbose', action='store_true', |
| help='display verbose output') |
| parser.add_option('-n', dest='not_topobjdir', action='store_true', |
| help='do not consider current directory as top object directory') |
| (options, args) = parser.parse_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) |
| |
| reader = BuildReader(env) |
| emitter = TreeMetadataEmitter(env) |
| backend = RecursiveMakeBackend(env) |
| # This won't actually do anything because of the magic of generators. |
| definitions = emitter.emit(reader.read_topsrcdir()) |
| |
| if options.recheck: |
| # Execute configure from the top object directory |
| if not os.path.isabs(topsrcdir): |
| topsrcdir = relpath(topsrcdir, topobjdir) |
| os.chdir(topobjdir) |
| os.execlp('sh', 'sh', '-c', ' '.join([os.path.join(topsrcdir, 'configure'), env.substs['ac_configure_args'], '--no-create', '--no-recursion'])) |
| |
| if options.files: |
| files = options.files |
| headers = [] |
| if options.headers: |
| headers = options.headers |
| if not options.files: |
| files = [] |
| # Default to display messages when giving --file or --headers on the |
| # command line. |
| log_level = logging.INFO |
| |
| if options.files or options.headers or options.verbose: |
| log_level = logging.DEBUG |
| |
| log_manager.add_terminal_logging(level=log_level) |
| log_manager.enable_unstructured() |
| |
| if not options.files and not options.headers: |
| print('Reticulating splines...', file=sys.stderr) |
| summary = backend.consume(definitions) |
| |
| for line in summary.summaries(): |
| print(line, file=sys.stderr) |
| |
| files = [os.path.join(topobjdir, f) for f in files] |
| headers = [os.path.join(topobjdir, f) for f in headers] |
| |
| for file in files: |
| env.create_config_file(file) |
| for header in headers: |
| env.create_config_header(header) |