1# This Source Code Form is subject to the terms of the Mozilla Public 2# License, v. 2.0. If a copy of the MPL was not distributed with this 3# file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 5# This module produces a JSON file that provides basic build info and 6# configuration metadata. 7 8from __future__ import absolute_import, print_function, unicode_literals 9 10import json 11import os 12import re 13import six 14 15 16def build_dict(config, env=os.environ): 17 """ 18 Build a dict containing data about the build configuration from 19 the environment. 20 """ 21 substs = config.substs 22 23 # Check that all required variables are present first. 24 required = ["TARGET_CPU", "OS_TARGET"] 25 missing = [r for r in required if r not in substs] 26 if missing: 27 raise Exception( 28 "Missing required environment variables: %s" % ", ".join(missing) 29 ) 30 31 d = {} 32 d["topsrcdir"] = config.topsrcdir 33 34 if config.mozconfig: 35 d["mozconfig"] = config.mozconfig 36 37 # os 38 o = substs["OS_TARGET"] 39 known_os = {"Linux": "linux", "WINNT": "win", "Darwin": "mac", "Android": "android"} 40 if o in known_os: 41 d["os"] = known_os[o] 42 else: 43 # Allow unknown values, just lowercase them. 44 d["os"] = o.lower() 45 46 # Widget toolkit, just pass the value directly through. 47 d["toolkit"] = substs.get("MOZ_WIDGET_TOOLKIT") 48 49 # Application name 50 if "MOZ_APP_NAME" in substs: 51 d["appname"] = substs["MOZ_APP_NAME"] 52 53 # Build app name 54 if "MOZ_BUILD_APP" in substs: 55 d["buildapp"] = substs["MOZ_BUILD_APP"] 56 57 # processor 58 p = substs["TARGET_CPU"] 59 # do some slight massaging for some values 60 # TODO: retain specific values in case someone wants them? 61 if p.startswith("arm"): 62 p = "arm" 63 elif re.match("i[3-9]86", p): 64 p = "x86" 65 d["processor"] = p 66 # hardcoded list of 64-bit CPUs 67 if p in ["x86_64", "ppc64", "aarch64"]: 68 d["bits"] = 64 69 # hardcoded list of known 32-bit CPUs 70 elif p in ["x86", "arm", "ppc"]: 71 d["bits"] = 32 72 # other CPUs will wind up with unknown bits 73 74 d["debug"] = substs.get("MOZ_DEBUG") == "1" 75 d["nightly_build"] = substs.get("NIGHTLY_BUILD") == "1" 76 d["early_beta_or_earlier"] = substs.get("EARLY_BETA_OR_EARLIER") == "1" 77 d["release_or_beta"] = substs.get("RELEASE_OR_BETA") == "1" 78 d["devedition"] = substs.get("MOZ_DEV_EDITION") == "1" 79 d["pgo"] = substs.get("MOZ_PGO") == "1" 80 d["crashreporter"] = bool(substs.get("MOZ_CRASHREPORTER")) 81 d["normandy"] = substs.get("MOZ_NORMANDY") == "1" 82 d["datareporting"] = bool(substs.get("MOZ_DATA_REPORTING")) 83 d["healthreport"] = substs.get("MOZ_SERVICES_HEALTHREPORT") == "1" 84 d["sync"] = substs.get("MOZ_SERVICES_SYNC") == "1" 85 # FIXME(emilio): We need to update a lot of WPT expectations before removing this. 86 d["stylo"] = True 87 d["asan"] = substs.get("MOZ_ASAN") == "1" 88 d["tsan"] = substs.get("MOZ_TSAN") == "1" 89 d["ubsan"] = substs.get("MOZ_UBSAN") == "1" 90 d["telemetry"] = substs.get("MOZ_TELEMETRY_REPORTING") == "1" 91 d["tests_enabled"] = substs.get("ENABLE_TESTS") == "1" 92 d["bin_suffix"] = substs.get("BIN_SUFFIX", "") 93 d["require_signing"] = substs.get("MOZ_REQUIRE_SIGNING") == "1" 94 d["official"] = bool(substs.get("MOZILLA_OFFICIAL")) 95 d["updater"] = substs.get("MOZ_UPDATER") == "1" 96 d["artifact"] = substs.get("MOZ_ARTIFACT_BUILDS") == "1" 97 d["ccov"] = substs.get("MOZ_CODE_COVERAGE") == "1" 98 d["cc_type"] = substs.get("CC_TYPE") 99 d["non_native_theme"] = True 100 d["domstreams"] = substs.get("MOZ_DOM_STREAMS") == "1" 101 102 def guess_platform(): 103 if d["buildapp"] == "browser": 104 p = d["os"] 105 if p == "mac": 106 p = "macosx64" 107 elif d["bits"] == 64: 108 p = "{}64".format(p) 109 elif p in ("win",): 110 p = "{}32".format(p) 111 112 if d["asan"]: 113 p = "{}-asan".format(p) 114 115 return p 116 117 if d["buildapp"] == "mobile/android": 118 if d["processor"] == "x86": 119 return "android-x86" 120 if d["processor"] == "x86_64": 121 return "android-x86_64" 122 if d["processor"] == "aarch64": 123 return "android-aarch64" 124 return "android-arm" 125 126 def guess_buildtype(): 127 if d["debug"]: 128 return "debug" 129 if d["pgo"]: 130 return "pgo" 131 return "opt" 132 133 # if buildapp or bits are unknown, we don't have a configuration similar to 134 # any in automation and the guesses are useless. 135 if "buildapp" in d and (d["os"] == "mac" or "bits" in d): 136 d["platform_guess"] = guess_platform() 137 d["buildtype_guess"] = guess_buildtype() 138 139 if ( 140 d.get("buildapp", "") == "mobile/android" 141 and "MOZ_ANDROID_MIN_SDK_VERSION" in substs 142 ): 143 d["android_min_sdk"] = substs["MOZ_ANDROID_MIN_SDK_VERSION"] 144 145 return d 146 147 148def write_mozinfo(file, config, env=os.environ): 149 """Write JSON data about the configuration specified in config and an 150 environment variable dict to ``|file|``, which may be a filename or file-like 151 object. 152 See build_dict for information about what environment variables are used, 153 and what keys are produced. 154 """ 155 build_conf = build_dict(config, env) 156 if isinstance(file, six.text_type): 157 file = open(file, "wt") 158 159 json.dump(build_conf, file, sort_keys=True, indent=4) 160