--- a/build/autoconf/altoptions.m4
+++ b/build/autoconf/altoptions.m4
@@ -15,109 +15,81 @@ dnl MOZ_ARG_DISABLE_BOOL( NAME,
dnl MOZ_ARG_ENABLE_STRING( NAME, HELP, IF-SET [, ELSE])
dnl MOZ_ARG_ENABLE_BOOL_OR_STRING( NAME, HELP, IF-YES, IF-NO, IF-SET[, ELSE]]])
dnl MOZ_ARG_WITH_BOOL( NAME, HELP, IF-YES [, IF-NO [, ELSE])
dnl MOZ_ARG_WITHOUT_BOOL( NAME, HELP, IF-NO [, IF-YES [, ELSE])
dnl MOZ_ARG_WITH_STRING( NAME, HELP, IF-SET [, ELSE])
dnl MOZ_ARG_HEADER(Comment)
dnl MOZ_READ_MYCONFIG() - Read in 'myconfig.sh' file
+define([MOZ_DIVERSION_ARGS], 12)
+
+AC_DEFUN([MOZ_ARG],[dnl
+AC_DIVERT_PUSH(MOZ_DIVERSION_ARGS)dnl
+ '$1',
+AC_DIVERT_POP()dnl
+])
+AC_DEFUN([MOZ_AC_ARG_ENABLE],[MOZ_ARG([--enable-]translit([$1],[_],[-]))AC_ARG_ENABLE([$1], [$2], [$3], [$4])])
+AC_DEFUN([MOZ_AC_ARG_WITH],[MOZ_ARG([--with-]translit([$1],[_],[-]))AC_ARG_WITH([$1], [$2], [$3], [$4])])
dnl MOZ_TWO_STRING_TEST(NAME, VAL, STR1, IF-STR1, STR2, IF-STR2 [, ELSE])
AC_DEFUN([MOZ_TWO_STRING_TEST],
[if test "[$2]" = "[$3]"; then
ifelse([$4], , :, [$4])
elif test "[$2]" = "[$5]"; then
ifelse([$6], , :, [$6])
else
ifelse([$7], ,
[AC_MSG_ERROR([Option, [$1], does not take an argument ([$2]).])],
[$7])
fi])
dnl MOZ_ARG_ENABLE_BOOL(NAME, HELP, IF-YES [, IF-NO [, ELSE]])
AC_DEFUN([MOZ_ARG_ENABLE_BOOL],
-[AC_ARG_ENABLE([$1], [$2],
+[MOZ_AC_ARG_ENABLE([$1], [$2],
[MOZ_TWO_STRING_TEST([$1], [$enableval], yes, [$3], no, [$4])],
[$5])])
dnl MOZ_ARG_DISABLE_BOOL(NAME, HELP, IF-NO [, IF-YES [, ELSE]])
AC_DEFUN([MOZ_ARG_DISABLE_BOOL],
-[AC_ARG_ENABLE([$1], [$2],
+[MOZ_AC_ARG_ENABLE([$1], [$2],
[MOZ_TWO_STRING_TEST([$1], [$enableval], no, [$3], yes, [$4])],
[$5])])
dnl MOZ_ARG_ENABLE_STRING(NAME, HELP, IF-SET [, ELSE])
AC_DEFUN([MOZ_ARG_ENABLE_STRING],
-[AC_ARG_ENABLE([$1], [$2], [$3], [$4])])
+[MOZ_AC_ARG_ENABLE([$1], [$2], [$3], [$4])])
dnl MOZ_ARG_ENABLE_BOOL_OR_STRING(NAME, HELP, IF-YES, IF-NO, IF-SET[, ELSE]]])
AC_DEFUN([MOZ_ARG_ENABLE_BOOL_OR_STRING],
[ifelse([$5], ,
[errprint([Option, $1, needs an "IF-SET" argument.
])
m4exit(1)],
- [AC_ARG_ENABLE([$1], [$2],
+ [MOZ_AC_ARG_ENABLE([$1], [$2],
[MOZ_TWO_STRING_TEST([$1], [$enableval], yes, [$3], no, [$4], [$5])],
[$6])])])
dnl MOZ_ARG_WITH_BOOL(NAME, HELP, IF-YES [, IF-NO [, ELSE])
AC_DEFUN([MOZ_ARG_WITH_BOOL],
-[AC_ARG_WITH([$1], [$2],
+[MOZ_AC_ARG_WITH([$1], [$2],
[MOZ_TWO_STRING_TEST([$1], [$withval], yes, [$3], no, [$4])],
[$5])])
dnl MOZ_ARG_WITHOUT_BOOL(NAME, HELP, IF-NO [, IF-YES [, ELSE])
AC_DEFUN([MOZ_ARG_WITHOUT_BOOL],
-[AC_ARG_WITH([$1], [$2],
+[MOZ_AC_ARG_WITH([$1], [$2],
[MOZ_TWO_STRING_TEST([$1], [$withval], no, [$3], yes, [$4])],
[$5])])
dnl MOZ_ARG_WITH_STRING(NAME, HELP, IF-SET [, ELSE])
AC_DEFUN([MOZ_ARG_WITH_STRING],
-[AC_ARG_WITH([$1], [$2], [$3], [$4])])
+[MOZ_AC_ARG_WITH([$1], [$2], [$3], [$4])])
dnl MOZ_ARG_HEADER(Comment)
dnl This is used by webconfig to group options
define(MOZ_ARG_HEADER, [# $1])
dnl MOZ_READ_MYCONFIG() - Read in 'myconfig.sh' file
AC_DEFUN([MOZ_READ_MOZCONFIG],
[AC_REQUIRE([AC_INIT_BINSH])dnl
-inserted=
-dnl Shell is hard, so here is what the following does:
-dnl - Reset $@ (command line arguments)
-dnl - Add the configure options from mozconfig to $@ one by one
-dnl - Add the original command line arguments after that, one by one
-dnl
-dnl There are several tricks involved:
-dnl - It is not possible to preserve the whitespaces in $@ by assigning to
-dnl another variable, so the two first steps above need to happen in the first
-dnl iteration of the third step.
-dnl - We always want the configure options to be added, so the loop must be
-dnl iterated at least once, so we add a dummy argument first, and discard it.
-dnl - something | while read line ... makes the while run in a subshell, meaning
-dnl that anything it does is not propagated to the main shell, so we can't do
-dnl set -- foo there. As a consequence, what the while loop reading mach
-dnl environment output does is output a set of shell commands for the main shell
-dnl to eval.
-dnl - Extra care is due when lines from mach environment output contain special
-dnl shell characters, so we use ' for quoting and ensure no ' end up in between
-dnl the quoting mark unescaped.
-dnl Some of the above is directly done in mach environment --format=configure.
-failed_eval() {
- echo "Failed eval'ing the following:"
- $(dirname [$]0)/[$1]/mach environment --format=configure
- exit 1
-}
-
-set -- dummy "[$]@"
-for ac_option
-do
- if test -z "$inserted"; then
- set --
- eval "$($(dirname [$]0)/[$1]/mach environment --format=configure)" || failed_eval
- inserted=1
- else
- set -- "[$]@" "$ac_option"
- fi
-done
+. ./old-configure.vars
])
--- a/build/autoconf/config.status.m4
+++ b/build/autoconf/config.status.m4
@@ -152,16 +152,20 @@ EOF
if test -n "$_NON_GLOBAL_ACDEFINES"; then
for var in $_NON_GLOBAL_ACDEFINES; do
echo " '$var'," >> $CONFIG_STATUS
done
fi
cat >> $CONFIG_STATUS <<EOF
]
+
+flags = [
+undivert(MOZ_DIVERSION_ARGS)dnl
+]
EOF
changequote([, ])
])
define([m4_fatal],[
errprint([$1
])
new file mode 100644
--- /dev/null
+++ b/build/moz.configure/init.configure
@@ -0,0 +1,119 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+include('util.configure')
+
+option(env='DIST', nargs=1, help='DIST directory')
+
+# Do not allow objdir == srcdir builds.
+# ==============================================================
+@depends('--help', 'DIST')
+def check_build_environment(help, dist):
+ topobjdir = os.path.realpath(os.path.abspath('.'))
+ topsrcdir = os.path.realpath(os.path.abspath(
+ os.path.join(os.path.dirname(__file__), '..', '..')))
+
+ set_config('TOPSRCDIR', topsrcdir)
+ set_config('TOPOBJDIR', topobjdir)
+ set_config('MOZ_BUILD_ROOT', topobjdir)
+ if dist:
+ set_config('DIST', normsep(dist[0]))
+ else:
+ set_config('DIST', os.path.join(topobjdir, 'dist'))
+
+ if help:
+ return
+
+ if topsrcdir == topobjdir:
+ error(
+ ' ***\n'
+ ' * Building directly in the main source directory is not allowed.\n'
+ ' *\n'
+ ' * To build, you must run configure from a separate directory\n'
+ ' * (referred to as an object directory).\n'
+ ' *\n'
+ ' * If you are building with a mozconfig, you will need to change your\n'
+ ' * mozconfig to point to a different object directory.\n'
+ ' ***'
+ )
+
+ # Check for a couple representative files in the source tree
+ conflict_files = [
+ '* %s' % f for f in ('Makefile', 'config/autoconf.mk')
+ if os.path.exists(os.path.join(topsrcdir, f))
+ ]
+ if conflict_files:
+ error(
+ ' ***\n'
+ ' * Your source tree contains these files:\n'
+ ' %s\n'
+ ' * This indicates that you previously built in the source tree.\n'
+ ' * A source tree build can confuse the separate objdir build.\n'
+ ' *\n'
+ ' * To clean up the source tree:\n'
+ ' * 1. cd %s\n'
+ ' * 2. gmake distclean\n'
+ ' ***'
+ % ('\n '.join(conflict_files), topsrcdir)
+ )
+
+
+option(env='MOZ_CURRENT_PROJECT', nargs=1, help='Current build project')
+option(env='MOZCONFIG', nargs=1, help='Mozconfig location')
+
+# Read user mozconfig
+# ==============================================================
+@depends('MOZ_CURRENT_PROJECT', 'MOZCONFIG', check_build_environment, '--help')
+@advanced
+def mozconfig(current_project, mozconfig, build_env, help):
+ from mozbuild.mozconfig import MozconfigLoader
+
+ # Don't read the mozconfig for the js configure (yay backwards
+ # compatibility)
+ if build_env['TOPOBJDIR'].endswith('/js/src'):
+ return {'path': None}
+
+ loader = MozconfigLoader(build_env['TOPSRCDIR'])
+ current_project = current_project[0] if current_project else None
+ mozconfig = mozconfig[0] if mozconfig else None
+ mozconfig = loader.find_mozconfig(env={'MOZCONFIG': mozconfig})
+ mozconfig = loader.read_mozconfig(mozconfig, moz_build_app=current_project)
+
+ return mozconfig
+
+
+@template
+@advanced
+def command_line_helper():
+ # This escapes the sandbox. Don't copy this. This is only here because
+ # it is a one off and because the required functionality doesn't need
+ # to be exposed for other usecases.
+ return depends.__self__._helper
+
+
+@depends(mozconfig)
+def mozconfig_options(mozconfig):
+ if mozconfig['path']:
+ helper = command_line_helper()
+ warn('Adding configure options from %s' % mozconfig['path'])
+ for arg in mozconfig['configure_args']:
+ warn(' %s' % arg)
+ # We could be using imply_option() here, but it has other
+ # contraints that don't really apply to the command-line
+ # emulation that mozconfig provides.
+ helper.add(arg, origin='mozconfig', args=helper._args)
+
+ # Ideally we'd handle mozconfig['env'] and mozconfig['vars'] here,
+ # but at the moment, moz.configure has no knowledge of the options
+ # that may appear there. We'll opt-in when we move things from
+ # old-configure.in, which will be tedious but necessary until we
+ # can discriminate what old-configure.in supports.
+
+del command_line_helper
+
+
+option(env='MOZILLABUILD', nargs=1,
+ help='Path to Mozilla Build (Windows-only)')
new file mode 100644
--- /dev/null
+++ b/build/moz.configure/old.configure
@@ -0,0 +1,399 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+# It feels dirty replicating this from python/mozbuild/mozbuild/mozconfig.py,
+# but the end goal being that the configure script would go away...
+@depends('MOZILLABUILD')
+@advanced
+def shell(mozillabuild):
+ import sys
+
+ shell = 'sh'
+ if mozillabuild:
+ shell = mozillabuild[0] + '/msys/bin/sh'
+ if sys.platform == 'win32':
+ shell = shell + '.exe'
+ return shell
+
+
+option(env='AUTOCONF', nargs=1, help='Path to autoconf 2.13')
+
+@depends(mozconfig, 'AUTOCONF')
+@advanced
+def autoconf(mozconfig, autoconf):
+ import re
+
+ mozconfig_autoconf = None
+ if mozconfig['path']:
+ make_extra = mozconfig['make_extra']
+ if make_extra:
+ for assignment in make_extra:
+ m = re.match('(?:export\s+)?AUTOCONF\s*:?=\s*(.+)$',
+ assignment)
+ if m:
+ mozconfig_autoconf = m.group(1)
+
+ autoconf = autoconf[0] if autoconf else None
+
+ for ac in (mozconfig_autoconf, autoconf, 'autoconf-2.13', 'autoconf2.13',
+ 'autoconf213'):
+ if ac:
+ autoconf = find_program(ac)
+ if autoconf:
+ break
+ else:
+ fink = find_program('fink')
+ if find:
+ autoconf = os.path.normpath(os.path.join(
+ fink, '..', '..', 'lib', 'autoconf2.13', 'bin', 'autoconf'))
+
+ if not autoconf:
+ error('Could not find autoconf 2.13')
+
+ set_config('AUTOCONF', autoconf)
+ return autoconf
+
+
+option(env='OLD_CONFIGURE', nargs=1, help='Path to the old configure script')
+
+@depends('OLD_CONFIGURE', mozconfig, autoconf, check_build_environment, shell)
+@advanced
+def prepare_configure(old_configure, mozconfig, autoconf, build_env, shell):
+ import glob
+ import itertools
+ import subprocess
+ import sys
+ # Import getmtime without overwriting the sandbox os.path.
+ from os.path import getmtime
+
+ from mozbuild.shellutil import quote
+
+ if not old_configure:
+ error('The OLD_CONFIGURE environment variable must be set')
+
+ # os.path.abspath in the sandbox will ensure forward slashes on Windows,
+ # which is actually necessary because this path actually ends up literally
+ # as $0, and backslashes there breaks autoconf's detection of the source
+ # directory.
+ old_configure = os.path.abspath(old_configure[0])
+
+ refresh = True
+ if os.path.exists(old_configure):
+ mtime = getmtime(old_configure)
+ aclocal = os.path.join(build_env['TOPSRCDIR'], 'build', 'autoconf',
+ '*.m4')
+ for input in itertools.chain(
+ (old_configure + '.in',
+ os.path.join(os.path.dirname(old_configure), 'aclocal.m4')),
+ glob.iglob(aclocal),
+ ):
+ if getmtime(input) > mtime:
+ break
+ else:
+ refresh = False
+
+ if refresh:
+ warn('Refreshing %s with %s' % (old_configure, autoconf))
+ with open(old_configure, 'wb') as fh:
+ subprocess.check_call([
+ shell, autoconf,
+ '--localdir=%s' % os.path.dirname(old_configure),
+ old_configure + '.in'], stdout=fh)
+
+ cmd = [shell, old_configure] + sys.argv[1:]
+ with open('old-configure.vars', 'w') as out:
+ if mozconfig['path']:
+ if mozconfig['configure_args']:
+ cmd += mozconfig['configure_args']
+
+ for key, value in mozconfig['env']['added'].items():
+ print("export %s=%s" % (key, quote(value)), file=out)
+ for key, (old, value) in mozconfig['env']['modified'].items():
+ print("export %s=%s" % (key, quote(value)), file=out)
+ for key, value in mozconfig['vars']['added'].items():
+ print("%s=%s" % (key, quote(value)), file=out)
+ for key, (old, value) in mozconfig['vars']['modified'].items():
+ print("%s=%s" % (key, quote(value)), file=out)
+ for t in ('env', 'vars'):
+ for key in mozconfig[t]['removed'].keys():
+ print("unset %s" % key, file=out)
+
+ return cmd
+
+
+@template
+def old_configure_options(*options):
+ for opt in options:
+ option(opt, nargs='*', help='Help missing for old configure options')
+
+ @depends('--help')
+ def all_options(help):
+ return set(options)
+
+ return depends(prepare_configure, all_options, *options)
+
+
+@old_configure_options(
+ '--cache-file',
+ '--enable-accessibility',
+ '--enable-address-sanitizer',
+ '--enable-alsa',
+ '--enable-android-apz',
+ '--enable-android-omx',
+ '--enable-android-resource-constrained',
+ '--enable-application',
+ '--enable-approximate-location',
+ '--enable-artifact-builds',
+ '--enable-b2g-bt',
+ '--enable-b2g-camera',
+ '--enable-b2g-ril',
+ '--enable-build-backend',
+ '--enable-bundled-fonts',
+ '--enable-callgrind',
+ '--enable-chrome-format',
+ '--enable-clang-plugin',
+ '--enable-compile-environment',
+ '--enable-content-sandbox',
+ '--enable-cookies',
+ '--enable-cpp-rtti',
+ '--enable-crashreporter',
+ '--enable-ctypes',
+ '--enable-dbm',
+ '--enable-dbus',
+ '--enable-debug',
+ '--enable-debug-js-modules',
+ '--enable-debug-symbols',
+ '--enable-default-toolkit',
+ '--enable-directshow',
+ '--enable-dmd',
+ '--enable-dtrace',
+ '--enable-dump-painting',
+ '--enable-elf-hack',
+ '--enable-eme',
+ '--enable-export-js',
+ '--enable-extensions',
+ '--enable-faststripe',
+ '--enable-feeds',
+ '--enable-ffmpeg',
+ '--enable-fmp4',
+ '--enable-gamepad',
+ '--enable-gc-trace',
+ '--enable-gconf',
+ '--enable-gczeal',
+ '--enable-gio',
+ '--enable-gnomeui',
+ '--enable-gold',
+ '--enable-gps-debug',
+ '--enable-hardware-aec-ns',
+ '--enable-icf',
+ '--enable-install-strip',
+ '--enable-instruments',
+ '--enable-ion',
+ '--enable-ios-target',
+ '--enable-ipdl-tests',
+ '--enable-jemalloc',
+ '--enable-jitspew',
+ '--enable-jprof',
+ '--enable-libjpeg-turbo',
+ '--enable-libproxy',
+ '--enable-llvm-hacks',
+ '--enable-logrefcnt',
+ '--enable-macos-target',
+ '--enable-maintenance-service',
+ '--enable-media-navigator',
+ '--enable-memory-sanitizer',
+ '--enable-mobile-optimize',
+ '--enable-more-deterministic',
+ '--enable-mozril-geoloc',
+ '--enable-necko-protocols',
+ '--enable-necko-wifi',
+ '--enable-negotiateauth',
+ '--enable-nfc',
+ '--enable-nspr-build',
+ '--enable-official-branding',
+ '--enable-omx-plugin',
+ '--enable-oom-breakpoint',
+ '--enable-optimize',
+ '--enable-parental-controls',
+ '--enable-perf',
+ '--enable-permissions',
+ '--enable-pie',
+ '--enable-png-arm-neon-support',
+ '--enable-posix-nspr-emulation',
+ '--enable-pref-extensions',
+ '--enable-printing',
+ '--enable-profilelocking',
+ '--enable-profiling',
+ '--enable-pulseaudio',
+ '--enable-raw',
+ '--enable-readline',
+ '--enable-reflow-perf',
+ '--enable-release',
+ '--enable-replace-malloc',
+ '--enable-require-all-d3dc-versions',
+ '--enable-rust',
+ '--enable-safe-browsing',
+ '--enable-sandbox',
+ '--enable-shared-js',
+ '--enable-signmar',
+ '--enable-simulator',
+ '--enable-skia',
+ '--enable-skia-gpu',
+ '--enable-small-chunk-size',
+ '--enable-startup-notification',
+ '--enable-startupcache',
+ '--enable-stdcxx-compat',
+ '--enable-strip',
+ '--enable-synth-pico',
+ '--enable-synth-speechd',
+ '--enable-system-cairo',
+ '--enable-system-extension-dirs',
+ '--enable-system-ffi',
+ '--enable-system-hunspell',
+ '--enable-system-pixman',
+ '--enable-system-sqlite',
+ '--enable-systrace',
+ '--enable-tasktracer',
+ '--enable-tests',
+ '--enable-thread-sanitizer',
+ '--enable-trace-logging',
+ '--enable-tree-freetype',
+ '--enable-ui-locale',
+ '--enable-universalchardet',
+ '--enable-update-channel',
+ '--enable-update-packaging',
+ '--enable-updater',
+ '--enable-url-classifier',
+ '--enable-valgrind',
+ '--enable-verify-mar',
+ '--enable-vtune',
+ '--enable-warnings-as-errors',
+ '--enable-webapp-runtime',
+ '--enable-webrtc',
+ '--enable-websms-backend',
+ '--enable-webspeech',
+ '--enable-webspeechtestbackend',
+ '--enable-wmf',
+ '--enable-xterm-updates',
+ '--enable-xul',
+ '--enable-zipwriter',
+ '--host',
+ '--no-create',
+ '--prefix',
+ '--target',
+ '--with-adjust-sdk-keyfile',
+ '--with-android-cxx-stl',
+ '--with-android-distribution-directory',
+ '--with-android-gnu-compiler-version',
+ '--with-android-max-sdk',
+ '--with-android-min-sdk',
+ '--with-android-ndk',
+ '--with-android-sdk',
+ '--with-android-toolchain',
+ '--with-android-version',
+ '--with-app-basename',
+ '--with-app-name',
+ '--with-arch',
+ '--with-arm-kuser',
+ '--with-bing-api-keyfile',
+ '--with-branding',
+ '--with-ccache',
+ '--with-compiler-wrapper',
+ '--with-crashreporter-enable-percent',
+ '--with-cross-lib',
+ '--with-debug-label',
+ '--with-default-mozilla-five-home',
+ '--with-distribution-id',
+ '--with-doc-include-dirs',
+ '--with-doc-input-dirs',
+ '--with-doc-output-dir',
+ '--with-external-source-dir',
+ '--with-float-abi',
+ '--with-fpu',
+ '--with-gl-provider',
+ '--with-gonk',
+ '--with-gonk-toolchain-prefix',
+ '--with-google-api-keyfile',
+ '--with-google-oauth-api-keyfile',
+ '--with-gradle',
+ '--with-intl-api',
+ '--with-ios-sdk',
+ '--with-java-bin-path',
+ '--with-jitreport-granularity',
+ '--with-l10n-base',
+ '--with-libxul-sdk',
+ '--with-linux-headers',
+ '--with-macbundlename-prefix',
+ '--with-macos-private-frameworks',
+ '--with-macos-sdk',
+ '--with-mozilla-api-keyfile',
+ '--with-nspr-cflags',
+ '--with-nspr-libs',
+ '--with-pthreads',
+ '--with-qemu-exe',
+ '--with-qtdir',
+ '--with-servo',
+ '--with-sixgill',
+ '--with-soft-float',
+ '--with-system-bz2',
+ '--with-system-icu',
+ '--with-system-jpeg',
+ '--with-system-libevent',
+ '--with-system-libvpx',
+ '--with-system-nspr',
+ '--with-system-nss',
+ '--with-system-png',
+ '--with-system-zlib',
+ '--with-thumb',
+ '--with-thumb-interwork',
+ '--with-unify-dist',
+ '--with-user-appdir',
+ '--with-windows-version',
+ '--with-x',
+ '--with-xulrunner-stub-name',
+ '--x-includes',
+ '--x-libraries',
+)
+@advanced
+def old_configure(prepare_configure, all_options, *options):
+ import codecs
+ import os
+ import subprocess
+ import sys
+ import types
+
+ ret = subprocess.call(prepare_configure)
+ if ret:
+ sys.exit(ret)
+
+ raw_config = {}
+ encoding = 'mbcs' if sys.platform == 'win32' else 'utf-8'
+ with codecs.open('config.data', 'r', encoding) as fh:
+ code = compile(fh.read(), 'config.data', 'exec')
+ # Every variation of the exec() function I tried led to:
+ # SyntaxError: unqualified exec is not allowed in function 'main' it
+ # contains a nested function with free variables
+ exec code in raw_config
+
+ # Ensure all the flags known to old-configure appear in the
+ # @old_configure_options above.
+ for flag in raw_config['flags']:
+ if flag not in all_options:
+ error('Missing option in `@old_configure_options` in %s: %s'
+ % (__file__, flag))
+
+ # If the code execution above fails, we want to keep the file around for
+ # debugging.
+ os.remove('config.data')
+
+ config = {}
+ for k, v in raw_config['substs']:
+ set_config(k[1:-1], v[1:-1] if isinstance(v, types.StringTypes) else v)
+
+ for k, v in dict(raw_config['defines']).iteritems():
+ set_define(k[1:-1], v[1:-1])
+
+ set_config('non_global_defines', raw_config['non_global_defines'])
new file mode 100644
--- /dev/null
+++ b/build/moz.configure/util.configure
@@ -0,0 +1,67 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+@template
+@advanced
+def warn(*args):
+ import sys
+ print(*args, file=sys.stderr)
+
+
+@template
+@advanced
+def error(*args):
+ import sys
+ print(*args, file=sys.stderr)
+ sys.exit(1)
+
+
+@template
+@advanced
+def is_absolute_or_relative(path):
+ import os
+ if os.altsep and os.altsep in path:
+ return True
+ return os.sep in path
+
+
+@template
+@advanced
+def normsep(path):
+ import mozpack.path as mozpath
+ return mozpath.normsep(path)
+
+
+@template
+@advanced
+def find_program(file):
+ if is_absolute_or_relative(file):
+ return os.path.abspath(file) if os.path.isfile(file) else None
+ from which import which, WhichError
+ try:
+ return normsep(which(file))
+ except WhichError:
+ return None
+
+
+@depends('--help')
+def _defines(help):
+ ret = {}
+ set_config('DEFINES', ret)
+ return ret
+
+
+@template
+def set_define(name, value):
+ @depends(_defines)
+ @advanced
+ def _add_define(defines):
+ from mozbuild.configure import ConfigureError
+ if name in defines:
+ raise ConfigureError("'%s' is already defined" % name)
+ defines[name] = value
+
+del _defines
--- a/configure.py
+++ b/configure.py
@@ -1,189 +1,74 @@
# 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 glob
-import itertools
import json
import os
import subprocess
import sys
-import re
-import types
base_dir = os.path.abspath(os.path.dirname(__file__))
sys.path.append(os.path.join(base_dir, 'python', 'which'))
sys.path.append(os.path.join(base_dir, 'python', 'mozbuild'))
-from which import which, WhichError
-from mozbuild.mozconfig import MozconfigLoader
-
-
-# If feel dirty replicating this from python/mozbuild/mozbuild/mozconfig.py,
-# but the end goal being that the configure script would go away...
-shell = 'sh'
-if 'MOZILLABUILD' in os.environ:
- shell = os.environ['MOZILLABUILD'] + '/msys/bin/sh'
-if sys.platform == 'win32':
- shell = shell + '.exe'
-
-
-def is_absolute_or_relative(path):
- if os.altsep and os.altsep in path:
- return True
- return os.sep in path
-
-
-def find_program(file):
- if is_absolute_or_relative(file):
- return os.path.abspath(file) if os.path.isfile(file) else None
- try:
- return which(file)
- except WhichError:
- return None
+from mozbuild.configure import ConfigureSandbox
-def autoconf_refresh(configure):
- if os.path.exists(configure):
- mtime = os.path.getmtime(configure)
- aclocal = os.path.join(base_dir, 'build', 'autoconf', '*.m4')
- for input in itertools.chain(
- (configure + '.in',
- os.path.join(os.path.dirname(configure), 'aclocal.m4')),
- glob.iglob(aclocal),
- ):
- if os.path.getmtime(input) > mtime:
- break
- else:
- return
+def main(argv):
+ config = {}
+ sandbox = ConfigureSandbox(config, os.environ, argv)
+ sandbox.run(os.path.join(os.path.dirname(__file__), 'moz.configure'))
- mozconfig_autoconf = None
- configure_dir = os.path.dirname(configure)
- # Don't read the mozconfig for the js configure (yay backwards
- # compatibility)
- if not configure_dir.replace(os.sep, '/').endswith('/js/src'):
- loader = MozconfigLoader(os.path.dirname(configure))
- project = os.environ.get('MOZ_CURRENT_PROJECT')
- mozconfig = loader.find_mozconfig(env=os.environ)
- mozconfig = loader.read_mozconfig(mozconfig, moz_build_app=project)
- make_extra = mozconfig['make_extra']
- if make_extra:
- for assignment in make_extra:
- m = re.match('(?:export\s+)?AUTOCONF\s*:?=\s*(.+)$',
- assignment)
- if m:
- mozconfig_autoconf = m.group(1)
-
- for ac in (mozconfig_autoconf, os.environ.get('AUTOCONF'), 'autoconf-2.13',
- 'autoconf2.13', 'autoconf213'):
- if ac:
- autoconf = find_program(ac)
- if autoconf:
- break
- else:
- fink = find_program('fink')
- if fink:
- autoconf = os.path.normpath(os.path.join(
- fink, '..', '..', 'lib', 'autoconf2.13', 'bin', 'autoconf'))
-
- if not autoconf:
- raise RuntimeError('Could not find autoconf 2.13')
-
- # Add or adjust AUTOCONF for subprocesses, especially the js/src configure
- os.environ['AUTOCONF'] = autoconf
-
- print('Refreshing %s with %s' % (configure, autoconf), file=sys.stderr)
+ if sandbox._help:
+ return 0
- with open(configure, 'wb') as fh:
- subprocess.check_call([
- shell, autoconf, '--localdir=%s' % os.path.dirname(configure),
- configure + '.in'], stdout=fh)
-
-
-def main(args):
- old_configure = os.environ.get('OLD_CONFIGURE')
-
- if not old_configure:
- raise Exception('The OLD_CONFIGURE environment variable must be set')
-
- # We need to replace backslashes with forward slashes on Windows because
- # this path actually ends up literally as $0, which breaks autoconf's
- # detection of the source directory.
- old_configure = os.path.abspath(old_configure).replace(os.sep, '/')
-
- try:
- autoconf_refresh(old_configure)
- except RuntimeError as e:
- print(e.message, file=sys.stderr)
- return 1
-
- ret = subprocess.call([shell, old_configure] + args)
- # We don't want to create and run config.status if --help was one of the
- # command line arguments.
- if ret or '--help' in args:
- return ret
-
- raw_config = {}
- encoding = 'mbcs' if sys.platform == 'win32' else 'utf-8'
- with codecs.open('config.data', 'r', encoding) as fh:
- code = compile(fh.read(), 'config.data', 'exec')
- # Every variation of the exec() function I tried led to:
- # SyntaxError: unqualified exec is not allowed in function 'main' it
- # contains a nested function with free variables
- exec code in raw_config
- # If the code execution above fails, we want to keep the file around for
- # debugging.
- os.remove('config.data')
-
- # Sanitize config data
- config = {}
- substs = config['substs'] = {
- k[1:-1]: v[1:-1] if isinstance(v, types.StringTypes) else v
- for k, v in raw_config['substs']
+ # Sanitize config data to feed config.status
+ sanitized_config = {}
+ sanitized_config['substs'] = {
+ k: v for k, v in config.iteritems()
+ if k not in ('DEFINES', 'non_global_defines', 'TOPSRCDIR', 'TOPOBJDIR')
}
- config['defines'] = {
- k[1:-1]: v[1:-1]
- for k, v in raw_config['defines']
- }
- config['non_global_defines'] = raw_config['non_global_defines']
- config['topsrcdir'] = base_dir
- config['topobjdir'] = os.path.abspath(os.getcwd())
+ sanitized_config['defines'] = config['DEFINES']
+ sanitized_config['non_global_defines'] = config['non_global_defines']
+ sanitized_config['topsrcdir'] = config['TOPSRCDIR']
+ sanitized_config['topobjdir'] = config['TOPOBJDIR']
# 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('#!%s\n' % config['substs']['PYTHON'])
+ fh.write('#!%s\n' % config['PYTHON'])
fh.write('# coding=%s\n' % encoding)
- for k, v in config.iteritems():
+ for k, v in sanitized_config.iteritems():
fh.write('%s = ' % k)
json.dump(v, fh, sort_keys=True, indent=4, ensure_ascii=False)
fh.write('\n')
fh.write("__all__ = ['topobjdir', 'topsrcdir', 'defines', "
"'non_global_defines', 'substs']")
- if not substs.get('BUILDING_JS') or substs.get('JS_STANDALONE'):
+ if not config.get('BUILDING_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)
''')
# Other things than us are going to run this file, so we need to give it
# executable permissions.
os.chmod('config.status', 0755)
- if not substs.get('BUILDING_JS') or substs.get('JS_STANDALONE'):
- if not substs.get('JS_STANDALONE'):
+ if not config.get('BUILDING_JS') or config.get('JS_STANDALONE'):
+ if not 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['substs']['PYTHON'], 'config.status'])
+ return subprocess.call([config['PYTHON'], 'config.status'])
return 0
if __name__ == '__main__':
- sys.exit(main(sys.argv[1:]))
+ sys.exit(main(sys.argv))
--- a/js/src/old-configure.in
+++ b/js/src/old-configure.in
@@ -71,52 +71,16 @@ dnl ====================================
USE_PTHREADS=
_PTHREAD_LDFLAGS=""
dnl Do not allow objdir == srcdir builds
dnl ==============================================================
_topsrcdir=`cd $srcdir; pwd -W 2>/dev/null || pwd -P`
_objdir=`pwd -P`
-if test "$_topsrcdir" = "$_objdir"
-then
- echo " ***"
- echo " * Building directly in the main source directory is not allowed."
- echo " *"
- echo " * To build, you must run configure from a separate directory"
- echo " * (referred to as an object directory)."
- echo " ***"
- exit 1
-fi
-
-# Check for a couple representative files in the source tree
-_conflict_files=
-for file in $_topsrcdir/Makefile $_topsrcdir/config/autoconf.mk; do
- if test -f $file; then
- _conflict_files="$_conflict_files $file"
- fi
-done
-if test "$_conflict_files"; then
- echo "***"
- echo "* Your source tree contains these files:"
- for file in $_conflict_files; do
- echo "* $file"
- done
- cat 1>&2 <<-EOF
- * This indicates that you previously built in the source tree.
- * A source tree build can confuse the separate objdir build.
- *
- * To clean up the source tree:
- * 1. cd $_topsrcdir
- * 2. gmake distclean
- ***
- EOF
- exit 1
- break
-fi
MOZ_BUILD_ROOT=`pwd -W 2>/dev/null || pwd -P`
MOZ_BUILD_BACKEND(../..)
MOZ_DEFAULT_COMPILER
COMPILE_ENVIRONMENT=1
MOZ_ARG_DISABLE_BOOL(compile-environment,
@@ -3430,18 +3394,16 @@ AC_SUBST(ENABLE_STRIP)
AC_SUBST(PKG_SKIP_STRIP)
AC_SUBST(INCREMENTAL_LINKER)
AC_SUBST(MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS)
AC_SUBST(MOZ_FIX_LINK_PATHS)
AC_SUBST(USE_DEPENDENT_LIBS)
-AC_SUBST(MOZ_BUILD_ROOT)
-
AC_SUBST(MOZ_POST_PROGRAM_COMMAND)
AC_SUBST(MOZ_APP_NAME)
AC_SUBST(MOZ_APP_DISPLAYNAME)
AC_SUBST(MOZ_APP_VERSION)
AC_SUBST(MOZ_PKG_SPECIAL)
new file mode 100644
--- /dev/null
+++ b/moz.configure
@@ -0,0 +1,10 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+include('build/moz.configure/init.configure')
+
+# Fallthrough to autoconf-based configure
+include('build/moz.configure/old.configure')
--- a/old-configure.in
+++ b/old-configure.in
@@ -91,54 +91,16 @@ dnl ====================================
MOZ_USE_PTHREADS=
_PTHREAD_LDFLAGS=""
dnl Do not allow objdir == srcdir builds.
dnl ==============================================================
_topsrcdir=`cd \`dirname $0\`; pwd -W 2>/dev/null || pwd -P`
_objdir=`pwd -P`
-if test "$_topsrcdir" = "$_objdir"; then
- echo " ***"
- echo " * Building directly in the main source directory is not allowed."
- echo " *"
- echo " * To build, you must run configure from a separate directory"
- echo " * (referred to as an object directory)."
- echo " *"
- echo " * If you are building with a mozconfig, you will need to change your"
- echo " * mozconfig to point to a different object directory."
- echo " ***"
- exit 1
-fi
-
-# Check for a couple representative files in the source tree
-_conflict_files=
-for file in $_topsrcdir/Makefile $_topsrcdir/config/autoconf.mk; do
- if test -f $file; then
- _conflict_files="$_conflict_files $file"
- fi
-done
-if test "$_conflict_files"; then
- echo "***"
- echo "* Your source tree contains these files:"
- for file in $_conflict_files; do
- echo "* $file"
- done
- cat 1>&2 <<-EOF
- * This indicates that you previously built in the source tree.
- * A source tree build can confuse the separate objdir build.
- *
- * To clean up the source tree:
- * 1. cd $_topsrcdir
- * 2. gmake distclean
- ***
-EOF
- exit 1
- break
-fi
MOZ_BUILD_ROOT=`pwd -W 2>/dev/null || pwd -P`
DIST="$MOZ_BUILD_ROOT/dist"
MOZ_PYTHON
MOZ_DEFAULT_COMPILER
COMPILE_ENVIRONMENT=1
@@ -8488,18 +8450,16 @@ AC_SUBST(USE_ELF_HACK)
AC_SUBST(INCREMENTAL_LINKER)
AC_SUBST(MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS)
AC_SUBST(MOZ_COMPONENT_NSPR_LIBS)
AC_SUBST(MOZ_FIX_LINK_PATHS)
AC_SUBST(USE_DEPENDENT_LIBS)
-AC_SUBST(MOZ_BUILD_ROOT)
-
AC_SUBST(MOZ_POST_PROGRAM_COMMAND)
AC_SUBST(MOZ_LINKER_EXTRACT)
AC_SUBST(MOZ_ADDON_SIGNING)
AC_SUBST(MOZ_REQUIRE_SIGNING)
if test -n "$MOZ_BINARY_EXTENSIONS"; then
AC_DEFINE(MOZ_BINARY_EXTENSIONS)
--- a/python/mozbuild/mozbuild/configure/options.py
+++ b/python/mozbuild/mozbuild/configure/options.py
@@ -353,34 +353,37 @@ class CommandLineHelper(object):
Extra options can be added afterwards through API calls. For those,
conflicting values will raise an exception.
'''
def __init__(self, environ=os.environ, argv=sys.argv):
self._environ = dict(environ)
self._args = OrderedDict()
self._extra_args = OrderedDict()
self._origins = {}
+ self._last = 0
- for position, arg in enumerate(argv[1:]):
- prefix, name, values = Option.split_option(arg)
- self._args[name] = arg, position
+ for arg in argv[1:]:
+ self.add(arg, 'command-line', self._args)
- def add(self, arg, origin='command-line'):
+ def add(self, arg, origin='command-line', args=None):
assert origin != 'default'
prefix, name, values = Option.split_option(arg)
- if name in self._extra_args:
+ if args is None:
+ args = self._extra_args
+ if args is self._extra_args and name in self._extra_args:
old_arg = self._extra_args[name][0]
old_prefix, _, old_values = Option.split_option(old_arg)
if prefix != old_prefix or values != old_values:
raise ConflictingOption(
"Cannot add '{arg}' to the {origin} set because it "
"conflicts with '{old_arg}' that was added earlier",
arg=arg, origin=origin, old_arg=old_arg,
old_origin=self._origins[old_arg])
- self._extra_args[name] = arg, -1 - len(self._extra_args)
+ self._last += 1
+ args[name] = arg, self._last
self._origins[arg] = origin
def _prepare(self, option, args):
arg, pos = None, 0
origin = 'command-line'
from_name = args.get(option.name)
from_env = args.get(option.env)
if from_name and from_env:
--- a/python/mozbuild/mozbuild/mach_commands.py
+++ b/python/mozbuild/mozbuild/mach_commands.py
@@ -1391,40 +1391,16 @@ class MachDebug(MachCommandBase):
print('MOZ_OBJDIR=%s' % objdir, file=out)
if 'MOZ_CURRENT_PROJECT' in os.environ:
objdir = mozpath.join(objdir, os.environ['MOZ_CURRENT_PROJECT'])
print('OBJDIR=%s' % objdir, file=out)
if self.mozconfig['path']:
print('FOUND_MOZCONFIG=%s' % mozpath.normsep(self.mozconfig['path']),
file=out)
- def _environment_configure(self, out, verbose):
- if self.mozconfig['path']:
- # Replace ' with '"'"', so that shell quoting e.g.
- # a'b becomes 'a'"'"'b'.
- quote = lambda s: s.replace("'", """'"'"'""")
- if self.mozconfig['configure_args']:
- print('echo Adding configure options from %s' %
- mozpath.normsep(self.mozconfig['path']), file=out)
- for arg in self.mozconfig['configure_args']:
- quoted_arg = quote(arg)
- print("echo ' %s'" % quoted_arg, file=out)
- print("""set -- "$@" '%s'""" % quoted_arg, file=out)
- for key, value in self.mozconfig['env']['added'].items():
- print("export %s='%s'" % (key, quote(value)), file=out)
- for key, (old, value) in self.mozconfig['env']['modified'].items():
- print("export %s='%s'" % (key, quote(value)), file=out)
- for key, value in self.mozconfig['vars']['added'].items():
- print("%s='%s'" % (key, quote(value)), file=out)
- for key, (old, value) in self.mozconfig['vars']['modified'].items():
- print("%s='%s'" % (key, quote(value)), file=out)
- for key in self.mozconfig['env']['removed'].keys() + \
- self.mozconfig['vars']['removed'].keys():
- print("unset %s" % key, file=out)
-
def _environment_json(self, out, verbose):
import json
class EnvironmentEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, MozbuildObject):
result = {
'topsrcdir': obj.topsrcdir,
'topobjdir': obj.topobjdir,