diff options
-rw-r--r-- | apex/builder.go | 4 | ||||
-rw-r--r-- | cc/lto.go | 1 | ||||
-rw-r--r-- | filesystem/vbmeta.go | 25 | ||||
-rw-r--r-- | genrule/allowlists.go | 14 | ||||
-rw-r--r-- | java/dex.go | 7 | ||||
-rw-r--r-- | java/sdk_library.go | 16 | ||||
-rw-r--r-- | java/sdk_library_test.go | 32 | ||||
-rw-r--r-- | java/test_spec_test.go | 3 | ||||
-rw-r--r-- | rust/binary.go | 7 | ||||
-rw-r--r-- | rust/builder.go | 8 | ||||
-rw-r--r-- | rust/compiler.go | 103 | ||||
-rw-r--r-- | rust/compiler_test.go | 3 | ||||
-rw-r--r-- | rust/library.go | 18 | ||||
-rw-r--r-- | rust/prebuilt.go | 23 | ||||
-rw-r--r-- | rust/proc_macro.go | 3 | ||||
-rw-r--r-- | rust/project_json.go | 154 | ||||
-rw-r--r-- | rust/rust.go | 38 |
17 files changed, 233 insertions, 226 deletions
diff --git a/apex/builder.go b/apex/builder.go index 9f9e486b7..3f358acd4 100644 --- a/apex/builder.go +++ b/apex/builder.go @@ -344,10 +344,12 @@ func (a *apexBundle) buildManifest(ctx android.ModuleContext, provideNativeLibs, func (a *apexBundle) buildFileContexts(ctx android.ModuleContext) android.OutputPath { var fileContexts android.Path var fileContextsDir string + isFileContextsModule := false if a.properties.File_contexts == nil { fileContexts = android.PathForSource(ctx, "system/sepolicy/apex", ctx.ModuleName()+"-file_contexts") } else { if m, t := android.SrcIsModuleWithTag(*a.properties.File_contexts); m != "" { + isFileContextsModule = true otherModule := android.GetModuleFromPathDep(ctx, m, t) fileContextsDir = ctx.OtherModuleDir(otherModule) } @@ -363,7 +365,7 @@ func (a *apexBundle) buildFileContexts(ctx android.ModuleContext) android.Output ctx.PropertyErrorf("file_contexts", "should be under system/sepolicy, but found in %q", fileContextsDir) } } - if !android.ExistentPathForSource(ctx, fileContexts.String()).Valid() { + if !isFileContextsModule && !android.ExistentPathForSource(ctx, fileContexts.String()).Valid() { ctx.PropertyErrorf("file_contexts", "cannot find file_contexts file: %q", fileContexts.String()) } @@ -150,7 +150,6 @@ func (lto *lto) flags(ctx BaseModuleContext, flags Flags) Flags { if !ctx.Config().IsEnvFalse("THINLTO_USE_MLGO") { // Register allocation MLGO flags for ARM64. if ctx.Arch().ArchType == android.Arm64 { - ltoCFlags = append(ltoCFlags, "-mllvm -regalloc-enable-advisor=release") ltoLdFlags = append(ltoLdFlags, "-Wl,-mllvm,-regalloc-enable-advisor=release") } // Flags for training MLGO model. diff --git a/filesystem/vbmeta.go b/filesystem/vbmeta.go index 63e0abaac..43a2f3712 100644 --- a/filesystem/vbmeta.go +++ b/filesystem/vbmeta.go @@ -63,6 +63,17 @@ type vbmetaProperties struct { // List of chained partitions that this vbmeta deletages the verification. Chained_partitions []chainedPartitionProperties + + // List of key-value pair of avb properties + Avb_properties []avbProperty +} + +type avbProperty struct { + // Key of given avb property + Key *string + + // Value of given avb property + Value *string } type chainedPartitionProperties struct { @@ -135,6 +146,20 @@ func (v *vbmeta) GenerateAndroidBuildActions(ctx android.ModuleContext) { } cmd.FlagWithArg("--rollback_index_location ", strconv.Itoa(ril)) + for _, avb_prop := range v.properties.Avb_properties { + key := proptools.String(avb_prop.Key) + if key == "" { + ctx.PropertyErrorf("avb_properties", "key must be specified") + continue + } + value := proptools.String(avb_prop.Value) + if value == "" { + ctx.PropertyErrorf("avb_properties", "value must be specified") + continue + } + cmd.FlagWithArg("--prop ", key+":"+value) + } + for _, p := range ctx.GetDirectDepsWithTag(vbmetaPartitionDep) { f, ok := p.(Filesystem) if !ok { diff --git a/genrule/allowlists.go b/genrule/allowlists.go index f0fcbbfa7..fa4af8739 100644 --- a/genrule/allowlists.go +++ b/genrule/allowlists.go @@ -24,20 +24,9 @@ var ( SandboxingDenyModuleList = []string{ // go/keep-sorted start "CtsApkVerityTestDebugFiles", - "MultiDexLegacyTestApp_genrule", "ScriptGroupTest-rscript", - "TracingVMProtoStub_cc", - "TracingVMProtoStub_h", - "VehicleServerProtoStub_cc", - "VehicleServerProtoStub_cc@2.0-grpc-trout", - "VehicleServerProtoStub_cc@default-grpc", - "VehicleServerProtoStub_h", - "VehicleServerProtoStub_h@2.0-grpc-trout", - "VehicleServerProtoStub_h@default-grpc", "aidl-golden-test-build-hook-gen", "aidl_camera_build_version", - "android-cts-verifier", - "atest_integration_fake_src", "camera-its", "checkIn-service-stub-lite", "chre_atoms_log.h", @@ -48,12 +37,9 @@ var ( "deqp_spvtools_update_build_version", "gen_corrupt_rebootless_apex", "gen_key_mismatch_capex", - "libbssl_sys_src_nostd", "libc_musl_sysroot_bits", "libcore-non-cts-tests-txt", "pvmfw_fdt_template_rs", - "r8retrace-dexdump-sample-app", - "r8retrace-run-retrace", "seller-frontend-service-stub-lite", "swiftshader_spvtools_update_build_version", "ue_unittest_erofs_imgs", diff --git a/java/dex.go b/java/dex.go index aa017834d..dab0836ff 100644 --- a/java/dex.go +++ b/java/dex.go @@ -106,7 +106,7 @@ func (d *dexer) effectiveOptimizeEnabled() bool { var d8, d8RE = pctx.MultiCommandRemoteStaticRules("d8", blueprint.RuleParams{ Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` + - `$d8Template${config.D8Cmd} ${config.D8Flags} --output $outDir $d8Flags --no-dex-input-jar $in && ` + + `$d8Template${config.D8Cmd} ${config.D8Flags} $d8Flags --output $outDir --no-dex-input-jar $in && ` + `$zipTemplate${config.SoongZipCmd} $zipFlags -o $outDir/classes.dex.jar -C $outDir -f "$outDir/classes*.dex" && ` + `${config.MergeZipsCmd} -D -stripFile "**/*.class" $mergeZipsFlags $out $outDir/classes.dex.jar $in && ` + `rm -f "$outDir/classes*.dex" "$outDir/classes.dex.jar"`, @@ -137,13 +137,12 @@ var r8, r8RE = pctx.MultiCommandRemoteStaticRules("r8", Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` + `rm -f "$outDict" && rm -f "$outConfig" && rm -rf "${outUsageDir}" && ` + `mkdir -p $$(dirname ${outUsage}) && ` + - `$r8Template${config.R8Cmd} ${config.R8Flags} -injars $in --output $outDir ` + + `$r8Template${config.R8Cmd} ${config.R8Flags} $r8Flags -injars $in --output $outDir ` + `--no-data-resources ` + `-printmapping ${outDict} ` + `-printconfiguration ${outConfig} ` + `-printusage ${outUsage} ` + - `--deps-file ${out}.d ` + - `$r8Flags && ` + + `--deps-file ${out}.d && ` + `touch "${outDict}" "${outConfig}" "${outUsage}" && ` + `${config.SoongZipCmd} -o ${outUsageZip} -C ${outUsageDir} -f ${outUsage} && ` + `rm -rf ${outUsageDir} && ` + diff --git a/java/sdk_library.go b/java/sdk_library.go index fb2781213..fbfe509b8 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -1993,6 +1993,7 @@ func (module *SdkLibrary) createXmlFile(mctx android.DefaultableHookContext) { Min_device_sdk *string Max_device_sdk *string Sdk_library_min_api_level *string + Uses_libs_dependencies []string }{ Name: proptools.StringPtr(module.xmlPermissionsModuleName()), Lib_name: proptools.StringPtr(module.BaseModuleName()), @@ -2002,6 +2003,7 @@ func (module *SdkLibrary) createXmlFile(mctx android.DefaultableHookContext) { Min_device_sdk: module.commonSdkLibraryProperties.Min_device_sdk, Max_device_sdk: module.commonSdkLibraryProperties.Max_device_sdk, Sdk_library_min_api_level: &moduleMinApiLevelStr, + Uses_libs_dependencies: module.usesLibraryProperties.Uses_libs, } mctx.CreateModule(sdkLibraryXmlFactory, &props) @@ -2968,6 +2970,11 @@ type sdkLibraryXmlProperties struct { // // This value comes from the ApiLevel of the MinSdkVersion property. Sdk_library_min_api_level *string + + // Uses-libs dependencies that the shared library requires to work correctly. + // + // This will add dependency="foo:bar" to the <library> section. + Uses_libs_dependencies []string } // java_sdk_library_xml builds the permission xml file for a java_sdk_library. @@ -3076,6 +3083,13 @@ func formattedOptionalAttribute(attrName string, value *string) string { return fmt.Sprintf(` %s=\"%s\"\n`, attrName, *value) } +func formattedDependenciesAttribute(dependencies []string) string { + if dependencies == nil { + return "" + } + return fmt.Sprintf(` dependency=\"%s\"\n`, strings.Join(dependencies, ":")) +} + func (module *sdkLibraryXml) permissionsContents(ctx android.ModuleContext) string { libName := proptools.String(module.properties.Lib_name) libNameAttr := formattedOptionalAttribute("name", &libName) @@ -3085,6 +3099,7 @@ func (module *sdkLibraryXml) permissionsContents(ctx android.ModuleContext) stri implicitUntilAttr := formattedOptionalSdkLevelAttribute(ctx, "on-bootclasspath-before", module.properties.On_bootclasspath_before) minSdkAttr := formattedOptionalSdkLevelAttribute(ctx, "min-device-sdk", module.properties.Min_device_sdk) maxSdkAttr := formattedOptionalSdkLevelAttribute(ctx, "max-device-sdk", module.properties.Max_device_sdk) + dependenciesAttr := formattedDependenciesAttribute(module.properties.Uses_libs_dependencies) // <library> is understood in all android versions whereas <apex-library> is only understood from API T (and ignored before that). // similarly, min_device_sdk is only understood from T. So if a library is using that, we need to use the apex-library to make sure this library is not loaded before T var libraryTag string @@ -3118,6 +3133,7 @@ func (module *sdkLibraryXml) permissionsContents(ctx android.ModuleContext) stri implicitUntilAttr, minSdkAttr, maxSdkAttr, + dependenciesAttr, ` />\n`, `</permissions>\n`}, "") } diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go index 82f8a4d50..a136818ca 100644 --- a/java/sdk_library_test.go +++ b/java/sdk_library_test.go @@ -1665,3 +1665,35 @@ func TestStaticDepStubLibrariesVisibility(t *testing.T) { } `) } + +func TestSdkLibraryDependency(t *testing.T) { + result := android.GroupFixturePreparers( + prepareForJavaTest, + PrepareForTestWithJavaSdkLibraryFiles, + FixtureWithPrebuiltApis(map[string][]string{ + "30": {"bar", "foo"}, + }), + ).RunTestWithBp(t, + ` + java_sdk_library { + name: "foo", + srcs: ["a.java", "b.java"], + api_packages: ["foo"], + } + + java_sdk_library { + name: "bar", + srcs: ["c.java", "b.java"], + libs: [ + "foo", + ], + uses_libs: [ + "foo", + ], + } +`) + + barPermissions := result.ModuleForTests("bar.xml", "android_common").Rule("java_sdk_xml") + + android.AssertStringDoesContain(t, "bar.xml java_sdk_xml command", barPermissions.RuleParams.Command, `dependency=\"foo\"`) +} diff --git a/java/test_spec_test.go b/java/test_spec_test.go index 22a8e60ee..39aff4cef 100644 --- a/java/test_spec_test.go +++ b/java/test_spec_test.go @@ -86,7 +86,8 @@ func TestTestSpec(t *testing.T) { // Tests for all_test_spec singleton. singleton := result.SingletonForTests("all_test_specs") rule := singleton.Rule("all_test_specs_rule") - expectedCmd := "out/soong/host/linux-x86/bin/metadata -rule test_spec -inputFile out/soong/all_test_spec_paths.rsp -outputFile out/soong/ownership/all_test_specs.pb" + prebuiltOs := result.Config.PrebuiltOS() + expectedCmd := "out/soong/host/" + prebuiltOs + "/bin/metadata -rule test_spec -inputFile out/soong/all_test_spec_paths.rsp -outputFile out/soong/ownership/all_test_specs.pb" expectedOutputFile := "out/soong/ownership/all_test_specs.pb" expectedInputFile := "out/soong/.intermediates/module-name/intermediateTestSpecMetadata.pb" if !strings.Contains( diff --git a/rust/binary.go b/rust/binary.go index 860dc948a..5e7e922cf 100644 --- a/rust/binary.go +++ b/rust/binary.go @@ -137,12 +137,7 @@ func (binary *binaryDecorator) compile(ctx ModuleContext, flags Flags, deps Path fileName := binary.getStem(ctx) + ctx.toolchain().ExecutableSuffix() outputFile := android.PathForModuleOut(ctx, fileName) ret := buildOutput{outputFile: outputFile} - var crateRootPath android.Path - if binary.baseCompiler.Properties.Crate_root == nil { - crateRootPath, _ = srcPathFromModuleSrcs(ctx, binary.baseCompiler.Properties.Srcs) - } else { - crateRootPath = android.PathForModuleSrc(ctx, *binary.baseCompiler.Properties.Crate_root) - } + crateRootPath := crateRootPath(ctx, binary) flags.RustFlags = append(flags.RustFlags, deps.depFlags...) flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...) diff --git a/rust/builder.go b/rust/builder.go index 162d1aab0..c855cfbd2 100644 --- a/rust/builder.go +++ b/rust/builder.go @@ -196,7 +196,7 @@ func rustEnvVars(ctx ModuleContext, deps PathDeps) []string { } if len(deps.SrcDeps) > 0 { - moduleGenDir := ctx.RustModule().compiler.CargoOutDir() + moduleGenDir := ctx.RustModule().compiler.cargoOutDir() // We must calculate an absolute path for OUT_DIR since Rust's include! macro (which normally consumes this) // assumes that paths are relative to the source file. var outDirPrefix string @@ -215,13 +215,13 @@ func rustEnvVars(ctx ModuleContext, deps PathDeps) []string { envVars = append(envVars, "ANDROID_RUST_VERSION="+config.GetRustVersion(ctx)) - if ctx.RustModule().compiler.CargoEnvCompat() { + if ctx.RustModule().compiler.cargoEnvCompat() { if bin, ok := ctx.RustModule().compiler.(*binaryDecorator); ok { envVars = append(envVars, "CARGO_BIN_NAME="+bin.getStem(ctx)) } envVars = append(envVars, "CARGO_CRATE_NAME="+ctx.RustModule().CrateName()) envVars = append(envVars, "CARGO_PKG_NAME="+ctx.RustModule().CrateName()) - pkgVersion := ctx.RustModule().compiler.CargoPkgVersion() + pkgVersion := ctx.RustModule().compiler.cargoPkgVersion() if pkgVersion != "" { envVars = append(envVars, "CARGO_PKG_VERSION="+pkgVersion) @@ -327,7 +327,7 @@ func transformSrctoCrate(ctx ModuleContext, main android.Path, deps PathDeps, fl orderOnly = append(orderOnly, deps.SharedLibs...) if len(deps.SrcDeps) > 0 { - moduleGenDir := ctx.RustModule().compiler.CargoOutDir() + moduleGenDir := ctx.RustModule().compiler.cargoOutDir() var outputs android.WritablePaths for _, genSrc := range deps.SrcDeps { diff --git a/rust/compiler.go b/rust/compiler.go index 4c7961d44..d453a5d6f 100644 --- a/rust/compiler.go +++ b/rust/compiler.go @@ -16,6 +16,7 @@ package rust import ( "android/soong/cc" + "errors" "fmt" "path/filepath" "strings" @@ -34,6 +35,48 @@ const ( DylibLinkage ) +type compiler interface { + initialize(ctx ModuleContext) + compilerFlags(ctx ModuleContext, flags Flags) Flags + cfgFlags(ctx ModuleContext, flags Flags) Flags + featureFlags(ctx ModuleContext, flags Flags) Flags + compilerProps() []interface{} + compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput + compilerDeps(ctx DepsContext, deps Deps) Deps + crateName() string + edition() string + features() []string + rustdoc(ctx ModuleContext, flags Flags, deps PathDeps) android.OptionalPath + + // Output directory in which source-generated code from dependencies is + // copied. This is equivalent to Cargo's OUT_DIR variable. + cargoOutDir() android.OptionalPath + + // cargoPkgVersion returns the value of the Cargo_pkg_version property. + cargoPkgVersion() string + + // cargoEnvCompat returns whether Cargo environment variables should be used. + cargoEnvCompat() bool + + inData() bool + install(ctx ModuleContext) + relativeInstallPath() string + everInstallable() bool + + nativeCoverage() bool + + Disabled() bool + SetDisabled() + + stdLinkage(ctx *depsContext) RustLinkage + noStdlibs() bool + + unstrippedOutputFilePath() android.Path + strippedOutputFilePath() android.OptionalPath + + checkedCrateRootPath() (android.Path, error) +} + func (compiler *baseCompiler) edition() string { return proptools.StringDefault(compiler.Properties.Edition, config.DefaultEdition) } @@ -204,7 +247,16 @@ type baseCompiler struct { // If a crate has a source-generated dependency, a copy of the source file // will be available in cargoOutDir (equivalent to Cargo OUT_DIR). - cargoOutDir android.ModuleOutPath + // This is stored internally because it may not be available during + // singleton-generation passes like rustdoc/rust_project.json, but should + // be stashed during initial generation. + cachedCargoOutDir android.ModuleOutPath + // Calculated crate root cached internally because ModuleContext is not + // available to singleton targets like rustdoc/rust_project.json + cachedCrateRootPath android.Path + // If cachedCrateRootPath is nil after initialization, this will contain + // an explanation of why + cachedCrateRootError error } func (compiler *baseCompiler) Disabled() bool { @@ -257,9 +309,13 @@ func (compiler *baseCompiler) cfgsToFlags() []string { return flags } +func (compiler *baseCompiler) features() []string { + return compiler.Properties.Features +} + func (compiler *baseCompiler) featuresToFlags() []string { flags := []string{} - for _, feature := range compiler.Properties.Features { + for _, feature := range compiler.features() { flags = append(flags, "--cfg 'feature=\""+feature+"\"'") } @@ -355,18 +411,24 @@ func (compiler *baseCompiler) rustdoc(ctx ModuleContext, flags Flags, } func (compiler *baseCompiler) initialize(ctx ModuleContext) { - compiler.cargoOutDir = android.PathForModuleOut(ctx, genSubDir) + compiler.cachedCargoOutDir = android.PathForModuleOut(ctx, genSubDir) + if compiler.Properties.Crate_root == nil { + compiler.cachedCrateRootPath, compiler.cachedCrateRootError = srcPathFromModuleSrcs(ctx, compiler.Properties.Srcs) + } else { + compiler.cachedCrateRootPath = android.PathForModuleSrc(ctx, *compiler.Properties.Crate_root) + compiler.cachedCrateRootError = nil + } } -func (compiler *baseCompiler) CargoOutDir() android.OptionalPath { - return android.OptionalPathForPath(compiler.cargoOutDir) +func (compiler *baseCompiler) cargoOutDir() android.OptionalPath { + return android.OptionalPathForPath(compiler.cachedCargoOutDir) } -func (compiler *baseCompiler) CargoEnvCompat() bool { +func (compiler *baseCompiler) cargoEnvCompat() bool { return Bool(compiler.Properties.Cargo_env_compat) } -func (compiler *baseCompiler) CargoPkgVersion() string { +func (compiler *baseCompiler) cargoPkgVersion() string { return String(compiler.Properties.Cargo_pkg_version) } @@ -496,12 +558,20 @@ func (compiler *baseCompiler) relativeInstallPath() string { return String(compiler.Properties.Relative_install_path) } -// Returns the Path for the main source file along with Paths for generated source files from modules listed in srcs. -func srcPathFromModuleSrcs(ctx ModuleContext, srcs []string) (android.Path, android.Paths) { - if len(srcs) == 0 { - ctx.PropertyErrorf("srcs", "srcs must not be empty") +func (compiler *baseCompiler) checkedCrateRootPath() (android.Path, error) { + return compiler.cachedCrateRootPath, compiler.cachedCrateRootError +} + +func crateRootPath(ctx ModuleContext, compiler compiler) android.Path { + root, err := compiler.checkedCrateRootPath() + if err != nil { + ctx.PropertyErrorf("srcs", err.Error()) } + return root +} +// Returns the Path for the main source file along with Paths for generated source files from modules listed in srcs. +func srcPathFromModuleSrcs(ctx ModuleContext, srcs []string) (android.Path, error) { // The srcs can contain strings with prefix ":". // They are dependent modules of this module, with android.SourceDepTag. // They are not the main source file compiled by rustc. @@ -514,19 +584,22 @@ func srcPathFromModuleSrcs(ctx ModuleContext, srcs []string) (android.Path, andr } } if numSrcs > 1 { - ctx.PropertyErrorf("srcs", incorrectSourcesError) + return nil, errors.New(incorrectSourcesError) } // If a main source file is not provided we expect only a single SourceProvider module to be defined // within srcs, with the expectation that the first source it provides is the entry point. if srcIndex != 0 { - ctx.PropertyErrorf("srcs", "main source file must be the first in srcs") + return nil, errors.New("main source file must be the first in srcs") } else if numSrcs > 1 { - ctx.PropertyErrorf("srcs", "only a single generated source module can be defined without a main source file.") + return nil, errors.New("only a single generated source module can be defined without a main source file.") } // TODO: b/297264540 - once all modules are sandboxed, we need to select the proper // entry point file from Srcs rather than taking the first one paths := android.PathsForModuleSrc(ctx, srcs) - return paths[srcIndex], paths[1:] + if len(paths) == 0 { + return nil, errors.New("srcs must not be empty") + } + return paths[srcIndex], nil } diff --git a/rust/compiler_test.go b/rust/compiler_test.go index ec6829a1b..89f4d1abf 100644 --- a/rust/compiler_test.go +++ b/rust/compiler_test.go @@ -67,6 +67,7 @@ func TestCfgsToFlags(t *testing.T) { func TestEnforceSingleSourceFile(t *testing.T) { singleSrcError := "srcs can only contain one path for a rust file and source providers prefixed by \":\"" + prebuiltSingleSrcError := "prebuilt libraries can only have one entry in srcs" // Test libraries testRustError(t, singleSrcError, ` @@ -90,7 +91,7 @@ func TestEnforceSingleSourceFile(t *testing.T) { }`) // Test prebuilts - testRustError(t, singleSrcError, ` + testRustError(t, prebuiltSingleSrcError, ` rust_prebuilt_dylib { name: "foo-bar-prebuilt", srcs: ["liby.so", "libz.so"], diff --git a/rust/library.go b/rust/library.go index 18bf0a05b..c0ff741db 100644 --- a/rust/library.go +++ b/rust/library.go @@ -15,6 +15,7 @@ package rust import ( + "errors" "fmt" "regexp" "strings" @@ -489,7 +490,7 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa var outputFile android.ModuleOutPath var ret buildOutput var fileName string - crateRootPath := library.crateRootPath(ctx, deps) + crateRootPath := crateRootPath(ctx, library) if library.sourceProvider != nil { deps.srcProviderFiles = append(deps.srcProviderFiles, library.sourceProvider.Srcs()...) @@ -584,15 +585,16 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa return ret } -func (library *libraryDecorator) crateRootPath(ctx ModuleContext, _ PathDeps) android.Path { +func (library *libraryDecorator) checkedCrateRootPath() (android.Path, error) { if library.sourceProvider != nil { + srcs := library.sourceProvider.Srcs() + if len(srcs) == 0 { + return nil, errors.New("Source provider generated 0 sources") + } // Assume the first source from the source provider is the library entry point. - return library.sourceProvider.Srcs()[0] - } else if library.baseCompiler.Properties.Crate_root == nil { - path, _ := srcPathFromModuleSrcs(ctx, library.baseCompiler.Properties.Srcs) - return path + return srcs[0], nil } else { - return android.PathForModuleSrc(ctx, *library.baseCompiler.Properties.Crate_root) + return library.baseCompiler.checkedCrateRootPath() } } @@ -607,7 +609,7 @@ func (library *libraryDecorator) rustdoc(ctx ModuleContext, flags Flags, return android.OptionalPath{} } - return android.OptionalPathForPath(Rustdoc(ctx, library.crateRootPath(ctx, deps), + return android.OptionalPathForPath(Rustdoc(ctx, crateRootPath(ctx, library), deps, flags)) } diff --git a/rust/prebuilt.go b/rust/prebuilt.go index fe9d0b5dd..e35e510da 100644 --- a/rust/prebuilt.go +++ b/rust/prebuilt.go @@ -76,6 +76,17 @@ var _ compiler = (*prebuiltProcMacroDecorator)(nil) var _ exportedFlagsProducer = (*prebuiltProcMacroDecorator)(nil) var _ rustPrebuilt = (*prebuiltProcMacroDecorator)(nil) +func prebuiltPath(ctx ModuleContext, prebuilt rustPrebuilt) android.Path { + srcs := android.PathsForModuleSrc(ctx, prebuilt.prebuiltSrcs()) + if len(srcs) == 0 { + ctx.PropertyErrorf("srcs", "srcs must not be empty") + } + if len(srcs) > 1 { + ctx.PropertyErrorf("srcs", "prebuilt libraries can only have one entry in srcs (the prebuilt path)") + } + return srcs[0] +} + func PrebuiltLibraryFactory() android.Module { module, _ := NewPrebuiltLibrary(android.HostAndDeviceSupported) return module.Init() @@ -148,11 +159,7 @@ func (prebuilt *prebuiltLibraryDecorator) compilerProps() []interface{} { func (prebuilt *prebuiltLibraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput { prebuilt.flagExporter.exportLinkDirs(android.PathsForModuleSrc(ctx, prebuilt.Properties.Link_dirs).Strings()...) prebuilt.flagExporter.setProvider(ctx) - - srcPath, paths := srcPathFromModuleSrcs(ctx, prebuilt.prebuiltSrcs()) - if len(paths) > 0 { - ctx.PropertyErrorf("srcs", "prebuilt libraries can only have one entry in srcs (the prebuilt path)") - } + srcPath := prebuiltPath(ctx, prebuilt) prebuilt.baseCompiler.unstrippedOutputFile = srcPath return buildOutput{outputFile: srcPath} } @@ -205,11 +212,7 @@ func (prebuilt *prebuiltProcMacroDecorator) compilerProps() []interface{} { func (prebuilt *prebuiltProcMacroDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput { prebuilt.flagExporter.exportLinkDirs(android.PathsForModuleSrc(ctx, prebuilt.Properties.Link_dirs).Strings()...) prebuilt.flagExporter.setProvider(ctx) - - srcPath, paths := srcPathFromModuleSrcs(ctx, prebuilt.prebuiltSrcs()) - if len(paths) > 0 { - ctx.PropertyErrorf("srcs", "prebuilt libraries can only have one entry in srcs (the prebuilt path)") - } + srcPath := prebuiltPath(ctx, prebuilt) prebuilt.baseCompiler.unstrippedOutputFile = srcPath return buildOutput{outputFile: srcPath} } diff --git a/rust/proc_macro.go b/rust/proc_macro.go index b93b24f15..c18d5ec70 100644 --- a/rust/proc_macro.go +++ b/rust/proc_macro.go @@ -78,8 +78,7 @@ func (procMacro *procMacroDecorator) compilerFlags(ctx ModuleContext, flags Flag func (procMacro *procMacroDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput { fileName := procMacro.getStem(ctx) + ctx.toolchain().ProcMacroSuffix() outputFile := android.PathForModuleOut(ctx, fileName) - - srcPath, _ := srcPathFromModuleSrcs(ctx, procMacro.baseCompiler.Properties.Srcs) + srcPath := crateRootPath(ctx, procMacro) ret := TransformSrctoProcMacro(ctx, srcPath, deps, flags, outputFile) procMacro.baseCompiler.unstrippedOutputFile = outputFile return ret diff --git a/rust/project_json.go b/rust/project_json.go index 40aa7c736..83c16ca38 100644 --- a/rust/project_json.go +++ b/rust/project_json.go @@ -17,7 +17,6 @@ package rust import ( "encoding/json" "fmt" - "path" "android/soong/android" ) @@ -60,8 +59,9 @@ type rustProjectJson struct { // crateInfo is used during the processing to keep track of the known crates. type crateInfo struct { - Idx int // Index of the crate in rustProjectJson.Crates slice. - Deps map[string]int // The keys are the module names and not the crate names. + Idx int // Index of the crate in rustProjectJson.Crates slice. + Deps map[string]int // The keys are the module names and not the crate names. + Device bool // True if the crate at idx was a device crate } type projectGeneratorSingleton struct { @@ -77,85 +77,6 @@ func init() { android.RegisterParallelSingletonType("rust_project_generator", rustProjectGeneratorSingleton) } -// sourceProviderVariantSource returns the path to the source file if this -// module variant should be used as a priority. -// -// SourceProvider modules may have multiple variants considered as source -// (e.g., x86_64 and armv8). For a module available on device, use the source -// generated for the target. For a host-only module, use the source generated -// for the host. -func sourceProviderVariantSource(ctx android.SingletonContext, rModule *Module) (string, bool) { - rustLib, ok := rModule.compiler.(*libraryDecorator) - if !ok { - return "", false - } - if rustLib.source() { - switch rModule.hod { - case android.HostSupported, android.HostSupportedNoCross: - if rModule.Target().String() == ctx.Config().BuildOSTarget.String() { - src := rustLib.sourceProvider.Srcs()[0] - return src.String(), true - } - default: - if rModule.Target().String() == ctx.Config().AndroidFirstDeviceTarget.String() { - src := rustLib.sourceProvider.Srcs()[0] - return src.String(), true - } - } - } - return "", false -} - -// sourceProviderSource finds the main source file of a source-provider crate. -func sourceProviderSource(ctx android.SingletonContext, rModule *Module) (string, bool) { - rustLib, ok := rModule.compiler.(*libraryDecorator) - if !ok { - return "", false - } - if rustLib.source() { - // This is a source-variant, check if we are the right variant - // depending on the module configuration. - if src, ok := sourceProviderVariantSource(ctx, rModule); ok { - return src, true - } - } - foundSource := false - sourceSrc := "" - // Find the variant with the source and return its. - ctx.VisitAllModuleVariants(rModule, func(variant android.Module) { - if foundSource { - return - } - // All variants of a source provider library are libraries. - rVariant, _ := variant.(*Module) - variantLib, _ := rVariant.compiler.(*libraryDecorator) - if variantLib.source() { - sourceSrc, ok = sourceProviderVariantSource(ctx, rVariant) - if ok { - foundSource = true - } - } - }) - if !foundSource { - ctx.Errorf("No valid source for source provider found: %v\n", rModule) - } - return sourceSrc, foundSource -} - -// crateSource finds the main source file (.rs) for a crate. -func crateSource(ctx android.SingletonContext, rModule *Module, comp *baseCompiler) (string, bool) { - // Basic libraries, executables and tests. - srcs := comp.Properties.Srcs - if len(srcs) != 0 { - return path.Join(ctx.ModuleDir(rModule), srcs[0]), true - } - // SourceProvider libraries. - if rModule.sourceProvider != nil { - return sourceProviderSource(ctx, rModule) - } - return "", false -} - // mergeDependencies visits all the dependencies for module and updates crate and deps // with any new dependency. func (singleton *projectGeneratorSingleton) mergeDependencies(ctx android.SingletonContext, @@ -167,7 +88,7 @@ func (singleton *projectGeneratorSingleton) mergeDependencies(ctx android.Single return } // Skip unsupported modules. - rChild, compChild, ok := isModuleSupported(ctx, child) + rChild, ok := isModuleSupported(ctx, child) if !ok { return } @@ -175,7 +96,7 @@ func (singleton *projectGeneratorSingleton) mergeDependencies(ctx android.Single var childId int cInfo, known := singleton.knownCrates[rChild.Name()] if !known { - childId, ok = singleton.addCrate(ctx, rChild, compChild) + childId, ok = singleton.addCrate(ctx, rChild, make(map[string]int)) if !ok { return } @@ -191,41 +112,22 @@ func (singleton *projectGeneratorSingleton) mergeDependencies(ctx android.Single }) } -// isModuleSupported returns the RustModule and baseCompiler if the module +// isModuleSupported returns the RustModule if the module // should be considered for inclusion in rust-project.json. -func isModuleSupported(ctx android.SingletonContext, module android.Module) (*Module, *baseCompiler, bool) { +func isModuleSupported(ctx android.SingletonContext, module android.Module) (*Module, bool) { rModule, ok := module.(*Module) if !ok { - return nil, nil, false - } - if rModule.compiler == nil { - return nil, nil, false + return nil, false } - var comp *baseCompiler - switch c := rModule.compiler.(type) { - case *libraryDecorator: - comp = c.baseCompiler - case *binaryDecorator: - comp = c.baseCompiler - case *testDecorator: - comp = c.binaryDecorator.baseCompiler - case *procMacroDecorator: - comp = c.baseCompiler - case *toolchainLibraryDecorator: - comp = c.baseCompiler - default: - return nil, nil, false - } - return rModule, comp, true + return rModule, true } // addCrate adds a crate to singleton.project.Crates ensuring that required // dependencies are also added. It returns the index of the new crate in // singleton.project.Crates -func (singleton *projectGeneratorSingleton) addCrate(ctx android.SingletonContext, rModule *Module, comp *baseCompiler) (int, bool) { - rootModule, ok := crateSource(ctx, rModule, comp) - if !ok { - ctx.Errorf("Unable to find source for valid module: %v", rModule) +func (singleton *projectGeneratorSingleton) addCrate(ctx android.SingletonContext, rModule *Module, deps map[string]int) (int, bool) { + rootModule, err := rModule.compiler.checkedCrateRootPath() + if err != nil { return 0, false } @@ -233,28 +135,33 @@ func (singleton *projectGeneratorSingleton) addCrate(ctx android.SingletonContex crate := rustProjectCrate{ DisplayName: rModule.Name(), - RootModule: rootModule, - Edition: comp.edition(), + RootModule: rootModule.String(), + Edition: rModule.compiler.edition(), Deps: make([]rustProjectDep, 0), Cfg: make([]string, 0), Env: make(map[string]string), ProcMacro: procMacro, } - if comp.CargoOutDir().Valid() { - crate.Env["OUT_DIR"] = comp.CargoOutDir().String() + if rModule.compiler.cargoOutDir().Valid() { + crate.Env["OUT_DIR"] = rModule.compiler.cargoOutDir().String() } - for _, feature := range comp.Properties.Features { + for _, feature := range rModule.compiler.features() { crate.Cfg = append(crate.Cfg, "feature=\""+feature+"\"") } - deps := make(map[string]int) singleton.mergeDependencies(ctx, rModule, &crate, deps) - idx := len(singleton.project.Crates) - singleton.knownCrates[rModule.Name()] = crateInfo{Idx: idx, Deps: deps} - singleton.project.Crates = append(singleton.project.Crates, crate) + var idx int + if cInfo, ok := singleton.knownCrates[rModule.Name()]; ok { + idx = cInfo.Idx + singleton.project.Crates[idx] = crate + } else { + idx = len(singleton.project.Crates) + singleton.project.Crates = append(singleton.project.Crates, crate) + } + singleton.knownCrates[rModule.Name()] = crateInfo{Idx: idx, Deps: deps, Device: rModule.Device()} return idx, true } @@ -262,18 +169,23 @@ func (singleton *projectGeneratorSingleton) addCrate(ctx android.SingletonContex // It visits the dependencies of the module depth-first so the dependency ID can be added to the current module. If the // current module is already in singleton.knownCrates, its dependencies are merged. func (singleton *projectGeneratorSingleton) appendCrateAndDependencies(ctx android.SingletonContext, module android.Module) { - rModule, comp, ok := isModuleSupported(ctx, module) + rModule, ok := isModuleSupported(ctx, module) if !ok { return } // If we have seen this crate already; merge any new dependencies. if cInfo, ok := singleton.knownCrates[module.Name()]; ok { + // If we have a new device variant, override the old one + if !cInfo.Device && rModule.Device() { + singleton.addCrate(ctx, rModule, cInfo.Deps) + return + } crate := singleton.project.Crates[cInfo.Idx] singleton.mergeDependencies(ctx, rModule, &crate, cInfo.Deps) singleton.project.Crates[cInfo.Idx] = crate return } - singleton.addCrate(ctx, rModule, comp) + singleton.addCrate(ctx, rModule, make(map[string]int)) } func (singleton *projectGeneratorSingleton) GenerateBuildActions(ctx android.SingletonContext) { diff --git a/rust/rust.go b/rust/rust.go index 15144acad..d4d33c71d 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -487,44 +487,6 @@ type RustLibrary struct { CrateName string } -type compiler interface { - initialize(ctx ModuleContext) - compilerFlags(ctx ModuleContext, flags Flags) Flags - cfgFlags(ctx ModuleContext, flags Flags) Flags - featureFlags(ctx ModuleContext, flags Flags) Flags - compilerProps() []interface{} - compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput - compilerDeps(ctx DepsContext, deps Deps) Deps - crateName() string - rustdoc(ctx ModuleContext, flags Flags, deps PathDeps) android.OptionalPath - - // Output directory in which source-generated code from dependencies is - // copied. This is equivalent to Cargo's OUT_DIR variable. - CargoOutDir() android.OptionalPath - - // CargoPkgVersion returns the value of the Cargo_pkg_version property. - CargoPkgVersion() string - - // CargoEnvCompat returns whether Cargo environment variables should be used. - CargoEnvCompat() bool - - inData() bool - install(ctx ModuleContext) - relativeInstallPath() string - everInstallable() bool - - nativeCoverage() bool - - Disabled() bool - SetDisabled() - - stdLinkage(ctx *depsContext) RustLinkage - noStdlibs() bool - - unstrippedOutputFilePath() android.Path - strippedOutputFilePath() android.OptionalPath -} - type exportedFlagsProducer interface { exportLinkDirs(...string) exportLinkObjects(...string) |