Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5f364b63 authored by Ulya Trafimovich's avatar Ulya Trafimovich
Browse files

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
parent c4dac265
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -383,7 +383,7 @@ func createGlobalSoongConfig(ctx android.ModuleContext) *GlobalSoongConfig {
		SoongZip:         ctx.Config().HostToolPath(ctx, "soong_zip"),
		Zip2zip:          ctx.Config().HostToolPath(ctx, "zip2zip"),
		ManifestCheck:    ctx.Config().HostToolPath(ctx, "manifest_check"),
		ConstructContext: android.PathForSource(ctx, "build/soong/scripts/construct_context.sh"),
		ConstructContext: ctx.Config().HostToolPath(ctx, "construct_context"),
	}
}

@@ -574,7 +574,7 @@ func GlobalSoongConfigForTests(config android.Config) *GlobalSoongConfig {
			SoongZip:         android.PathForTesting("soong_zip"),
			Zip2zip:          android.PathForTesting("zip2zip"),
			ManifestCheck:    android.PathForTesting("manifest_check"),
			ConstructContext: android.PathForTesting("construct_context.sh"),
			ConstructContext: android.PathForTesting("construct_context"),
		}
	}).(*GlobalSoongConfig)
}
+11 −12
Original line number Diff line number Diff line
@@ -208,7 +208,7 @@ type classLoaderContext struct {
// 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 @@ func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, g
				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.
+2 −3
Original line number Diff line number Diff line
@@ -1860,9 +1860,8 @@ func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, hasFrameworkLibs
		// creating a cyclic dependency:
		//     e.g. framework-res -> org.apache.http.legacy -> ... -> framework-res.
		if hasFrameworkLibs {
			// dexpreopt/dexpreopt.go needs the paths to the dex jars of these libraries in case construct_context.sh needs
			// to pass them to dex2oat.  Add them as a dependency so we can determine the path to the dex jar of each
			// library to dexpreopt.
			// Dexpreopt needs paths to the dex jars of these libraries in order to construct
			// class loader context for dex2oat. Add them as a dependency with a special tag.
			ctx.AddVariationDependencies(nil, usesLibTag,
				"org.apache.http.legacy",
				"android.hidl.base-V1.0-java",
+2 −2
Original line number Diff line number Diff line
@@ -2587,13 +2587,13 @@ func TestUsesLibraries(t *testing.T) {
	// Test that only present libraries are preopted
	cmd = app.Rule("dexpreopt").RuleParams.Command

	if w := `dex_preopt_target_libraries="/system/framework/foo.jar /system/framework/bar.jar"`; !strings.Contains(cmd, w) {
	if w := `--target-classpath-for-sdk any /system/framework/foo.jar:/system/framework/bar.jar`; !strings.Contains(cmd, w) {
		t.Errorf("wanted %q in %q", w, cmd)
	}

	cmd = prebuilt.Rule("dexpreopt").RuleParams.Command

	if w := `dex_preopt_target_libraries="/system/framework/foo.jar /system/framework/bar.jar"`; !strings.Contains(cmd, w) {
	if w := `--target-classpath-for-sdk any /system/framework/foo.jar:/system/framework/bar.jar`; !strings.Contains(cmd, w) {
		t.Errorf("wanted %q in %q", w, cmd)
	}
}
+40 −0
Original line number Diff line number Diff line
@@ -149,6 +149,46 @@ python_test_host {
    test_suites: ["general-tests"],
}

python_binary_host {
    name: "construct_context",
    main: "construct_context.py",
    srcs: [
        "construct_context.py",
    ],
    version: {
        py2: {
            enabled: true,
        },
        py3: {
            enabled: false,
        },
    },
    libs: [
        "manifest_utils",
    ],
}

python_test_host {
    name: "construct_context_test",
    main: "construct_context_test.py",
    srcs: [
        "construct_context_test.py",
        "construct_context.py",
    ],
    version: {
        py2: {
            enabled: true,
        },
        py3: {
            enabled: false,
        },
    },
    libs: [
        "manifest_utils",
    ],
    test_suites: ["general-tests"],
}

python_binary_host {
    name: "lint-project-xml",
    main: "lint-project-xml.py",
Loading