summaryrefslogtreecommitdiffstats
path: root/build/moz.configure/old.configure
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--build/moz.configure/old.configure394
1 files changed, 394 insertions, 0 deletions
diff --git a/build/moz.configure/old.configure b/build/moz.configure/old.configure
new file mode 100644
index 0000000000..a37fd265a2
--- /dev/null
+++ b/build/moz.configure/old.configure
@@ -0,0 +1,394 @@
+# -*- Mode: python; 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/.
+
+
+m4 = check_prog(
+ "M4",
+ (
+ "gm4",
+ "m4",
+ ),
+ paths=prefer_mozillabuild_path,
+)
+
+
+@depends(mozconfig)
+def prepare_mozconfig(mozconfig):
+ if mozconfig["path"]:
+ items = {}
+ for key, value in mozconfig["vars"]["added"].items():
+ items[key] = (value, "added")
+ for key, (old, value) in mozconfig["vars"]["modified"].items():
+ items[key] = (value, "modified")
+ for t in ("env", "vars"):
+ for key in mozconfig[t]["removed"].keys():
+ items[key] = (None, "removed " + t)
+ return items
+
+
+@depends("OLD_CONFIGURE", build_project)
+def old_configure(old_configure, build_project):
+ if not old_configure:
+ die("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])
+ if build_project == "js":
+ old_configure_dir = os.path.dirname(old_configure)
+ if not old_configure_dir.endswith("/js/src"):
+ old_configure = os.path.join(
+ old_configure_dir, "js", "src", os.path.basename(old_configure)
+ )
+ return old_configure
+
+
+@depends(prepare_mozconfig, old_configure_assignments)
+@imports(_from="__builtin__", _import="open")
+@imports(_from="__builtin__", _import="print")
+@imports(_from="mozbuild.shellutil", _import="quote")
+def prepare_configure(mozconfig, old_configure_assignments):
+ assignments = {}
+
+ with open("old-configure.vars", "w") as out:
+ log.debug("Injecting the following to old-configure:")
+
+ def inject(command):
+ print(command, file=out) # noqa Python 2vs3
+ log.debug("| %s", command)
+
+ if mozconfig:
+ inject("# start of mozconfig values")
+ for key, (value, action) in sorted(mozconfig.items()):
+ if action.startswith("removed "):
+ inject("unset %s # from %s" % (key, action[len("removed ") :]))
+ else:
+ inject("%s=%s # %s" % (key, quote(value), action))
+ assignments[key] = value
+
+ inject("# end of mozconfig values")
+
+ for k, v in old_configure_assignments:
+ inject("%s=%s" % (k, quote(v)))
+ assignments[k] = v
+
+ return namespace(assignments=assignments)
+
+
+@template
+def old_configure_options(*options):
+ for opt in options:
+ option(opt, nargs="*", help="Help missing for old configure options")
+
+ @dependable
+ def all_options():
+ return list(options)
+
+ return depends(
+ host_for_sub_configure, target_for_sub_configure, all_options, *options
+ )
+
+
+@old_configure_options(
+ "--cache-file",
+ "--datadir",
+ "--enable-official-branding",
+ "--includedir",
+ "--libdir",
+ "--prefix",
+ "--with-branding",
+ "--with-distribution-id",
+ "--with-macbundlename-prefix",
+ "--x-includes",
+ "--x-libraries",
+)
+def prepare_configure_options(host, target, all_options, *options):
+ # old-configure only supports the options listed in @old_configure_options
+ # so we don't need to pass it every single option we've been passed. Only
+ # the ones that are not supported by python configure need to.
+ options = [
+ value.format(name)
+ for name, value in zip(all_options, options)
+ if value.origin != "default"
+ ] + [host, target]
+
+ return namespace(options=options, all_options=all_options)
+
+
+@template
+def old_configure_for(old_configure_path, extra_env=None):
+ if extra_env is None:
+ extra_env = dependable(None)
+
+ @depends(
+ prepare_configure,
+ prepare_configure_options,
+ prefer_mozillabuild_path,
+ altered_path,
+ extra_env,
+ build_environment,
+ old_configure_path,
+ awk,
+ m4,
+ shell,
+ "--cache-file",
+ )
+ @imports(_from="__builtin__", _import="compile")
+ @imports(_from="__builtin__", _import="open")
+ @imports(_from="__builtin__", _import="OSError")
+ @imports("glob")
+ @imports("itertools")
+ @imports("logging")
+ @imports("os")
+ @imports("re")
+ @imports("subprocess")
+ @imports("sys")
+ @imports(_from="mozbuild.shellutil", _import="quote")
+ @imports(_from="mozbuild.shellutil", _import="split")
+ @imports(_from="tempfile", _import="NamedTemporaryFile")
+ @imports(_from="subprocess", _import="CalledProcessError")
+ @imports(_from="__builtin__", _import="exec")
+ def old_configure(
+ prepare_configure,
+ prepare_configure_options,
+ prefer_mozillabuild_path,
+ altered_path,
+ extra_env,
+ build_env,
+ old_configure,
+ awk,
+ m4,
+ shell,
+ cache_file_option,
+ ):
+ if altered_path:
+ path = altered_path
+ else:
+ path = os.pathsep.join(prefer_mozillabuild_path)
+
+ cxx = prepare_configure.assignments.get("CXX")
+ cc = prepare_configure.assignments.get("CC")
+
+ if cc and cxx:
+ if cache_file_option:
+ config_cache = cache_file_option[0]
+ else:
+ config_cache = "config.cache"
+
+ if os.path.exists(config_cache):
+ remove = False
+ with open(config_cache, "r") as cfg_cache:
+ cxx_pattern = re.compile(
+ r"^ac_cv_prog_CXX=\${ac_cv_prog_CXX='(.*)'}$"
+ )
+ cc_pattern = re.compile(r"^ac_cv_prog_CC=\${ac_cv_prog_CC='(.*)'}$")
+ for line in cfg_cache:
+ m = cc_pattern.match(line)
+ if m and m.group(1) != cc:
+ remove = True
+ break
+ m = cxx_pattern.match(line)
+ if m and m.group(1) != cxx:
+ remove = True
+ break
+
+ if remove:
+ log.info("invalidating config.cache")
+ os.remove(config_cache)
+
+ refresh = True
+ if os.path.exists(old_configure):
+ mtime = os.path.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 os.path.getmtime(input) > mtime:
+ break
+ else:
+ refresh = False
+
+ if refresh:
+ autoconf = os.path.join(
+ build_env.topsrcdir, "build", "autoconf", "autoconf.sh"
+ )
+ log.info("Refreshing %s with %s", old_configure, autoconf)
+ env = dict(os.environ)
+ env["M4"] = m4
+ env["AWK"] = awk
+ env["AC_MACRODIR"] = os.path.join(build_env.topsrcdir, "build", "autoconf")
+ env["PATH"] = path
+
+ try:
+ script = subprocess.check_output(
+ [
+ shell,
+ autoconf,
+ "--localdir=%s" % os.path.dirname(old_configure),
+ old_configure + ".in",
+ ],
+ # Fix the working directory, so that when m4 is called, that
+ # includes of relative paths are deterministically resolved
+ # relative to the directory containing old-configure.
+ cwd=os.path.dirname(old_configure),
+ env=env,
+ )
+ except CalledProcessError as exc:
+ die("autoconf exited with return code {}".format(exc.returncode))
+
+ if not script:
+ die(
+ "Generated old-configure is empty! Check that your autoconf 2.13 program works!"
+ )
+
+ # Make old-configure append to config.log, where we put our own log.
+ # This could be done with a m4 macro, but it's way easier this way
+ script = script.replace(b">./config.log", b">>${CONFIG_LOG=./config.log}")
+
+ with NamedTemporaryFile(
+ mode="wb",
+ prefix=os.path.basename(old_configure),
+ dir=os.path.dirname(old_configure),
+ delete=False,
+ ) as fh:
+ fh.write(script)
+
+ try:
+ os.rename(fh.name, old_configure)
+ except OSError:
+ try:
+ # Likely the file already existed (on Windows). Retry after removing it.
+ os.remove(old_configure)
+ os.rename(fh.name, old_configure)
+ except OSError as e:
+ die("Failed re-creating old-configure: %s" % e.message)
+
+ cmd = [shell, old_configure] + prepare_configure_options.options
+
+ env = dict(os.environ)
+
+ # For debugging purpose, in case it's not what we'd expect.
+ log.debug("Running %s", quote(*cmd))
+
+ # Our logging goes to config.log, the same file old.configure uses.
+ # We can't share the handle on the file, so close it.
+ logger = logging.getLogger("moz.configure")
+ config_log = None
+ for handler in logger.handlers:
+ if isinstance(handler, logging.FileHandler):
+ config_log = handler
+ config_log.close()
+ logger.removeHandler(config_log)
+ env["CONFIG_LOG"] = config_log.baseFilename
+ log_size = os.path.getsize(config_log.baseFilename)
+ break
+
+ env["PATH"] = path
+
+ if extra_env:
+ env.update(extra_env)
+
+ env["OLD_CONFIGURE_VARS"] = os.path.join(
+ build_env.topobjdir, "old-configure.vars"
+ )
+ proc = subprocess.Popen(
+ cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=env
+ )
+ while True:
+ line = proc.stdout.readline()
+ if not line:
+ break
+ log.info(line.rstrip())
+
+ ret = proc.wait()
+ if ret:
+ with log.queue_debug():
+ if config_log:
+ with open(config_log.baseFilename, "r") as fh:
+ fh.seek(log_size)
+ for line in fh:
+ log.debug(line.rstrip())
+ log.error("old-configure failed")
+ sys.exit(ret)
+
+ if config_log:
+ # Create a new handler in append mode
+ handler = logging.FileHandler(config_log.baseFilename, mode="a", delay=True)
+ handler.setFormatter(config_log.formatter)
+ logger.addHandler(handler)
+
+ raw_config = {
+ "split": split,
+ "unique_list": unique_list,
+ }
+ with open("config.data", "r") as fh:
+ code = compile(fh.read(), "config.data", "exec")
+ exec(code, raw_config)
+
+ # Ensure all the flags known to old-configure appear in the
+ # @old_configure_options above.
+ all_options = set(prepare_configure_options.all_options)
+ for flag in raw_config["flags"]:
+ if flag not in all_options:
+ die(
+ "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")
+
+ return namespace(
+ **{
+ c: [
+ (k[1:-1], v[1:-1] if isinstance(v, str) else v)
+ for k, v in raw_config[c]
+ # Eventually we'll want to filter out all lowercase keys. (bug 1869127)
+ # For now, we only filter out the most problematic one that
+ # we know is unused.
+ if k != " target_cpu "
+ ]
+ for c in ("substs", "defines")
+ }
+ )
+
+ return old_configure
+
+
+old_configure = old_configure_for(old_configure)
+set_config("OLD_CONFIGURE_SUBSTS", old_configure.substs)
+set_config("OLD_CONFIGURE_DEFINES", old_configure.defines)
+
+
+# Assuming no other option is declared after this function, handle the
+# env options that were injected by mozconfig_options by creating dummy
+# Option instances and having the sandbox's CommandLineHelper handle
+# them. We only do so for options that haven't been declared so far,
+# which should be a proxy for the options that old-configure handles
+# and that we don't know anything about.
+@depends("--help")
+@imports("__sandbox__")
+@imports(_from="mozbuild.configure.options", _import="Option")
+def remaining_mozconfig_options(_):
+ helper = __sandbox__._helper
+ for arg in list(helper):
+ if helper._origins[arg] != "mozconfig":
+ continue
+ name = arg.split("=", 1)[0]
+ if name.isupper() and name not in __sandbox__._options:
+ option = Option(env=name, nargs="*", help=name)
+ helper.handle(option)
+
+
+# Please do not add anything after remaining_mozconfig_options()