summaryrefslogtreecommitdiffstats
path: root/comm/build
diff options
context:
space:
mode:
Diffstat (limited to 'comm/build')
-rw-r--r--comm/build/mach_initialize.py64
-rw-r--r--comm/build/macosx/hardenedruntime/developer.entitlements.xml56
-rw-r--r--comm/build/macosx/hardenedruntime/production.entitlements.xml50
-rw-r--r--comm/build/moz.configure/gecko_source.configure261
-rw-r--r--comm/build/mozconfig.comm-sccache19
-rw-r--r--comm/build/source_repos.py120
-rw-r--r--comm/build/sparse-profiles/comm_taskgraph14
-rw-r--r--comm/build/sparse-profiles/comm_toolchain6
8 files changed, 590 insertions, 0 deletions
diff --git a/comm/build/mach_initialize.py b/comm/build/mach_initialize.py
new file mode 100644
index 0000000000..17d2019ca6
--- /dev/null
+++ b/comm/build/mach_initialize.py
@@ -0,0 +1,64 @@
+# 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/.
+
+"""
+mach_initialize.py
+
+This file contains initialization code for mach commands that are outside of
+the Firefox source repository.
+"""
+
+import os
+import sys
+
+from build import mach_initialize as mach_init
+
+# Individual files that provide mach commands
+MACH_MODULES = [
+ "comm/python/l10n/mach_commands.py",
+ "comm/tools/lint/mach_commands.py",
+ "comm/tools/esmify/mach_commands.py",
+ "comm/mail/components/storybook/mach_commands.py",
+]
+
+CATEGORIES = {
+ "thunderbird": {
+ "short": "Thunderbird Development",
+ "long": "Mach commands that aid Thunderbird Development",
+ "priority": 65,
+ },
+}
+
+
+def mach_sys_path(mozilla_dir):
+ from mach.requirements import MachEnvRequirements
+
+ requirements = MachEnvRequirements.from_requirements_definition(
+ mozilla_dir,
+ True, # is_thunderbird
+ False,
+ os.path.join(mozilla_dir, "comm/python/sites/tb_common.txt"),
+ )
+ return sorted(
+ [
+ os.path.normcase(os.path.join(mozilla_dir, pth.path))
+ for pth in requirements.pth_requirements
+ ]
+ )
+
+
+def initialize(topsrcdir):
+ driver = mach_init.initialize(topsrcdir)
+
+ # Add comm Python module paths
+ sys.path.extend(mach_sys_path(topsrcdir))
+
+ # Define Thunderbird mach command categories
+ for category, meta in CATEGORIES.items():
+ driver.define_category(category, meta["short"], meta["long"], meta["priority"])
+
+ for path in MACH_MODULES:
+ driver.load_commands_from_file(os.path.join(topsrcdir, path))
+
+ return driver
diff --git a/comm/build/macosx/hardenedruntime/developer.entitlements.xml b/comm/build/macosx/hardenedruntime/developer.entitlements.xml
new file mode 100644
index 0000000000..b71fe31cb6
--- /dev/null
+++ b/comm/build/macosx/hardenedruntime/developer.entitlements.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<!--
+ Entitlements to apply during codesigning of developer builds. These
+ differ from the production entitlements in that they allow debugging of
+ executables and allow dyld environment variables to be used. This set of
+ entitlements is intended to be used for signing of builds used in
+ automated testing or local developer builds where debugging of a signed
+ build might be necessary. The com.apple.security.get-task-allow
+ entitlement must be set to true to allow debuggers to attach to
+ application processes but prohibits notarization with the notary service.
+ dyld environment variables are used for some tests and may be useful for
+ developers.
+ This file is based on the developer.entitlements.xml file used for Firefox.
+-->
+<plist version="1.0">
+ <dict>
+ <!-- Thunderbird does not use MAP_JIT for executable mappings -->
+ <key>com.apple.security.cs.allow-jit</key><false/>
+
+ <!-- Thunderbird needs to create executable pages (without MAP_JIT) -->
+ <key>com.apple.security.cs.allow-unsigned-executable-memory</key><true/>
+
+ <!-- Code paged in from disk should match the signature at page-in time -->
+ <key>com.apple.security.cs.disable-executable-page-protection</key><false/>
+
+ <!-- Allow loading third party libraries. Possibly needed by some legacy extensions. -->
+ <key>com.apple.security.cs.disable-library-validation</key><true/>
+
+ <!-- Allow dyld environment variables for gtests and debugging -->
+ <key>com.apple.security.cs.allow-dyld-environment-variables</key><true/>
+
+ <!-- Allow debuggers to attach to running executables -->
+ <key>com.apple.security.get-task-allow</key><true/>
+
+ <!-- Thunderbird needs to access the microphone on sites the user allows -->
+ <key>com.apple.security.device.audio-input</key><true/>
+
+ <!-- Thunderbird needs to access the camera on sites the user allows -->
+ <key>com.apple.security.device.camera</key><true/>
+
+ <!-- Thunderbird needs to access the location on sites the user allows -->
+ <key>com.apple.security.personal-information.location</key><true/>
+
+ <!-- Thunderbird uses the macOS addressbook for contacts storage. -->
+ <key>com.apple.security.personal-information.addressbook</key><true/>
+
+ <!-- Allow Thunderbird to send Apple events to other applications. Needed
+ for native messaging webextension helper applications launched by
+ Thunderbird which rely on Apple Events to signal other processes. -->
+ <key>com.apple.security.automation.apple-events</key><true/>
+
+ <!-- For SmartCardServices(7) -->
+ <key>com.apple.security.smartcard</key><true/>
+ </dict>
+</plist>
diff --git a/comm/build/macosx/hardenedruntime/production.entitlements.xml b/comm/build/macosx/hardenedruntime/production.entitlements.xml
new file mode 100644
index 0000000000..e99e9fa79e
--- /dev/null
+++ b/comm/build/macosx/hardenedruntime/production.entitlements.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<!--
+ Entitlements to apply during codesigning of production builds.
+ This file is based on the production.entitlements.xml file used for Firefox.
+-->
+<plist version="1.0">
+ <dict>
+ <!-- Thunderbird does not use MAP_JIT for executable mappings -->
+ <key>com.apple.security.cs.allow-jit</key><false/>
+
+ <!-- Thunderbird needs to create executable pages (without MAP_JIT) -->
+ <key>com.apple.security.cs.allow-unsigned-executable-memory</key><true/>
+
+ <!-- Code paged in from disk should match the signature at page in-time -->
+ <key>com.apple.security.cs.disable-executable-page-protection</key><false/>
+
+ <!-- Allow loading third party libraries. Possibly needed by some legacy extensions. -->
+ <key>com.apple.security.cs.disable-library-validation</key><true/>
+
+ <!-- Don't allow dyld environment variables -->
+ <key>com.apple.security.cs.allow-dyld-environment-variables</key><false/>
+
+ <!-- Don't allow debugging of the executable. Debuggers will be prevented
+ from attaching to running executables. Notarization does not permit
+ access to get-task-allow (as documented by Apple) so this must be
+ disabled on notarized builds. -->
+ <key>com.apple.security.get-task-allow</key><false/>
+
+ <!-- Thunderbird needs to access the microphone on sites the user allows -->
+ <key>com.apple.security.device.audio-input</key><true/>
+
+ <!-- Thunderbird needs to access the camera on sites the user allows -->
+ <key>com.apple.security.device.camera</key><true/>
+
+ <!-- Thunderbird needs to access the location on sites the user allows -->
+ <key>com.apple.security.personal-information.location</key><true/>
+
+ <!-- Thunderbird uses the macOS addressbook for contacts storage. -->
+ <key>com.apple.security.personal-information.addressbook</key><true/>
+
+ <!-- Allow Thunderbird to send Apple events to other applications. Needed
+ for native messaging webextension helper applications launched by
+ Thunderbird which rely on Apple Events to signal other processes. -->
+ <key>com.apple.security.automation.apple-events</key><true/>
+
+ <!-- For SmartCardServices(7) -->
+ <key>com.apple.security.smartcard</key><true/>
+ </dict>
+</plist>
diff --git a/comm/build/moz.configure/gecko_source.configure b/comm/build/moz.configure/gecko_source.configure
new file mode 100644
index 0000000000..319150c81a
--- /dev/null
+++ b/comm/build/moz.configure/gecko_source.configure
@@ -0,0 +1,261 @@
+# -*- 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/.
+
+# Attempt to ascertain the Gecko source repository information.
+# We need to have accurate source repository information for MPL compliance.
+
+
+def get_fail_msg(source_name, repo_name, rev_name):
+ return """Unable to determine {} source repository.
+Try setting {} and {}
+environment variables or build from a Mercurial checkout.""".format(
+ source_name, repo_name, rev_name
+ )
+
+
+# Wrap check_cmd_output so that it does not fatally end configure on command
+# failure.
+def hg_cmd_output(*args, **kwargs):
+ def hg_error():
+ return None
+
+ kwargs["onerror"] = hg_error
+
+ return check_cmd_output(*args, **kwargs)
+
+
+@template
+def read_sourcestamp(repository):
+ """
+ Last resort, look for the revision data in the sourcestamp file.
+ This file only exists in release tar files created in CI.
+ repository must be one of "GECKO" or "COMM".
+ """
+ log.info("Determining %s source information from sourcestamp.txt..." % repository)
+
+ line2read = {"COMM": 1, "GECKO": 2}[repository]
+
+ @depends(build_environment)
+ @imports(_from="os.path", _import="exists")
+ @imports(_from="os.path", _import="join")
+ @imports(_from="__builtin__", _import="open")
+ def get_sourcestamp(build_env):
+ sourcestamp_file = join(build_env.topsrcdir, "sourcestamp.txt")
+ if exists(sourcestamp_file):
+ try:
+ lines = open(sourcestamp_file).readlines()
+ except:
+ pass
+
+ if len(lines) != 3:
+ log.warn("sourcestamp.txt is corrupt!")
+ return
+
+ if lines and lines[line2read].startswith("http"):
+ repo_line = lines[line2read]
+ repo_url = repo_line.split("/rev/")
+ return namespace(repo_url=repo_url[0], repo_rev=repo_url[1])
+
+ return get_sourcestamp
+
+
+@template
+def read_gecko_rev_yml():
+ def get_value(x):
+ return x.split()[1]
+
+ @depends(commtopsrcdir)
+ @imports(_from="os.path", _import="exists")
+ @imports(_from="os.path", _import="join")
+ @imports(_from="__builtin__", _import="open")
+ def wrapped(commtopsrcdir):
+ log.info("Determining GECKO source information from .gecko_rev.yml")
+ rev_file = join(commtopsrcdir, ".gecko_rev.yml")
+ if not exists(rev_file):
+ return
+
+ repo = rev = ref = None
+
+ for line in open(rev_file).readlines():
+ if line.startswith("GECKO_HEAD_REPOSITORY:"):
+ repo = get_value(line)
+ elif line.startswith("GECKO_HEAD_REV:"):
+ rev = get_value(line)
+ elif line.startswith("GECKO_HEAD_REF:"):
+ ref = get_value(line)
+ else:
+ pass
+
+ return namespace(repo=repo, rev=rev, ref=ref)
+
+ return wrapped
+
+
+@depends(application)
+@imports(_from="os", _import="environ")
+def comm_repo_from_environ(app):
+ """
+ Read the Thunderbird source repository information from the environment.
+
+ Taskcluster builds set COMM_HEAD_REPOSITORY and COMM_HEAD_REV pointing
+ to the comm-* repository.
+ """
+ log.info("Determining COMM source information from environment...")
+ comm_repo = environ.get("COMM_HEAD_REPOSITORY", None)
+ comm_rev = environ.get("COMM_HEAD_REV", None)
+
+ if all([comm_repo, comm_rev]):
+ log.info("{}/rev/{}".format(comm_repo, comm_rev))
+ return namespace(comm_repo=comm_repo, comm_rev=comm_rev)
+
+
+# Read sourcestamp.txt and return the Thunderbird source URL (with changeset).
+# Silent fail if the file cannot be read.
+comm_sourcestamp = read_sourcestamp("COMM")
+
+
+@depends(comm_repo_from_environ, commtopsrcdir, hg, comm_sourcestamp)
+@imports(_from="os", _import="environ")
+def comm_repo_heuristics(comm_environ, commtopsrcdir, hg, sourcestamp):
+ """
+ Determine the Thunderbird Mercurial repository and revision from Mercurial
+ or sourcestamp.txt when COMM_HEAD_REPOSITORY and COMM_HEAD_REV are unset
+ (local developer builds).
+ """
+ if not comm_environ:
+ comm_repo = comm_rev = None
+ if hg:
+ log.info("Determining COMM source information from Mercurial...")
+ comm_rev = hg_cmd_output(hg, "-R", commtopsrcdir, "parent", "--template={node}")
+ comm_repo = hg_cmd_output(hg, "-R", commtopsrcdir, "path", "default")
+ if comm_repo:
+ comm_repo = comm_repo.strip()
+ if comm_repo.startswith("ssh://"):
+ comm_repo = "https://" + comm_repo[6:]
+ comm_repo = comm_repo.rstrip("/")
+ # TODO: git-cinnabar support?
+
+ if not comm_repo or not comm_rev:
+ try:
+ comm_repo, comm_rev = sourcestamp.repo_url, sourcestamp.repo_rev
+ except:
+ pass
+
+ if comm_repo and comm_rev:
+ return namespace(comm_repo=comm_repo, comm_rev=comm_rev)
+
+
+@depends(comm_repo_from_environ, comm_repo_heuristics, "MOZ_AUTOMATION")
+@imports(_from="os", _import="environ")
+def comm_source_repo(from_environ, from_config, automation):
+ rv = None
+ if from_environ:
+ rv = from_environ
+ elif from_config:
+ rv = from_config
+ elif automation:
+ die(get_fail_msg("COMM", "COMM_HEAD_REPOSITORY", "COMM_HEAD_REV"))
+ else:
+ log.info(get_fail_msg("COMM", "COMM_HEAD_REPOSITORY", "COMM_HEAD_REV"))
+ rv = namespace(comm_repo="unknown", comm_rev="unknown")
+
+ log.info("COMM_SOURCE_REPOSITORY: {}".format(rv.comm_repo))
+ log.info("COMM_SOURCE_CHANGESET: {}".format(rv.comm_rev))
+
+ # Used by old-configure to set in buildconfig. This is configure's environment
+ # not the same as used by the build itself.
+ environ["MOZ_SOURCE_REPO"] = rv.comm_repo
+ environ["MOZ_SOURCE_CHANGESET"] = rv.comm_rev
+
+ return rv
+
+
+@depends(application)
+@imports(_from="os", _import="environ")
+def gecko_repo_from_environ(app):
+ """
+ Same as above, but this time checking for the mozilla- repository.
+ """
+ log.info("Determining GECKO source information from environment...")
+ gecko_repo = environ.get("GECKO_HEAD_REPOSITORY", None)
+ gecko_rev = environ.get("GECKO_HEAD_REV", None)
+ if all([gecko_repo, gecko_rev]):
+ log.info("{}/rev/{}".format(gecko_repo, gecko_rev))
+ return namespace(gecko_repo=gecko_repo, gecko_rev=gecko_rev)
+
+
+# Read sourcestamp.txt, this time returning the mozilla- data
+gecko_sourcestamp = read_sourcestamp("GECKO")
+# Look in comm/.gecko_rev.yml fpr repository information
+gecko_yml = read_gecko_rev_yml()
+
+
+@depends(gecko_repo_from_environ, build_environment, hg, gecko_sourcestamp, gecko_yml)
+@imports(_from="os.path", _import="join")
+@imports(_from="os.path", _import="exists")
+def gecko_repo_heuristics(gecko_environ, build_env, hg, sourcestamp, gecko_yml):
+ """
+ Look for the source repository and changeset for the mozilla- repository
+ when the Taskcluster environment variables are not set, checking
+ .gecko_rev.yml before falling back to Mercurial and sourcestamp.txt.
+ """
+ if not gecko_environ:
+ gecko_repo = gecko_rev = gecko_ref = None
+
+ try:
+ gecko_repo = gecko_yml.repo
+ gecko_rev = gecko_yml.rev
+ gecko_ref = gecko_yml.ref
+ except:
+ pass
+
+ if gecko_repo:
+ if not gecko_rev and gecko_ref:
+ # gecko_repo is known, but we have a branch ref like
+ # "default" when a revision hash is needed. Try to query
+ # Mercurial first.
+ if hg:
+ log.info("Determining GECKO source information from Mercurial...")
+ gecko_rev = hg_cmd_output(
+ hg, "-R", build_env.topsrcdir, "parent", "--template={node}"
+ )
+ # TODO: git-cinnabar support?
+
+ if not gecko_repo or not gecko_rev:
+ # See if we have a sourcestamp file. Last ditch effort!
+ try:
+ gecko_repo, gecko_rev = sourcestamp.repo_url, sourcestamp.repo_rev
+ except:
+ pass
+
+ # Check one last time to see if both gecko_repo and gecko_rev
+ # are set
+ if gecko_repo and gecko_rev:
+ return namespace(gecko_repo=gecko_repo, gecko_rev=gecko_rev)
+
+
+@depends(gecko_repo_from_environ, gecko_repo_heuristics, "MOZ_AUTOMATION")
+def gecko_source_repo(from_environ, from_heuristics, automation):
+ rv = None
+ if from_environ:
+ rv = from_environ
+ elif from_heuristics:
+ rv = from_heuristics
+ elif automation:
+ die(get_fail_msg("GECKO", "GECKO_HEAD_REPOSITORY", "GECKO_HEAD_REV"))
+ else:
+ log.info(get_fail_msg("GECKO", "GECKO_HEAD_REPOSITORY", "GECKO_HEAD_REV"))
+ rv = namespace(gecko_repo="unknown", gecko_rev="unknown")
+
+ log.info("GECKO_SOURCE_REPOSITORY: {}".format(rv.gecko_repo))
+ log.info("GECKO_SOURCE_CHANGESET: {}".format(rv.gecko_rev))
+ return rv
+
+
+set_config("MOZ_COMM_SOURCE_REPO", comm_source_repo.comm_repo)
+set_config("MOZ_COMM_SOURCE_CHANGESET", comm_source_repo.comm_rev)
+set_config("MOZ_GECKO_SOURCE_REPO", gecko_source_repo.gecko_repo)
+set_config("MOZ_GECKO_SOURCE_CHANGESET", gecko_source_repo.gecko_rev)
diff --git a/comm/build/mozconfig.comm-sccache b/comm/build/mozconfig.comm-sccache
new file mode 100644
index 0000000000..ed75504324
--- /dev/null
+++ b/comm/build/mozconfig.comm-sccache
@@ -0,0 +1,19 @@
+# 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/.
+
+# Must be included before M-C:build/mozconfig.cache
+if test -z "$bucket" -a -z "$SCCACHE_DISABLE"; then
+ if test -n "$TASKCLUSTER_WORKER_LOCATION" -a -x "$(command -v jq)"; then
+ cloud=$(echo $TASKCLUSTER_WORKER_LOCATION | jq .cloud | tr -d \")
+
+ case $cloud in
+ google)
+ gcp_prefix="comm-sccache"
+ ;;
+ aws)
+ aws_prefix="comm-central"
+ ;;
+ esac
+ fi
+fi
diff --git a/comm/build/source_repos.py b/comm/build/source_repos.py
new file mode 100644
index 0000000000..fc2aa461d2
--- /dev/null
+++ b/comm/build/source_repos.py
@@ -0,0 +1,120 @@
+# 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 json
+import os
+import sys
+
+import buildconfig
+
+sourcestamp_tmpl = """{buildid}
+{comm_repo}/rev/{comm_rev}
+{gecko_repo}/rev/{gecko_rev}
+"""
+
+
+def mk_hg_url(repo, revision):
+ """
+ Return a URL to a specific revision in the given repo.
+ """
+ return "{}/rev/{}".format(repo, revision)
+
+
+def gen_treeherder_build_links(output):
+ """
+ Create a JSON file that is used by Treeherder to display "Built from" links.
+ """
+ gecko_repo = buildconfig.substs.get("MOZ_GECKO_SOURCE_REPO")
+ gecko_rev = buildconfig.substs.get("MOZ_GECKO_SOURCE_CHANGESET")
+ comm_repo = buildconfig.substs.get("MOZ_COMM_SOURCE_REPO")
+ comm_rev = buildconfig.substs.get("MOZ_COMM_SOURCE_CHANGESET")
+
+ def mk_built_from_line(repo, revision):
+ repo_name = repo.split("/")[-1] # Last component of base URL
+ title = "Built from {} revision {}".format(repo_name, revision)
+ url = mk_hg_url(repo, revision)
+ return dict(title=title, value=revision, url=url)
+
+ built_from = [
+ mk_built_from_line(gecko_repo, gecko_rev),
+ mk_built_from_line(comm_repo, comm_rev),
+ ]
+ json.dump(built_from, output)
+
+
+def gen_platformini(output, platform_ini):
+ gecko_repo = buildconfig.substs.get("MOZ_GECKO_SOURCE_REPO", "")
+ gecko_rev = buildconfig.substs.get("MOZ_GECKO_SOURCE_CHANGESET", "")
+
+ with open(platform_ini, "r") as fp:
+ data = fp.readlines()
+
+ for i in range(len(data)):
+ if data[i].startswith("SourceRepository="):
+ data[i] = "SourceRepository=%s\n" % gecko_repo
+ elif data[i].startswith("SourceStamp="):
+ data[i] = "SourceStamp=%s\n" % gecko_rev
+
+ with open(platform_ini, "w") as fp:
+ fp.writelines(data)
+
+ output.write("platform.ini updated.\n")
+
+
+def gen_sourcestamp(output):
+ data = dict(
+ buildid=os.environ.get("MOZ_BUILD_DATE", "unknown"),
+ gecko_repo=buildconfig.substs.get("MOZ_GECKO_SOURCE_REPO", None),
+ gecko_rev=buildconfig.substs.get("MOZ_GECKO_SOURCE_CHANGESET", None),
+ comm_repo=buildconfig.substs.get("MOZ_COMM_SOURCE_REPO", None),
+ comm_rev=buildconfig.substs.get("MOZ_COMM_SOURCE_CHANGESET", None),
+ )
+
+ output.write(sourcestamp_tmpl.format(**data))
+
+
+def source_repo_header(output):
+ """
+ Appends the Gecko source repository information to source-repo.h
+ This information should be set in buildconfig.substs by moz.configure
+ """
+ gecko_repo = buildconfig.substs.get("MOZ_GECKO_SOURCE_REPO", None)
+ gecko_rev = buildconfig.substs.get("MOZ_GECKO_SOURCE_CHANGESET", None)
+ comm_repo = buildconfig.substs.get("MOZ_COMM_SOURCE_REPO", None)
+ comm_rev = buildconfig.substs.get("MOZ_COMM_SOURCE_CHANGESET", None)
+
+ if None in [gecko_repo, gecko_rev, comm_repo, comm_rev]:
+ Exception(
+ "Source information not found in buildconfig."
+ "Try setting GECKO_HEAD_REPOSITORY and GECKO_HEAD_REV"
+ "as well as MOZ_SOURCE_REPO and MOZ_SOURCE_CHANGESET"
+ "environment variables and running mach configure again."
+ )
+
+ output.write("#define MOZ_GECKO_SOURCE_STAMP {}\n".format(gecko_rev))
+ output.write("#define MOZ_COMM_SOURCE_STAMP {}\n".format(comm_rev))
+ output.write("#define MOZ_SOURCE_STAMP {}\n".format(comm_rev))
+
+ if buildconfig.substs.get("MOZ_INCLUDE_SOURCE_INFO"):
+ gecko_source_url = mk_hg_url(gecko_repo, gecko_rev)
+ comm_source_url = mk_hg_url(comm_repo, comm_rev)
+ output.write("#define MOZ_GECKO_SOURCE_REPO {}\n".format(gecko_repo))
+ output.write("#define MOZ_GECKO_SOURCE_URL {}\n".format(gecko_source_url))
+ output.write("#define MOZ_COMM_SOURCE_REPO {}\n".format(comm_repo))
+ output.write("#define MOZ_COMM_SOURCE_URL {}\n".format(comm_source_url))
+ output.write("#define MOZ_SOURCE_REPO {}\n".format(comm_repo))
+ output.write("#define MOZ_SOURCE_URL {}\n".format(comm_source_url))
+
+
+def main(args):
+ if args:
+ func = globals().get(args[0])
+ if func:
+ return func(sys.stdout, *args[1:])
+
+ return 1
+
+
+if __name__ == "__main__":
+ sys.exit(main(sys.argv[1:]))
diff --git a/comm/build/sparse-profiles/comm_taskgraph b/comm/build/sparse-profiles/comm_taskgraph
new file mode 100644
index 0000000000..a904073bf3
--- /dev/null
+++ b/comm/build/sparse-profiles/comm_taskgraph
@@ -0,0 +1,14 @@
+# Start with the gecko sparse-profile
+%include build/sparse-profiles/taskgraph
+
+[include]
+path:comm/build/
+path:comm/mail/config/
+path:comm/mail/locales/l10n-changesets.json
+path:comm/mail/locales/l10n-onchange-changesets.json
+path:comm/mail/locales/onchange-locales
+path:comm/mail/locales/shipped-locales
+path:comm/taskcluster
+path:comm/testing/
+path:comm/tools/lint/
+
diff --git a/comm/build/sparse-profiles/comm_toolchain b/comm/build/sparse-profiles/comm_toolchain
new file mode 100644
index 0000000000..4fed6f34a4
--- /dev/null
+++ b/comm/build/sparse-profiles/comm_toolchain
@@ -0,0 +1,6 @@
+# Start with the comm_taskgraph sparse profile
+%include comm/build/sparse-profiles/comm_taskgraph
+
+# Add in third_party code since libotr is still built as a toolchain
+[include]
+path:comm/third_party/