Merge "Return product config variables from board_configuration"
diff --git a/core/board_config.mk b/core/board_config.mk
index b3e6957..120f511 100644
--- a/core/board_config.mk
+++ b/core/board_config.mk
@@ -214,10 +214,8 @@
$(error board configuration converter failed: $(.SHELLSTATUS))
endif
- $(shell $(OUT_DIR)/soong/rbcrun \
- RBC_OUT="make,global" \
- $(OUT_DIR)/rbc/boardlauncher.rbc \
- >$(OUT_DIR)/rbc/rbc_board_config_results.mk)
+ $(shell build/soong/scripts/update_out $(OUT_DIR)/rbc/rbc_board_config_results.mk \
+ $(OUT_DIR)/soong/rbcrun RBC_OUT="make,global" $(OUT_DIR)/rbc/boardlauncher.rbc)
ifneq ($(.SHELLSTATUS),0)
$(error board configuration runner failed: $(.SHELLSTATUS))
endif
diff --git a/core/package_internal.mk b/core/package_internal.mk
index 9f5a599..800dbbc 100644
--- a/core/package_internal.mk
+++ b/core/package_internal.mk
@@ -35,6 +35,10 @@
endif
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
+ifneq ($(strip $(LOCAL_MODULE_STEM)$(LOCAL_BUILT_MODULE_STEM)),)
+$(error $(LOCAL_PATH): Package modules may not define LOCAL_MODULE_STEM or LOCAL_BUILT_MODULE_STEM)
+endif
+
ifneq ($(strip $(LOCAL_MODULE)),)
$(error $(LOCAL_PATH): Package modules may not define LOCAL_MODULE)
endif
diff --git a/core/product.mk b/core/product.mk
index 683c429..503b44f 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -275,10 +275,10 @@
_product_single_value_vars += PRODUCT_DEX_PREOPT_RESOLVE_STARTUP_STRINGS
# Boot image options.
+_product_list_vars += PRODUCT_DEX_PREOPT_BOOT_IMAGE_PROFILE_LOCATION
_product_single_value_vars += \
PRODUCT_EXPORT_BOOT_IMAGE_TO_DIST \
PRODUCT_USE_PROFILE_FOR_BOOT_IMAGE \
- PRODUCT_DEX_PREOPT_BOOT_IMAGE_PROFILE_LOCATION \
PRODUCT_USES_DEFAULT_ART_CONFIG \
_product_single_value_vars += PRODUCT_SYSTEM_SERVER_COMPILER_FILTER
diff --git a/core/product_config.mk b/core/product_config.mk
index 6588b8e..614dfa2 100644
--- a/core/product_config.mk
+++ b/core/product_config.mk
@@ -206,8 +206,8 @@
ifndef RBC_PRODUCT_CONFIG
$(call import-products, $(current_product_makefile))
else
- $(shell build/soong/scripts/rbc-run $(current_product_makefile) \
- >$(OUT_DIR)/rbctemp.mk)
+ $(shell build/soong/scripts/update_out $(OUT_DIR)/rbctemp.mk \
+ build/soong/scripts/rbc-run $(current_product_makefile))
ifneq ($(.SHELLSTATUS),0)
$(error product configuration converter failed: $(.SHELLSTATUS))
endif
diff --git a/core/product_config.rbc b/core/product_config.rbc
index fde05f5..c0bf281 100644
--- a/core/product_config.rbc
+++ b/core/product_config.rbc
@@ -17,6 +17,7 @@
"""Runtime functions."""
_soong_config_namespaces_key = "$SOONG_CONFIG_NAMESPACES"
+_dist_for_goals_key = "$dist_for_goals"
def _init_globals(version_info):
"""Returns dict created from the runtime environment."""
globals = dict()
@@ -90,6 +91,18 @@
__print_attr("SOONG_CONFIG_%s_%s" % (nsname, var), val)
else:
print("SOONG_CONFIG_%s_%s :=" % (nsname, var))
+ elif attr == _dist_for_goals_key:
+ goals = []
+ src_dst_list = []
+ goal_dst_list = []
+ for goal_name, goal_src_dst_list in sorted(val.items()):
+ goals.append(goal_name)
+ for sd in sorted(goal_src_dst_list):
+ src_dst_list.append(":".join(sd))
+ goal_dst_list.append(":".join((goal_name, sd[1])))
+ print("_all_dist_goal_output_pairs:=", " ".join(goal_dst_list))
+ print("_all_dist_goals:=", " ".join(goals))
+ print("_all_dist_src_dst_pairs:=", " ".join(src_dst_list))
elif attr not in globals_base or globals_base[attr] != val:
__print_attr(attr, val)
@@ -521,6 +534,21 @@
"""Expands shell wildcard pattern."""
return rblf_wildcard(pattern)
+def _mkdist_for_goals(g, goal, src_dst_list):
+ """Implements dist-for-goals macro."""
+ goals_map = g.get(_dist_for_goals_key, {})
+ pairs = goals_map.get(goal)
+ if pairs == None:
+ pairs = []
+ g[_dist_for_goals_key] = dict([(k,v) for k,v in goals_map.items()] + [(goal, pairs)])
+ for src_dst in __words(src_dst_list):
+ pair=src_dst.split(":")
+ if len(pair) > 2:
+ fail(src_dst + " should be a :-separated pair")
+ pairs.append((pair[0],pair[1] if len(pair) == 2 and pair[1] else __base(pair[0])))
+ g[_dist_for_goals_key][goal] = pairs
+
+
def _mkerror(file, message = ""):
"""Prints error and stops."""
fail("%s: %s. Stop" % (file, message))
@@ -529,6 +557,18 @@
"""Prints warning."""
rblf_log(file, "warning", message, sep = ':')
+def _mk2rbc_error(loc, message):
+ """Prints a message about conversion error and stops.
+
+ If RBC_MK2RBC_CONTINUE environment variable is set,
+ the execution will continue after the message is printed.
+ """
+ if _options.mk2rbc_continue:
+ rblf_log(loc, message, sep = ':')
+ else:
+ _mkerror(loc, message)
+
+
def _mkinfo(file, message = ""):
"""Prints info."""
rblf_log(message)
@@ -639,6 +679,7 @@
rearrange = "",
trace_modules = False,
trace_variables = [],
+ mk2rbc_continue = False,
)
for x in getattr(rblf_cli, "RBC_OUT", "").split(","):
if x == "sort" or x == "unique":
@@ -656,6 +697,8 @@
settings["trace_modules"] = True
elif x != "":
settings["trace_variables"].append(x)
+ if getattr(rblf_cli, "RBC_MK2RBC_CONTINUE", ""):
+ settings["mk2rbc_continue"] = True
return struct(**settings)
# Settings used during debugging.
@@ -683,6 +726,8 @@
init_globals = _init_globals,
inherit = _inherit,
indirect = _indirect,
+ mk2rbc_error = _mk2rbc_error,
+ mkdist_for_goals = _mkdist_for_goals,
mkinfo = _mkinfo,
mkerror = _mkerror,
mkpatsubst = _mkpatsubst,
diff --git a/core/soong_android_app_set.mk b/core/soong_android_app_set.mk
index f994165..ec3d8c8 100644
--- a/core/soong_android_app_set.mk
+++ b/core/soong_android_app_set.mk
@@ -6,9 +6,8 @@
$(call pretty-error,soong_apk_set.mk may only be used from Soong)
endif
-LOCAL_BUILT_MODULE_STEM := $(LOCAL_APK_SET_INSTALL_FILE)
-LOCAL_INSTALLED_MODULE_STEM := $(LOCAL_APK_SET_INSTALL_FILE)
-
+LOCAL_BUILT_MODULE_STEM := package.apk
+LOCAL_INSTALLED_MODULE_STEM := $(notdir $(LOCAL_PREBUILT_MODULE_FILE))
# Use the Soong output as the checkbuild target instead of LOCAL_BUILT_MODULE
# to avoid checkbuilds making an extra copy of every module.
@@ -18,22 +17,8 @@
include $(BUILD_SYSTEM)/base_rules.mk
#######################################
-## Extract master APK from APK set into given directory
-# $(1) APK set
-# $(2) APK entry to install (e.g., splits/base.apk
+$(eval $(call copy-one-file,$(LOCAL_PREBUILT_MODULE_FILE),$(LOCAL_BUILT_MODULE)))
-define extract-install-file-from-apk-set
-$(LOCAL_BUILT_MODULE): $(1)
- @echo "Extracting $$@"
- unzip -pq $$< $(2) >$$@
-endef
-
-$(eval $(call extract-install-file-from-apk-set,$(LOCAL_PREBUILT_MODULE_FILE),$(LOCAL_APK_SET_INSTALL_FILE)))
-# unzip returns 11 it there was nothing to extract, which is expected,
-# $(LOCAL_APK_SET_INSTALL_FILE) has is already there.
-LOCAL_POST_INSTALL_CMD := unzip -qoDD -j -d $(dir $(LOCAL_INSTALLED_MODULE)) \
- $(LOCAL_PREBUILT_MODULE_FILE) -x $(LOCAL_APK_SET_INSTALL_FILE) || [[ $$? -eq 11 ]]
-$(LOCAL_INSTALLED_MODULE): PRIVATE_POST_INSTALL_CMD := $(LOCAL_POST_INSTALL_CMD)
PACKAGES.$(LOCAL_MODULE).OVERRIDES := $(strip $(LOCAL_OVERRIDES_PACKAGES))
PACKAGES := $(PACKAGES) $(LOCAL_MODULE)
diff --git a/target/product/default_art_config.mk b/target/product/default_art_config.mk
index 071edbf..e988d00 100644
--- a/target/product/default_art_config.mk
+++ b/target/product/default_art_config.mk
@@ -14,6 +14,9 @@
# limitations under the License.
#
+# This file contains product config for the ART module that is common for
+# platform and unbundled builds.
+
ifeq ($(ART_APEX_JARS),)
$(error ART_APEX_JARS is empty; cannot initialize PRODUCT_BOOT_JARS variable)
endif
@@ -69,6 +72,8 @@
com.android.media:service-media-s \
com.android.permission:service-permission \
+PRODUCT_DEX_PREOPT_BOOT_IMAGE_PROFILE_LOCATION += art/build/boot/boot-image-profile.txt
+
# Minimal configuration for running dex2oat (default argument values).
# PRODUCT_USES_DEFAULT_ART_CONFIG must be true to enable boot image compilation.
PRODUCT_USES_DEFAULT_ART_CONFIG := true
diff --git a/target/product/runtime_libart.mk b/target/product/runtime_libart.mk
index 43fb8fc..ee63757 100644
--- a/target/product/runtime_libart.mk
+++ b/target/product/runtime_libart.mk
@@ -75,6 +75,14 @@
PRODUCT_PACKAGES += \
hiddenapi-package-whitelist.xml \
+ifeq (,$(TARGET_BUILD_UNBUNDLED))
+ # Don't depend on the framework boot image profile in unbundled builds where
+ # frameworks/base may not be present.
+ # TODO(b/179900989): We may not need this check once we stop using full
+ # platform products on the thin ART manifest branch.
+ PRODUCT_DEX_PREOPT_BOOT_IMAGE_PROFILE_LOCATION += frameworks/base/boot/boot-image-profile.txt
+endif
+
# The dalvik.vm.dexopt.thermal-cutoff property must contain one of the values
# listed here:
#
diff --git a/tests/conversion_error.rbc b/tests/conversion_error.rbc
new file mode 100644
index 0000000..5212378
--- /dev/null
+++ b/tests/conversion_error.rbc
@@ -0,0 +1,27 @@
+# Copyright 2021 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Run test configuration and verify its result.
+# The main configuration file is device.rbc.
+# It inherits part1.rbc and also includes include1.rbc
+# TODO(asmundak): more tests are needed to verify that:
+# * multi-level inheritance works as expected
+# * all runtime functions (wildcard, regex, etc.) work
+
+load("//build/make/core:product_config.rbc", "rblf")
+load(":version_defaults.rbc", "version_defaults")
+load(":device.rbc", "init")
+
+rblf.mk2rbc_error("file.mk:123", "cannot convert")
diff --git a/tests/device.rbc b/tests/device.rbc
index 37c5d0c..9ae6393 100644
--- a/tests/device.rbc
+++ b/tests/device.rbc
@@ -55,6 +55,9 @@
rblf.soong_config_set(g, "NS2", "v3", "abc")
rblf.soong_config_set(g, "NS2", "v3", "xyz")
+ rblf.mkdist_for_goals(g, "goal", "dir1/file1:out1 dir1/file2:out2")
+ rblf.mkdist_for_goals(g, "goal", "dir2/file2:")
+
if rblf.board_platform_in(g, "board1 board2"):
cfg["PRODUCT_PACKAGES"] += ["bad_package"]
g["TARGET_BOARD_PLATFORM"] = "board1"
diff --git a/tests/run.rbc b/tests/run.rbc
index d222341..31436c5 100644
--- a/tests/run.rbc
+++ b/tests/run.rbc
@@ -102,3 +102,11 @@
assert_eq("xyz", rblf.soong_config_get(globals, "NS2", "v3"))
assert_eq(None, rblf.soong_config_get(globals, "NS2", "nonexistant_var"))
+
+goals = globals["$dist_for_goals"]
+assert_eq(
+ {
+ "goal": [("dir1/file1", "out1"), ("dir1/file2", "out2"), ("dir2/file2", "file2")]
+ },
+ { k:v for k,v in sorted(goals.items()) }
+)
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 1533030..64ac95a 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -68,6 +68,9 @@
self.search_path = os.path.dirname(os.path.dirname(exec_path))
self.signapk_path = "framework/signapk.jar" # Relative to search_path
+ if not os.path.exists(os.path.join(self.search_path, self.signapk_path)):
+ if "ANDROID_HOST_OUT" in os.environ:
+ self.search_path = os.environ["ANDROID_HOST_OUT"]
self.signapk_shared_library_path = "lib64" # Relative to search_path
self.extra_signapk_args = []
self.java_path = "java" # Use the one on the path by default.
@@ -973,6 +976,8 @@
break
except KeyError:
logger.warning('Failed to read %s', prop_file)
+ if data == '':
+ logger.warning("Failed to read build.prop for partition {}".format(name))
return data
@staticmethod
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index e99152a..5d9cbd2 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -1479,7 +1479,7 @@
# Only check for existence of key file if using the default signer.
# Because the custom signer might not need the key file AT all.
# b/191704641
- if not OPTIONS.signapk_path:
+ if not OPTIONS.payload_signer:
private_key_path = OPTIONS.package_key + OPTIONS.private_key_suffix
if not os.path.exists(private_key_path):
raise common.ExternalError(
@@ -1487,6 +1487,11 @@
" correct key path through -k option".format(
private_key_path)
)
+ signapk_abs_path = os.path.join(
+ OPTIONS.search_path, OPTIONS.signapk_path)
+ if not os.path.exists(signapk_abs_path):
+ raise common.ExternalError(
+ "Failed to find sign apk binary {} in search path {}. Make sure the correct search path is passed via -p".format(OPTIONS.signapk_path, OPTIONS.search_path))
if OPTIONS.source_info_dict:
source_build_prop = OPTIONS.source_info_dict["build.prop"]
diff --git a/tools/signapk/src/com/android/signapk/SignApk.java b/tools/signapk/src/com/android/signapk/SignApk.java
index 8bf1005..232e119 100644
--- a/tools/signapk/src/com/android/signapk/SignApk.java
+++ b/tools/signapk/src/com/android/signapk/SignApk.java
@@ -64,12 +64,19 @@
import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
+import java.security.NoSuchAlgorithmException;
import java.security.Key;
import java.security.KeyFactory;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.KeyStore.PrivateKeyEntry;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.Security;
+import java.security.UnrecoverableEntryException;
+import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;
@@ -286,6 +293,32 @@
}
}
+ private static KeyStore createKeyStore(String keyStoreName, String keyStorePin) throws
+ CertificateException,
+ IOException,
+ KeyStoreException,
+ NoSuchAlgorithmException {
+ KeyStore keyStore = KeyStore.getInstance(keyStoreName);
+ keyStore.load(null, keyStorePin == null ? null : keyStorePin.toCharArray());
+ return keyStore;
+ }
+
+ /** Get a PKCS#11 private key from keyStore */
+ private static PrivateKey loadPrivateKeyFromKeyStore(
+ final KeyStore keyStore, final String keyName, final String password)
+ throws CertificateException, KeyStoreException, NoSuchAlgorithmException,
+ UnrecoverableKeyException, UnrecoverableEntryException {
+ final Key key = keyStore.getKey(keyName, password == null ? null : password.toCharArray());
+ final PrivateKeyEntry privateKeyEntry = (PrivateKeyEntry) keyStore.getEntry(keyName, null);
+ if (privateKeyEntry == null) {
+ throw new Error(
+ "Key "
+ + keyName
+ + " not found in the token provided by PKCS11 library!");
+ }
+ return privateKeyEntry.getPrivateKey();
+ }
+
/**
* Add a copy of the public key to the archive; this should
* exactly match one of the files in
@@ -1022,6 +1055,8 @@
"[-a <alignment>] " +
"[--align-file-size] " +
"[-providerClass <className>] " +
+ "[-loadPrivateKeysFromKeyStore <keyStoreName>]" +
+ "[-keyStorePin <pin>]" +
"[--min-sdk-version <n>] " +
"[--disable-v2] " +
"[--enable-v4] " +
@@ -1044,6 +1079,8 @@
boolean signWholeFile = false;
String providerClass = null;
+ String keyStoreName = null;
+ String keyStorePin = null;
int alignment = 4;
boolean alignFileSize = false;
Integer minSdkVersionOverride = null;
@@ -1062,6 +1099,18 @@
}
providerClass = args[++argstart];
++argstart;
+ } else if ("-loadPrivateKeysFromKeyStore".equals(args[argstart])) {
+ if (argstart + 1 >= args.length) {
+ usage();
+ }
+ keyStoreName = args[++argstart];
+ ++argstart;
+ } else if ("-keyStorePin".equals(args[argstart])) {
+ if (argstart + 1 >= args.length) {
+ usage();
+ }
+ keyStorePin = args[++argstart];
+ ++argstart;
} else if ("-a".equals(args[argstart])) {
alignment = Integer.parseInt(args[++argstart]);
++argstart;
@@ -1142,11 +1191,21 @@
// timestamp using the current timezone. We thus adjust the milliseconds since epoch
// value to end up with MS-DOS timestamp of Jan 1 2009 00:00:00.
timestamp -= TimeZone.getDefault().getOffset(timestamp);
-
+ KeyStore keyStore = null;
+ if (keyStoreName != null) {
+ keyStore = createKeyStore(keyStoreName, keyStorePin);
+ }
PrivateKey[] privateKey = new PrivateKey[numKeys];
for (int i = 0; i < numKeys; ++i) {
int argNum = argstart + i*2 + 1;
- privateKey[i] = readPrivateKey(new File(args[argNum]));
+ if (keyStore == null) {
+ privateKey[i] = readPrivateKey(new File(args[argNum]));
+ } else {
+ String[] splits = args[argNum].split(":", 2);
+ final String keyAlias = splits[0];
+ final String password = splits.length > 1 ? splits[1] : null;
+ privateKey[i] = loadPrivateKeyFromKeyStore(keyStore, keyAlias, password);
+ }
}
inputJar = new JarFile(new File(inputFilename), false); // Don't verify.