summaryrefslogtreecommitdiffstats
path: root/python/mozbuild/mozbuild/backend/make.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/mozbuild/mozbuild/backend/make.py')
-rw-r--r--python/mozbuild/mozbuild/backend/make.py139
1 files changed, 139 insertions, 0 deletions
diff --git a/python/mozbuild/mozbuild/backend/make.py b/python/mozbuild/mozbuild/backend/make.py
new file mode 100644
index 0000000000..90b37e6758
--- /dev/null
+++ b/python/mozbuild/mozbuild/backend/make.py
@@ -0,0 +1,139 @@
+# 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/.
+
+import mozpack.path as mozpath
+
+from mozbuild.frontend.data import GeneratedFile
+from mozbuild.shellutil import quote as shell_quote
+
+from .common import CommonBackend
+
+
+class MakeBackend(CommonBackend):
+ """Class encapsulating logic for backends that use Make."""
+
+ def _init(self):
+ CommonBackend._init(self)
+
+ def _format_statements_for_generated_file(self, obj, tier, extra_dependencies=""):
+ """Return the list of statements to write to the Makefile for this
+ GeneratedFile.
+
+ This function will invoke _format_generated_file_input_name and
+ _format_generated_file_output_name to munge the input/output filenames
+ before sending them to the output.
+ """
+ assert isinstance(obj, GeneratedFile)
+
+ # Localized generated files can use {AB_CD} and {AB_rCD} in their
+ # output paths.
+ if obj.localized:
+ substs = {"AB_CD": "$(AB_CD)", "AB_rCD": "$(AB_rCD)"}
+ else:
+ substs = {}
+
+ outputs = []
+ needs_AB_rCD = False
+ for o in obj.outputs:
+ needs_AB_rCD = needs_AB_rCD or ("AB_rCD" in o)
+ try:
+ outputs.append(
+ self._format_generated_file_output_name(o.format(**substs), obj)
+ )
+ except KeyError as e:
+ raise ValueError(
+ "%s not in %s is not a valid substitution in %s"
+ % (e.args[0], ", ".join(sorted(substs.keys())), o)
+ )
+
+ first_output = outputs[0]
+ dep_file = mozpath.join(
+ mozpath.dirname(first_output),
+ "$(MDDEPDIR)",
+ "%s.pp" % mozpath.basename(first_output),
+ )
+ # The stub target file needs to go in MDDEPDIR so that it doesn't
+ # get written into generated Android resource directories, breaking
+ # Gradle tooling and/or polluting the Android packages.
+ stub_file = mozpath.join(
+ mozpath.dirname(first_output),
+ "$(MDDEPDIR)",
+ "%s.stub" % mozpath.basename(first_output),
+ )
+
+ if obj.inputs:
+ inputs = [
+ self._format_generated_file_input_name(f, obj) for f in obj.inputs
+ ]
+ else:
+ inputs = []
+
+ force = ""
+ if obj.force:
+ force = " FORCE"
+ elif obj.localized:
+ force = " $(if $(IS_LANGUAGE_REPACK),FORCE)"
+
+ ret = []
+
+ if obj.script:
+ # If we are doing an artifact build, we don't run compiler, so
+ # we can skip generated files that are needed during compile,
+ # or let the rule run as the result of something depending on
+ # it.
+ if (
+ not (obj.required_before_compile or obj.required_during_compile)
+ or not self.environment.is_artifact_build
+ ):
+ if tier and not needs_AB_rCD:
+ # Android localized resources have special Makefile
+ # handling.
+
+ # Double-colon tiers via a variable that the backend adds as a dependency
+ # later. See https://bugzilla.mozilla.org/show_bug.cgi?id=1645986#c0 as
+ # to why.
+ if tier in ("export", "pre-compile", "libs", "misc"):
+ dep = "%s_TARGETS" % tier.replace("-", "_").upper()
+ ret.append("%s += %s" % (dep, stub_file))
+ else:
+ ret.append("%s: %s" % (tier, stub_file))
+ for output in outputs:
+ ret.append("%s: %s ;" % (output, stub_file))
+ ret.append("EXTRA_MDDEPEND_FILES += %s" % dep_file)
+
+ ret.append(
+ (
+ """{stub}: {script}{inputs}{backend}{force}
+\t$(REPORT_BUILD)
+\t$(call py_action,file_generate,{locale}{script} """ # wrap for E501
+ """{method} {output} {dep_file} {stub}{inputs}{flags})
+\t@$(TOUCH) $@
+"""
+ ).format(
+ stub=stub_file,
+ output=first_output,
+ dep_file=dep_file,
+ inputs=" " + " ".join(inputs) if inputs else "",
+ flags=" " + " ".join(shell_quote(f) for f in obj.flags)
+ if obj.flags
+ else "",
+ backend=" " + extra_dependencies if extra_dependencies else "",
+ # Locale repacks repack multiple locales from a single configured objdir,
+ # so standard mtime dependencies won't work properly when the build is re-run
+ # with a different locale as input. IS_LANGUAGE_REPACK will reliably be set
+ # in this situation, so simply force the generation to run in that case.
+ force=force,
+ locale="--locale=$(AB_CD) " if obj.localized else "",
+ script=obj.script,
+ method=obj.method,
+ )
+ )
+
+ return ret
+
+ def _format_generated_file_input_name(self, path, obj):
+ raise NotImplementedError("Subclass must implement")
+
+ def _format_generated_file_output_name(self, path, obj):
+ raise NotImplementedError("Subclass must implement")