Sfoglia il codice sorgente

Merge "rust: Add whole_static_libs, revert static_lib"

Ivan Lozano 3 anni fa
parent
commit
352bdf29b3
4 ha cambiato i file con 55 aggiunte e 27 eliminazioni
  1. 10 2
      cc/linkable.go
  2. 18 5
      rust/compiler.go
  3. 19 18
      rust/rust.go
  4. 8 2
      rust/rust_test.go

+ 10 - 2
cc/linkable.go

@@ -158,8 +158,16 @@ func SharedDepTag() blueprint.DependencyTag {
 }
 
 // StaticDepTag returns the dependency tag for any C++ static libraries.
-func StaticDepTag() blueprint.DependencyTag {
-	return libraryDependencyTag{Kind: staticLibraryDependency}
+func StaticDepTag(wholeStatic bool) blueprint.DependencyTag {
+	return libraryDependencyTag{Kind: staticLibraryDependency, wholeStatic: wholeStatic}
+}
+
+// IsWholeStaticLib whether a dependency tag is a whole static library dependency.
+func IsWholeStaticLib(depTag blueprint.DependencyTag) bool {
+	if tag, ok := depTag.(libraryDependencyTag); ok {
+		return tag.wholeStatic
+	}
+	return false
 }
 
 // HeaderDepTag returns the dependency tag for any C++ "header-only" libraries.

+ 18 - 5
rust/compiler.go

@@ -97,13 +97,25 @@ type BaseCompilerProperties struct {
 	// list of C shared library dependencies
 	Shared_libs []string `android:"arch_variant"`
 
-	// list of C static library dependencies. Note, static libraries prefixed by "lib" will be passed to rustc
-	// along with "-lstatic=<name>". This will bundle the static library into rlib/static libraries so dependents do
-	// not need to also declare the static library as a dependency. Static libraries which are not prefixed by "lib"
-	// cannot be passed to rustc with this flag and will not be bundled into rlib/static libraries, and thus must
-	// be redeclared in dependents.
+	// list of C static library dependencies. These dependencies do not normally propagate to dependents
+	// and may need to be redeclared. See whole_static_libs for bundling static dependencies into a library.
 	Static_libs []string `android:"arch_variant"`
 
+	// Similar to static_libs, but will bundle the static library dependency into a library. This is helpful
+	// to avoid having to redeclare the dependency for dependents of this library, but in some cases may also
+	// result in bloat if multiple dependencies all include the same static library whole.
+	//
+	// The common use case for this is when the static library is unlikely to be a dependency of other modules to avoid
+	// having to redeclare the static library dependency for every dependent module.
+	// If you are not sure what to, for rust_library modules most static dependencies should go in static_libraries,
+	// and for rust_ffi modules most static dependencies should go into whole_static_libraries.
+	//
+	// For rust_ffi static variants, these libraries will be included in the resulting static library archive.
+	//
+	// For rust_library rlib variants, these libraries will be bundled into the resulting rlib library. This will
+	// include all of the static libraries symbols in any dylibs or binaries which use this rlib as well.
+	Whole_static_libs []string `android:"arch_variant"`
+
 	// crate name, required for modules which produce Rust libraries: rust_library, rust_ffi and SourceProvider
 	// modules which create library variants (rust_bindgen). This must be the expected extern crate name used in
 	// source, and is required to conform to an enforced format matching library output files (if the output file is
@@ -266,6 +278,7 @@ func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps {
 	deps.Rustlibs = append(deps.Rustlibs, compiler.Properties.Rustlibs...)
 	deps.ProcMacros = append(deps.ProcMacros, compiler.Properties.Proc_macros...)
 	deps.StaticLibs = append(deps.StaticLibs, compiler.Properties.Static_libs...)
+	deps.WholeStaticLibs = append(deps.WholeStaticLibs, compiler.Properties.Whole_static_libs...)
 	deps.SharedLibs = append(deps.SharedLibs, compiler.Properties.Shared_libs...)
 
 	if !Bool(compiler.Properties.No_stdlibs) {

+ 19 - 18
rust/rust.go

@@ -273,14 +273,15 @@ func (mod *Module) SplitPerApiLevel() bool {
 }
 
 type Deps struct {
-	Dylibs     []string
-	Rlibs      []string
-	Rustlibs   []string
-	Stdlibs    []string
-	ProcMacros []string
-	SharedLibs []string
-	StaticLibs []string
-	HeaderLibs []string
+	Dylibs          []string
+	Rlibs           []string
+	Rustlibs        []string
+	Stdlibs         []string
+	ProcMacros      []string
+	SharedLibs      []string
+	StaticLibs      []string
+	WholeStaticLibs []string
+	HeaderLibs      []string
 
 	CrtBegin, CrtEnd string
 }
@@ -755,7 +756,7 @@ func (mod *Module) deps(ctx DepsContext) Deps {
 	deps.ProcMacros = android.LastUniqueStrings(deps.ProcMacros)
 	deps.SharedLibs = android.LastUniqueStrings(deps.SharedLibs)
 	deps.StaticLibs = android.LastUniqueStrings(deps.StaticLibs)
-
+	deps.WholeStaticLibs = android.LastUniqueStrings(deps.WholeStaticLibs)
 	return deps
 
 }
@@ -915,16 +916,13 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
 			exportDep := false
 			switch {
 			case cc.IsStaticDepTag(depTag):
-				// Only pass -lstatic for rlibs as it results in dylib bloat.
-				if lib, ok := ctx.Module().(*Module).compiler.(libraryInterface); ok && lib.rlib() {
-					// Link cc static libraries using "-lstatic" so rustc can reason about how to handle these
-					// (for example, bundling them into rlibs).
-					//
-					// rustc does not support linking libraries with the "-l" flag unless they are prefixed by "lib".
-					// If we need to link a library that isn't prefixed by "lib", we'll just link to it directly through
-					// linkObjects; such a library may need to be redeclared by static dependents.
+				if cc.IsWholeStaticLib(depTag) {
+					// rustc will bundle static libraries when they're passed with "-lstatic=<lib>". This will fail
+					// if the library is not prefixed by "lib".
 					if libName, ok := libNameFromFilePath(linkObject.Path()); ok {
 						depPaths.depFlags = append(depPaths.depFlags, "-lstatic="+libName)
+					} else {
+						ctx.ModuleErrorf("'%q' cannot be listed as a whole_static_library in Rust modules unless the output is prefixed by 'lib'", depName, ctx.ModuleName())
 					}
 				}
 
@@ -1103,7 +1101,10 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
 		cc.SharedDepTag(), deps.SharedLibs...)
 	actx.AddVariationDependencies(append(commonDepVariations,
 		blueprint.Variation{Mutator: "link", Variation: "static"}),
-		cc.StaticDepTag(), deps.StaticLibs...)
+		cc.StaticDepTag(false), deps.StaticLibs...)
+	actx.AddVariationDependencies(append(commonDepVariations,
+		blueprint.Variation{Mutator: "link", Variation: "static"}),
+		cc.StaticDepTag(true), deps.WholeStaticLibs...)
 
 	actx.AddVariationDependencies(nil, cc.HeaderDepTag(), deps.HeaderLibs...)
 

+ 8 - 2
rust/rust_test.go

@@ -149,6 +149,11 @@ func TestDepsTracking(t *testing.T) {
 			srcs: ["foo.rs"],
 			crate_name: "static",
 		}
+		rust_ffi_host_static {
+			name: "libwholestatic",
+			srcs: ["foo.rs"],
+			crate_name: "wholestatic",
+		}
 		rust_ffi_host_shared {
 			name: "libshared",
 			srcs: ["foo.rs"],
@@ -164,6 +169,7 @@ func TestDepsTracking(t *testing.T) {
 			srcs: ["foo.rs"],
 			crate_name: "rlib",
 			static_libs: ["libstatic"],
+			whole_static_libs: ["libwholestatic"],
 		}
 		rust_proc_macro {
 			name: "libpm",
@@ -204,8 +210,8 @@ func TestDepsTracking(t *testing.T) {
 		t.Errorf("Static library dependency not detected (dependency missing from AndroidMkStaticLibs)")
 	}
 
-	if !strings.Contains(rustc.Args["rustcFlags"], "-lstatic=static") {
-		t.Errorf("-lstatic flag not being passed to rustc for static library")
+	if !strings.Contains(rustc.Args["rustcFlags"], "-lstatic=wholestatic") {
+		t.Errorf("-lstatic flag not being passed to rustc for static library %#v", rustc.Args["rustcFlags"])
 	}
 
 }