Rewrite construct_context.sh in Python.
This allows to reuse SDK version comparison routine from other Python
scripts. With the addition of non-numeric versions comparison has become
more complex, and the deleted shell script did it incorrectly: it used
comparisons like `[[ "S" -lt 28 ]]` which results in "true" as strings
are converted to zero in numeric context. This resulted in adding legacy
libraries to class loader context of apps targeting recent SDK versions.
The error was masked because currently there is only one non-AOSP app
that uses the script (GoogleDialer), and it targets numeric SDK version.
Test: lunch aosp_cf_x86_phone-userdebug && m
Bug: 132357300
Change-Id: I26e752e29b5453fd3e29d5dbfbe4d9df9c0a55b7
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index edfd2ad..e49fa98 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -208,7 +208,7 @@
// targetSdkVersion in the manifest or APK is less than that API version.
type classLoaderContextMap map[int]*classLoaderContext
-const anySdkVersion int = -1
+const anySdkVersion int = 9999 // should go last in class loader context
func (m classLoaderContextMap) getSortedKeys() []int {
keys := make([]int, 0, len(m))
@@ -340,22 +340,21 @@
Text(`)"`)
}
- // Generate commands that define shell variables for versioned classpaths
- // and construct class loader context from them using construct_context.sh.
+ // Generate command that saves host and target class loader context in shell variables.
+ cmd := rule.Command().
+ Text(`eval "$(`).Tool(globalSoong.ConstructContext).
+ Text(` --target-sdk-version ${target_sdk_version}`)
for _, ver := range classLoaderContexts.getSortedKeys() {
clc := classLoaderContexts.getValue(ver)
- var varHost, varTarget string
+ verString := fmt.Sprintf("%d", ver)
if ver == anySdkVersion {
- varHost = "dex_preopt_host_libraries"
- varTarget = "dex_preopt_target_libraries"
- } else {
- varHost = fmt.Sprintf("conditional_host_libs_%d", ver)
- varTarget = fmt.Sprintf("conditional_target_libs_%d", ver)
+ verString = "any" // a special keyword that means any SDK version
}
- rule.Command().Textf(varHost+`="%s"`, strings.Join(clc.Host.Strings(), " ")).Implicits(clc.Host)
- rule.Command().Textf(varTarget+`="%s"`, strings.Join(clc.Target, " "))
+ cmd.Textf(`--host-classpath-for-sdk %s %s`, verString, strings.Join(clc.Host.Strings(), ":")).
+ Implicits(clc.Host).
+ Textf(`--target-classpath-for-sdk %s %s`, verString, strings.Join(clc.Target, ":"))
}
- rule.Command().Text("source").Tool(globalSoong.ConstructContext).Input(module.DexPath)
+ cmd.Text(`)"`)
} else {
// Pass special class loader context to skip the classpath and collision check.
// This will get removed once LOCAL_USES_LIBRARIES is enforced.