diff --git a/android/arch.go b/android/arch.go index f4b0d66d9..f505ec653 100644 --- a/android/arch.go +++ b/android/arch.go @@ -811,10 +811,16 @@ func osMutator(bpctx blueprint.BottomUpMutatorContext) { } } -// Identifies the dependency from CommonOS variant to the os specific variants. -type commonOSTag struct{ blueprint.BaseDependencyTag } +type archDepTag struct { + blueprint.BaseDependencyTag + name string +} -var commonOsToOsSpecificVariantTag = commonOSTag{} +// Identifies the dependency from CommonOS variant to the os specific variants. +var commonOsToOsSpecificVariantTag = archDepTag{name: "common os to os specific"} + +// Identifies the dependency from arch variant to the common variant for a "common_first" multilib. +var firstArchToCommonArchDepTag = archDepTag{name: "first arch to common arch"} // Get the OsType specific variants for the current CommonOS variant. // @@ -831,7 +837,6 @@ func GetOsSpecificVariantsOfCommonOSVariant(mctx BaseModuleContext) []Module { } } }) - return variants } @@ -955,6 +960,12 @@ func archMutator(bpctx blueprint.BottomUpMutatorContext) { addTargetProperties(m, targets[i], multiTargets, i == 0) m.base().setArchProperties(mctx) } + + if multilib == "common_first" && len(modules) >= 2 { + for i := range modules[1:] { + mctx.AddInterVariantDependency(firstArchToCommonArchDepTag, modules[i+1], modules[0]) + } + } } func addTargetProperties(m Module, target Target, multiTargets []Target, primaryTarget bool) { diff --git a/java/app.go b/java/app.go index e788ca99f..46ca96918 100755 --- a/java/app.go +++ b/java/app.go @@ -379,7 +379,6 @@ func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) { "can only be set for modules that set sdk_version") } - tag := &jniDependencyTag{} for _, jniTarget := range ctx.MultiTargets() { variation := append(jniTarget.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"}) @@ -393,7 +392,7 @@ func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) { Bool(a.appProperties.Jni_uses_sdk_apis) { variation = append(variation, blueprint.Variation{Mutator: "sdk", Variation: "sdk"}) } - ctx.AddFarVariationDependencies(variation, tag, a.appProperties.Jni_libs...) + ctx.AddFarVariationDependencies(variation, jniLibTag, a.appProperties.Jni_libs...) } a.usesLibrary.deps(ctx, sdkDep.hasFrameworkLibs()) diff --git a/java/java.go b/java/java.go index 2553a30bd..3ce188586 100644 --- a/java/java.go +++ b/java/java.go @@ -547,13 +547,8 @@ type dependencyTag struct { name string } -type jniDependencyTag struct { - blueprint.BaseDependencyTag -} - func IsJniDepTag(depTag blueprint.DependencyTag) bool { - _, ok := depTag.(*jniDependencyTag) - return ok + return depTag == jniLibTag } var ( @@ -573,6 +568,7 @@ var ( instrumentationForTag = dependencyTag{name: "instrumentation_for"} usesLibTag = dependencyTag{name: "uses-library"} extraLintCheckTag = dependencyTag{name: "extra-lint-check"} + jniLibTag = dependencyTag{name: "jnilib"} ) func IsLibDepTag(depTag blueprint.DependencyTag) bool { @@ -1001,7 +997,7 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { otherName := ctx.OtherModuleName(module) tag := ctx.OtherModuleDependencyTag(module) - if _, ok := tag.(*jniDependencyTag); ok { + if IsJniDepTag(tag) { // Handled by AndroidApp.collectAppDeps return } @@ -2436,6 +2432,10 @@ type binaryProperties struct { // Name of the class containing main to be inserted into the manifest as Main-Class. Main_class *string + + // Names of modules containing JNI libraries that should be installed alongside the host + // variant of the binary. + Jni_libs []string } type Binary struct { @@ -2476,18 +2476,21 @@ func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) { j.wrapperFile = android.PathForSource(ctx, "build/soong/scripts/jar-wrapper.sh") } - // Depend on the installed jar so that the wrapper doesn't get executed by - // another build rule before the jar has been installed. - jarFile := ctx.PrimaryModule().(*Binary).installFile - + // The host installation rules make the installed wrapper depend on all the dependencies + // of the wrapper variant, which will include the common variant's jar file and any JNI + // libraries. This is verified by TestBinary. j.binaryFile = ctx.InstallExecutable(android.PathForModuleInstall(ctx, "bin"), - ctx.ModuleName(), j.wrapperFile, jarFile) + ctx.ModuleName(), j.wrapperFile) } } func (j *Binary) DepsMutator(ctx android.BottomUpMutatorContext) { if ctx.Arch().ArchType == android.Common { j.deps(ctx) + } else { + // This dependency ensures the host installation rules will install the jni libraries + // when the wrapper is installed. + ctx.AddVariationDependencies(nil, jniLibTag, j.binaryProperties.Jni_libs...) } } diff --git a/java/java_test.go b/java/java_test.go index 53053df0e..c751ea4e7 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -460,6 +460,14 @@ func TestBinary(t *testing.T) { name: "bar", srcs: ["b.java"], static_libs: ["foo"], + jni_libs: ["libjni"], + } + + cc_library_shared { + name: "libjni", + host_supported: true, + device_supported: false, + stl: "none", } `) @@ -470,10 +478,17 @@ func TestBinary(t *testing.T) { barWrapper := ctx.ModuleForTests("bar", buildOS+"_x86_64") barWrapperDeps := barWrapper.Output("bar").Implicits.Strings() + libjni := ctx.ModuleForTests("libjni", buildOS+"_x86_64_shared") + libjniSO := libjni.Rule("Cp").Output.String() + // Test that the install binary wrapper depends on the installed jar file - if len(barWrapperDeps) != 1 || barWrapperDeps[0] != barJar { - t.Errorf("expected binary wrapper implicits [%q], got %v", - barJar, barWrapperDeps) + if g, w := barWrapperDeps, barJar; !android.InList(w, g) { + t.Errorf("expected binary wrapper implicits to contain %q, got %q", w, g) + } + + // Test that the install binary wrapper depends on the installed JNI libraries + if g, w := barWrapperDeps, libjniSO; !android.InList(w, g) { + t.Errorf("expected binary wrapper implicits to contain %q, got %q", w, g) } }