Annotate dependency tags for dependencies of installed files
Relands Ic22603a5c0718b5a21686672a7471f952b4d1017 with a minor
change to track libc++ dependencies for python hosts and after
a fix to an internal genrule that depended on transitively
installed java libraries (ag/13068670).
Soong currently assumes that installed files should depend on
installed files of all transitive dependencies, which results
in extra installed file dependencies through genrules, static
libs, etc.
Annotate dependency tags for dependencies for which the
installed files are necessary such as shared libraries
and JNI libraries.
This avoids extra installed files, and is also a first step
towards genrules using their own copy of tools instead of
the installed copy.
Bug: 124313442
Test: m checkbuild
Test: java.TestBinary
Test: cc.TestInstallSharedLibs
Test: deptag_test.go
Change-Id: I725871249d561428e6f67bba6a7c65b580012b72
diff --git a/cc/cc.go b/cc/cc.go
index bd6e5d5..3a9349b 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -551,7 +551,15 @@
return d.Kind == staticLibraryDependency
}
-// dependencyTag is used for tagging miscellanous dependency types that don't fit into
+// InstallDepNeeded returns true for shared libraries so that shared library dependencies of
+// binaries or other shared libraries are installed as dependencies.
+func (d libraryDependencyTag) InstallDepNeeded() bool {
+ return d.shared()
+}
+
+var _ android.InstallNeededDependencyTag = libraryDependencyTag{}
+
+// dependencyTag is used for tagging miscellaneous dependency types that don't fit into
// libraryDependencyTag. Each tag object is created globally and reused for multiple
// dependencies (although since the object contains no references, assigning a tag to a
// variable and modifying it will not modify the original). Users can compare the tag
@@ -561,6 +569,15 @@
name string
}
+// installDependencyTag is used for tagging miscellaneous dependency types that don't fit into
+// libraryDependencyTag, but where the dependency needs to be installed when the parent is
+// installed.
+type installDependencyTag struct {
+ blueprint.BaseDependencyTag
+ android.InstallAlwaysNeededDependencyTag
+ name string
+}
+
var (
genSourceDepTag = dependencyTag{name: "gen source"}
genHeaderDepTag = dependencyTag{name: "gen header"}
@@ -572,7 +589,7 @@
staticVariantTag = dependencyTag{name: "static variant"}
vndkExtDepTag = dependencyTag{name: "vndk extends"}
dataLibDepTag = dependencyTag{name: "data lib"}
- runtimeDepTag = dependencyTag{name: "runtime lib"}
+ runtimeDepTag = installDependencyTag{name: "runtime lib"}
testPerSrcDepTag = dependencyTag{name: "test_per_src"}
stubImplDepTag = dependencyTag{name: "stub_impl"}
)
@@ -599,8 +616,7 @@
}
func IsRuntimeDepTag(depTag blueprint.DependencyTag) bool {
- ccDepTag, ok := depTag.(dependencyTag)
- return ok && ccDepTag == runtimeDepTag
+ return depTag == runtimeDepTag
}
func IsTestPerSrcDepTag(depTag blueprint.DependencyTag) bool {
diff --git a/cc/cc_test.go b/cc/cc_test.go
index f5ce867..7c98585 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -4069,3 +4069,98 @@
}
}
+
+func TestInstallSharedLibs(t *testing.T) {
+ bp := `
+ cc_binary {
+ name: "bin",
+ host_supported: true,
+ shared_libs: ["libshared"],
+ runtime_libs: ["libruntime"],
+ srcs: [":gen"],
+ }
+
+ cc_library_shared {
+ name: "libshared",
+ host_supported: true,
+ shared_libs: ["libtransitive"],
+ }
+
+ cc_library_shared {
+ name: "libtransitive",
+ host_supported: true,
+ }
+
+ cc_library_shared {
+ name: "libruntime",
+ host_supported: true,
+ }
+
+ cc_binary_host {
+ name: "tool",
+ srcs: ["foo.cpp"],
+ }
+
+ genrule {
+ name: "gen",
+ tools: ["tool"],
+ out: ["gen.cpp"],
+ cmd: "$(location tool) $(out)",
+ }
+ `
+
+ config := TestConfig(buildDir, android.Android, nil, bp, nil)
+ ctx := testCcWithConfig(t, config)
+
+ hostBin := ctx.ModuleForTests("bin", config.BuildOSTarget.String()).Description("install")
+ hostShared := ctx.ModuleForTests("libshared", config.BuildOSTarget.String()+"_shared").Description("install")
+ hostRuntime := ctx.ModuleForTests("libruntime", config.BuildOSTarget.String()+"_shared").Description("install")
+ hostTransitive := ctx.ModuleForTests("libtransitive", config.BuildOSTarget.String()+"_shared").Description("install")
+ hostTool := ctx.ModuleForTests("tool", config.BuildOSTarget.String()).Description("install")
+
+ if g, w := hostBin.Implicits.Strings(), hostShared.Output.String(); !android.InList(w, g) {
+ t.Errorf("expected host bin dependency %q, got %q", w, g)
+ }
+
+ if g, w := hostBin.Implicits.Strings(), hostTransitive.Output.String(); !android.InList(w, g) {
+ t.Errorf("expected host bin dependency %q, got %q", w, g)
+ }
+
+ if g, w := hostShared.Implicits.Strings(), hostTransitive.Output.String(); !android.InList(w, g) {
+ t.Errorf("expected host bin dependency %q, got %q", w, g)
+ }
+
+ if g, w := hostBin.Implicits.Strings(), hostRuntime.Output.String(); !android.InList(w, g) {
+ t.Errorf("expected host bin dependency %q, got %q", w, g)
+ }
+
+ if g, w := hostBin.Implicits.Strings(), hostTool.Output.String(); android.InList(w, g) {
+ t.Errorf("expected no host bin dependency %q, got %q", w, g)
+ }
+
+ deviceBin := ctx.ModuleForTests("bin", "android_arm64_armv8-a").Description("install")
+ deviceShared := ctx.ModuleForTests("libshared", "android_arm64_armv8-a_shared").Description("install")
+ deviceTransitive := ctx.ModuleForTests("libtransitive", "android_arm64_armv8-a_shared").Description("install")
+ deviceRuntime := ctx.ModuleForTests("libruntime", "android_arm64_armv8-a_shared").Description("install")
+
+ if g, w := deviceBin.OrderOnly.Strings(), deviceShared.Output.String(); !android.InList(w, g) {
+ t.Errorf("expected device bin dependency %q, got %q", w, g)
+ }
+
+ if g, w := deviceBin.OrderOnly.Strings(), deviceTransitive.Output.String(); !android.InList(w, g) {
+ t.Errorf("expected device bin dependency %q, got %q", w, g)
+ }
+
+ if g, w := deviceShared.OrderOnly.Strings(), deviceTransitive.Output.String(); !android.InList(w, g) {
+ t.Errorf("expected device bin dependency %q, got %q", w, g)
+ }
+
+ if g, w := deviceBin.OrderOnly.Strings(), deviceRuntime.Output.String(); !android.InList(w, g) {
+ t.Errorf("expected device bin dependency %q, got %q", w, g)
+ }
+
+ if g, w := deviceBin.OrderOnly.Strings(), hostTool.Output.String(); android.InList(w, g) {
+ t.Errorf("expected no device bin dependency %q, got %q", w, g)
+ }
+
+}
diff --git a/cc/testing.go b/cc/testing.go
index 7161313..198764b 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -16,6 +16,7 @@
import (
"android/soong/android"
+ "android/soong/genrule"
)
func RegisterRequiredBuildComponentsForTest(ctx android.RegistrationContext) {
@@ -24,6 +25,7 @@
RegisterBinaryBuildComponents(ctx)
RegisterLibraryBuildComponents(ctx)
RegisterLibraryHeadersBuildComponents(ctx)
+ genrule.RegisterGenruleBuildComponents(ctx)
ctx.RegisterModuleType("toolchain_library", ToolchainLibraryFactory)
ctx.RegisterModuleType("llndk_library", LlndkLibraryFactory)