diff options
59 files changed, 1458 insertions, 758 deletions
diff --git a/android/module.go b/android/module.go index 70b602bf4..a6b8d5364 100644 --- a/android/module.go +++ b/android/module.go @@ -1195,9 +1195,9 @@ func (m *moduleContext) Variable(pctx PackageContext, name, value string) { func (m *moduleContext) Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule { - if m.config.UseGoma() && params.Pool == nil { - // When USE_GOMA=true is set and the rule is not supported by goma, restrict jobs to the - // local parallelism value + if (m.config.UseGoma() || m.config.UseRBE()) && params.Pool == nil { + // When USE_GOMA=true or USE_RBE=true are set and the rule is not supported by goma/RBE, restrict + // jobs to the local parallelism value params.Pool = localPool } diff --git a/android/neverallow.go b/android/neverallow.go index aff706ca3..48efb4f9a 100644 --- a/android/neverallow.go +++ b/android/neverallow.go @@ -64,6 +64,8 @@ func createIncludeDirsRules() []Rule { // The list of paths that cannot be referenced using include_dirs paths := []string{ "art", + "art/libnativebridge", + "art/libnativeloader", "libcore", "libnativehelper", "external/apache-harmony", @@ -75,8 +77,6 @@ func createIncludeDirsRules() []Rule { "external/okhttp", "external/vixl", "external/wycheproof", - "system/core/libnativebridge", - "system/core/libnativehelper", } // Create a composite matcher that will match if the value starts with any of the restricted diff --git a/android/package_ctx.go b/android/package_ctx.go index 548450e44..cf8facef4 100644 --- a/android/package_ctx.go +++ b/android/package_ctx.go @@ -115,9 +115,9 @@ func (p PackageContext) RuleFunc(name string, if len(ctx.errors) > 0 { return params, ctx.errors[0] } - if ctx.Config().UseGoma() && params.Pool == nil { - // When USE_GOMA=true is set and the rule is not supported by goma, restrict jobs to the - // local parallelism value + if (ctx.Config().UseGoma() || ctx.Config().UseRBE()) && params.Pool == nil { + // When USE_GOMA=true or USE_RBE=true are set and the rule is not supported by + // goma/RBE, restrict jobs to the local parallelism value params.Pool = localPool } return params, nil @@ -254,9 +254,35 @@ func (p PackageContext) StaticRule(name string, params blueprint.RuleParams, }, argNames...) } -// AndroidGomaStaticRule wraps blueprint.StaticRule but uses goma's parallelism if goma is enabled -func (p PackageContext) AndroidGomaStaticRule(name string, params blueprint.RuleParams, +// RemoteRuleSupports selects if a AndroidRemoteStaticRule supports goma, RBE, or both. +type RemoteRuleSupports int + +const ( + SUPPORTS_NONE = 0 + SUPPORTS_GOMA = 1 << iota + SUPPORTS_RBE = 1 << iota + SUPPORTS_BOTH = SUPPORTS_GOMA | SUPPORTS_RBE +) + +// AndroidRemoteStaticRule wraps blueprint.StaticRule but uses goma or RBE's parallelism if goma or RBE are enabled +// and the appropriate SUPPORTS_* flag is set. +func (p PackageContext) AndroidRemoteStaticRule(name string, supports RemoteRuleSupports, params blueprint.RuleParams, argNames ...string) blueprint.Rule { - // bypass android.PackageContext.StaticRule so that Pool does not get set to local_pool. - return p.PackageContext.StaticRule(name, params, argNames...) + + return p.PackageContext.RuleFunc(name, func(config interface{}) (blueprint.RuleParams, error) { + ctx := &configErrorWrapper{p, config.(Config), nil} + if ctx.Config().UseGoma() && supports&SUPPORTS_GOMA == 0 { + // When USE_GOMA=true is set and the rule is not supported by goma, restrict jobs to the + // local parallelism value + params.Pool = localPool + } + + if ctx.Config().UseRBE() && supports&SUPPORTS_RBE == 0 { + // When USE_RBE=true is set and the rule is not supported by RBE, restrict jobs to the + // local parallelism value + params.Pool = localPool + } + + return params, nil + }, argNames...) } diff --git a/android/prebuilt_etc.go b/android/prebuilt_etc.go index 6c4813bd1..6c8037051 100644 --- a/android/prebuilt_etc.go +++ b/android/prebuilt_etc.go @@ -54,6 +54,12 @@ type prebuiltEtcProperties struct { Installable *bool } +type PrebuiltEtcModule interface { + Module + SubDir() string + OutputFile() OutputPath +} + type PrebuiltEtc struct { ModuleBase diff --git a/android/singleton.go b/android/singleton.go index 33bc6d147..5519ca019 100644 --- a/android/singleton.go +++ b/android/singleton.go @@ -131,9 +131,9 @@ func (s *singletonContextAdaptor) Variable(pctx PackageContext, name, value stri } func (s *singletonContextAdaptor) Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule { - if s.Config().UseGoma() && params.Pool == nil { - // When USE_GOMA=true is set and the rule is not supported by goma, restrict jobs to the - // local parallelism value + if (s.Config().UseGoma() || s.Config().UseRBE()) && params.Pool == nil { + // When USE_GOMA=true or USE_RBE=true are set and the rule is not supported by goma/RBE, restrict + // jobs to the local parallelism value params.Pool = localPool } rule := s.SingletonContext.Rule(pctx.PackageContext, name, params, argNames...) diff --git a/apex/apex.go b/apex/apex.go index 4e6827f62..477f917e6 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -41,7 +41,6 @@ var ( // TODO(b/113082813) make this configurable using config.fs syntax generateFsConfig = pctx.StaticRule("generateFsConfig", blueprint.RuleParams{ Command: `echo '/ 1000 1000 0755' > ${out} && ` + - `echo '/apex_manifest.json 1000 1000 0644' >> ${out} && ` + `echo ${ro_paths} | tr ' ' '\n' | awk '{print "/"$$1 " 1000 1000 0644"}' >> ${out} && ` + `echo ${exec_paths} | tr ' ' '\n' | awk '{print "/"$$1 " 0 2000 0755"}' >> ${out}`, Description: "fs_config ${out}", @@ -57,6 +56,18 @@ var ( Description: "prepare ${out}", }, "provideNativeLibs", "requireNativeLibs", "opt") + stripApexManifestRule = pctx.StaticRule("stripApexManifestRule", blueprint.RuleParams{ + Command: `rm -f $out && ${conv_apex_manifest} strip $in -o $out`, + CommandDeps: []string{"${conv_apex_manifest}"}, + Description: "strip ${in}=>${out}", + }) + + pbApexManifestRule = pctx.StaticRule("pbApexManifestRule", blueprint.RuleParams{ + Command: `rm -f $out && ${conv_apex_manifest} proto $in -o $out`, + CommandDeps: []string{"${conv_apex_manifest}"}, + Description: "convert ${in}=>${out}", + }) + // TODO(b/113233103): make sure that file_contexts is sane, i.e., validate // against the binary policy using sefcontext_compiler -p <policy>. @@ -66,6 +77,7 @@ var ( `(. ${out}.copy_commands) && ` + `APEXER_TOOL_PATH=${tool_path} ` + `${apexer} --force --manifest ${manifest} ` + + `--manifest_json ${manifest_json} --manifest_json_full ${manifest_json_full} ` + `--file_contexts ${file_contexts} ` + `--canned_fs_config ${canned_fs_config} ` + `--payload_type image ` + @@ -76,20 +88,22 @@ var ( Rspfile: "${out}.copy_commands", RspfileContent: "${copy_commands}", Description: "APEX ${image_dir} => ${out}", - }, "tool_path", "image_dir", "copy_commands", "manifest", "file_contexts", "canned_fs_config", "key", "opt_flags") + }, "tool_path", "image_dir", "copy_commands", "file_contexts", "canned_fs_config", "key", "opt_flags", + "manifest", "manifest_json", "manifest_json_full", + ) zipApexRule = pctx.StaticRule("zipApexRule", blueprint.RuleParams{ Command: `rm -rf ${image_dir} && mkdir -p ${image_dir} && ` + `(. ${out}.copy_commands) && ` + `APEXER_TOOL_PATH=${tool_path} ` + - `${apexer} --force --manifest ${manifest} ` + + `${apexer} --force --manifest ${manifest} --manifest_json_full ${manifest_json_full} ` + `--payload_type zip ` + `${image_dir} ${out} `, CommandDeps: []string{"${apexer}", "${merge_zips}", "${soong_zip}", "${zipalign}", "${aapt2}"}, Rspfile: "${out}.copy_commands", RspfileContent: "${copy_commands}", Description: "ZipAPEX ${image_dir} => ${out}", - }, "tool_path", "image_dir", "copy_commands", "manifest") + }, "tool_path", "image_dir", "copy_commands", "manifest", "manifest_json_full") apexProtoConvertRule = pctx.AndroidStaticRule("apexProtoConvertRule", blueprint.RuleParams{ @@ -181,6 +195,7 @@ func init() { pctx.HostBinToolVariable("zip2zip", "zip2zip") pctx.HostBinToolVariable("zipalign", "zipalign") pctx.HostBinToolVariable("jsonmodify", "jsonmodify") + pctx.HostBinToolVariable("conv_apex_manifest", "conv_apex_manifest") android.RegisterModuleType("apex", BundleFactory) android.RegisterModuleType("apex_test", testApexBundleFactory) @@ -249,6 +264,9 @@ func apexVndkDepsMutator(mctx android.BottomUpMutatorContext) { if vndkApex, ok := vndkApexList[vndkVersion]; ok { mctx.AddReverseDependency(mctx.Module(), sharedLibTag, vndkApex) } + } else if a, ok := mctx.Module().(*apexBundle); ok && a.vndkApex { + vndkVersion := proptools.StringDefault(a.vndkProperties.Vndk_version, "current") + mctx.AddDependency(mctx.Module(), prebuiltTag, cc.VndkLibrariesTxtModules(vndkVersion)...) } } @@ -637,7 +655,9 @@ type apexBundle struct { primaryApexType bool // intermediate path for apex_manifest.json - manifestOut android.WritablePath + manifestJsonOut android.WritablePath + manifestJsonFullOut android.WritablePath + manifestPbOut android.WritablePath // list of commands to create symlinks for backward compatibility // these commands will be attached as LOCAL_POST_INSTALL_CMD to @@ -975,7 +995,7 @@ func getCopyManifestForPrebuiltJavaLibrary(java *java.Import) (fileToCopy androi return } -func getCopyManifestForPrebuiltEtc(prebuilt *android.PrebuiltEtc) (fileToCopy android.Path, dirInApex string) { +func getCopyManifestForPrebuiltEtc(prebuilt android.PrebuiltEtcModule) (fileToCopy android.Path, dirInApex string) { dirInApex = filepath.Join("etc", prebuilt.SubDir()) fileToCopy = prebuilt.OutputFile() return @@ -1131,7 +1151,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { ctx.PropertyErrorf("java_libs", "%q of type %q is not supported", depName, ctx.OtherModuleType(child)) } case prebuiltTag: - if prebuilt, ok := child.(*android.PrebuiltEtc); ok { + if prebuilt, ok := child.(android.PrebuiltEtcModule); ok { fileToCopy, dirInApex := getCopyManifestForPrebuiltEtc(prebuilt) filesInfo = append(filesInfo, apexFile{fileToCopy, depName, dirInApex, etc, prebuilt, nil}) return true @@ -1196,7 +1216,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { if am, ok := child.(android.ApexModule); ok { // We cannot use a switch statement on `depTag` here as the checked // tags used below are private (e.g. `cc.sharedDepTag`). - if cc.IsSharedDepTag(depTag) || cc.IsRuntimeDepTag(depTag) { + if cc.IsSharedDepTag(depTag) || cc.IsRuntimeDepTag(depTag) || java.IsJniDepTag(depTag) { if cc, ok := child.(*cc.Module); ok { if android.InList(cc.Name(), providedNativeSharedLibs) { // If we're using a shared library which is provided from other APEX, @@ -1288,9 +1308,24 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { a.filesInfo = filesInfo // prepare apex_manifest.json - a.manifestOut = android.PathForModuleOut(ctx, "apex_manifest.json") + a.buildManifest(ctx, provideNativeLibs, requireNativeLibs) + + a.setCertificateAndPrivateKey(ctx) + if a.properties.ApexType == flattenedApex { + a.buildFlattenedApex(ctx) + } else { + a.buildUnflattenedApex(ctx) + } + + apexName := proptools.StringDefault(a.properties.Apex_name, ctx.ModuleName()) + a.compatSymlinks = makeCompatSymlinks(apexName, ctx) +} + +func (a *apexBundle) buildManifest(ctx android.ModuleContext, provideNativeLibs, requireNativeLibs []string) { manifestSrc := android.PathForModuleSrc(ctx, proptools.StringDefault(a.properties.Manifest, "apex_manifest.json")) + a.manifestJsonFullOut = android.PathForModuleOut(ctx, "apex_manifest_full.json") + // put dependency({provide|require}NativeLibs) in apex_manifest.json provideNativeLibs = android.SortedUniqueStrings(provideNativeLibs) requireNativeLibs = android.SortedUniqueStrings(android.RemoveListFromList(requireNativeLibs, provideNativeLibs)) @@ -1304,7 +1339,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { ctx.Build(pctx, android.BuildParams{ Rule: apexManifestRule, Input: manifestSrc, - Output: a.manifestOut, + Output: a.manifestJsonFullOut, Args: map[string]string{ "provideNativeLibs": strings.Join(provideNativeLibs, " "), "requireNativeLibs": strings.Join(requireNativeLibs, " "), @@ -1312,15 +1347,22 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { }, }) - a.setCertificateAndPrivateKey(ctx) - if a.properties.ApexType == flattenedApex { - a.buildFlattenedApex(ctx) - } else { - a.buildUnflattenedApex(ctx) - } + // b/143654022 Q apexd can't understand newly added keys in apex_manifest.json + // prepare stripp-downed version so that APEX modules built from R+ can be installed to Q + a.manifestJsonOut = android.PathForModuleOut(ctx, "apex_manifest.json") + ctx.Build(pctx, android.BuildParams{ + Rule: stripApexManifestRule, + Input: a.manifestJsonFullOut, + Output: a.manifestJsonOut, + }) - apexName := proptools.StringDefault(a.properties.Apex_name, ctx.ModuleName()) - a.compatSymlinks = makeCompatSymlinks(apexName, ctx) + // from R+, protobuf binary format (.pb) is the standard format for apex_manifest + a.manifestPbOut = android.PathForModuleOut(ctx, "apex_manifest.pb") + ctx.Build(pctx, android.BuildParams{ + Rule: pbApexManifestRule, + Input: a.manifestJsonFullOut, + Output: a.manifestPbOut, + }) } func (a *apexBundle) buildNoticeFile(ctx android.ModuleContext, apexFileName string) android.OptionalPath { @@ -1382,7 +1424,7 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) { emitCommands = append(emitCommands, "sort -o "+imageContentFile.String()+" "+imageContentFile.String()) implicitInputs := append(android.Paths(nil), filesToCopy...) - implicitInputs = append(implicitInputs, a.manifestOut) + implicitInputs = append(implicitInputs, a.manifestPbOut, a.manifestJsonFullOut, a.manifestJsonOut) if a.properties.Whitelisted_files != nil { ctx.Build(pctx, android.BuildParams{ @@ -1418,7 +1460,7 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) { if apexType == imageApex { // files and dirs that will be created in APEX - var readOnlyPaths []string + var readOnlyPaths = []string{"apex_manifest.json", "apex_manifest.pb"} var executablePaths []string // this also includes dirs for _, f := range a.filesInfo { pathInApex := filepath.Join(f.installDir, f.builtFile.Base()) @@ -1516,14 +1558,16 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) { Output: unsignedOutputFile, Description: "apex (" + apexType.name() + ")", Args: map[string]string{ - "tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir, - "image_dir": android.PathForModuleOut(ctx, "image"+suffix).String(), - "copy_commands": strings.Join(copyCommands, " && "), - "manifest": a.manifestOut.String(), - "file_contexts": fileContexts.String(), - "canned_fs_config": cannedFsConfig.String(), - "key": a.private_key_file.String(), - "opt_flags": strings.Join(optFlags, " "), + "tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir, + "image_dir": android.PathForModuleOut(ctx, "image"+suffix).String(), + "copy_commands": strings.Join(copyCommands, " && "), + "manifest_json_full": a.manifestJsonFullOut.String(), + "manifest_json": a.manifestJsonOut.String(), + "manifest": a.manifestPbOut.String(), + "file_contexts": fileContexts.String(), + "canned_fs_config": cannedFsConfig.String(), + "key": a.private_key_file.String(), + "opt_flags": strings.Join(optFlags, " "), }, }) @@ -1554,10 +1598,11 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) { Output: unsignedOutputFile, Description: "apex (" + apexType.name() + ")", Args: map[string]string{ - "tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir, - "image_dir": android.PathForModuleOut(ctx, "image"+suffix).String(), - "copy_commands": strings.Join(copyCommands, " && "), - "manifest": a.manifestOut.String(), + "tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir, + "image_dir": android.PathForModuleOut(ctx, "image"+suffix).String(), + "copy_commands": strings.Join(copyCommands, " && "), + "manifest": a.manifestPbOut.String(), + "manifest_json_full": a.manifestJsonFullOut.String(), }, }) } @@ -1615,7 +1660,8 @@ func (a *apexBundle) buildFilesInfo(ctx android.ModuleContext) { if a.installable() { // For flattened APEX, do nothing but make sure that apex_manifest.json and apex_pubkey are also copied along // with other ordinary files. - a.filesInfo = append(a.filesInfo, apexFile{a.manifestOut, "apex_manifest.json." + ctx.ModuleName() + a.suffix, ".", etc, nil, nil}) + a.filesInfo = append(a.filesInfo, apexFile{a.manifestJsonOut, "apex_manifest.json." + ctx.ModuleName() + a.suffix, ".", etc, nil, nil}) + a.filesInfo = append(a.filesInfo, apexFile{a.manifestPbOut, "apex_manifest.pb." + ctx.ModuleName() + a.suffix, ".", etc, nil, nil}) // rename to apex_pubkey copiedPubkey := android.PathForModuleOut(ctx, "apex_pubkey") @@ -1752,7 +1798,7 @@ func (a *apexBundle) androidMkForFiles(w io.Writer, apexName, moduleDir string) } else { fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", fi.builtFile.Base()) // For flattened apexes, compat symlinks are attached to apex_manifest.json which is guaranteed for every apex - if a.primaryApexType && fi.builtFile.Base() == "apex_manifest.json" && len(a.compatSymlinks) > 0 { + if a.primaryApexType && fi.builtFile == a.manifestPbOut && len(a.compatSymlinks) > 0 { fmt.Fprintln(w, "LOCAL_POST_INSTALL_CMD :=", strings.Join(a.compatSymlinks, " && ")) } fmt.Fprintln(w, "include $(BUILD_PREBUILT)") diff --git a/apex/apex_test.go b/apex/apex_test.go index 77c1fb035..614164deb 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -17,6 +17,7 @@ package apex import ( "io/ioutil" "os" + "path" "reflect" "sort" "strings" @@ -117,6 +118,7 @@ func testApexContext(t *testing.T, bp string, handlers ...testCustomizer) (*andr ctx.RegisterModuleType("cc_test", android.ModuleFactoryAdaptor(cc.TestFactory)) ctx.RegisterModuleType("llndk_library", android.ModuleFactoryAdaptor(cc.LlndkLibraryFactory)) ctx.RegisterModuleType("vndk_prebuilt_shared", android.ModuleFactoryAdaptor(cc.VndkPrebuiltSharedFactory)) + ctx.RegisterModuleType("vndk_libraries_txt", android.ModuleFactoryAdaptor(cc.VndkLibrariesTxtFactory)) ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(cc.ToolchainLibraryFactory)) ctx.RegisterModuleType("prebuilt_etc", android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory)) ctx.RegisterModuleType("sh_binary", android.ModuleFactoryAdaptor(android.ShBinaryFactory)) @@ -298,6 +300,7 @@ func testApexContext(t *testing.T, bp string, handlers ...testCustomizer) (*andr "framework/aidl/a.aidl": nil, "build/make/core/proguard.flags": nil, "build/make/core/proguard_basic_keeps.flags": nil, + "dummy.txt": nil, } for _, handler := range handlers { @@ -517,6 +520,26 @@ func TestBasicApex(t *testing.T) { ensureListContains(t, noticeInputs, "custom_notice") } +func TestApexManifest(t *testing.T) { + ctx, _ := testApex(t, ` + apex { + name: "myapex", + key: "myapex.key", + } + + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + `) + + module := ctx.ModuleForTests("myapex", "android_common_myapex_image") + module.Output("apex_manifest.pb") + module.Output("apex_manifest.json") + module.Output("apex_manifest_full.json") +} + func TestBasicZipApex(t *testing.T) { ctx, _ := testApex(t, ` apex { @@ -1319,7 +1342,18 @@ func ensureExactContents(t *testing.T, ctx *android.TestContext, moduleName stri apexRule := ctx.ModuleForTests(moduleName, "android_common_"+moduleName+"_image").Rule("apexRule") copyCmds := apexRule.Args["copy_commands"] imageApexDir := "/image.apex/" - dstFiles := []string{} + var failed bool + var surplus []string + filesMatched := make(map[string]bool) + addContent := func(content string) { + for _, expected := range files { + if matched, _ := path.Match(expected, content); matched { + filesMatched[expected] = true + return + } + } + surplus = append(surplus, content) + } for _, cmd := range strings.Split(copyCmds, "&&") { cmd = strings.TrimSpace(cmd) if cmd == "" { @@ -1338,42 +1372,26 @@ func ensureExactContents(t *testing.T, ctx *android.TestContext, moduleName stri t.Fatal("copyCmds should copy a file to image.apex/", cmd) } dstFile := dst[index+len(imageApexDir):] - dstFiles = append(dstFiles, dstFile) + addContent(dstFile) default: t.Fatalf("copyCmds should contain mkdir/cp commands only: %q", cmd) } } - sort.Strings(dstFiles) - sort.Strings(files) - missing := []string{} - surplus := []string{} - i := 0 - j := 0 - for i < len(dstFiles) && j < len(files) { - if dstFiles[i] == files[j] { - i++ - j++ - } else if dstFiles[i] < files[j] { - surplus = append(surplus, dstFiles[i]) - i++ - } else { - missing = append(missing, files[j]) - j++ - } - } - if i < len(dstFiles) { - surplus = append(surplus, dstFiles[i:]...) - } - if j < len(files) { - missing = append(missing, files[j:]...) - } - failed := false if len(surplus) > 0 { + sort.Strings(surplus) t.Log("surplus files", surplus) failed = true } - if len(missing) > 0 { + + if len(files) > len(filesMatched) { + var missing []string + for _, expected := range files { + if !filesMatched[expected] { + missing = append(missing, expected) + } + } + sort.Strings(missing) t.Log("missing files", missing) failed = true } @@ -1418,13 +1436,18 @@ func TestVndkApexCurrent(t *testing.T) { system_shared_libs: [], stl: "none", } - `) + `+vndkLibrariesTxtFiles("current")) ensureExactContents(t, ctx, "myapex", []string{ "lib/libvndk.so", "lib/libvndksp.so", "lib64/libvndk.so", "lib64/libvndksp.so", + "etc/llndk.libraries.VER.txt", + "etc/vndkcore.libraries.VER.txt", + "etc/vndksp.libraries.VER.txt", + "etc/vndkprivate.libraries.VER.txt", + "etc/vndkcorevariant.libraries.VER.txt", }) } @@ -1469,18 +1492,44 @@ func TestVndkApexWithPrebuilt(t *testing.T) { system_shared_libs: [], stl: "none", } - `, withFiles(map[string][]byte{ - "libvndk.so": nil, - "libvndk.arm.so": nil, - })) + `+vndkLibrariesTxtFiles("current"), + withFiles(map[string][]byte{ + "libvndk.so": nil, + "libvndk.arm.so": nil, + })) ensureExactContents(t, ctx, "myapex", []string{ "lib/libvndk.so", "lib/libvndk.arm.so", "lib64/libvndk.so", + "etc/*", }) } +func vndkLibrariesTxtFiles(vers ...string) (result string) { + for _, v := range vers { + if v == "current" { + for _, txt := range []string{"llndk", "vndkcore", "vndksp", "vndkprivate", "vndkcorevariant"} { + result += ` + vndk_libraries_txt { + name: "` + txt + `.libraries.txt", + } + ` + } + } else { + for _, txt := range []string{"llndk", "vndkcore", "vndksp", "vndkprivate"} { + result += ` + prebuilt_etc { + name: "` + txt + `.libraries.` + v + `.txt", + src: "dummy.txt", + } + ` + } + } + } + return +} + func TestVndkApexVersion(t *testing.T) { ctx, _ := testApex(t, ` apex_vndk { @@ -1530,17 +1579,19 @@ func TestVndkApexVersion(t *testing.T) { srcs: ["libvndk27_x86_64.so"], }, }, - } - `, withFiles(map[string][]byte{ - "libvndk27_arm.so": nil, - "libvndk27_arm64.so": nil, - "libvndk27_x86.so": nil, - "libvndk27_x86_64.so": nil, - })) + } + `+vndkLibrariesTxtFiles("27"), + withFiles(map[string][]byte{ + "libvndk27_arm.so": nil, + "libvndk27_arm64.so": nil, + "libvndk27_x86.so": nil, + "libvndk27_x86_64.so": nil, + })) ensureExactContents(t, ctx, "myapex_v27", []string{ "lib/libvndk27_arm.so", "lib64/libvndk27_arm64.so", + "etc/*", }) } @@ -1607,7 +1658,7 @@ func TestVndkApexNameRule(t *testing.T) { name: "myapex.key", public_key: "testkey.avbpubkey", private_key: "testkey.pem", - }`) + }`+vndkLibrariesTxtFiles("28", "current")) assertApexName := func(expected, moduleName string) { bundle := ctx.ModuleForTests(moduleName, "android_common_"+moduleName+"_image").Module().(*apexBundle) @@ -1647,18 +1698,20 @@ func TestVndkApexSkipsNativeBridgeSupportedModules(t *testing.T) { system_shared_libs: [], stl: "none", } - `, withTargets(map[android.OsType][]android.Target{ - android.Android: []android.Target{ - {Os: android.Android, Arch: android.Arch{ArchType: android.Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}}, NativeBridge: android.NativeBridgeDisabled, NativeBridgeHostArchName: "", NativeBridgeRelativePath: ""}, - {Os: android.Android, Arch: android.Arch{ArchType: android.Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}}, NativeBridge: android.NativeBridgeDisabled, NativeBridgeHostArchName: "", NativeBridgeRelativePath: ""}, - {Os: android.Android, Arch: android.Arch{ArchType: android.X86_64, ArchVariant: "silvermont", Abi: []string{"arm64-v8a"}}, NativeBridge: android.NativeBridgeEnabled, NativeBridgeHostArchName: "arm64", NativeBridgeRelativePath: "x86_64"}, - {Os: android.Android, Arch: android.Arch{ArchType: android.X86, ArchVariant: "silvermont", Abi: []string{"armeabi-v7a"}}, NativeBridge: android.NativeBridgeEnabled, NativeBridgeHostArchName: "arm", NativeBridgeRelativePath: "x86"}, - }, - })) + `+vndkLibrariesTxtFiles("current"), + withTargets(map[android.OsType][]android.Target{ + android.Android: []android.Target{ + {Os: android.Android, Arch: android.Arch{ArchType: android.Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}}, NativeBridge: android.NativeBridgeDisabled, NativeBridgeHostArchName: "", NativeBridgeRelativePath: ""}, + {Os: android.Android, Arch: android.Arch{ArchType: android.Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}}, NativeBridge: android.NativeBridgeDisabled, NativeBridgeHostArchName: "", NativeBridgeRelativePath: ""}, + {Os: android.Android, Arch: android.Arch{ArchType: android.X86_64, ArchVariant: "silvermont", Abi: []string{"arm64-v8a"}}, NativeBridge: android.NativeBridgeEnabled, NativeBridgeHostArchName: "arm64", NativeBridgeRelativePath: "x86_64"}, + {Os: android.Android, Arch: android.Arch{ArchType: android.X86, ArchVariant: "silvermont", Abi: []string{"armeabi-v7a"}}, NativeBridge: android.NativeBridgeEnabled, NativeBridgeHostArchName: "arm", NativeBridgeRelativePath: "x86"}, + }, + })) ensureExactContents(t, ctx, "myapex", []string{ "lib/libvndk.so", "lib64/libvndk.so", + "etc/*", }) } @@ -1693,8 +1746,7 @@ func TestVndkApexDoesntSupportNativeBridgeSupported(t *testing.T) { } func TestVndkApexWithBinder32(t *testing.T) { - ctx, _ := testApex(t, - ` + ctx, _ := testApex(t, ` apex_vndk { name: "myapex_v27", key: "myapex.key", @@ -1738,7 +1790,7 @@ func TestVndkApexWithBinder32(t *testing.T) { } }, } - `, + `+vndkLibrariesTxtFiles("27"), withFiles(map[string][]byte{ "libvndk27.so": nil, "libvndk27binder32.so": nil, @@ -1753,6 +1805,7 @@ func TestVndkApexWithBinder32(t *testing.T) { ensureExactContents(t, ctx, "myapex_v27", []string{ "lib/libvndk27binder32.so", + "etc/*", }) } @@ -2460,6 +2513,7 @@ func TestApexWithApps(t *testing.T) { srcs: ["foo/bar/MyClass.java"], sdk_version: "none", system_modules: "none", + jni_libs: ["libjni"], } android_app { @@ -2469,6 +2523,13 @@ func TestApexWithApps(t *testing.T) { system_modules: "none", privileged: true, } + + cc_library_shared { + name: "libjni", + srcs: ["mylib.cpp"], + stl: "none", + system_shared_libs: [], + } `) module := ctx.ModuleForTests("myapex", "android_common_myapex_image") @@ -2477,6 +2538,7 @@ func TestApexWithApps(t *testing.T) { ensureContains(t, copyCmds, "image.apex/app/AppFoo/AppFoo.apk") ensureContains(t, copyCmds, "image.apex/priv-app/AppFooPriv/AppFooPriv.apk") + ensureContains(t, copyCmds, "image.apex/lib64/libjni.so") } func TestApexWithAppImports(t *testing.T) { diff --git a/bpf/bpf.go b/bpf/bpf.go index 90ec963d1..024fcbccc 100644 --- a/bpf/bpf.go +++ b/bpf/bpf.go @@ -33,7 +33,7 @@ func init() { var ( pctx = android.NewPackageContext("android/soong/bpf") - ccRule = pctx.AndroidGomaStaticRule("ccRule", + ccRule = pctx.AndroidRemoteStaticRule("ccRule", android.SUPPORTS_GOMA, blueprint.RuleParams{ Depfile: "${out}.d", Deps: blueprint.DepsGCC, diff --git a/bpfix/bpfix/bpfix.go b/bpfix/bpfix/bpfix.go index 9cba80a75..4633aa64d 100644 --- a/bpfix/bpfix/bpfix.go +++ b/bpfix/bpfix/bpfix.go @@ -116,6 +116,10 @@ var fixSteps = []FixStep{ Name: "rewriteAndroidAppImport", Fix: rewriteAndroidAppImport, }, + { + Name: "removeEmptyLibDependencies", + Fix: removeEmptyLibDependencies, + }, } func NewFixRequest() FixRequest { @@ -650,6 +654,50 @@ func rewriteAndroidAppImport(f *Fixer) error { return nil } +// Removes library dependencies which are empty (and restricted from usage in Soong) +func removeEmptyLibDependencies(f *Fixer) error { + emptyLibraries := []string{ + "libhidltransport", + "libhwbinder", + } + relevantFields := []string{ + "export_shared_lib_headers", + "export_static_lib_headers", + "static_libs", + "whole_static_libs", + "shared_libs", + } + for _, def := range f.tree.Defs { + mod, ok := def.(*parser.Module) + if !ok { + continue + } + for _, field := range relevantFields { + listValue, ok := getLiteralListProperty(mod, field) + if !ok { + continue + } + newValues := []parser.Expression{} + for _, v := range listValue.Values { + stringValue, ok := v.(*parser.String) + if !ok { + return fmt.Errorf("Expecting string for %s.%s fields", mod.Type, field) + } + if inList(stringValue.Value, emptyLibraries) { + continue + } + newValues = append(newValues, stringValue) + } + if len(newValues) == 0 && len(listValue.Values) != 0 { + removeProperty(mod, field) + } else { + listValue.Values = newValues + } + } + } + return nil +} + // Converts the default source list property, 'srcs', to a single source property with a given name. // "LOCAL_MODULE" reference is also resolved during the conversion process. func convertToSingleSource(mod *parser.Module, srcPropertyName string) { @@ -1084,3 +1132,12 @@ func removeProperty(mod *parser.Module, propertyName string) { } mod.Properties = newList } + +func inList(s string, list []string) bool { + for _, v := range list { + if s == v { + return true + } + } + return false +} diff --git a/bpfix/bpfix/bpfix_test.go b/bpfix/bpfix/bpfix_test.go index 5e0b81754..032282f84 100644 --- a/bpfix/bpfix/bpfix_test.go +++ b/bpfix/bpfix/bpfix_test.go @@ -833,3 +833,57 @@ func TestRewriteAndroidAppImport(t *testing.T) { }) } } + +func TestRemoveEmptyLibDependencies(t *testing.T) { + tests := []struct { + name string + in string + out string + }{ + { + name: "remove sole shared lib", + in: ` + cc_library { + name: "foo", + shared_libs: ["libhwbinder"], + } + `, + out: ` + cc_library { + name: "foo", + + } + `, + }, + { + name: "remove a shared lib", + in: ` + cc_library { + name: "foo", + shared_libs: [ + "libhwbinder", + "libfoo", + "libhidltransport", + ], + } + `, + out: ` + cc_library { + name: "foo", + shared_libs: [ + + "libfoo", + + ], + } + `, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + runPass(t, test.in, test.out, func(fixer *Fixer) error { + return removeEmptyLibDependencies(fixer) + }) + }) + } +} diff --git a/cc/androidmk.go b/cc/androidmk.go index 91a3c99ac..ff181d80e 100644 --- a/cc/androidmk.go +++ b/cc/androidmk.go @@ -327,14 +327,15 @@ func (fuzz *fuzzBinary) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkDa filepath.Dir(fuzz.config.String())+":config.json") } - if len(fuzzFiles) > 0 { - ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) { - fmt.Fprintln(w, "LOCAL_TEST_DATA := "+strings.Join(fuzzFiles, " ")) - }) - } - ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) { fmt.Fprintln(w, "LOCAL_IS_FUZZ_TARGET := true") + if len(fuzzFiles) > 0 { + fmt.Fprintln(w, "LOCAL_TEST_DATA := "+strings.Join(fuzzFiles, " ")) + } + if fuzz.installedSharedDeps != nil { + fmt.Fprintln(w, "LOCAL_FUZZ_INSTALLED_SHARED_DEPS :="+ + strings.Join(fuzz.installedSharedDeps, " ")) + } }) } diff --git a/cc/binary.go b/cc/binary.go index b27142cf7..617d4dda0 100644 --- a/cc/binary.go +++ b/cc/binary.go @@ -227,7 +227,7 @@ func (binary *binaryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags if ctx.Host() && !ctx.Windows() && !binary.static() { if !ctx.Config().IsEnvTrue("DISABLE_HOST_PIE") { - flags.LdFlags = append(flags.LdFlags, "-pie") + flags.Global.LdFlags = append(flags.Global.LdFlags, "-pie") } } @@ -235,7 +235,7 @@ func (binary *binaryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags // all code is position independent, and then those warnings get promoted to // errors. if !ctx.Windows() { - flags.CFlags = append(flags.CFlags, "-fPIE") + flags.Global.CFlags = append(flags.Global.CFlags, "-fPIE") } if ctx.toolchain().Bionic() { @@ -244,11 +244,11 @@ func (binary *binaryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags // However, bionic/linker uses -shared to overwrite. // Linker for x86 targets does not allow coexistance of -static and -shared, // so we add -static only if -shared is not used. - if !inList("-shared", flags.LdFlags) { - flags.LdFlags = append(flags.LdFlags, "-static") + if !inList("-shared", flags.Local.LdFlags) { + flags.Global.LdFlags = append(flags.Global.LdFlags, "-static") } - flags.LdFlags = append(flags.LdFlags, + flags.Global.LdFlags = append(flags.Global.LdFlags, "-nostdlib", "-Bstatic", "-Wl,--gc-sections", @@ -278,14 +278,14 @@ func (binary *binaryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags if ctx.Os() == android.LinuxBionic { // Use the dlwrap entry point, but keep _start around so // that it can be used by host_bionic_inject - flags.LdFlags = append(flags.LdFlags, + flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--entry=__dlwrap__start", "-Wl,--undefined=_start", ) } } - flags.LdFlags = append(flags.LdFlags, + flags.Global.LdFlags = append(flags.Global.LdFlags, "-pie", "-nostdlib", "-Bdynamic", @@ -295,10 +295,10 @@ func (binary *binaryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags } } else { if binary.static() { - flags.LdFlags = append(flags.LdFlags, "-static") + flags.Global.LdFlags = append(flags.Global.LdFlags, "-static") } if ctx.Darwin() { - flags.LdFlags = append(flags.LdFlags, "-Wl,-headerpad_max_install_names") + flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,-headerpad_max_install_names") } } @@ -315,14 +315,14 @@ func (binary *binaryDecorator) link(ctx ModuleContext, var linkerDeps android.Paths if deps.LinkerFlagsFile.Valid() { - flags.LdFlags = append(flags.LdFlags, "$$(cat "+deps.LinkerFlagsFile.String()+")") + flags.Local.LdFlags = append(flags.Local.LdFlags, "$$(cat "+deps.LinkerFlagsFile.String()+")") linkerDeps = append(linkerDeps, deps.LinkerFlagsFile.Path()) } if flags.DynamicLinker != "" { - flags.LdFlags = append(flags.LdFlags, "-Wl,-dynamic-linker,"+flags.DynamicLinker) + flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-dynamic-linker,"+flags.DynamicLinker) } else if ctx.toolchain().Bionic() && !binary.static() { - flags.LdFlags = append(flags.LdFlags, "-Wl,--no-dynamic-linker") + flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--no-dynamic-linker") } builderFlags := flagsToBuilderFlags(flags) diff --git a/cc/builder.go b/cc/builder.go index 491ebc59e..1ec323f19 100644 --- a/cc/builder.go +++ b/cc/builder.go @@ -46,7 +46,7 @@ var ( var ( pctx = android.NewPackageContext("android/soong/cc") - cc = pctx.AndroidGomaStaticRule("cc", + cc = pctx.AndroidRemoteStaticRule("cc", android.SUPPORTS_BOTH, blueprint.RuleParams{ Depfile: "${out}.d", Deps: blueprint.DepsGCC, @@ -55,7 +55,7 @@ var ( }, "ccCmd", "cFlags") - ccNoDeps = pctx.AndroidGomaStaticRule("ccNoDeps", + ccNoDeps = pctx.AndroidRemoteStaticRule("ccNoDeps", android.SUPPORTS_GOMA, blueprint.RuleParams{ Command: "$relPwd ${config.CcWrapper}$ccCmd -c $cFlags -o $out $in", CommandDeps: []string{"$ccCmd"}, @@ -261,27 +261,37 @@ func init() { } type builderFlags struct { - globalFlags string - arFlags string - asFlags string - cFlags string - toolingCFlags string // A separate set of cFlags for clang LibTooling tools - toolingCppFlags string // A separate set of cppFlags for clang LibTooling tools - conlyFlags string - cppFlags string - ldFlags string - libFlags string - extraLibFlags string - tidyFlags string - sAbiFlags string - yasmFlags string - aidlFlags string - rsFlags string - toolchain config.Toolchain - tidy bool - coverage bool - sAbiDump bool - emitXrefs bool + globalCommonFlags string + globalAsFlags string + globalYasmFlags string + globalCFlags string + globalToolingCFlags string // A separate set of cFlags for clang LibTooling tools + globalToolingCppFlags string // A separate set of cppFlags for clang LibTooling tools + globalConlyFlags string + globalCppFlags string + globalLdFlags string + + localCommonFlags string + localAsFlags string + localYasmFlags string + localCFlags string + localToolingCFlags string // A separate set of cFlags for clang LibTooling tools + localToolingCppFlags string // A separate set of cppFlags for clang LibTooling tools + localConlyFlags string + localCppFlags string + localLdFlags string + + libFlags string + extraLibFlags string + tidyFlags string + sAbiFlags string + aidlFlags string + rsFlags string + toolchain config.Toolchain + tidy bool + coverage bool + sAbiDump bool + emitXrefs bool assemblerWithCpp bool @@ -349,39 +359,45 @@ func TransformSourceToObj(ctx android.ModuleContext, subdir string, srcFiles and kytheFiles = make(android.Paths, 0, len(srcFiles)) } - commonFlags := strings.Join([]string{ - flags.globalFlags, - flags.systemIncludeFlags, - }, " ") - - toolingCflags := strings.Join([]string{ - commonFlags, - flags.toolingCFlags, - flags.conlyFlags, - }, " ") - - cflags := strings.Join([]string{ - commonFlags, - flags.cFlags, - flags.conlyFlags, - }, " ") - - toolingCppflags := strings.Join([]string{ - commonFlags, - flags.toolingCFlags, - flags.toolingCppFlags, - }, " ") - - cppflags := strings.Join([]string{ - commonFlags, - flags.cFlags, - flags.cppFlags, - }, " ") - - asflags := strings.Join([]string{ - commonFlags, - flags.asFlags, - }, " ") + // Produce fully expanded flags for use by C tools, C compiles, C++ tools, C++ compiles, and asm compiles + // respectively. + toolingCflags := flags.globalCommonFlags + " " + + flags.globalToolingCFlags + " " + + flags.globalConlyFlags + " " + + flags.localCommonFlags + " " + + flags.localToolingCFlags + " " + + flags.localConlyFlags + " " + + flags.systemIncludeFlags + + cflags := flags.globalCommonFlags + " " + + flags.globalCFlags + " " + + flags.globalConlyFlags + " " + + flags.localCommonFlags + " " + + flags.localCFlags + " " + + flags.localConlyFlags + " " + + flags.systemIncludeFlags + + toolingCppflags := flags.globalCommonFlags + " " + + flags.globalToolingCFlags + " " + + flags.globalToolingCppFlags + " " + + flags.localCommonFlags + " " + + flags.localToolingCFlags + " " + + flags.localToolingCppFlags + " " + + flags.systemIncludeFlags + + cppflags := flags.globalCommonFlags + " " + + flags.globalCFlags + " " + + flags.globalCppFlags + " " + + flags.localCommonFlags + " " + + flags.localCFlags + " " + + flags.localCppFlags + " " + + flags.systemIncludeFlags + + asflags := flags.globalCommonFlags + " " + + flags.globalAsFlags + " " + + flags.localCommonFlags + " " + + flags.localAsFlags + " " + + flags.systemIncludeFlags var sAbiDumpFiles android.Paths if flags.sAbiDump { @@ -408,7 +424,7 @@ func TransformSourceToObj(ctx android.ModuleContext, subdir string, srcFiles and Implicits: cFlagsDeps, OrderOnly: pathDeps, Args: map[string]string{ - "asFlags": flags.yasmFlags, + "asFlags": flags.globalYasmFlags + " " + flags.localYasmFlags, }, }) continue @@ -431,8 +447,9 @@ func TransformSourceToObj(ctx android.ModuleContext, subdir string, srcFiles and continue } - var moduleCflags string - var moduleToolingCflags string + var moduleFlags string + var moduleToolingFlags string + var ccCmd string tidy := flags.tidy coverage := flags.coverage @@ -448,19 +465,19 @@ func TransformSourceToObj(ctx android.ModuleContext, subdir string, srcFiles and fallthrough case ".S": ccCmd = "clang" - moduleCflags = asflags + moduleFlags = asflags tidy = false coverage = false dump = false emitXref = false case ".c": ccCmd = "clang" - moduleCflags = cflags - moduleToolingCflags = toolingCflags + moduleFlags = cflags + moduleToolingFlags = toolingCflags case ".cpp", ".cc", ".cxx", ".mm": ccCmd = "clang++" - moduleCflags = cppflags - moduleToolingCflags = toolingCppflags + moduleFlags = cppflags + moduleToolingFlags = toolingCppflags default: ctx.ModuleErrorf("File %s has unknown extension", srcFile) continue @@ -486,7 +503,7 @@ func TransformSourceToObj(ctx android.ModuleContext, subdir string, srcFiles and Implicits: cFlagsDeps, OrderOnly: pathDeps, Args: map[string]string{ - "cFlags": moduleCflags, + "cFlags": moduleFlags, "ccCmd": ccCmd, }, }) @@ -501,7 +518,7 @@ func TransformSourceToObj(ctx android.ModuleContext, subdir string, srcFiles and Implicits: cFlagsDeps, OrderOnly: pathDeps, Args: map[string]string{ - "cFlags": moduleCflags, + "cFlags": moduleFlags, }, }) kytheFiles = append(kytheFiles, kytheFile) @@ -522,7 +539,7 @@ func TransformSourceToObj(ctx android.ModuleContext, subdir string, srcFiles and Implicits: cFlagsDeps, OrderOnly: pathDeps, Args: map[string]string{ - "cFlags": moduleToolingCflags, + "cFlags": moduleToolingFlags, "tidyFlags": flags.tidyFlags, }, }) @@ -541,7 +558,7 @@ func TransformSourceToObj(ctx android.ModuleContext, subdir string, srcFiles and Implicits: cFlagsDeps, OrderOnly: pathDeps, Args: map[string]string{ - "cFlags": moduleToolingCflags, + "cFlags": moduleToolingFlags, "exportDirs": flags.sAbiFlags, }, }) @@ -567,9 +584,6 @@ func TransformObjToStaticLib(ctx android.ModuleContext, objFiles android.Paths, if !ctx.Darwin() { arFlags += " -format=gnu" } - if flags.arFlags != "" { - arFlags += " " + flags.arFlags - } ctx.Build(pctx, android.BuildParams{ Rule: ar, @@ -651,7 +665,7 @@ func TransformObjToDynamicBinary(ctx android.ModuleContext, "crtBegin": crtBegin.String(), "libFlags": strings.Join(libFlagsList, " "), "extraLibFlags": flags.extraLibFlags, - "ldFlags": flags.ldFlags, + "ldFlags": flags.globalLdFlags + " " + flags.localLdFlags, "crtEnd": crtEnd.String(), }, }) @@ -788,7 +802,7 @@ func TransformObjsToObj(ctx android.ModuleContext, objFiles android.Paths, Implicits: deps, Args: map[string]string{ "ldCmd": ldCmd, - "ldFlags": flags.ldFlags, + "ldFlags": flags.globalLdFlags + " " + flags.localLdFlags, }, }) } @@ -140,26 +140,34 @@ type PathDeps struct { DynamicLinker android.OptionalPath } -type Flags struct { - GlobalFlags []string // Flags that apply to C, C++, and assembly source files - ArFlags []string // Flags that apply to ar +// LocalOrGlobalFlags contains flags that need to have values set globally by the build system or locally by the module +// tracked separately, in order to maintain the required ordering (most of the global flags need to go first on the +// command line so they can be overridden by the local module flags). +type LocalOrGlobalFlags struct { + CommonFlags []string // Flags that apply to C, C++, and assembly source files AsFlags []string // Flags that apply to assembly source files + YasmFlags []string // Flags that apply to yasm assembly source files CFlags []string // Flags that apply to C and C++ source files ToolingCFlags []string // Flags that apply to C and C++ source files parsed by clang LibTooling tools ConlyFlags []string // Flags that apply to C source files CppFlags []string // Flags that apply to C++ source files ToolingCppFlags []string // Flags that apply to C++ source files parsed by clang LibTooling tools - aidlFlags []string // Flags that apply to aidl source files - rsFlags []string // Flags that apply to renderscript source files LdFlags []string // Flags that apply to linker command lines - libFlags []string // Flags to add libraries early to the link order - extraLibFlags []string // Flags to add libraries late in the link order after LdFlags - TidyFlags []string // Flags that apply to clang-tidy - SAbiFlags []string // Flags that apply to header-abi-dumper - YasmFlags []string // Flags that apply to yasm assembly source files +} + +type Flags struct { + Local LocalOrGlobalFlags + Global LocalOrGlobalFlags + + aidlFlags []string // Flags that apply to aidl source files + rsFlags []string // Flags that apply to renderscript source files + libFlags []string // Flags to add libraries early to the link order + extraLibFlags []string // Flags to add libraries late in the link order after LdFlags + TidyFlags []string // Flags that apply to clang-tidy + SAbiFlags []string // Flags that apply to header-abi-dumper // Global include flags that apply to C, C++, and assembly source files - // These must be after any module include flags, which will be in GlobalFlags. + // These must be after any module include flags, which will be in CommonFlags. SystemIncludeFlags []string Toolchain config.Toolchain @@ -858,21 +866,28 @@ func (c *Module) ExportedIncludeDirs() android.Paths { if flagsProducer, ok := c.linker.(exportedFlagsProducer); ok { return flagsProducer.exportedDirs() } - return []android.Path{} + return nil } func (c *Module) ExportedSystemIncludeDirs() android.Paths { if flagsProducer, ok := c.linker.(exportedFlagsProducer); ok { return flagsProducer.exportedSystemDirs() } - return []android.Path{} + return nil } func (c *Module) ExportedFlags() []string { if flagsProducer, ok := c.linker.(exportedFlagsProducer); ok { return flagsProducer.exportedFlags() } - return []string{} + return nil +} + +func (c *Module) ExportedDeps() android.Paths { + if flagsProducer, ok := c.linker.(exportedFlagsProducer); ok { + return flagsProducer.exportedDeps() + } + return nil } func isBionic(name string) bool { @@ -1277,17 +1292,17 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { return } - flags.CFlags, _ = filterList(flags.CFlags, config.IllegalFlags) - flags.CppFlags, _ = filterList(flags.CppFlags, config.IllegalFlags) - flags.ConlyFlags, _ = filterList(flags.ConlyFlags, config.IllegalFlags) + flags.Local.CFlags, _ = filterList(flags.Local.CFlags, config.IllegalFlags) + flags.Local.CppFlags, _ = filterList(flags.Local.CppFlags, config.IllegalFlags) + flags.Local.ConlyFlags, _ = filterList(flags.Local.ConlyFlags, config.IllegalFlags) - flags.GlobalFlags = append(flags.GlobalFlags, deps.Flags...) + flags.Local.CommonFlags = append(flags.Local.CommonFlags, deps.Flags...) for _, dir := range deps.IncludeDirs { - flags.GlobalFlags = append(flags.GlobalFlags, "-I"+dir.String()) + flags.Local.CommonFlags = append(flags.Local.CommonFlags, "-I"+dir.String()) } for _, dir := range deps.SystemIncludeDirs { - flags.GlobalFlags = append(flags.GlobalFlags, "-isystem "+dir.String()) + flags.Local.CommonFlags = append(flags.Local.CommonFlags, "-isystem "+dir.String()) } c.flags = flags @@ -1296,16 +1311,16 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { flags = c.sabi.flags(ctx, flags) } - flags.AssemblerWithCpp = inList("-xassembler-with-cpp", flags.AsFlags) + flags.AssemblerWithCpp = inList("-xassembler-with-cpp", flags.Local.AsFlags) // Optimization to reduce size of build.ninja // Replace the long list of flags for each file with a module-local variable - ctx.Variable(pctx, "cflags", strings.Join(flags.CFlags, " ")) - ctx.Variable(pctx, "cppflags", strings.Join(flags.CppFlags, " ")) - ctx.Variable(pctx, "asflags", strings.Join(flags.AsFlags, " ")) - flags.CFlags = []string{"$cflags"} - flags.CppFlags = []string{"$cppflags"} - flags.AsFlags = []string{"$asflags"} + ctx.Variable(pctx, "cflags", strings.Join(flags.Local.CFlags, " ")) + ctx.Variable(pctx, "cppflags", strings.Join(flags.Local.CppFlags, " ")) + ctx.Variable(pctx, "asflags", strings.Join(flags.Local.AsFlags, " ")) + flags.Local.CFlags = []string{"$cflags"} + flags.Local.CppFlags = []string{"$cppflags"} + flags.Local.AsFlags = []string{"$asflags"} var objs Objects if c.compiler != nil { diff --git a/cc/cc_test.go b/cc/cc_test.go index dcf117c27..0cbdd5236 100644 --- a/cc/cc_test.go +++ b/cc/cc_test.go @@ -248,27 +248,45 @@ func checkVndkModule(t *testing.T, ctx *android.TestContext, name, subDir string } } -func checkVndkSnapshot(t *testing.T, ctx *android.TestContext, name, subDir, variant string) { +func checkVndkSnapshot(t *testing.T, ctx *android.TestContext, moduleName, snapshotFilename, subDir, variant string) { vndkSnapshot := ctx.SingletonForTests("vndk-snapshot") - mod := ctx.ModuleForTests(name, variant).Module().(*Module) - if !mod.outputFile.Valid() { - t.Errorf("%q must have output\n", name) + mod, ok := ctx.ModuleForTests(moduleName, variant).Module().(android.OutputFileProducer) + if !ok { + t.Errorf("%q must have output\n", moduleName) + return + } + outputFiles, err := mod.OutputFiles("") + if err != nil || len(outputFiles) != 1 { + t.Errorf("%q must have single output\n", moduleName) return } - snapshotPath := filepath.Join(subDir, mod.outputFile.Path().Base()) + snapshotPath := filepath.Join(subDir, snapshotFilename) out := vndkSnapshot.Output(snapshotPath) - if out.Input != mod.outputFile.Path() { - t.Errorf("The input of VNDK snapshot must be %q, but %q", out.Input.String(), mod.outputFile.String()) + if out.Input.String() != outputFiles[0].String() { + t.Errorf("The input of VNDK snapshot must be %q, but %q", out.Input.String(), outputFiles[0]) } } +func checkWriteFileOutput(t *testing.T, params android.TestingBuildParams, expected []string) { + t.Helper() + assertString(t, params.Rule.String(), android.WriteFile.String()) + actual := strings.FieldsFunc(strings.ReplaceAll(params.Args["content"], "\\n", "\n"), func(r rune) bool { return r == '\n' }) + assertArrayString(t, actual, expected) +} + func checkVndkOutput(t *testing.T, ctx *android.TestContext, output string, expected []string) { t.Helper() vndkSnapshot := ctx.SingletonForTests("vndk-snapshot") - actual := strings.FieldsFunc(strings.ReplaceAll(vndkSnapshot.Output(output).Args["content"], "\\n", "\n"), func(r rune) bool { return r == '\n' }) - assertArrayString(t, actual, expected) + checkWriteFileOutput(t, vndkSnapshot.Output(output), expected) +} + +func checkVndkLibrariesOutput(t *testing.T, ctx *android.TestContext, module string, expected []string) { + t.Helper() + vndkLibraries := ctx.ModuleForTests(module, "") + output := insertVndkVersion(module, "VER") + checkWriteFileOutput(t, vndkLibraries.Output(output), expected) } func TestVndk(t *testing.T) { @@ -321,6 +339,21 @@ func TestVndk(t *testing.T) { }, }, } + vndk_libraries_txt { + name: "llndk.libraries.txt", + } + vndk_libraries_txt { + name: "vndkcore.libraries.txt", + } + vndk_libraries_txt { + name: "vndksp.libraries.txt", + } + vndk_libraries_txt { + name: "vndkprivate.libraries.txt", + } + vndk_libraries_txt { + name: "vndkcorevariant.libraries.txt", + } `, config) checkVndkModule(t, ctx, "libvndk", "vndk-VER", false, "") @@ -346,17 +379,17 @@ func TestVndk(t *testing.T) { variant := "android_arm64_armv8-a_vendor.VER_shared" variant2nd := "android_arm_armv7-a-neon_vendor.VER_shared" - checkVndkSnapshot(t, ctx, "libvndk", vndkCoreLibPath, variant) - checkVndkSnapshot(t, ctx, "libvndk", vndkCoreLib2ndPath, variant2nd) - checkVndkSnapshot(t, ctx, "libvndk_sp", vndkSpLibPath, variant) - checkVndkSnapshot(t, ctx, "libvndk_sp", vndkSpLib2ndPath, variant2nd) - - checkVndkOutput(t, ctx, "vndk/llndk.libraries.txt", []string{"libc.so", "libdl.so", "libft2.so", "libm.so"}) - checkVndkOutput(t, ctx, "vndk/vndkcore.libraries.txt", []string{"libvndk-private.so", "libvndk.so"}) - checkVndkOutput(t, ctx, "vndk/vndkprivate.libraries.txt", []string{"libft2.so", "libvndk-private.so", "libvndk_sp_private-x.so"}) - checkVndkOutput(t, ctx, "vndk/vndksp.libraries.txt", []string{"libc++.so", "libvndk_sp-x.so", "libvndk_sp_private-x.so"}) - checkVndkOutput(t, ctx, "vndk/vndkcorevariant.libraries.txt", nil) - // merged & tagged & filtered-out(libclang_rt) + checkVndkSnapshot(t, ctx, "libvndk", "libvndk.so", vndkCoreLibPath, variant) + checkVndkSnapshot(t, ctx, "libvndk", "libvndk.so", vndkCoreLib2ndPath, variant2nd) + checkVndkSnapshot(t, ctx, "libvndk_sp", "libvndk_sp-x.so", vndkSpLibPath, variant) + checkVndkSnapshot(t, ctx, "libvndk_sp", "libvndk_sp-x.so", vndkSpLib2ndPath, variant2nd) + + snapshotConfigsPath := filepath.Join(snapshotVariantPath, "configs") + checkVndkSnapshot(t, ctx, "llndk.libraries.txt", "llndk.libraries.txt", snapshotConfigsPath, "") + checkVndkSnapshot(t, ctx, "vndkcore.libraries.txt", "vndkcore.libraries.txt", snapshotConfigsPath, "") + checkVndkSnapshot(t, ctx, "vndksp.libraries.txt", "vndksp.libraries.txt", snapshotConfigsPath, "") + checkVndkSnapshot(t, ctx, "vndkprivate.libraries.txt", "vndkprivate.libraries.txt", snapshotConfigsPath, "") + checkVndkOutput(t, ctx, "vndk/vndk.libraries.txt", []string{ "LLNDK: libc.so", "LLNDK: libdl.so", @@ -371,19 +404,25 @@ func TestVndk(t *testing.T) { "VNDK-private: libvndk-private.so", "VNDK-private: libvndk_sp_private-x.so", }) - checkVndkOutput(t, ctx, "vndk/llndk.libraries.txt", []string{ - "libc.so", "libdl.so", "libft2.so", "libm.so", - }) - checkVndkOutput(t, ctx, "vndk/vndkcore.libraries.txt", []string{ - "libvndk-private.so", "libvndk.so", - }) - checkVndkOutput(t, ctx, "vndk/vndksp.libraries.txt", []string{ - "libc++.so", "libvndk_sp-x.so", "libvndk_sp_private-x.so", - }) - checkVndkOutput(t, ctx, "vndk/vndkprivate.libraries.txt", []string{ - "libft2.so", "libvndk-private.so", "libvndk_sp_private-x.so", - }) - checkVndkOutput(t, ctx, "vndk/vndkcorevariant.libraries.txt", []string{}) + checkVndkLibrariesOutput(t, ctx, "llndk.libraries.txt", []string{"libc.so", "libdl.so", "libft2.so", "libm.so"}) + checkVndkLibrariesOutput(t, ctx, "vndkcore.libraries.txt", []string{"libvndk-private.so", "libvndk.so"}) + checkVndkLibrariesOutput(t, ctx, "vndkprivate.libraries.txt", []string{"libft2.so", "libvndk-private.so", "libvndk_sp_private-x.so"}) + checkVndkLibrariesOutput(t, ctx, "vndksp.libraries.txt", []string{"libc++.so", "libvndk_sp-x.so", "libvndk_sp_private-x.so"}) + checkVndkLibrariesOutput(t, ctx, "vndkcorevariant.libraries.txt", nil) +} + +func TestVndkLibrariesTxtAndroidMk(t *testing.T) { + config := android.TestArchConfig(buildDir, nil) + config.TestProductVariables.DeviceVndkVersion = StringPtr("current") + config.TestProductVariables.Platform_vndk_version = StringPtr("VER") + ctx := testCcWithConfig(t, ` + vndk_libraries_txt { + name: "llndk.libraries.txt", + }`, config) + + module := ctx.ModuleForTests("llndk.libraries.txt", "") + entries := android.AndroidMkEntriesForTest(t, config, "", module.Module()) + assertArrayString(t, entries.EntryMap["LOCAL_MODULE_STEM"], []string{"llndk.libraries.VER.txt"}) } func TestVndkUsingCoreVariant(t *testing.T) { @@ -422,20 +461,17 @@ func TestVndkUsingCoreVariant(t *testing.T) { }, nocrt: true, } + + vndk_libraries_txt { + name: "vndkcorevariant.libraries.txt", + } `, config) - checkVndkOutput(t, ctx, "vndk/vndkcore.libraries.txt", []string{"libvndk.so", "libvndk2.so"}) - checkVndkOutput(t, ctx, "vndk/vndkcorevariant.libraries.txt", []string{ - "libc++.so", "libvndk2.so", "libvndk_sp.so", - }) + checkVndkLibrariesOutput(t, ctx, "vndkcorevariant.libraries.txt", []string{"libc++.so", "libvndk2.so", "libvndk_sp.so"}) } func TestVndkWhenVndkVersionIsNotSet(t *testing.T) { - config := android.TestArchConfig(buildDir, nil) - config.TestProductVariables.DeviceVndkVersion = nil - config.TestProductVariables.Platform_vndk_version = nil - - ctx := testCcWithConfig(t, ` + ctx := testCcNoVndk(t, ` cc_library { name: "libvndk", vendor_available: true, @@ -444,7 +480,7 @@ func TestVndkWhenVndkVersionIsNotSet(t *testing.T) { }, nocrt: true, } - `, config) + `) checkVndkOutput(t, ctx, "vndk/vndk.libraries.txt", []string{ "LLNDK: libc.so", diff --git a/cc/cflag_artifacts.go b/cc/cflag_artifacts.go index 9ed3876ab..b61f2a8be 100644 --- a/cc/cflag_artifacts.go +++ b/cc/cflag_artifacts.go @@ -147,8 +147,8 @@ func (s *cflagArtifactsText) GenerateBuildActions(ctx android.SingletonContext) ctx.VisitAllModules(func(module android.Module) { if ccModule, ok := module.(*Module); ok { if allowedDir(ctx.ModuleDir(ccModule)) { - cflags := ccModule.flags.CFlags - cppflags := ccModule.flags.CppFlags + cflags := ccModule.flags.Local.CFlags + cppflags := ccModule.flags.Local.CppFlags module := fmt.Sprintf("%s:%s (%s)", ctx.BlueprintFile(ccModule), ctx.ModuleName(ccModule), diff --git a/cc/cmakelists.go b/cc/cmakelists.go index 7b4f89b54..97d21f444 100644 --- a/cc/cmakelists.go +++ b/cc/cmakelists.go @@ -162,25 +162,41 @@ func generateCLionProject(compiledModule CompiledInterface, ctx android.Singleto f.WriteString(")\n") // Add all header search path and compiler parameters (-D, -W, -f, -XXXX) - f.WriteString("\n# GLOBAL FLAGS:\n") - globalParameters := parseCompilerParameters(ccModule.flags.GlobalFlags, ctx, f) - translateToCMake(globalParameters, f, true, true) + f.WriteString("\n# GLOBAL ALL FLAGS:\n") + globalAllParameters := parseCompilerParameters(ccModule.flags.Global.CommonFlags, ctx, f) + translateToCMake(globalAllParameters, f, true, true) - f.WriteString("\n# CFLAGS:\n") - cParameters := parseCompilerParameters(ccModule.flags.CFlags, ctx, f) - translateToCMake(cParameters, f, true, true) + f.WriteString("\n# LOCAL ALL FLAGS:\n") + localAllParameters := parseCompilerParameters(ccModule.flags.Local.CommonFlags, ctx, f) + translateToCMake(localAllParameters, f, true, true) - f.WriteString("\n# C ONLY FLAGS:\n") - cOnlyParameters := parseCompilerParameters(ccModule.flags.ConlyFlags, ctx, f) - translateToCMake(cOnlyParameters, f, true, false) + f.WriteString("\n# GLOBAL CFLAGS:\n") + globalCParameters := parseCompilerParameters(ccModule.flags.Global.CFlags, ctx, f) + translateToCMake(globalCParameters, f, true, true) - f.WriteString("\n# CPP FLAGS:\n") - cppParameters := parseCompilerParameters(ccModule.flags.CppFlags, ctx, f) - translateToCMake(cppParameters, f, false, true) + f.WriteString("\n# LOCAL CFLAGS:\n") + localCParameters := parseCompilerParameters(ccModule.flags.Local.CFlags, ctx, f) + translateToCMake(localCParameters, f, true, true) - f.WriteString("\n# SYSTEM INCLUDE FLAGS:\n") - includeParameters := parseCompilerParameters(ccModule.flags.SystemIncludeFlags, ctx, f) - translateToCMake(includeParameters, f, true, true) + f.WriteString("\n# GLOBAL C ONLY FLAGS:\n") + globalConlyParameters := parseCompilerParameters(ccModule.flags.Global.ConlyFlags, ctx, f) + translateToCMake(globalConlyParameters, f, true, false) + + f.WriteString("\n# LOCAL C ONLY FLAGS:\n") + localConlyParameters := parseCompilerParameters(ccModule.flags.Local.ConlyFlags, ctx, f) + translateToCMake(localConlyParameters, f, true, false) + + f.WriteString("\n# GLOBAL CPP FLAGS:\n") + globalCppParameters := parseCompilerParameters(ccModule.flags.Global.CppFlags, ctx, f) + translateToCMake(globalCppParameters, f, false, true) + + f.WriteString("\n# LOCAL CPP FLAGS:\n") + localCppParameters := parseCompilerParameters(ccModule.flags.Local.CppFlags, ctx, f) + translateToCMake(localCppParameters, f, false, true) + + f.WriteString("\n# GLOBAL SYSTEM INCLUDE FLAGS:\n") + globalIncludeParameters := parseCompilerParameters(ccModule.flags.SystemIncludeFlags, ctx, f) + translateToCMake(globalIncludeParameters, f, true, true) // Add project executable. f.WriteString(fmt.Sprintf("\nadd_executable(%s ${SOURCE_FILES})\n", @@ -306,6 +322,20 @@ func categorizeParameter(parameter string) parameterType { return flag } +// Flattens a list of strings potentially containing space characters into a list of string containing no +// spaces. +func normalizeParameters(params []string) []string { + var flatParams []string + for _, s := range params { + s = strings.Trim(s, " ") + if len(s) == 0 { + continue + } + flatParams = append(flatParams, strings.Split(s, " ")...) + } + return flatParams +} + func parseCompilerParameters(params []string, ctx android.SingletonContext, f *os.File) compilerParameters { var compilerParameters = makeCompilerParameters() @@ -313,6 +343,15 @@ func parseCompilerParameters(params []string, ctx android.SingletonContext, f *o f.WriteString(fmt.Sprintf("# Raw param [%d] = '%s'\n", i, str)) } + // Soong does not guarantee that each flag will be in an individual string. e.g: The + // input received could be: + // params = {"-isystem", "path/to/system"} + // or it could be + // params = {"-isystem path/to/system"} + // To normalize the input, we split all strings with the "space" character and consolidate + // all tokens into a flattened parameters list + params = normalizeParameters(params) + for i := 0; i < len(params); i++ { param := params[i] if param == "" { diff --git a/cc/compdb.go b/cc/compdb.go index ecc67b8b0..519380fa9 100644 --- a/cc/compdb.go +++ b/cc/compdb.go @@ -152,12 +152,16 @@ func getArguments(src android.Path, ctx android.SingletonContext, ccModule *Modu clangPath = ccPath } args = append(args, clangPath) - args = append(args, expandAllVars(ctx, ccModule.flags.GlobalFlags)...) - args = append(args, expandAllVars(ctx, ccModule.flags.CFlags)...) + args = append(args, expandAllVars(ctx, ccModule.flags.Global.CommonFlags)...) + args = append(args, expandAllVars(ctx, ccModule.flags.Local.CommonFlags)...) + args = append(args, expandAllVars(ctx, ccModule.flags.Global.CFlags)...) + args = append(args, expandAllVars(ctx, ccModule.flags.Local.CFlags)...) if isCpp { - args = append(args, expandAllVars(ctx, ccModule.flags.CppFlags)...) + args = append(args, expandAllVars(ctx, ccModule.flags.Global.CppFlags)...) + args = append(args, expandAllVars(ctx, ccModule.flags.Local.CppFlags)...) } else if !isAsm { - args = append(args, expandAllVars(ctx, ccModule.flags.ConlyFlags)...) + args = append(args, expandAllVars(ctx, ccModule.flags.Global.ConlyFlags)...) + args = append(args, expandAllVars(ctx, ccModule.flags.Local.ConlyFlags)...) } args = append(args, expandAllVars(ctx, ccModule.flags.SystemIncludeFlags)...) args = append(args, src.String()) diff --git a/cc/compiler.go b/cc/compiler.go index ff681017e..bb40a5bd2 100644 --- a/cc/compiler.go +++ b/cc/compiler.go @@ -265,11 +265,11 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps esc := proptools.NinjaAndShellEscapeList - flags.CFlags = append(flags.CFlags, esc(compiler.Properties.Cflags)...) - flags.CppFlags = append(flags.CppFlags, esc(compiler.Properties.Cppflags)...) - flags.ConlyFlags = append(flags.ConlyFlags, esc(compiler.Properties.Conlyflags)...) - flags.AsFlags = append(flags.AsFlags, esc(compiler.Properties.Asflags)...) - flags.YasmFlags = append(flags.YasmFlags, esc(compiler.Properties.Asflags)...) + flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Cflags)...) + flags.Local.CppFlags = append(flags.Local.CppFlags, esc(compiler.Properties.Cppflags)...) + flags.Local.ConlyFlags = append(flags.Local.ConlyFlags, esc(compiler.Properties.Conlyflags)...) + flags.Local.AsFlags = append(flags.Local.AsFlags, esc(compiler.Properties.Asflags)...) + flags.Local.YasmFlags = append(flags.Local.YasmFlags, esc(compiler.Properties.Asflags)...) flags.Yacc = compiler.Properties.Yacc @@ -277,20 +277,20 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps localIncludeDirs := android.PathsForModuleSrc(ctx, compiler.Properties.Local_include_dirs) if len(localIncludeDirs) > 0 { f := includeDirsToFlags(localIncludeDirs) - flags.GlobalFlags = append(flags.GlobalFlags, f) - flags.YasmFlags = append(flags.YasmFlags, f) + flags.Local.CommonFlags = append(flags.Local.CommonFlags, f) + flags.Local.YasmFlags = append(flags.Local.YasmFlags, f) } rootIncludeDirs := android.PathsForSource(ctx, compiler.Properties.Include_dirs) if len(rootIncludeDirs) > 0 { f := includeDirsToFlags(rootIncludeDirs) - flags.GlobalFlags = append(flags.GlobalFlags, f) - flags.YasmFlags = append(flags.YasmFlags, f) + flags.Local.CommonFlags = append(flags.Local.CommonFlags, f) + flags.Local.YasmFlags = append(flags.Local.YasmFlags, f) } if compiler.Properties.Include_build_directory == nil || *compiler.Properties.Include_build_directory { - flags.GlobalFlags = append(flags.GlobalFlags, "-I"+android.PathForModuleSrc(ctx).String()) - flags.YasmFlags = append(flags.YasmFlags, "-I"+android.PathForModuleSrc(ctx).String()) + flags.Local.CommonFlags = append(flags.Local.CommonFlags, "-I"+android.PathForModuleSrc(ctx).String()) + flags.Local.YasmFlags = append(flags.Local.YasmFlags, "-I"+android.PathForModuleSrc(ctx).String()) } if !(ctx.useSdk() || ctx.useVndk()) || ctx.Host() { @@ -312,16 +312,17 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps } if ctx.useVndk() { - flags.GlobalFlags = append(flags.GlobalFlags, "-D__ANDROID_VNDK__") + flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_VNDK__") } if ctx.inRecovery() { - flags.GlobalFlags = append(flags.GlobalFlags, "-D__ANDROID_RECOVERY__") + flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_RECOVERY__") } if ctx.apexName() != "" { - flags.GlobalFlags = append(flags.GlobalFlags, "-D__ANDROID_APEX__") - flags.GlobalFlags = append(flags.GlobalFlags, "-D__ANDROID_APEX_"+makeDefineString(ctx.apexName())+"__") + flags.Global.CommonFlags = append(flags.Global.CommonFlags, + "-D__ANDROID_APEX__", + "-D__ANDROID_APEX_"+makeDefineString(ctx.apexName())+"__") } instructionSet := String(compiler.Properties.Instruction_set) @@ -336,17 +337,17 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps CheckBadCompilerFlags(ctx, "release.cflags", compiler.Properties.Release.Cflags) // TODO: debug - flags.CFlags = append(flags.CFlags, esc(compiler.Properties.Release.Cflags)...) + flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Release.Cflags)...) CheckBadCompilerFlags(ctx, "clang_cflags", compiler.Properties.Clang_cflags) CheckBadCompilerFlags(ctx, "clang_asflags", compiler.Properties.Clang_asflags) - flags.CFlags = config.ClangFilterUnknownCflags(flags.CFlags) - flags.CFlags = append(flags.CFlags, esc(compiler.Properties.Clang_cflags)...) - flags.AsFlags = append(flags.AsFlags, esc(compiler.Properties.Clang_asflags)...) - flags.CppFlags = config.ClangFilterUnknownCflags(flags.CppFlags) - flags.ConlyFlags = config.ClangFilterUnknownCflags(flags.ConlyFlags) - flags.LdFlags = config.ClangFilterUnknownCflags(flags.LdFlags) + flags.Local.CFlags = config.ClangFilterUnknownCflags(flags.Local.CFlags) + flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Clang_cflags)...) + flags.Local.AsFlags = append(flags.Local.AsFlags, esc(compiler.Properties.Clang_asflags)...) + flags.Local.CppFlags = config.ClangFilterUnknownCflags(flags.Local.CppFlags) + flags.Local.ConlyFlags = config.ClangFilterUnknownCflags(flags.Local.ConlyFlags) + flags.Local.LdFlags = config.ClangFilterUnknownCflags(flags.Local.LdFlags) target := "-target " + tc.ClangTriple() if ctx.Os().Class == android.Device { @@ -360,45 +361,45 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps gccPrefix := "-B" + config.ToolPath(tc) - flags.CFlags = append(flags.CFlags, target, gccPrefix) - flags.AsFlags = append(flags.AsFlags, target, gccPrefix) - flags.LdFlags = append(flags.LdFlags, target, gccPrefix) + flags.Global.CFlags = append(flags.Global.CFlags, target, gccPrefix) + flags.Global.AsFlags = append(flags.Global.AsFlags, target, gccPrefix) + flags.Global.LdFlags = append(flags.Global.LdFlags, target, gccPrefix) hod := "Host" if ctx.Os().Class == android.Device { hod = "Device" } - flags.GlobalFlags = append(flags.GlobalFlags, instructionSetFlags) - flags.ConlyFlags = append([]string{"${config.CommonGlobalConlyflags}"}, flags.ConlyFlags...) - flags.CppFlags = append([]string{fmt.Sprintf("${config.%sGlobalCppflags}", hod)}, flags.CppFlags...) + flags.Global.CommonFlags = append(flags.Global.CommonFlags, instructionSetFlags) + flags.Global.ConlyFlags = append([]string{"${config.CommonGlobalConlyflags}"}, flags.Global.ConlyFlags...) + flags.Global.CppFlags = append([]string{fmt.Sprintf("${config.%sGlobalCppflags}", hod)}, flags.Global.CppFlags...) - flags.AsFlags = append(flags.AsFlags, tc.ClangAsflags()) - flags.CppFlags = append([]string{"${config.CommonClangGlobalCppflags}"}, flags.CppFlags...) - flags.GlobalFlags = append(flags.GlobalFlags, + flags.Global.AsFlags = append(flags.Global.AsFlags, tc.ClangAsflags()) + flags.Global.CppFlags = append([]string{"${config.CommonClangGlobalCppflags}"}, flags.Global.CppFlags...) + flags.Global.CommonFlags = append(flags.Global.CommonFlags, tc.ClangCflags(), "${config.CommonClangGlobalCflags}", fmt.Sprintf("${config.%sClangGlobalCflags}", hod)) if strings.HasPrefix(android.PathForModuleSrc(ctx).String(), "external/") { - flags.GlobalFlags = append([]string{"${config.ClangExternalCflags}"}, flags.GlobalFlags...) + flags.Global.CommonFlags = append([]string{"${config.ClangExternalCflags}"}, flags.Global.CommonFlags...) } if tc.Bionic() { if Bool(compiler.Properties.Rtti) { - flags.CppFlags = append(flags.CppFlags, "-frtti") + flags.Local.CppFlags = append(flags.Local.CppFlags, "-frtti") } else { - flags.CppFlags = append(flags.CppFlags, "-fno-rtti") + flags.Local.CppFlags = append(flags.Local.CppFlags, "-fno-rtti") } } - flags.AsFlags = append(flags.AsFlags, "-D__ASSEMBLY__") + flags.Global.AsFlags = append(flags.Global.AsFlags, "-D__ASSEMBLY__") - flags.CppFlags = append(flags.CppFlags, tc.ClangCppflags()) + flags.Global.CppFlags = append(flags.Global.CppFlags, tc.ClangCppflags()) - flags.YasmFlags = append(flags.YasmFlags, tc.YasmFlags()) + flags.Global.YasmFlags = append(flags.Global.YasmFlags, tc.YasmFlags()) - flags.GlobalFlags = append(flags.GlobalFlags, tc.ToolchainClangCflags()) + flags.Global.CommonFlags = append(flags.Global.CommonFlags, tc.ToolchainClangCflags()) cStd := config.CStdVersion if String(compiler.Properties.C_std) == "experimental" { @@ -420,15 +421,15 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps cppStd = gnuToCReplacer.Replace(cppStd) } - flags.ConlyFlags = append([]string{"-std=" + cStd}, flags.ConlyFlags...) - flags.CppFlags = append([]string{"-std=" + cppStd}, flags.CppFlags...) + flags.Local.ConlyFlags = append([]string{"-std=" + cStd}, flags.Local.ConlyFlags...) + flags.Local.CppFlags = append([]string{"-std=" + cppStd}, flags.Local.CppFlags...) if ctx.useVndk() { - flags.CFlags = append(flags.CFlags, esc(compiler.Properties.Target.Vendor.Cflags)...) + flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Target.Vendor.Cflags)...) } if ctx.inRecovery() { - flags.CFlags = append(flags.CFlags, esc(compiler.Properties.Target.Recovery.Cflags)...) + flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Target.Recovery.Cflags)...) } // We can enforce some rules more strictly in the code we own. strict @@ -444,7 +445,7 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps // Can be used to make some annotations stricter for code we can fix // (such as when we mark functions as deprecated). if strict { - flags.CFlags = append(flags.CFlags, "-DANDROID_STRICT") + flags.Global.CFlags = append(flags.Global.CFlags, "-DANDROID_STRICT") } if compiler.hasSrcExt(".proto") { @@ -452,12 +453,12 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps } if compiler.hasSrcExt(".y") || compiler.hasSrcExt(".yy") { - flags.GlobalFlags = append(flags.GlobalFlags, + flags.Local.CommonFlags = append(flags.Local.CommonFlags, "-I"+android.PathForModuleGen(ctx, "yacc", ctx.ModuleDir()).String()) } if compiler.hasSrcExt(".mc") { - flags.GlobalFlags = append(flags.GlobalFlags, + flags.Local.CommonFlags = append(flags.Local.CommonFlags, "-I"+android.PathForModuleGen(ctx, "windmc", ctx.ModuleDir()).String()) } @@ -475,7 +476,7 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps flags.aidlFlags = append(flags.aidlFlags, "-t") } - flags.GlobalFlags = append(flags.GlobalFlags, + flags.Local.CommonFlags = append(flags.Local.CommonFlags, "-I"+android.PathForModuleGen(ctx, "aidl").String()) } @@ -484,26 +485,26 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps } if compiler.hasSrcExt(".sysprop") { - flags.GlobalFlags = append(flags.GlobalFlags, + flags.Local.CommonFlags = append(flags.Local.CommonFlags, "-I"+android.PathForModuleGen(ctx, "sysprop", "include").String()) } if len(compiler.Properties.Srcs) > 0 { module := ctx.ModuleDir() + "/Android.bp:" + ctx.ModuleName() - if inList("-Wno-error", flags.CFlags) || inList("-Wno-error", flags.CppFlags) { + if inList("-Wno-error", flags.Local.CFlags) || inList("-Wno-error", flags.Local.CppFlags) { addToModuleList(ctx, modulesUsingWnoErrorKey, module) - } else if !inList("-Werror", flags.CFlags) && !inList("-Werror", flags.CppFlags) { + } else if !inList("-Werror", flags.Local.CFlags) && !inList("-Werror", flags.Local.CppFlags) { if warningsAreAllowed(ctx.ModuleDir()) { addToModuleList(ctx, modulesAddedWallKey, module) - flags.CFlags = append([]string{"-Wall"}, flags.CFlags...) + flags.Local.CFlags = append([]string{"-Wall"}, flags.Local.CFlags...) } else { - flags.CFlags = append([]string{"-Wall", "-Werror"}, flags.CFlags...) + flags.Local.CFlags = append([]string{"-Wall", "-Werror"}, flags.Local.CFlags...) } } } if Bool(compiler.Properties.Openmp) { - flags.CFlags = append(flags.CFlags, "-fopenmp") + flags.Local.CFlags = append(flags.Local.CFlags, "-fopenmp") } return flags diff --git a/cc/config/clang.go b/cc/config/clang.go index 71bea4263..1b6744e61 100644 --- a/cc/config/clang.go +++ b/cc/config/clang.go @@ -139,9 +139,7 @@ func init() { pctx.StaticVariable("ClangExtraCppflags", strings.Join([]string{ // Enable clang's thread-safety annotations in libcxx. - // Turn off -Wthread-safety-negative, to avoid breaking projects that use -Weverything. "-D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS", - "-Wno-thread-safety-negative", // libc++'s math.h has an #include_next outside of system_headers. "-Wno-gnu-include-next", diff --git a/cc/coverage.go b/cc/coverage.go index 2e81a9e4c..c03a568c3 100644 --- a/cc/coverage.go +++ b/cc/coverage.go @@ -69,12 +69,12 @@ func (cov *coverage) flags(ctx ModuleContext, flags Flags, deps PathDeps) (Flags if cov.Properties.CoverageEnabled { flags.Coverage = true - flags.GlobalFlags = append(flags.GlobalFlags, "--coverage", "-O0") + flags.Local.CommonFlags = append(flags.Local.CommonFlags, "--coverage", "-O0") cov.linkCoverage = true // Override -Wframe-larger-than and non-default optimization // flags that the module may use. - flags.CFlags = append(flags.CFlags, "-Wno-frame-larger-than=", "-O0") + flags.Local.CFlags = append(flags.Local.CFlags, "-Wno-frame-larger-than=", "-O0") } // Even if we don't have coverage enabled, if any of our object files were compiled @@ -112,12 +112,12 @@ func (cov *coverage) flags(ctx ModuleContext, flags Flags, deps PathDeps) (Flags } if cov.linkCoverage { - flags.LdFlags = append(flags.LdFlags, "--coverage") + flags.Local.LdFlags = append(flags.Local.LdFlags, "--coverage") coverage := ctx.GetDirectDepWithTag(getProfileLibraryName(ctx), coverageDepTag).(*Module) deps.WholeStaticLibs = append(deps.WholeStaticLibs, coverage.OutputFile().Path()) - flags.LdFlags = append(flags.LdFlags, "-Wl,--wrap,getenv") + flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--wrap,getenv") } return flags, deps diff --git a/cc/fuzz.go b/cc/fuzz.go index 577fa704e..1f06fb03c 100644 --- a/cc/fuzz.go +++ b/cc/fuzz.go @@ -17,10 +17,9 @@ package cc import ( "encoding/json" "path/filepath" + "sort" "strings" - "github.com/google/blueprint/proptools" - "android/soong/android" "android/soong/cc/config" ) @@ -82,6 +81,7 @@ type fuzzBinary struct { corpus android.Paths corpusIntermediateDir android.Path config android.Path + installedSharedDeps []string } func (fuzz *fuzzBinary) linkerProps() []interface{} { @@ -91,21 +91,6 @@ func (fuzz *fuzzBinary) linkerProps() []interface{} { } func (fuzz *fuzzBinary) linkerInit(ctx BaseModuleContext) { - // Add ../lib[64] to rpath so that out/host/linux-x86/fuzz/<fuzzer> can - // find out/host/linux-x86/lib[64]/library.so - runpaths := []string{"../lib"} - for _, runpath := range runpaths { - if ctx.toolchain().Is64Bit() { - runpath += "64" - } - fuzz.binaryDecorator.baseLinker.dynamicProperties.RunPaths = append( - fuzz.binaryDecorator.baseLinker.dynamicProperties.RunPaths, runpath) - } - - // add "" to rpath so that fuzzer binaries can find libraries in their own fuzz directory - fuzz.binaryDecorator.baseLinker.dynamicProperties.RunPaths = append( - fuzz.binaryDecorator.baseLinker.dynamicProperties.RunPaths, "") - fuzz.binaryDecorator.linkerInit(ctx) } @@ -118,9 +103,80 @@ func (fuzz *fuzzBinary) linkerDeps(ctx DepsContext, deps Deps) Deps { func (fuzz *fuzzBinary) linkerFlags(ctx ModuleContext, flags Flags) Flags { flags = fuzz.binaryDecorator.linkerFlags(ctx, flags) + // RunPaths on devices isn't instantiated by the base linker. + flags.Local.LdFlags = append(flags.Local.LdFlags, `-Wl,-rpath,\$$ORIGIN/../lib`) return flags } +// This function performs a breadth-first search over the provided module's +// dependencies using `visitDirectDeps` to enumerate all shared library +// dependencies. We require breadth-first expansion, as otherwise we may +// incorrectly use the core libraries (sanitizer runtimes, libc, libdl, etc.) +// from a dependency. This may cause issues when dependencies have explicit +// sanitizer tags, as we may get a dependency on an unsanitized libc, etc. +func collectAllSharedDependencies( + module android.Module, + sharedDeps map[string]android.Path, + ctx android.SingletonContext) { + var fringe []android.Module + + // Enumerate the first level of dependencies, as we discard all non-library + // modules in the BFS loop below. + ctx.VisitDirectDeps(module, func(dep android.Module) { + fringe = append(fringe, dep) + }) + + for i := 0; i < len(fringe); i++ { + module := fringe[i] + if !isValidSharedDependency(module, sharedDeps) { + continue + } + + ccModule := module.(*Module) + sharedDeps[ccModule.Name()] = ccModule.UnstrippedOutputFile() + ctx.VisitDirectDeps(module, func(dep android.Module) { + fringe = append(fringe, dep) + }) + } +} + +// This function takes a module and determines if it is a unique shared library +// that should be installed in the fuzz target output directories. This function +// returns true, unless: +// - The module already exists in `sharedDeps`, or +// - The module is not a shared library, or +// - The module is a header, stub, or vendor-linked library. +func isValidSharedDependency( + dependency android.Module, + sharedDeps map[string]android.Path) bool { + // TODO(b/144090547): We should be parsing these modules using + // ModuleDependencyTag instead of the current brute-force checking. + + if linkable, ok := dependency.(LinkableInterface); !ok || // Discard non-linkables. + !linkable.CcLibraryInterface() || !linkable.Shared() || // Discard static libs. + linkable.UseVndk() || // Discard vendor linked libraries. + !linkable.CcLibrary() || linkable.BuildStubs() { // Discard stubs libs (only CCLibrary variants). + return false + } + + // If this library has already been traversed, we don't need to do any more work. + if _, exists := sharedDeps[dependency.Name()]; exists { + return false + } + return true +} + +func sharedLibraryInstallLocation( + libraryPath android.Path, isHost bool, archString string) string { + installLocation := "$(PRODUCT_OUT)/data" + if isHost { + installLocation = "$(HOST_OUT)" + } + installLocation = filepath.Join( + installLocation, "fuzz", archString, "lib", libraryPath.Base()) + return installLocation +} + func (fuzz *fuzzBinary) install(ctx ModuleContext, file android.Path) { fuzz.binaryDecorator.baseInstaller.dir = filepath.Join( "fuzz", ctx.Target().Arch.ArchType.String(), ctx.ModuleName()) @@ -160,6 +216,22 @@ func (fuzz *fuzzBinary) install(ctx ModuleContext, file android.Path) { }) fuzz.config = configPath } + + // Grab the list of required shared libraries. + sharedLibraries := make(map[string]android.Path) + ctx.WalkDeps(func(child, parent android.Module) bool { + if isValidSharedDependency(child, sharedLibraries) { + sharedLibraries[child.Name()] = child.(*Module).UnstrippedOutputFile() + return true + } + return false + }) + + for _, lib := range sharedLibraries { + fuzz.installedSharedDeps = append(fuzz.installedSharedDeps, + sharedLibraryInstallLocation( + lib, ctx.Host(), ctx.Arch().ArchType.String())) + } } func NewFuzz(hod android.HostOrDeviceSupported) *Module { @@ -193,28 +265,15 @@ func NewFuzz(hod android.HostOrDeviceSupported) *Module { ctx.AppendProperties(&disableDarwinAndLinuxBionic) }) - // Statically link the STL. This allows fuzz target deployment to not have to - // include the STL. - android.AddLoadHook(module, func(ctx android.LoadHookContext) { - staticStlLinkage := struct { - Target struct { - Linux_glibc struct { - Stl *string - } - } - }{} - - staticStlLinkage.Target.Linux_glibc.Stl = proptools.StringPtr("libc++_static") - ctx.AppendProperties(&staticStlLinkage) - }) - return module } // Responsible for generating GNU Make rules that package fuzz targets into // their architecture & target/host specific zip file. type fuzzPackager struct { - packages android.Paths + packages android.Paths + sharedLibInstallStrings []string + fuzzTargets map[string]bool } func fuzzPackagingFactory() android.Singleton { @@ -226,18 +285,31 @@ type fileToZip struct { DestinationPathPrefix string } +type archAndLibraryKey struct { + ArchDir android.OutputPath + Library android.Path +} + func (s *fuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { // Map between each architecture + host/device combination, and the files that // need to be packaged (in the tuple of {source file, destination folder in // archive}). archDirs := make(map[android.OutputPath][]fileToZip) + // List of shared library dependencies for each architecture + host/device combo. + archSharedLibraryDeps := make(map[archAndLibraryKey]bool) + + // List of individual fuzz targets, so that 'make fuzz' also installs the targets + // to the correct output directories as well. + s.fuzzTargets = make(map[string]bool) + ctx.VisitAllModules(func(module android.Module) { // Discard non-fuzz targets. ccModule, ok := module.(*Module) if !ok { return } + fuzzModule, ok := ccModule.compiler.(*fuzzBinary) if !ok { return @@ -249,6 +321,8 @@ func (s *fuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { return } + s.fuzzTargets[module.Name()] = true + hostOrTargetString := "target" if ccModule.Host() { hostOrTargetString = "host" @@ -257,6 +331,29 @@ func (s *fuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { archString := ccModule.Arch().ArchType.String() archDir := android.PathForIntermediates(ctx, "fuzz", hostOrTargetString, archString) + // Grab the list of required shared libraries. + sharedLibraries := make(map[string]android.Path) + collectAllSharedDependencies(module, sharedLibraries, ctx) + + for _, library := range sharedLibraries { + if _, exists := archSharedLibraryDeps[archAndLibraryKey{archDir, library}]; exists { + continue + } + + // For each architecture-specific shared library dependency, we need to + // install it to the output directory. Setup the install destination here, + // which will be used by $(copy-many-files) in the Make backend. + archSharedLibraryDeps[archAndLibraryKey{archDir, library}] = true + installDestination := sharedLibraryInstallLocation( + library, ccModule.Host(), archString) + // Escape all the variables, as the install destination here will be called + // via. $(eval) in Make. + installDestination = strings.ReplaceAll( + installDestination, "$", "$$") + s.sharedLibInstallStrings = append(s.sharedLibInstallStrings, + library.String()+":"+installDestination) + } + // The executable. archDirs[archDir] = append(archDirs[archDir], fileToZip{ccModule.UnstrippedOutputFile(), ccModule.Name()}) @@ -280,6 +377,12 @@ func (s *fuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { } }) + // Add the shared library deps for packaging. + for key, _ := range archSharedLibraryDeps { + archDirs[key.ArchDir] = append(archDirs[key.ArchDir], + fileToZip{key.Library, "lib"}) + } + for archDir, filesToZip := range archDirs { arch := archDir.Base() hostOrTarget := filepath.Base(filepath.Dir(archDir.String())) @@ -302,9 +405,22 @@ func (s *fuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { } func (s *fuzzPackager) MakeVars(ctx android.MakeVarsContext) { + packages := s.packages.Strings() + sort.Strings(packages) + sort.Strings(s.sharedLibInstallStrings) // TODO(mitchp): Migrate this to use MakeVarsContext::DistForGoal() when it's // ready to handle phony targets created in Soong. In the meantime, this // exports the phony 'fuzz' target and dependencies on packages to // core/main.mk so that we can use dist-for-goals. - ctx.Strict("SOONG_FUZZ_PACKAGING_ARCH_MODULES", strings.Join(s.packages.Strings(), " ")) + ctx.Strict("SOONG_FUZZ_PACKAGING_ARCH_MODULES", strings.Join(packages, " ")) + ctx.Strict("FUZZ_TARGET_SHARED_DEPS_INSTALL_PAIRS", + strings.Join(s.sharedLibInstallStrings, " ")) + + // Preallocate the slice of fuzz targets to minimise memory allocations. + fuzzTargets := make([]string, 0, len(s.fuzzTargets)) + for target, _ := range s.fuzzTargets { + fuzzTargets = append(fuzzTargets, target) + } + sort.Strings(fuzzTargets) + ctx.Strict("ALL_FUZZ_TARGETS", strings.Join(fuzzTargets, " ")) } diff --git a/cc/gen_test.go b/cc/gen_test.go index da3b4e8ad..ceecf1c16 100644 --- a/cc/gen_test.go +++ b/cc/gen_test.go @@ -34,7 +34,7 @@ func TestGen(t *testing.T) { aidl := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_core_shared").Rule("aidl") libfoo := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_core_shared").Module().(*Module) - if !inList("-I"+filepath.Dir(aidl.Output.String()), libfoo.flags.GlobalFlags) { + if !inList("-I"+filepath.Dir(aidl.Output.String()), libfoo.flags.Local.CommonFlags) { t.Errorf("missing aidl includes in global flags") } }) @@ -58,7 +58,7 @@ func TestGen(t *testing.T) { aidl := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_core_shared").Rule("aidl") libfoo := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_core_shared").Module().(*Module) - if !inList("-I"+filepath.Dir(aidl.Output.String()), libfoo.flags.GlobalFlags) { + if !inList("-I"+filepath.Dir(aidl.Output.String()), libfoo.flags.Local.CommonFlags) { t.Errorf("missing aidl includes in global flags") } diff --git a/cc/library.go b/cc/library.go index 8d90cd8bb..dde067cab 100644 --- a/cc/library.go +++ b/cc/library.go @@ -394,13 +394,13 @@ func (library *libraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Fla // all code is position independent, and then those warnings get promoted to // errors. if !ctx.Windows() { - flags.CFlags = append(flags.CFlags, "-fPIC") + flags.Global.CFlags = append(flags.Global.CFlags, "-fPIC") } if library.static() { - flags.CFlags = append(flags.CFlags, library.StaticProperties.Static.Cflags...) + flags.Local.CFlags = append(flags.Local.CFlags, library.StaticProperties.Static.Cflags...) } else if library.shared() { - flags.CFlags = append(flags.CFlags, library.SharedProperties.Shared.Cflags...) + flags.Local.CFlags = append(flags.Local.CFlags, library.SharedProperties.Shared.Cflags...) } if library.shared() { @@ -431,7 +431,7 @@ func (library *libraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Fla } } - flags.LdFlags = append(f, flags.LdFlags...) + flags.Global.LdFlags = append(flags.Global.LdFlags, f...) } return flags @@ -441,8 +441,8 @@ func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags, d exportIncludeDirs := library.flagExporter.exportedIncludes(ctx) if len(exportIncludeDirs) > 0 { f := includeDirsToFlags(exportIncludeDirs) - flags.GlobalFlags = append(flags.GlobalFlags, f) - flags.YasmFlags = append(flags.YasmFlags, f) + flags.Local.CommonFlags = append(flags.Local.CommonFlags, f) + flags.Local.YasmFlags = append(flags.Local.YasmFlags, f) } flags = library.baseCompiler.compilerFlags(ctx, flags, deps) @@ -462,8 +462,8 @@ func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags, d } return ret } - flags.GlobalFlags = removeInclude(flags.GlobalFlags) - flags.CFlags = removeInclude(flags.CFlags) + flags.Local.CommonFlags = removeInclude(flags.Local.CommonFlags) + flags.Local.CFlags = removeInclude(flags.Local.CFlags) flags = addStubLibraryCompilerFlags(flags) } @@ -776,21 +776,21 @@ func (library *libraryDecorator) linkShared(ctx ModuleContext, } } else { if unexportedSymbols.Valid() { - flags.LdFlags = append(flags.LdFlags, "-Wl,-unexported_symbols_list,"+unexportedSymbols.String()) + flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-unexported_symbols_list,"+unexportedSymbols.String()) linkerDeps = append(linkerDeps, unexportedSymbols.Path()) } if forceNotWeakSymbols.Valid() { - flags.LdFlags = append(flags.LdFlags, "-Wl,-force_symbols_not_weak_list,"+forceNotWeakSymbols.String()) + flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-force_symbols_not_weak_list,"+forceNotWeakSymbols.String()) linkerDeps = append(linkerDeps, forceNotWeakSymbols.Path()) } if forceWeakSymbols.Valid() { - flags.LdFlags = append(flags.LdFlags, "-Wl,-force_symbols_weak_list,"+forceWeakSymbols.String()) + flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-force_symbols_weak_list,"+forceWeakSymbols.String()) linkerDeps = append(linkerDeps, forceWeakSymbols.Path()) } } if library.buildStubs() { linkerScriptFlags := "-Wl,--version-script," + library.versionScriptPath.String() - flags.LdFlags = append(flags.LdFlags, linkerScriptFlags) + flags.Local.LdFlags = append(flags.Local.LdFlags, linkerScriptFlags) linkerDeps = append(linkerDeps, library.versionScriptPath) } @@ -802,7 +802,7 @@ func (library *libraryDecorator) linkShared(ctx ModuleContext, if ctx.Windows() { importLibraryPath := android.PathForModuleOut(ctx, pathtools.ReplaceExtension(fileName, "lib")) - flags.LdFlags = append(flags.LdFlags, "-Wl,--out-implib="+importLibraryPath.String()) + flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--out-implib="+importLibraryPath.String()) implicitOutputs = append(implicitOutputs, importLibraryPath) } @@ -862,7 +862,7 @@ func (library *libraryDecorator) linkShared(ctx ModuleContext, symbolOrderingFile := android.PathForModuleOut(ctx, "unsorted", fileName+".symbol_order") symbolOrderingFlag := library.baseLinker.sortBssSymbolsBySize(ctx, unsortedOutputFile, symbolOrderingFile, builderFlags) - builderFlags.ldFlags += " " + symbolOrderingFlag + builderFlags.localLdFlags += " " + symbolOrderingFlag linkerDeps = append(linkerDeps, symbolOrderingFile) } diff --git a/cc/library_test.go b/cc/library_test.go index 2acae35cf..f8d893465 100644 --- a/cc/library_test.go +++ b/cc/library_test.go @@ -181,7 +181,7 @@ func TestLibraryReuse(t *testing.T) { } libfoo := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_core_shared").Module().(*Module) - if !inList("-DGOOGLE_PROTOBUF_NO_RTTI", libfoo.flags.CFlags) { + if !inList("-DGOOGLE_PROTOBUF_NO_RTTI", libfoo.flags.Local.CFlags) { t.Errorf("missing protobuf cflags") } }) diff --git a/cc/linker.go b/cc/linker.go index e5e14861e..61ae7575a 100644 --- a/cc/linker.go +++ b/cc/linker.go @@ -331,65 +331,66 @@ func (linker *baseLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags { } if linker.useClangLld(ctx) { - flags.LdFlags = append(flags.LdFlags, fmt.Sprintf("${config.%sGlobalLldflags}", hod)) + flags.Global.LdFlags = append(flags.Global.LdFlags, fmt.Sprintf("${config.%sGlobalLldflags}", hod)) if !BoolDefault(linker.Properties.Pack_relocations, true) { - flags.LdFlags = append(flags.LdFlags, "-Wl,--pack-dyn-relocs=none") + flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--pack-dyn-relocs=none") } else if ctx.Device() { // The SHT_RELR relocations is only supported by API level >= 28. // Do not turn this on if older version NDK is used. if !ctx.useSdk() || CheckSdkVersionAtLeast(ctx, 28) { - flags.LdFlags = append(flags.LdFlags, "-Wl,--pack-dyn-relocs=android+relr") - flags.LdFlags = append(flags.LdFlags, "-Wl,--use-android-relr-tags") + flags.Global.LdFlags = append(flags.Global.LdFlags, + "-Wl,--pack-dyn-relocs=android+relr", + "-Wl,--use-android-relr-tags") } } } else { - flags.LdFlags = append(flags.LdFlags, fmt.Sprintf("${config.%sGlobalLdflags}", hod)) + flags.Global.LdFlags = append(flags.Global.LdFlags, fmt.Sprintf("${config.%sGlobalLdflags}", hod)) } if Bool(linker.Properties.Allow_undefined_symbols) { if ctx.Darwin() { // darwin defaults to treating undefined symbols as errors - flags.LdFlags = append(flags.LdFlags, "-Wl,-undefined,dynamic_lookup") + flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,-undefined,dynamic_lookup") } } else if !ctx.Darwin() && !ctx.Windows() { - flags.LdFlags = append(flags.LdFlags, "-Wl,--no-undefined") + flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--no-undefined") } if linker.useClangLld(ctx) { - flags.LdFlags = append(flags.LdFlags, toolchain.ClangLldflags()) + flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.ClangLldflags()) } else { - flags.LdFlags = append(flags.LdFlags, toolchain.ClangLdflags()) + flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.ClangLdflags()) } if !ctx.toolchain().Bionic() && !ctx.Fuchsia() { CheckBadHostLdlibs(ctx, "host_ldlibs", linker.Properties.Host_ldlibs) - flags.LdFlags = append(flags.LdFlags, linker.Properties.Host_ldlibs...) + flags.Local.LdFlags = append(flags.Local.LdFlags, linker.Properties.Host_ldlibs...) if !ctx.Windows() { // Add -ldl, -lpthread, -lm and -lrt to host builds to match the default behavior of device // builds - flags.LdFlags = append(flags.LdFlags, + flags.Global.LdFlags = append(flags.Global.LdFlags, "-ldl", "-lpthread", "-lm", ) if !ctx.Darwin() { - flags.LdFlags = append(flags.LdFlags, "-lrt") + flags.Global.LdFlags = append(flags.Global.LdFlags, "-lrt") } } } if ctx.Fuchsia() { - flags.LdFlags = append(flags.LdFlags, "-lfdio", "-lzircon") + flags.Global.LdFlags = append(flags.Global.LdFlags, "-lfdio", "-lzircon") } if ctx.toolchain().LibclangRuntimeLibraryArch() != "" { - flags.LdFlags = append(flags.LdFlags, "-Wl,--exclude-libs="+config.BuiltinsRuntimeLibrary(ctx.toolchain())+".a") + flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--exclude-libs="+config.BuiltinsRuntimeLibrary(ctx.toolchain())+".a") } CheckBadLinkerFlags(ctx, "ldflags", linker.Properties.Ldflags) - flags.LdFlags = append(flags.LdFlags, proptools.NinjaAndShellEscapeList(linker.Properties.Ldflags)...) + flags.Local.LdFlags = append(flags.Local.LdFlags, proptools.NinjaAndShellEscapeList(linker.Properties.Ldflags)...) if ctx.Host() && !ctx.Windows() { rpath_prefix := `\$$ORIGIN/` @@ -399,7 +400,7 @@ func (linker *baseLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags { if !ctx.static() { for _, rpath := range linker.dynamicProperties.RunPaths { - flags.LdFlags = append(flags.LdFlags, "-Wl,-rpath,"+rpath_prefix+rpath) + flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,-rpath,"+rpath_prefix+rpath) } } } @@ -409,10 +410,10 @@ func (linker *baseLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags { // to older devices requires the old style hash. Fortunately, we can build with both and // it'll work anywhere. // This is not currently supported on MIPS architectures. - flags.LdFlags = append(flags.LdFlags, "-Wl,--hash-style=both") + flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--hash-style=both") } - flags.LdFlags = append(flags.LdFlags, toolchain.ToolchainClangLdflags()) + flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.ToolchainClangLdflags()) if Bool(linker.Properties.Group_static_libs) { flags.GroupStaticLibs = true @@ -434,13 +435,13 @@ func (linker *baseLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags { if ctx.Darwin() { ctx.PropertyErrorf("version_script", "Not supported on Darwin") } else { - flags.LdFlags = append(flags.LdFlags, + flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--version-script,"+versionScript.String()) flags.LdFlagsDeps = append(flags.LdFlagsDeps, versionScript.Path()) if linker.sanitize.isSanitizerEnabled(cfi) { cfiExportsMap := android.PathForSource(ctx, cfiExportsMapPath) - flags.LdFlags = append(flags.LdFlags, + flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--version-script,"+cfiExportsMap.String()) flags.LdFlagsDeps = append(flags.LdFlagsDeps, cfiExportsMap) } diff --git a/cc/llndk_library.go b/cc/llndk_library.go index 16e089e61..3a5b3a6da 100644 --- a/cc/llndk_library.go +++ b/cc/llndk_library.go @@ -133,7 +133,7 @@ func (stub *llndkStubDecorator) link(ctx ModuleContext, flags Flags, deps PathDe if !Bool(stub.Properties.Unversioned) { linkerScriptFlag := "-Wl,--version-script," + stub.versionScriptPath.String() - flags.LdFlags = append(flags.LdFlags, linkerScriptFlag) + flags.Local.LdFlags = append(flags.Local.LdFlags, linkerScriptFlag) flags.LdFlagsDeps = append(flags.LdFlagsDeps, stub.versionScriptPath) } @@ -82,7 +82,7 @@ func (lto *lto) useClangLld(ctx BaseModuleContext) bool { func (lto *lto) flags(ctx BaseModuleContext, flags Flags) Flags { // TODO(b/131771163): Disable LTO when using explicit fuzzing configurations. // LTO breaks fuzzer builds. - if inList("-fsanitize=fuzzer-no-link", flags.CFlags) { + if inList("-fsanitize=fuzzer-no-link", flags.Local.CFlags) { return flags } @@ -94,27 +94,28 @@ func (lto *lto) flags(ctx BaseModuleContext, flags Flags) Flags { ltoFlag = "-flto" } - flags.CFlags = append(flags.CFlags, ltoFlag) - flags.LdFlags = append(flags.LdFlags, ltoFlag) + flags.Local.CFlags = append(flags.Local.CFlags, ltoFlag) + flags.Local.LdFlags = append(flags.Local.LdFlags, ltoFlag) if ctx.Config().IsEnvTrue("USE_THINLTO_CACHE") && Bool(lto.Properties.Lto.Thin) && lto.useClangLld(ctx) { // Set appropriate ThinLTO cache policy cacheDirFormat := "-Wl,--thinlto-cache-dir=" cacheDir := android.PathForOutput(ctx, "thinlto-cache").String() - flags.LdFlags = append(flags.LdFlags, cacheDirFormat+cacheDir) + flags.Local.LdFlags = append(flags.Local.LdFlags, cacheDirFormat+cacheDir) // Limit the size of the ThinLTO cache to the lesser of 10% of available // disk space and 10GB. cachePolicyFormat := "-Wl,--thinlto-cache-policy=" policy := "cache_size=10%:cache_size_bytes=10g" - flags.LdFlags = append(flags.LdFlags, cachePolicyFormat+policy) + flags.Local.LdFlags = append(flags.Local.LdFlags, cachePolicyFormat+policy) } // If the module does not have a profile, be conservative and do not inline // or unroll loops during LTO, in order to prevent significant size bloat. if !ctx.isPgoCompile() { - flags.LdFlags = append(flags.LdFlags, "-Wl,-plugin-opt,-inline-threshold=0") - flags.LdFlags = append(flags.LdFlags, "-Wl,-plugin-opt,-unroll-threshold=0") + flags.Local.LdFlags = append(flags.Local.LdFlags, + "-Wl,-plugin-opt,-inline-threshold=0", + "-Wl,-plugin-opt,-unroll-threshold=0") } } return flags diff --git a/cc/ndk_library.go b/cc/ndk_library.go index 3747b41cb..b75c4c898 100644 --- a/cc/ndk_library.go +++ b/cc/ndk_library.go @@ -257,7 +257,7 @@ func (c *stubDecorator) compilerInit(ctx BaseModuleContext) { } func addStubLibraryCompilerFlags(flags Flags) Flags { - flags.CFlags = append(flags.CFlags, + flags.Global.CFlags = append(flags.Global.CFlags, // We're knowingly doing some otherwise unsightly things with builtin // functions here. We're just generating stub libraries, so ignore it. "-Wno-incompatible-library-redeclaration", @@ -337,7 +337,7 @@ func (stub *stubDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps, if useVersionScript { linkerScriptFlag := "-Wl,--version-script," + stub.versionScriptPath.String() - flags.LdFlags = append(flags.LdFlags, linkerScriptFlag) + flags.Local.LdFlags = append(flags.Local.LdFlags, linkerScriptFlag) flags.LdFlagsDeps = append(flags.LdFlagsDeps, stub.versionScriptPath) } diff --git a/cc/object.go b/cc/object.go index 31729a5f8..ad31d09fc 100644 --- a/cc/object.go +++ b/cc/object.go @@ -87,10 +87,10 @@ func (object *objectLinker) linkerDeps(ctx DepsContext, deps Deps) Deps { } func (object *objectLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags { - flags.LdFlags = append(flags.LdFlags, ctx.toolchain().ToolchainClangLdflags()) + flags.Global.LdFlags = append(flags.Global.LdFlags, ctx.toolchain().ToolchainClangLdflags()) if lds := android.OptionalPathForModuleSrc(ctx, object.Properties.Linker_script); lds.Valid() { - flags.LdFlags = append(flags.LdFlags, "-Wl,-T,"+lds.String()) + flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-T,"+lds.String()) flags.LdFlagsDeps = append(flags.LdFlagsDeps, lds.Path()) } return flags @@ -89,18 +89,18 @@ func (pgo *pgo) props() []interface{} { } func (props *PgoProperties) addProfileGatherFlags(ctx ModuleContext, flags Flags) Flags { - flags.CFlags = append(flags.CFlags, props.Pgo.Cflags...) + flags.Local.CFlags = append(flags.Local.CFlags, props.Pgo.Cflags...) if props.isInstrumentation() { - flags.CFlags = append(flags.CFlags, profileInstrumentFlag) + flags.Local.CFlags = append(flags.Local.CFlags, profileInstrumentFlag) // The profile runtime is added below in deps(). Add the below // flag, which is the only other link-time action performed by // the Clang driver during link. - flags.LdFlags = append(flags.LdFlags, "-u__llvm_profile_runtime") + flags.Local.LdFlags = append(flags.Local.LdFlags, "-u__llvm_profile_runtime") } if props.isSampling() { - flags.CFlags = append(flags.CFlags, profileSamplingFlag) - flags.LdFlags = append(flags.LdFlags, profileSamplingFlag) + flags.Local.CFlags = append(flags.Local.CFlags, profileSamplingFlag) + flags.Local.LdFlags = append(flags.Local.LdFlags, profileSamplingFlag) } return flags } @@ -170,8 +170,8 @@ func (props *PgoProperties) addProfileUseFlags(ctx ModuleContext, flags Flags) F profileFilePath := profileFile.Path() profileUseFlags := props.profileUseFlags(ctx, profileFilePath.String()) - flags.CFlags = append(flags.CFlags, profileUseFlags...) - flags.LdFlags = append(flags.LdFlags, profileUseFlags...) + flags.Local.CFlags = append(flags.Local.CFlags, profileUseFlags...) + flags.Local.LdFlags = append(flags.Local.LdFlags, profileUseFlags...) // Update CFlagsDeps and LdFlagsDeps so the module is rebuilt // if profileFile gets updated diff --git a/cc/proto.go b/cc/proto.go index f818edc95..ae988ec4d 100644 --- a/cc/proto.go +++ b/cc/proto.go @@ -114,13 +114,13 @@ func protoDeps(ctx DepsContext, deps Deps, p *android.ProtoProperties, static bo } func protoFlags(ctx ModuleContext, flags Flags, p *android.ProtoProperties) Flags { - flags.CFlags = append(flags.CFlags, "-DGOOGLE_PROTOBUF_NO_RTTI") + flags.Local.CFlags = append(flags.Local.CFlags, "-DGOOGLE_PROTOBUF_NO_RTTI") flags.proto = android.GetProtoFlags(ctx, p) if flags.proto.CanonicalPathFromRoot { - flags.GlobalFlags = append(flags.GlobalFlags, "-I"+flags.proto.SubDir.String()) + flags.Local.CommonFlags = append(flags.Local.CommonFlags, "-I"+flags.proto.SubDir.String()) } - flags.GlobalFlags = append(flags.GlobalFlags, "-I"+flags.proto.Dir.String()) + flags.Local.CommonFlags = append(flags.Local.CommonFlags, "-I"+flags.proto.Dir.String()) if String(p.Proto.Plugin) == "" { var plugin string @@ -123,7 +123,7 @@ func rsFlags(ctx ModuleContext, flags Flags, properties *BaseCompilerProperties) rootRsIncludeDirs := android.PathsForSource(ctx, properties.Renderscript.Include_dirs) flags.rsFlags = append(flags.rsFlags, includeDirsToFlags(rootRsIncludeDirs)) - flags.GlobalFlags = append(flags.GlobalFlags, + flags.Local.CommonFlags = append(flags.Local.CommonFlags, "-I"+android.PathForModuleGen(ctx, "rs").String(), "-Iframeworks/rs", "-Iframeworks/rs/cpp", diff --git a/cc/sabi.go b/cc/sabi.go index 4760313e6..8cef1700c 100644 --- a/cc/sabi.go +++ b/cc/sabi.go @@ -70,8 +70,10 @@ func filterOutWithPrefix(list []string, filter []string) (remainder []string) { func (sabimod *sabi) flags(ctx ModuleContext, flags Flags) Flags { // Assuming that the cflags which clang LibTooling tools cannot // understand have not been converted to ninja variables yet. - flags.ToolingCFlags = filterOutWithPrefix(flags.CFlags, config.ClangLibToolingUnknownCflags) - flags.ToolingCppFlags = filterOutWithPrefix(flags.CppFlags, config.ClangLibToolingUnknownCflags) + flags.Local.ToolingCFlags = filterOutWithPrefix(flags.Local.CFlags, config.ClangLibToolingUnknownCflags) + flags.Global.ToolingCFlags = filterOutWithPrefix(flags.Global.CFlags, config.ClangLibToolingUnknownCflags) + flags.Local.ToolingCppFlags = filterOutWithPrefix(flags.Local.CppFlags, config.ClangLibToolingUnknownCflags) + flags.Global.ToolingCppFlags = filterOutWithPrefix(flags.Global.CppFlags, config.ClangLibToolingUnknownCflags) return flags } diff --git a/cc/sanitize.go b/cc/sanitize.go index a3b4e8ebd..2bf051e5a 100644 --- a/cc/sanitize.go +++ b/cc/sanitize.go @@ -426,8 +426,9 @@ func (sanitize *sanitize) flags(ctx ModuleContext, flags Flags) Flags { minimalRuntimePath := "${config.ClangAsanLibDir}/" + minimalRuntimeLib if ctx.Device() && sanitize.Properties.MinimalRuntimeDep { - flags.LdFlags = append(flags.LdFlags, minimalRuntimePath) - flags.LdFlags = append(flags.LdFlags, "-Wl,--exclude-libs,"+minimalRuntimeLib) + flags.Local.LdFlags = append(flags.Local.LdFlags, + minimalRuntimePath, + "-Wl,--exclude-libs,"+minimalRuntimeLib) } if !sanitize.Properties.SanitizerEnabled && !sanitize.Properties.UbsanRuntimeDep { return flags @@ -439,15 +440,15 @@ func (sanitize *sanitize) flags(ctx ModuleContext, flags Flags) Flags { // TODO: put in flags? flags.RequiredInstructionSet = "arm" } - flags.CFlags = append(flags.CFlags, asanCflags...) - flags.LdFlags = append(flags.LdFlags, asanLdflags...) + flags.Local.CFlags = append(flags.Local.CFlags, asanCflags...) + flags.Local.LdFlags = append(flags.Local.LdFlags, asanLdflags...) if ctx.Host() { // -nodefaultlibs (provided with libc++) prevents the driver from linking // libraries needed with -fsanitize=address. http://b/18650275 (WAI) - flags.LdFlags = append(flags.LdFlags, "-Wl,--no-as-needed") + flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--no-as-needed") } else { - flags.CFlags = append(flags.CFlags, "-mllvm", "-asan-globals=0") + flags.Local.CFlags = append(flags.Local.CFlags, "-mllvm", "-asan-globals=0") if ctx.bootstrap() { flags.DynamicLinker = "/system/bin/bootstrap/linker_asan" } else { @@ -460,33 +461,30 @@ func (sanitize *sanitize) flags(ctx ModuleContext, flags Flags) Flags { } if Bool(sanitize.Properties.Sanitize.Hwaddress) { - flags.CFlags = append(flags.CFlags, hwasanCflags...) + flags.Local.CFlags = append(flags.Local.CFlags, hwasanCflags...) } if Bool(sanitize.Properties.Sanitize.Fuzzer) { - flags.CFlags = append(flags.CFlags, "-fsanitize=fuzzer-no-link") + flags.Local.CFlags = append(flags.Local.CFlags, "-fsanitize=fuzzer-no-link") // TODO(b/131771163): LTO and Fuzzer support is mutually incompatible. - _, flags.LdFlags = removeFromList("-flto", flags.LdFlags) - _, flags.CFlags = removeFromList("-flto", flags.CFlags) - flags.LdFlags = append(flags.LdFlags, "-fno-lto") - flags.CFlags = append(flags.CFlags, "-fno-lto") + _, flags.Local.LdFlags = removeFromList("-flto", flags.Local.LdFlags) + _, flags.Local.CFlags = removeFromList("-flto", flags.Local.CFlags) + flags.Local.LdFlags = append(flags.Local.LdFlags, "-fno-lto") + flags.Local.CFlags = append(flags.Local.CFlags, "-fno-lto") // TODO(b/142430592): Upstream linker scripts for sanitizer runtime libraries // discard the sancov_lowest_stack symbol, because it's emulated TLS (and thus // doesn't match the linker script due to the "__emutls_v." prefix). - flags.LdFlags = append(flags.LdFlags, "-fno-sanitize-coverage=stack-depth") - flags.CFlags = append(flags.CFlags, "-fno-sanitize-coverage=stack-depth") + flags.Local.LdFlags = append(flags.Local.LdFlags, "-fno-sanitize-coverage=stack-depth") + flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize-coverage=stack-depth") // TODO(b/133876586): Experimental PM breaks sanitizer coverage. - _, flags.CFlags = removeFromList("-fexperimental-new-pass-manager", flags.CFlags) - flags.CFlags = append(flags.CFlags, "-fno-experimental-new-pass-manager") + flags.Local.CFlags = append(flags.Local.CFlags, "-fno-experimental-new-pass-manager") // Disable fortify for fuzzing builds. Generally, we'll be building with // UBSan or ASan here and the fortify checks pollute the stack traces. - _, flags.CFlags = removeFromList("-D_FORTIFY_SOURCE=1", flags.CFlags) - _, flags.CFlags = removeFromList("-D_FORTIFY_SOURCE=2", flags.CFlags) - flags.CFlags = append(flags.CFlags, "-U_FORTIFY_SOURCE") + flags.Local.CFlags = append(flags.Local.CFlags, "-U_FORTIFY_SOURCE") } if Bool(sanitize.Properties.Sanitize.Cfi) { @@ -496,75 +494,75 @@ func (sanitize *sanitize) flags(ctx ModuleContext, flags Flags) Flags { flags.RequiredInstructionSet = "thumb" } - flags.CFlags = append(flags.CFlags, cfiCflags...) - flags.AsFlags = append(flags.AsFlags, cfiAsflags...) + flags.Local.CFlags = append(flags.Local.CFlags, cfiCflags...) + flags.Local.AsFlags = append(flags.Local.AsFlags, cfiAsflags...) // Only append the default visibility flag if -fvisibility has not already been set // to hidden. - if !inList("-fvisibility=hidden", flags.CFlags) { - flags.CFlags = append(flags.CFlags, "-fvisibility=default") + if !inList("-fvisibility=hidden", flags.Local.CFlags) { + flags.Local.CFlags = append(flags.Local.CFlags, "-fvisibility=default") } - flags.LdFlags = append(flags.LdFlags, cfiLdflags...) + flags.Local.LdFlags = append(flags.Local.LdFlags, cfiLdflags...) if ctx.staticBinary() { - _, flags.CFlags = removeFromList("-fsanitize-cfi-cross-dso", flags.CFlags) - _, flags.LdFlags = removeFromList("-fsanitize-cfi-cross-dso", flags.LdFlags) + _, flags.Local.CFlags = removeFromList("-fsanitize-cfi-cross-dso", flags.Local.CFlags) + _, flags.Local.LdFlags = removeFromList("-fsanitize-cfi-cross-dso", flags.Local.LdFlags) } } if Bool(sanitize.Properties.Sanitize.Integer_overflow) { - flags.CFlags = append(flags.CFlags, intOverflowCflags...) + flags.Local.CFlags = append(flags.Local.CFlags, intOverflowCflags...) } if len(sanitize.Properties.Sanitizers) > 0 { sanitizeArg := "-fsanitize=" + strings.Join(sanitize.Properties.Sanitizers, ",") - flags.CFlags = append(flags.CFlags, sanitizeArg) - flags.AsFlags = append(flags.AsFlags, sanitizeArg) + flags.Local.CFlags = append(flags.Local.CFlags, sanitizeArg) + flags.Local.AsFlags = append(flags.Local.AsFlags, sanitizeArg) if ctx.Host() { // Host sanitizers only link symbols in the final executable, so // there will always be undefined symbols in intermediate libraries. - _, flags.LdFlags = removeFromList("-Wl,--no-undefined", flags.LdFlags) - flags.LdFlags = append(flags.LdFlags, sanitizeArg) + _, flags.Global.LdFlags = removeFromList("-Wl,--no-undefined", flags.Global.LdFlags) + flags.Local.LdFlags = append(flags.Local.LdFlags, sanitizeArg) } else { if enableMinimalRuntime(sanitize) { - flags.CFlags = append(flags.CFlags, strings.Join(minimalRuntimeFlags, " ")) + flags.Local.CFlags = append(flags.Local.CFlags, strings.Join(minimalRuntimeFlags, " ")) flags.libFlags = append([]string{minimalRuntimePath}, flags.libFlags...) - flags.LdFlags = append(flags.LdFlags, "-Wl,--exclude-libs,"+minimalRuntimeLib) + flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--exclude-libs,"+minimalRuntimeLib) } } if Bool(sanitize.Properties.Sanitize.Fuzzer) { // When fuzzing, we wish to crash with diagnostics on any bug. - flags.CFlags = append(flags.CFlags, "-fno-sanitize-trap=all", "-fno-sanitize-recover=all") + flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize-trap=all", "-fno-sanitize-recover=all") } else if ctx.Host() { - flags.CFlags = append(flags.CFlags, "-fno-sanitize-recover=all") + flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize-recover=all") } else { - flags.CFlags = append(flags.CFlags, "-fsanitize-trap=all", "-ftrap-function=abort") + flags.Local.CFlags = append(flags.Local.CFlags, "-fsanitize-trap=all", "-ftrap-function=abort") } // http://b/119329758, Android core does not boot up with this sanitizer yet. - if toDisableImplicitIntegerChange(flags.CFlags) { - flags.CFlags = append(flags.CFlags, "-fno-sanitize=implicit-integer-sign-change") + if toDisableImplicitIntegerChange(flags.Local.CFlags) { + flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize=implicit-integer-sign-change") } } if len(sanitize.Properties.DiagSanitizers) > 0 { - flags.CFlags = append(flags.CFlags, "-fno-sanitize-trap="+strings.Join(sanitize.Properties.DiagSanitizers, ",")) + flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize-trap="+strings.Join(sanitize.Properties.DiagSanitizers, ",")) } // FIXME: enable RTTI if diag + (cfi or vptr) if sanitize.Properties.Sanitize.Recover != nil { - flags.CFlags = append(flags.CFlags, "-fsanitize-recover="+ + flags.Local.CFlags = append(flags.Local.CFlags, "-fsanitize-recover="+ strings.Join(sanitize.Properties.Sanitize.Recover, ",")) } if sanitize.Properties.Sanitize.Diag.No_recover != nil { - flags.CFlags = append(flags.CFlags, "-fno-sanitize-recover="+ + flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize-recover="+ strings.Join(sanitize.Properties.Sanitize.Diag.No_recover, ",")) } blacklist := android.OptionalPathForModuleSrc(ctx, sanitize.Properties.Sanitize.Blacklist) if blacklist.Valid() { - flags.CFlags = append(flags.CFlags, "-fsanitize-blacklist="+blacklist.String()) + flags.Local.CFlags = append(flags.Local.CFlags, "-fsanitize-blacklist="+blacklist.String()) flags.CFlagsDeps = append(flags.CFlagsDeps, blacklist.Path()) } @@ -215,12 +215,12 @@ func (stl *stl) flags(ctx ModuleContext, flags Flags) Flags { // these availability attributes are meaningless for us but cause // build breaks when we try to use code that would not be available // in the system's dylib. - flags.CppFlags = append(flags.CppFlags, + flags.Local.CppFlags = append(flags.Local.CppFlags, "-D_LIBCPP_DISABLE_AVAILABILITY") } if !ctx.toolchain().Bionic() { - flags.CppFlags = append(flags.CppFlags, "-nostdinc++") + flags.Local.CppFlags = append(flags.Local.CppFlags, "-nostdinc++") flags.extraLibFlags = append(flags.extraLibFlags, "-nostdlib++") if ctx.Windows() { if stl.Properties.SelectedStl == "libc++_static" { @@ -231,9 +231,9 @@ func (stl *stl) flags(ctx ModuleContext, flags Flags) Flags { // Use SjLj exceptions for 32-bit. libgcc_eh implements SjLj // exception model for 32-bit. if ctx.Arch().ArchType == android.X86 { - flags.CppFlags = append(flags.CppFlags, "-fsjlj-exceptions") + flags.Local.CppFlags = append(flags.Local.CppFlags, "-fsjlj-exceptions") } - flags.CppFlags = append(flags.CppFlags, + flags.Local.CppFlags = append(flags.Local.CppFlags, // Disable visiblity annotations since we're using static // libc++. "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS", @@ -243,23 +243,23 @@ func (stl *stl) flags(ctx ModuleContext, flags Flags) Flags { } } else { if ctx.Arch().ArchType == android.Arm { - flags.LdFlags = append(flags.LdFlags, "-Wl,--exclude-libs,libunwind_llvm.a") + flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--exclude-libs,libunwind_llvm.a") } } case "libstdc++": // Nothing case "ndk_system": ndkSrcRoot := android.PathForSource(ctx, "prebuilts/ndk/current/sources/cxx-stl/system/include") - flags.CFlags = append(flags.CFlags, "-isystem "+ndkSrcRoot.String()) + flags.Local.CFlags = append(flags.Local.CFlags, "-isystem "+ndkSrcRoot.String()) case "ndk_libc++_shared", "ndk_libc++_static": if ctx.Arch().ArchType == android.Arm { // Make sure the _Unwind_XXX symbols are not re-exported. - flags.LdFlags = append(flags.LdFlags, "-Wl,--exclude-libs,libunwind.a") + flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--exclude-libs,libunwind.a") } case "": // None or error. if !ctx.toolchain().Bionic() { - flags.CppFlags = append(flags.CppFlags, "-nostdinc++") + flags.Local.CppFlags = append(flags.Local.CppFlags, "-nostdinc++") flags.extraLibFlags = append(flags.extraLibFlags, "-nostdlib++") } default: diff --git a/cc/test.go b/cc/test.go index 5c49d6e2b..05e6fe5e5 100644 --- a/cc/test.go +++ b/cc/test.go @@ -220,20 +220,20 @@ func (test *testDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags { return flags } - flags.CFlags = append(flags.CFlags, "-DGTEST_HAS_STD_STRING") + flags.Local.CFlags = append(flags.Local.CFlags, "-DGTEST_HAS_STD_STRING") if ctx.Host() { - flags.CFlags = append(flags.CFlags, "-O0", "-g") + flags.Local.CFlags = append(flags.Local.CFlags, "-O0", "-g") switch ctx.Os() { case android.Windows: - flags.CFlags = append(flags.CFlags, "-DGTEST_OS_WINDOWS") + flags.Local.CFlags = append(flags.Local.CFlags, "-DGTEST_OS_WINDOWS") case android.Linux: - flags.CFlags = append(flags.CFlags, "-DGTEST_OS_LINUX") + flags.Local.CFlags = append(flags.Local.CFlags, "-DGTEST_OS_LINUX") case android.Darwin: - flags.CFlags = append(flags.CFlags, "-DGTEST_OS_MAC") + flags.Local.CFlags = append(flags.Local.CFlags, "-DGTEST_OS_MAC") } } else { - flags.CFlags = append(flags.CFlags, "-DGTEST_OS_LINUX_ANDROID") + flags.Local.CFlags = append(flags.Local.CFlags, "-DGTEST_OS_LINUX_ANDROID") } return flags diff --git a/cc/testing.go b/cc/testing.go index fafaeb0c9..9ad72d9f5 100644 --- a/cc/testing.go +++ b/cc/testing.go @@ -269,6 +269,7 @@ func CreateTestContext(bp string, fs map[string][]byte, ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(ObjectFactory)) ctx.RegisterModuleType("filegroup", android.ModuleFactoryAdaptor(android.FileGroupFactory)) ctx.RegisterModuleType("vndk_prebuilt_shared", android.ModuleFactoryAdaptor(VndkPrebuiltSharedFactory)) + ctx.RegisterModuleType("vndk_libraries_txt", android.ModuleFactoryAdaptor(VndkLibrariesTxtFactory)) ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) { ctx.BottomUp("image", ImageMutator).Parallel() ctx.BottomUp("link", LinkageMutator).Parallel() diff --git a/cc/util.go b/cc/util.go index 2f7bec2bb..60070bbc4 100644 --- a/cc/util.go +++ b/cc/util.go @@ -55,27 +55,37 @@ func moduleToLibName(module string) (string, error) { func flagsToBuilderFlags(in Flags) builderFlags { return builderFlags{ - globalFlags: strings.Join(in.GlobalFlags, " "), - arFlags: strings.Join(in.ArFlags, " "), - asFlags: strings.Join(in.AsFlags, " "), - cFlags: strings.Join(in.CFlags, " "), - toolingCFlags: strings.Join(in.ToolingCFlags, " "), - toolingCppFlags: strings.Join(in.ToolingCppFlags, " "), - conlyFlags: strings.Join(in.ConlyFlags, " "), - cppFlags: strings.Join(in.CppFlags, " "), - aidlFlags: strings.Join(in.aidlFlags, " "), - rsFlags: strings.Join(in.rsFlags, " "), - ldFlags: strings.Join(in.LdFlags, " "), - libFlags: strings.Join(in.libFlags, " "), - extraLibFlags: strings.Join(in.extraLibFlags, " "), - tidyFlags: strings.Join(in.TidyFlags, " "), - sAbiFlags: strings.Join(in.SAbiFlags, " "), - yasmFlags: strings.Join(in.YasmFlags, " "), - toolchain: in.Toolchain, - coverage: in.Coverage, - tidy: in.Tidy, - sAbiDump: in.SAbiDump, - emitXrefs: in.EmitXrefs, + globalCommonFlags: strings.Join(in.Global.CommonFlags, " "), + globalAsFlags: strings.Join(in.Global.AsFlags, " "), + globalYasmFlags: strings.Join(in.Global.YasmFlags, " "), + globalCFlags: strings.Join(in.Global.CFlags, " "), + globalToolingCFlags: strings.Join(in.Global.ToolingCFlags, " "), + globalToolingCppFlags: strings.Join(in.Global.ToolingCppFlags, " "), + globalConlyFlags: strings.Join(in.Global.ConlyFlags, " "), + globalCppFlags: strings.Join(in.Global.CppFlags, " "), + globalLdFlags: strings.Join(in.Global.LdFlags, " "), + + localCommonFlags: strings.Join(in.Local.CommonFlags, " "), + localAsFlags: strings.Join(in.Local.AsFlags, " "), + localYasmFlags: strings.Join(in.Local.YasmFlags, " "), + localCFlags: strings.Join(in.Local.CFlags, " "), + localToolingCFlags: strings.Join(in.Local.ToolingCFlags, " "), + localToolingCppFlags: strings.Join(in.Local.ToolingCppFlags, " "), + localConlyFlags: strings.Join(in.Local.ConlyFlags, " "), + localCppFlags: strings.Join(in.Local.CppFlags, " "), + localLdFlags: strings.Join(in.Local.LdFlags, " "), + + aidlFlags: strings.Join(in.aidlFlags, " "), + rsFlags: strings.Join(in.rsFlags, " "), + libFlags: strings.Join(in.libFlags, " "), + extraLibFlags: strings.Join(in.extraLibFlags, " "), + tidyFlags: strings.Join(in.TidyFlags, " "), + sAbiFlags: strings.Join(in.SAbiFlags, " "), + toolchain: in.Toolchain, + coverage: in.Coverage, + tidy: in.Tidy, + sAbiDump: in.SAbiDump, + emitXrefs: in.EmitXrefs, systemIncludeFlags: strings.Join(in.SystemIncludeFlags, " "), diff --git a/cc/vendor_public_library.go b/cc/vendor_public_library.go index f0de267c1..e9d1c7378 100644 --- a/cc/vendor_public_library.go +++ b/cc/vendor_public_library.go @@ -124,7 +124,7 @@ func (stub *vendorPublicLibraryStubDecorator) link(ctx ModuleContext, flags Flag objs Objects) android.Path { if !Bool(stub.Properties.Unversioned) { linkerScriptFlag := "-Wl,--version-script," + stub.versionScriptPath.String() - flags.LdFlags = append(flags.LdFlags, linkerScriptFlag) + flags.Local.LdFlags = append(flags.Local.LdFlags, linkerScriptFlag) flags.LdFlagsDeps = append(flags.LdFlagsDeps, stub.versionScriptPath) } return stub.libraryDecorator.link(ctx, flags, deps, objs) diff --git a/cc/vndk.go b/cc/vndk.go index bb4aafce3..f25861af9 100644 --- a/cc/vndk.go +++ b/cc/vndk.go @@ -27,6 +27,34 @@ import ( "android/soong/cc/config" ) +const ( + llndkLibrariesTxt = "llndk.libraries.txt" + vndkCoreLibrariesTxt = "vndkcore.libraries.txt" + vndkSpLibrariesTxt = "vndksp.libraries.txt" + vndkPrivateLibrariesTxt = "vndkprivate.libraries.txt" + vndkUsingCoreVariantLibrariesTxt = "vndkcorevariant.libraries.txt" +) + +func VndkLibrariesTxtModules(vndkVersion string) []string { + if vndkVersion == "current" { + return []string{ + llndkLibrariesTxt, + vndkCoreLibrariesTxt, + vndkSpLibrariesTxt, + vndkPrivateLibrariesTxt, + vndkUsingCoreVariantLibrariesTxt, + } + } + // Snapshot vndks have their own *.libraries.VER.txt files. + // Note that snapshots don't have "vndkcorevariant.libraries.VER.txt" + return []string{ + insertVndkVersion(llndkLibrariesTxt, vndkVersion), + insertVndkVersion(vndkCoreLibrariesTxt, vndkVersion), + insertVndkVersion(vndkSpLibrariesTxt, vndkVersion), + insertVndkVersion(vndkPrivateLibrariesTxt, vndkVersion), + } +} + type VndkProperties struct { Vndk struct { // declared as a VNDK or VNDK-SP module. The vendor variant @@ -360,22 +388,109 @@ func VndkMutator(mctx android.BottomUpMutatorContext) { } func init() { + android.RegisterModuleType("vndk_libraries_txt", VndkLibrariesTxtFactory) android.RegisterSingletonType("vndk-snapshot", VndkSnapshotSingleton) } +type vndkLibrariesTxt struct { + android.ModuleBase + outputFile android.OutputPath +} + +var _ android.PrebuiltEtcModule = &vndkLibrariesTxt{} +var _ android.OutputFileProducer = &vndkLibrariesTxt{} + +// vndk_libraries_txt is a special kind of module type in that it name is one of +// - llndk.libraries.txt +// - vndkcore.libraries.txt +// - vndksp.libraries.txt +// - vndkprivate.libraries.txt +// - vndkcorevariant.libraries.txt +// A module behaves like a prebuilt_etc but its content is generated by soong. +// By being a soong module, these files can be referenced by other soong modules. +// For example, apex_vndk can depend on these files as prebuilt. +func VndkLibrariesTxtFactory() android.Module { + m := &vndkLibrariesTxt{} + android.InitAndroidModule(m) + return m +} + +func insertVndkVersion(filename string, vndkVersion string) string { + if index := strings.LastIndex(filename, "."); index != -1 { + return filename[:index] + "." + vndkVersion + filename[index:] + } + return filename +} + +func (txt *vndkLibrariesTxt) GenerateAndroidBuildActions(ctx android.ModuleContext) { + var list []string + switch txt.Name() { + case llndkLibrariesTxt: + for _, filename := range android.SortedStringMapValues(llndkLibraries(ctx.Config())) { + if strings.HasPrefix(filename, "libclang_rt.hwasan-") { + continue + } + list = append(list, filename) + } + case vndkCoreLibrariesTxt: + list = android.SortedStringMapValues(vndkCoreLibraries(ctx.Config())) + case vndkSpLibrariesTxt: + list = android.SortedStringMapValues(vndkSpLibraries(ctx.Config())) + case vndkPrivateLibrariesTxt: + list = android.SortedStringMapValues(vndkPrivateLibraries(ctx.Config())) + case vndkUsingCoreVariantLibrariesTxt: + list = android.SortedStringMapValues(vndkUsingCoreVariantLibraries(ctx.Config())) + default: + ctx.ModuleErrorf("name(%s) is unknown.", txt.Name()) + return + } + + filename := insertVndkVersion(txt.Name(), ctx.DeviceConfig().PlatformVndkVersion()) + txt.outputFile = android.PathForModuleOut(ctx, filename).OutputPath + ctx.Build(pctx, android.BuildParams{ + Rule: android.WriteFile, + Output: txt.outputFile, + Description: "Writing " + txt.outputFile.String(), + Args: map[string]string{ + "content": strings.Join(list, "\\n"), + }, + }) + + installPath := android.PathForModuleInstall(ctx, "etc") + ctx.InstallFile(installPath, filename, txt.outputFile) +} + +func (txt *vndkLibrariesTxt) AndroidMkEntries() android.AndroidMkEntries { + return android.AndroidMkEntries{ + Class: "ETC", + OutputFile: android.OptionalPathForPath(txt.outputFile), + ExtraEntries: []android.AndroidMkExtraEntriesFunc{ + func(entries *android.AndroidMkEntries) { + entries.SetString("LOCAL_MODULE_STEM", txt.outputFile.Base()) + }, + }, + } +} + +func (txt *vndkLibrariesTxt) OutputFile() android.OutputPath { + return txt.outputFile +} + +func (txt *vndkLibrariesTxt) OutputFiles(tag string) (android.Paths, error) { + return android.Paths{txt.outputFile}, nil +} + +func (txt *vndkLibrariesTxt) SubDir() string { + return "" +} + func VndkSnapshotSingleton() android.Singleton { return &vndkSnapshotSingleton{} } type vndkSnapshotSingleton struct { - installedLlndkLibraries []string - llndkLibrariesFile android.Path - vndkSpLibrariesFile android.Path - vndkCoreLibrariesFile android.Path - vndkPrivateLibrariesFile android.Path - vndkCoreVariantLibrariesFile android.Path - vndkLibrariesFile android.Path - vndkSnapshotZipFile android.OptionalPath + vndkLibrariesFile android.OutputPath + vndkSnapshotZipFile android.OptionalPath } func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) { @@ -650,12 +765,14 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex } } - snapshotOutputs = append(snapshotOutputs, - installSnapshotFileFromPath(c.vndkCoreLibrariesFile, filepath.Join(configsDir, "vndkcore.libraries.txt")), - installSnapshotFileFromPath(c.vndkPrivateLibrariesFile, filepath.Join(configsDir, "vndkprivate.libraries.txt")), - installSnapshotFileFromPath(c.vndkSpLibrariesFile, filepath.Join(configsDir, "vndksp.libraries.txt")), - installSnapshotFileFromPath(c.llndkLibrariesFile, filepath.Join(configsDir, "llndk.libraries.txt")), - ) + // install *.libraries.txt except vndkcorevariant.libraries.txt + ctx.VisitAllModules(func(module android.Module) { + m, ok := module.(*vndkLibrariesTxt) + if !ok || !m.Enabled() || m.Name() == vndkUsingCoreVariantLibrariesTxt { + return + } + snapshotOutputs = append(snapshotOutputs, installSnapshotFileFromPath(m.OutputFile(), filepath.Join(configsDir, m.Name()))) + }) /* Dump a map to a list file as: @@ -737,46 +854,12 @@ func getVndkFileName(m *Module) (string, error) { } func (c *vndkSnapshotSingleton) buildVndkLibrariesTxtFiles(ctx android.SingletonContext) { - // Make uses LLNDK_LIBRARIES to determine which libraries to install. - // HWASAN is only part of the LL-NDK in builds in which libc depends on HWASAN. - // Therefore, by removing the library here, we cause it to only be installed if libc - // depends on it. - installedLlndkLibraries := make(map[string]string) - for lib, filename := range llndkLibraries(ctx.Config()) { - if strings.HasPrefix(lib, "libclang_rt.hwasan-") { - continue - } - installedLlndkLibraries[lib] = filename - } - - installListFile := func(list []string, fileName string) android.Path { - out := android.PathForOutput(ctx, "vndk", fileName) - ctx.Build(pctx, android.BuildParams{ - Rule: android.WriteFile, - Output: out, - Description: "Writing " + out.String(), - Args: map[string]string{ - "content": strings.Join(list, "\\n"), - }, - }) - return out - } - - c.installedLlndkLibraries = android.SortedStringKeys(installedLlndkLibraries) - - llndk := android.SortedStringMapValues(installedLlndkLibraries) + llndk := android.SortedStringMapValues(llndkLibraries(ctx.Config())) vndkcore := android.SortedStringMapValues(vndkCoreLibraries(ctx.Config())) vndksp := android.SortedStringMapValues(vndkSpLibraries(ctx.Config())) vndkprivate := android.SortedStringMapValues(vndkPrivateLibraries(ctx.Config())) - vndkcorevariant := android.SortedStringMapValues(vndkUsingCoreVariantLibraries(ctx.Config())) - - c.llndkLibrariesFile = installListFile(llndk, "llndk.libraries.txt") - c.vndkCoreLibrariesFile = installListFile(vndkcore, "vndkcore.libraries.txt") - c.vndkSpLibrariesFile = installListFile(vndksp, "vndksp.libraries.txt") - c.vndkPrivateLibrariesFile = installListFile(vndkprivate, "vndkprivate.libraries.txt") - c.vndkCoreVariantLibrariesFile = installListFile(vndkcorevariant, "vndkcorevariant.libraries.txt") - // merged & tagged & filtered-out(libclang_rt) + // Build list of vndk libs as merged & tagged & filter-out(libclang_rt): // Since each target have different set of libclang_rt.* files, // keep the common set of files in vndk.libraries.txt var merged []string @@ -792,32 +875,48 @@ func (c *vndkSnapshotSingleton) buildVndkLibrariesTxtFiles(ctx android.Singleton merged = append(merged, addPrefix(vndksp, "VNDK-SP: ")...) merged = append(merged, addPrefix(filterOutLibClangRt(vndkcore), "VNDK-core: ")...) merged = append(merged, addPrefix(vndkprivate, "VNDK-private: ")...) - c.vndkLibrariesFile = installListFile(merged, "vndk.libraries.txt") + c.vndkLibrariesFile = android.PathForOutput(ctx, "vndk", "vndk.libraries.txt") + ctx.Build(pctx, android.BuildParams{ + Rule: android.WriteFile, + Output: c.vndkLibrariesFile, + Description: "Writing " + c.vndkLibrariesFile.String(), + Args: map[string]string{ + "content": strings.Join(merged, "\\n"), + }, + }) } func (c *vndkSnapshotSingleton) MakeVars(ctx android.MakeVarsContext) { // Make uses LLNDK_MOVED_TO_APEX_LIBRARIES to avoid installing libraries on /system if // they been moved to an apex. movedToApexLlndkLibraries := []string{} - for _, lib := range c.installedLlndkLibraries { + for lib := range llndkLibraries(ctx.Config()) { // Skip bionic libs, they are handled in different manner if android.DirectlyInAnyApex(¬OnHostContext{}, lib) && !isBionic(lib) { movedToApexLlndkLibraries = append(movedToApexLlndkLibraries, lib) } } ctx.Strict("LLNDK_MOVED_TO_APEX_LIBRARIES", strings.Join(movedToApexLlndkLibraries, " ")) - ctx.Strict("LLNDK_LIBRARIES", strings.Join(c.installedLlndkLibraries, " ")) + + // Make uses LLNDK_LIBRARIES to determine which libraries to install. + // HWASAN is only part of the LL-NDK in builds in which libc depends on HWASAN. + // Therefore, by removing the library here, we cause it to only be installed if libc + // depends on it. + installedLlndkLibraries := []string{} + for lib := range llndkLibraries(ctx.Config()) { + if strings.HasPrefix(lib, "libclang_rt.hwasan-") { + continue + } + installedLlndkLibraries = append(installedLlndkLibraries, lib) + } + sort.Strings(installedLlndkLibraries) + ctx.Strict("LLNDK_LIBRARIES", strings.Join(installedLlndkLibraries, " ")) + ctx.Strict("VNDK_CORE_LIBRARIES", strings.Join(android.SortedStringKeys(vndkCoreLibraries(ctx.Config())), " ")) ctx.Strict("VNDK_SAMEPROCESS_LIBRARIES", strings.Join(android.SortedStringKeys(vndkSpLibraries(ctx.Config())), " ")) ctx.Strict("VNDK_PRIVATE_LIBRARIES", strings.Join(android.SortedStringKeys(vndkPrivateLibraries(ctx.Config())), " ")) ctx.Strict("VNDK_USING_CORE_VARIANT_LIBRARIES", strings.Join(android.SortedStringKeys(vndkUsingCoreVariantLibraries(ctx.Config())), " ")) - ctx.Strict("LLNDK_LIBRARIES_FILE", c.llndkLibrariesFile.String()) - ctx.Strict("VNDKCORE_LIBRARIES_FILE", c.vndkCoreLibrariesFile.String()) - ctx.Strict("VNDKSP_LIBRARIES_FILE", c.vndkSpLibrariesFile.String()) - ctx.Strict("VNDKPRIVATE_LIBRARIES_FILE", c.vndkPrivateLibrariesFile.String()) - ctx.Strict("VNDKCOREVARIANT_LIBRARIES_FILE", c.vndkCoreVariantLibrariesFile.String()) - ctx.Strict("VNDK_LIBRARIES_FILE", c.vndkLibrariesFile.String()) ctx.Strict("SOONG_VNDK_SNAPSHOT_ZIP", c.vndkSnapshotZipFile.String()) } @@ -68,7 +68,7 @@ func (xom *xom) flags(ctx ModuleContext, flags Flags) Flags { if !disableXom || (xom.Properties.Xom != nil && *xom.Properties.Xom) { // XOM is only supported on AArch64 when using lld. if ctx.Arch().ArchType == android.Arm64 && ctx.useClangLld(ctx) { - flags.LdFlags = append(flags.LdFlags, "-Wl,-execute-only") + flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-execute-only") } } diff --git a/java/androidmk.go b/java/androidmk.go index cd91b4639..05106806a 100644 --- a/java/androidmk.go +++ b/java/androidmk.go @@ -332,10 +332,9 @@ func (app *AndroidApp) AndroidMkEntries() android.AndroidMkEntries { if len(app.dexpreopter.builtInstalled) > 0 { entries.SetString("LOCAL_SOONG_BUILT_INSTALLED", app.dexpreopter.builtInstalled) } - for _, split := range app.aapt.splits { - install := app.onDeviceDir + "/" + - strings.TrimSuffix(app.installApkName, ".apk") + "_" + split.suffix + ".apk" - entries.AddStrings("LOCAL_SOONG_BUILT_INSTALLED", split.path.String()+":"+install) + for _, extra := range app.extraOutputFiles { + install := app.onDeviceDir + "/" + extra.Base() + entries.AddStrings("LOCAL_SOONG_BUILT_INSTALLED", extra.String()+":"+install) } }, }, @@ -612,10 +611,15 @@ func (dstubs *Droidstubs) AndroidMkEntries() android.AndroidMkEntries { fmt.Fprintln(w, ".PHONY: checkapi") fmt.Fprintln(w, "checkapi:", - dstubs.apiLintTimestamp.String()) + dstubs.Name()+"-api-lint") fmt.Fprintln(w, ".PHONY: droidcore") fmt.Fprintln(w, "droidcore: checkapi") + + if dstubs.apiLintReport != nil { + fmt.Fprintf(w, "$(call dist-for-goals,%s,%s:%s)\n", dstubs.Name()+"-api-lint", + dstubs.apiLintReport.String(), "apilint/"+dstubs.Name()+"-lint-report.txt") + } } if dstubs.checkNullabilityWarningsTimestamp != nil { fmt.Fprintln(w, ".PHONY:", dstubs.Name()+"-check-nullability-warnings") diff --git a/java/app.go b/java/app.go index ddd63f90b..d53d62614 100644 --- a/java/app.go +++ b/java/app.go @@ -165,7 +165,6 @@ func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) { a.aapt.deps(ctx, sdkDep) } - embedJni := a.shouldEmbedJnis(ctx) for _, jniTarget := range ctx.MultiTargets() { variation := append(jniTarget.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"}) @@ -174,7 +173,7 @@ func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) { } ctx.AddFarVariationDependencies(variation, tag, a.appProperties.Jni_libs...) if String(a.appProperties.Stl) == "c++_shared" { - if embedJni { + if a.shouldEmbedJnis(ctx) { ctx.AddFarVariationDependencies(variation, tag, "ndk_libc++_shared") } } @@ -480,14 +479,13 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { a.certificate = certificates[0] // Build a final signed app package. - // TODO(jungjw): Consider changing this to installApkName. - packageFile := android.PathForModuleOut(ctx, ctx.ModuleName()+".apk") + packageFile := android.PathForModuleOut(ctx, a.installApkName+".apk") CreateAndSignAppPackage(ctx, packageFile, a.exportPackage, jniJarFile, dexJarFile, certificates, apkDeps) a.outputFile = packageFile for _, split := range a.aapt.splits { // Sign the split APKs - packageFile := android.PathForModuleOut(ctx, ctx.ModuleName()+"_"+split.suffix+".apk") + packageFile := android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk") CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps) a.extraOutputFiles = append(a.extraOutputFiles, packageFile) } @@ -498,9 +496,9 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { a.bundleFile = bundleFile // Install the app package. - ctx.InstallFile(a.installDir, a.installApkName+".apk", a.outputFile) - for _, split := range a.aapt.splits { - ctx.InstallFile(a.installDir, a.installApkName+"_"+split.suffix+".apk", split.path) + ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile) + for _, extra := range a.extraOutputFiles { + ctx.InstallFile(a.installDir, extra.Base(), extra) } } diff --git a/java/app_test.go b/java/app_test.go index ba08f5866..7635f3d3b 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -914,7 +914,7 @@ func TestPackageNameOverride(t *testing.T) { packageNameOverride: "foo:bar", expected: []string{ // The package apk should be still be the original name for test dependencies. - buildDir + "/.intermediates/foo/android_common/foo.apk", + buildDir + "/.intermediates/foo/android_common/bar.apk", buildDir + "/target/product/test_device/system/app/bar/bar.apk", }, }, @@ -1054,7 +1054,7 @@ func TestOverrideAndroidApp(t *testing.T) { } // Check the certificate paths - signapk := variant.Output("foo.apk") + signapk := variant.Output(expected.moduleName + ".apk") signFlag := signapk.Args["certificates"] if expected.signFlag != signFlag { t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected.signFlag, signFlag) diff --git a/java/builder.go b/java/builder.go index 5d36acdaa..417a7fa54 100644 --- a/java/builder.go +++ b/java/builder.go @@ -38,7 +38,7 @@ var ( // this, all java rules write into separate directories and then are combined into a .jar file // (if the rule produces .class files) or a .srcjar file (if the rule produces .java files). // .srcjar files are unzipped into a temporary directory when compiled with javac. - javac = pctx.AndroidGomaStaticRule("javac", + javac = pctx.AndroidRemoteStaticRule("javac", android.SUPPORTS_GOMA, blueprint.RuleParams{ Command: `rm -rf "$outDir" "$annoDir" "$srcJarDir" && mkdir -p "$outDir" "$annoDir" "$srcJarDir" && ` + `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` + @@ -313,7 +313,7 @@ func TransformJavaToHeaderClasses(ctx android.ModuleContext, outputFile android. // ensure turbine does not fall back to the default bootclasspath. bootClasspath = `--bootclasspath ""` } else { - bootClasspath = strings.Join(flags.bootClasspath.FormTurbineClasspath("--bootclasspath "), " ") + bootClasspath = flags.bootClasspath.FormTurbineClassPath("--bootclasspath ") } } @@ -330,7 +330,7 @@ func TransformJavaToHeaderClasses(ctx android.ModuleContext, outputFile android. "javacFlags": flags.javacFlags, "bootClasspath": bootClasspath, "srcJars": strings.Join(srcJars.Strings(), " "), - "classpath": strings.Join(classpath.FormTurbineClasspath("--classpath "), " "), + "classpath": classpath.FormTurbineClassPath("--classpath "), "outDir": android.PathForModuleOut(ctx, "turbine", "classes").String(), "javaVersion": flags.javaVersion.String(), }, @@ -523,18 +523,26 @@ func TransformZipAlign(ctx android.ModuleContext, outputFile android.WritablePat type classpath android.Paths -func (x *classpath) FormJavaClassPath(optName string) string { +func (x *classpath) formJoinedClassPath(optName string, sep string) string { if optName != "" && !strings.HasSuffix(optName, "=") && !strings.HasSuffix(optName, " ") { optName += " " } if len(*x) > 0 { - return optName + strings.Join(x.Strings(), ":") + return optName + strings.Join(x.Strings(), sep) } else { return "" } } +func (x *classpath) FormJavaClassPath(optName string) string { + return x.formJoinedClassPath(optName, ":") +} + +func (x *classpath) FormTurbineClassPath(optName string) string { + return x.formJoinedClassPath(optName, " ") +} -func (x *classpath) FormTurbineClasspath(optName string) []string { +// FormRepeatedClassPath returns a list of arguments with the given optName prefixed to each element of the classpath. +func (x *classpath) FormRepeatedClassPath(optName string) []string { if x == nil || *x == nil { return nil } diff --git a/java/config/config.go b/java/config/config.go index f418ee7f9..1c5596165 100644 --- a/java/config/config.go +++ b/java/config/config.go @@ -88,10 +88,10 @@ func init() { }) pctx.VariableFunc("JlinkVersion", func(ctx android.PackageVarContext) string { switch ctx.Config().Getenv("EXPERIMENTAL_USE_OPENJDK11_TOOLCHAIN") { - case "true": - return "11" - default: + case "false": return "9" + default: + return "11" } }) diff --git a/java/dex.go b/java/dex.go index c8a4fa8ed..5b25b2175 100644 --- a/java/dex.go +++ b/java/dex.go @@ -85,8 +85,8 @@ func (j *Module) dexCommonFlags(ctx android.ModuleContext) []string { func (j *Module) d8Flags(ctx android.ModuleContext, flags javaBuilderFlags) ([]string, android.Paths) { d8Flags := j.dexCommonFlags(ctx) - d8Flags = append(d8Flags, flags.bootClasspath.FormTurbineClasspath("--lib ")...) - d8Flags = append(d8Flags, flags.classpath.FormTurbineClasspath("--lib ")...) + d8Flags = append(d8Flags, flags.bootClasspath.FormRepeatedClassPath("--lib ")...) + d8Flags = append(d8Flags, flags.classpath.FormRepeatedClassPath("--lib ")...) var d8Deps android.Paths d8Deps = append(d8Deps, flags.bootClasspath...) diff --git a/java/droiddoc.go b/java/droiddoc.go index 9a3805023..54f93fec2 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -1182,6 +1182,7 @@ type Droidstubs struct { updateCurrentApiTimestamp android.WritablePath checkLastReleasedApiTimestamp android.WritablePath apiLintTimestamp android.WritablePath + apiLintReport android.WritablePath checkNullabilityWarningsTimestamp android.WritablePath @@ -1324,13 +1325,8 @@ func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.Ru validatingNullability := strings.Contains(d.Javadoc.args, "--validate-nullability-from-merged-stubs") || String(d.properties.Validate_nullability_from_list) != "" - migratingNullability := String(d.properties.Previous_api) != "" - - if !(migratingNullability || validatingNullability) { - ctx.PropertyErrorf("previous_api", - "has to be non-empty if annotations was enabled (unless validating nullability)") - } + migratingNullability := String(d.properties.Previous_api) != "" if migratingNullability { previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api)) cmd.FlagWithInput("--migrate-nullness ", previousApi) @@ -1552,6 +1548,8 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) { } else { cmd.Flag("--api-lint") } + d.apiLintReport = android.PathForModuleOut(ctx, "api_lint_report.txt") + cmd.FlagWithOutput("--report-even-if-suppressed ", d.apiLintReport) d.inclusionAnnotationsFlags(ctx, cmd) d.mergeAnnoDirFlags(ctx, cmd) diff --git a/java/java.go b/java/java.go index d043a12fe..9bbdff74c 100644 --- a/java/java.go +++ b/java/java.go @@ -442,6 +442,11 @@ type jniDependencyTag struct { target android.Target } +func IsJniDepTag(depTag blueprint.DependencyTag) bool { + _, ok := depTag.(*jniDependencyTag) + return ok +} + var ( staticLibTag = dependencyTag{name: "staticlib"} libTag = dependencyTag{name: "javalib"} @@ -967,6 +972,7 @@ func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaB // disk and memory usage. javacFlags = append(javacFlags, "-g:source,lines") } + javacFlags = append(javacFlags, "-Xlint:-dep-ann") if ctx.Config().RunErrorProne() { if config.ErrorProneClasspath == nil { diff --git a/java/kotlin.go b/java/kotlin.go index f8ae229de..5319a4ff9 100644 --- a/java/kotlin.go +++ b/java/kotlin.go @@ -26,7 +26,7 @@ import ( "github.com/google/blueprint" ) -var kotlinc = pctx.AndroidGomaStaticRule("kotlinc", +var kotlinc = pctx.AndroidRemoteStaticRule("kotlinc", android.SUPPORTS_GOMA, blueprint.RuleParams{ Command: `rm -rf "$classesDir" "$srcJarDir" "$kotlinBuildFile" "$emptyDir" && ` + `mkdir -p "$classesDir" "$srcJarDir" "$emptyDir" && ` + @@ -88,7 +88,7 @@ func kotlinCompile(ctx android.ModuleContext, outputFile android.WritablePath, }) } -var kapt = pctx.AndroidGomaStaticRule("kapt", +var kapt = pctx.AndroidRemoteStaticRule("kapt", android.SUPPORTS_GOMA, blueprint.RuleParams{ Command: `rm -rf "$srcJarDir" "$kotlinBuildFile" "$kaptDir" && mkdir -p "$srcJarDir" "$kaptDir" && ` + `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` + @@ -133,7 +133,7 @@ func kotlinKapt(ctx android.ModuleContext, outputFile android.WritablePath, deps = append(deps, srcJars...) deps = append(deps, flags.processorPath...) - kaptProcessorPath := flags.processorPath.FormTurbineClasspath("-P plugin:org.jetbrains.kotlin.kapt3:apclasspath=") + kaptProcessorPath := flags.processorPath.FormRepeatedClassPath("-P plugin:org.jetbrains.kotlin.kapt3:apclasspath=") kaptProcessor := "" if flags.processor != "" { diff --git a/python/python.go b/python/python.go index 1b606cbb9..c67c577dc 100644 --- a/python/python.go +++ b/python/python.go @@ -326,9 +326,24 @@ func (p *Module) DepsMutator(ctx android.BottomUpMutatorContext) { p.properties.Version.Py3.Libs)...) if p.bootstrapper != nil && p.isEmbeddedLauncherEnabled(pyVersion3) { - //TODO(nanzhang): Add embedded launcher for Python3. - ctx.PropertyErrorf("version.py3.embedded_launcher", - "is not supported yet for Python3.") + ctx.AddVariationDependencies(nil, pythonLibTag, "py3-stdlib") + + launcherModule := "py3-launcher" + if p.bootstrapper.autorun() { + launcherModule = "py3-launcher-autorun" + } + ctx.AddFarVariationDependencies(ctx.Target().Variations(), launcherTag, launcherModule) + + // Add py3-launcher shared lib dependencies. Ideally, these should be + // derived from the `shared_libs` property of "py3-launcher". However, we + // cannot read the property at this stage and it will be too late to add + // dependencies later. + ctx.AddFarVariationDependencies(ctx.Target().Variations(), launcherSharedLibTag, "libsqlite") + + if ctx.Target().Os.Bionic() { + ctx.AddFarVariationDependencies(ctx.Target().Variations(), launcherSharedLibTag, + "libc", "libdl", "libm") + } } default: panic(fmt.Errorf("unknown Python Actual_version: %q for module: %q.", @@ -370,11 +385,11 @@ func (p *Module) GenerateAndroidBuildActions(ctx android.ModuleContext) { // Only Python binaries and test has non-empty bootstrapper. if p.bootstrapper != nil { p.walkTransitiveDeps(ctx) - // TODO(nanzhang): Since embedded launcher is not supported for Python3 for now, - // so we initialize "embedded_launcher" to false. embeddedLauncher := false if p.properties.Actual_version == pyVersion2 { embeddedLauncher = p.isEmbeddedLauncherEnabled(pyVersion2) + } else { + embeddedLauncher = p.isEmbeddedLauncherEnabled(pyVersion3) } p.installSource = p.bootstrapper.bootstrap(ctx, p.properties.Actual_version, embeddedLauncher, p.srcsPathMappings, p.srcsZip, p.depsSrcsZips) diff --git a/python/tests/Android.bp b/python/tests/Android.bp index 1f4305c41..c8bf42023 100644 --- a/python/tests/Android.bp +++ b/python/tests/Android.bp @@ -27,6 +27,22 @@ python_test_host { }, py3: { enabled: false, + embedded_launcher: true, + }, + }, +} + +python_test_host { + name: "par_test3", + main: "par_test.py", + srcs: [ + "par_test.py", + "testpkg/par_test.py", + ], + + version: { + py3: { + embedded_launcher: true, }, }, } diff --git a/python/tests/runtest.sh b/python/tests/runtest.sh index a319558ff..1ecdebc9e 100755 --- a/python/tests/runtest.sh +++ b/python/tests/runtest.sh @@ -23,8 +23,8 @@ if [ -z $ANDROID_HOST_OUT ]; then exit 1 fi -if [ ! -f $ANDROID_HOST_OUT/nativetest64/par_test/par_test ]; then - echo "Run 'm par_test' first" +if [[ ( ! -f $ANDROID_HOST_OUT/nativetest64/par_test/par_test ) || ( ! -f $ANDROID_HOST_OUT/nativetest64/par_test3/par_test3 ) ]]; then + echo "Run 'm par_test par_test3' first" exit 1 fi @@ -36,4 +36,8 @@ PYTHONHOME= PYTHONPATH= $ANDROID_HOST_OUT/nativetest64/par_test/par_test PYTHONHOME=/usr $ANDROID_HOST_OUT/nativetest64/par_test/par_test PYTHONPATH=/usr $ANDROID_HOST_OUT/nativetest64/par_test/par_test +PYTHONHOME= PYTHONPATH= $ANDROID_HOST_OUT/nativetest64/par_test3/par_test3 +PYTHONHOME=/usr $ANDROID_HOST_OUT/nativetest64/par_test3/par_test3 +PYTHONPATH=/usr $ANDROID_HOST_OUT/nativetest64/par_test3/par_test3 + echo "Passed!" diff --git a/python/tests/testpkg/par_test.py b/python/tests/testpkg/par_test.py index 22dd09564..ffad430e4 100644 --- a/python/tests/testpkg/par_test.py +++ b/python/tests/testpkg/par_test.py @@ -29,7 +29,13 @@ archive = sys.modules["__main__"].__loader__.archive assert_equal("__name__", __name__, "testpkg.par_test") assert_equal("__file__", __file__, os.path.join(archive, "testpkg/par_test.py")) -assert_equal("__package__", __package__, "testpkg") + +# Python3 is returning None here for me, and I haven't found any problems caused by this. +if sys.version_info[0] == 2: + assert_equal("__package__", __package__, "testpkg") +else: + assert_equal("__package__", __package__, None) + assert_equal("__loader__.archive", __loader__.archive, archive) assert_equal("__loader__.prefix", __loader__.prefix, "testpkg/") diff --git a/sdk/sdk.go b/sdk/sdk.go index 002fb5dc7..4eb3665fb 100644 --- a/sdk/sdk.go +++ b/sdk/sdk.go @@ -19,6 +19,7 @@ import ( "strconv" "github.com/google/blueprint" + "github.com/google/blueprint/proptools" "android/soong/android" // This package doesn't depend on the apex package, but import it to make its mutators to be @@ -28,6 +29,7 @@ import ( ) func init() { + pctx.Import("android/soong/android") android.RegisterModuleType("sdk", ModuleFactory) android.RegisterModuleType("sdk_snapshot", SnapshotModuleFactory) android.PreDepsMutators(RegisterPreDepsMutators) @@ -40,8 +42,7 @@ type sdk struct { properties sdkProperties - updateScript android.OutputPath - freezeScript android.OutputPath + snapshotFile android.OptionalPath } type sdkProperties struct { @@ -60,6 +61,13 @@ func ModuleFactory() android.Module { s.AddProperties(&s.properties) android.InitAndroidMultiTargetsArchModule(s, android.HostAndDeviceSupported, android.MultilibCommon) android.InitDefaultableModule(s) + android.AddLoadHook(s, func(ctx android.LoadHookContext) { + type props struct { + Compile_multilib *string + } + p := &props{Compile_multilib: proptools.StringPtr("both")} + ctx.AppendProperties(p) + }) return s } @@ -96,11 +104,24 @@ func (s *sdk) frozenVersions(ctx android.BaseModuleContext) []string { } func (s *sdk) GenerateAndroidBuildActions(ctx android.ModuleContext) { - s.buildSnapshotGenerationScripts(ctx) + if !s.snapshot() { + // We don't need to create a snapshot out of sdk_snapshot. + // That doesn't make sense. We need a snapshot to create sdk_snapshot. + s.snapshotFile = android.OptionalPathForPath(s.buildSnapshot(ctx)) + } } func (s *sdk) AndroidMkEntries() android.AndroidMkEntries { - return s.androidMkEntriesForScript() + if !s.snapshotFile.Valid() { + return android.AndroidMkEntries{} + } + + return android.AndroidMkEntries{ + Class: "FAKE", + OutputFile: s.snapshotFile, + DistFile: s.snapshotFile, + Include: "$(BUILD_PHONY_PACKAGE)", + } } // RegisterPreDepsMutators registers pre-deps mutators to support modules implementing SdkAware diff --git a/sdk/sdk_test.go b/sdk/sdk_test.go index 664bb7c98..3471bc9da 100644 --- a/sdk/sdk_test.go +++ b/sdk/sdk_test.go @@ -17,6 +17,7 @@ package sdk import ( "io/ioutil" "os" + "path/filepath" "strings" "testing" @@ -100,6 +101,8 @@ func testSdkContext(t *testing.T, bp string) (*android.TestContext, android.Conf "myapex.pk8": nil, "Test.java": nil, "Test.cpp": nil, + "include/Test.h": nil, + "aidl/foo/bar/Test.aidl": nil, "libfoo.so": nil, }) @@ -377,6 +380,100 @@ func TestDepNotInRequiredSdks(t *testing.T) { `) } +func TestSdkIsCompileMultilibBoth(t *testing.T) { + ctx, _ := testSdk(t, ` + sdk { + name: "mysdk", + native_shared_libs: ["sdkmember"], + } + + cc_library_shared { + name: "sdkmember", + srcs: ["Test.cpp"], + system_shared_libs: [], + stl: "none", + } + `) + + armOutput := ctx.ModuleForTests("sdkmember", "android_arm_armv7-a-neon_core_shared").Module().(*cc.Module).OutputFile() + arm64Output := ctx.ModuleForTests("sdkmember", "android_arm64_armv8-a_core_shared").Module().(*cc.Module).OutputFile() + + var inputs []string + buildParams := ctx.ModuleForTests("mysdk", "android_common").Module().BuildParamsForTests() + for _, bp := range buildParams { + if bp.Input != nil { + inputs = append(inputs, bp.Input.String()) + } + } + + // ensure that both 32/64 outputs are inputs of the sdk snapshot + ensureListContains(t, inputs, armOutput.String()) + ensureListContains(t, inputs, arm64Output.String()) +} + +func TestSnapshot(t *testing.T) { + ctx, config := testSdk(t, ` + sdk { + name: "mysdk", + java_libs: ["myjavalib"], + native_shared_libs: ["mynativelib"], + } + + java_library { + name: "myjavalib", + srcs: ["Test.java"], + aidl: { + export_include_dirs: ["aidl"], + }, + system_modules: "none", + sdk_version: "none", + compile_dex: true, + host_supported: true, + } + + cc_library_shared { + name: "mynativelib", + srcs: [ + "Test.cpp", + "aidl/foo/bar/Test.aidl", + ], + export_include_dirs: ["include"], + aidl: { + export_aidl_headers: true, + }, + system_shared_libs: [], + stl: "none", + } + `) + + var copySrcs []string + var copyDests []string + buildParams := ctx.ModuleForTests("mysdk", "android_common").Module().BuildParamsForTests() + for _, bp := range buildParams { + if bp.Rule.String() == "android/soong/android.Cp" { + copySrcs = append(copySrcs, bp.Input.String()) + copyDests = append(copyDests, bp.Output.Rel()) // rooted at the snapshot root + } + } + + buildDir := config.BuildDir() + ensureListContains(t, copySrcs, "aidl/foo/bar/Test.aidl") + ensureListContains(t, copySrcs, "include/Test.h") + ensureListContains(t, copySrcs, filepath.Join(buildDir, ".intermediates/mynativelib/android_arm64_armv8-a_core_shared/gen/aidl/aidl/foo/bar/BnTest.h")) + ensureListContains(t, copySrcs, filepath.Join(buildDir, ".intermediates/mynativelib/android_arm64_armv8-a_core_shared/gen/aidl/aidl/foo/bar/BpTest.h")) + ensureListContains(t, copySrcs, filepath.Join(buildDir, ".intermediates/mynativelib/android_arm64_armv8-a_core_shared/gen/aidl/aidl/foo/bar/Test.h")) + ensureListContains(t, copySrcs, filepath.Join(buildDir, ".intermediates/myjavalib/android_common/turbine-combined/myjavalib.jar")) + ensureListContains(t, copySrcs, filepath.Join(buildDir, ".intermediates/mynativelib/android_arm64_armv8-a_core_shared/mynativelib.so")) + + ensureListContains(t, copyDests, "aidl/aidl/foo/bar/Test.aidl") + ensureListContains(t, copyDests, "arm64/include/include/Test.h") + ensureListContains(t, copyDests, "arm64/include_gen/mynativelib/aidl/foo/bar/BnTest.h") + ensureListContains(t, copyDests, "arm64/include_gen/mynativelib/aidl/foo/bar/BpTest.h") + ensureListContains(t, copyDests, "arm64/include_gen/mynativelib/aidl/foo/bar/Test.h") + ensureListContains(t, copyDests, "java/myjavalib.jar") + ensureListContains(t, copyDests, "arm64/lib/mynativelib.so") +} + var buildDir string func setUp() { diff --git a/sdk/update.go b/sdk/update.go index ce6082799..171bb3f8c 100644 --- a/sdk/update.go +++ b/sdk/update.go @@ -16,9 +16,7 @@ package sdk import ( "fmt" - "io" "path/filepath" - "strconv" "strings" "github.com/google/blueprint/proptools" @@ -38,9 +36,9 @@ type generatedFile struct { indentLevel int } -func newGeneratedFile(ctx android.ModuleContext, name string) *generatedFile { +func newGeneratedFile(ctx android.ModuleContext, path ...string) *generatedFile { return &generatedFile{ - path: android.PathForModuleOut(ctx, name).OutputPath, + path: android.PathForModuleOut(ctx, path...).OutputPath, indentLevel: 0, } } @@ -89,6 +87,7 @@ type archSpecificNativeLibInfo struct { exportedIncludeDirs android.Paths exportedSystemIncludeDirs android.Paths exportedFlags []string + exportedDeps android.Paths outputFile android.Path } @@ -132,6 +131,7 @@ func (s *sdk) nativeMemberInfos(ctx android.ModuleContext) []*nativeLibInfo { exportedIncludeDirs: ccModule.ExportedIncludeDirs(), exportedSystemIncludeDirs: ccModule.ExportedSystemIncludeDirs(), exportedFlags: ccModule.ExportedFlags(), + exportedDeps: ccModule.ExportedDeps(), outputFile: ccModule.OutputFile().Path(), }) }) @@ -169,11 +169,11 @@ func (s *sdk) nativeMemberInfos(ctx android.ModuleContext) []*nativeLibInfo { // aidl/ // frameworks/base/core/..../IFoo.aidl : an exported AIDL file // java/ -// java/<module_name>/stub.jar : a stub jar for a java library 'module_name' +// <module_name>.jar : the stub jar for a java library 'module_name' // include/ // bionic/libc/include/stdlib.h : an exported header file // include_gen/ -// com/android/.../IFoo.h : a generated header file +// <module_name>/com/android/.../IFoo.h : a generated header file // <arch>/include/ : arch-specific exported headers // <arch>/include_gen/ : arch-specific generated headers // <arch>/lib/ @@ -182,7 +182,7 @@ func (s *sdk) nativeMemberInfos(ctx android.ModuleContext) []*nativeLibInfo { const ( aidlIncludeDir = "aidl" javaStubDir = "java" - javaStubFile = "stub.jar" + javaStubFileSuffix = ".jar" nativeIncludeDir = "include" nativeGeneratedIncludeDir = "include_gen" nativeStubDir = "lib" @@ -191,7 +191,7 @@ const ( // path to the stub file of a java library. Relative to <sdk_root>/<api_dir> func javaStubFilePathFor(javaLib *java.Library) string { - return filepath.Join(javaStubDir, javaLib.Name(), javaStubFile) + return filepath.Join(javaStubDir, javaLib.Name()+javaStubFileSuffix) } // path to the stub file of a native shared library. Relative to <sdk_root>/<api_dir> @@ -204,7 +204,6 @@ func nativeStubFilePathFor(lib archSpecificNativeLibInfo) string { func nativeIncludeDirPathsFor(ctx android.ModuleContext, lib archSpecificNativeLibInfo, systemInclude bool, archSpecific bool) []string { var result []string - buildDir := ctx.Config().BuildDir() var includeDirs []android.Path if !systemInclude { includeDirs = lib.exportedIncludeDirs @@ -213,8 +212,8 @@ func nativeIncludeDirPathsFor(ctx android.ModuleContext, lib archSpecificNativeL } for _, dir := range includeDirs { var path string - if gen := strings.HasPrefix(dir.String(), buildDir); gen { - path = filepath.Join(nativeGeneratedIncludeDir, dir.Rel()) + if _, gen := dir.(android.WritablePath); gen { + path = filepath.Join(nativeGeneratedIncludeDir, lib.name) } else { path = filepath.Join(nativeIncludeDir, dir.String()) } @@ -226,21 +225,19 @@ func nativeIncludeDirPathsFor(ctx android.ModuleContext, lib archSpecificNativeL return result } -// A name that uniquely identifies an prebuilt SDK member for a version of SDK snapshot +// A name that uniquely identifies a prebuilt SDK member for a version of SDK snapshot // This isn't visible to users, so could be changed in future. func versionedSdkMemberName(ctx android.ModuleContext, memberName string, version string) string { return ctx.ModuleName() + "_" + memberName + string(android.SdkVersionSeparator) + version } -// arm64, arm, x86, x86_64, etc. -func archTypeOf(module android.Module) string { - return module.Target().Arch.ArchType.String() -} - // buildAndroidBp creates the blueprint file that defines prebuilt modules for each of // the SDK members, and the entire sdk_snapshot module for the specified version +// TODO(jiyong): create a meta info file (e.g. json, protobuf, etc.) instead, and convert it to +// Android.bp in the (presumably old) branch where the snapshots will be used. This will give us +// some flexibility to introduce backwards incompatible changes in soong. func (s *sdk) buildAndroidBp(ctx android.ModuleContext, version string) android.OutputPath { - bp := newGeneratedFile(ctx, "blueprint-"+version+".bp") + bp := newGeneratedFile(ctx, "snapshot", "Android.bp") bp.printfln("// This is auto-generated. DO NOT EDIT.") bp.printfln("") @@ -352,52 +349,42 @@ func (s *sdk) buildAndroidBp(ctx android.ModuleContext, version string) android. return bp.path } -func (s *sdk) buildScript(ctx android.ModuleContext, version string) android.OutputPath { - sh := newGeneratedFile(ctx, "update_prebuilt-"+version+".sh") - buildDir := ctx.Config().BuildDir() - - snapshotPath := func(paths ...string) string { - return filepath.Join(ctx.ModuleDir(), version, filepath.Join(paths...)) +// buildSnapshot is the main function in this source file. It creates rules to copy +// the contents (header files, stub libraries, etc) into the zip file. +func (s *sdk) buildSnapshot(ctx android.ModuleContext) android.OutputPath { + snapshotPath := func(paths ...string) android.OutputPath { + return android.PathForModuleOut(ctx, "snapshot").Join(ctx, paths...) } - // TODO(jiyong) instead of creating script, create a zip file having the Android.bp, the headers, - // and the stubs and put it to the dist directory. The dist'ed zip file then would be downloaded, - // unzipped and then uploaded to gerrit again. - sh.printfln("#!/bin/bash") - sh.printfln("echo Updating snapshot of %s in %s", ctx.ModuleName(), snapshotPath()) - sh.printfln("pushd $ANDROID_BUILD_TOP > /dev/null") - sh.printfln("mkdir -p %s", snapshotPath(aidlIncludeDir)) - sh.printfln("mkdir -p %s", snapshotPath(javaStubDir)) - sh.printfln("mkdir -p %s", snapshotPath(nativeIncludeDir)) - sh.printfln("mkdir -p %s", snapshotPath(nativeGeneratedIncludeDir)) - for _, target := range ctx.MultiTargets() { - arch := target.Arch.ArchType.String() - sh.printfln("mkdir -p %s", snapshotPath(arch, nativeStubDir)) - sh.printfln("mkdir -p %s", snapshotPath(arch, nativeIncludeDir)) - sh.printfln("mkdir -p %s", snapshotPath(arch, nativeGeneratedIncludeDir)) + var filesToZip android.Paths + // copy src to dest and add the dest to the zip + copy := func(src android.Path, dest android.OutputPath) { + ctx.Build(pctx, android.BuildParams{ + Rule: android.Cp, + Input: src, + Output: dest, + }) + filesToZip = append(filesToZip, dest) } - var implicits android.Paths + // copy exported AIDL files and stub jar files for _, m := range s.javaLibs(ctx) { headerJars := m.HeaderJars() if len(headerJars) != 1 { panic(fmt.Errorf("there must be only one header jar from %q", m.Name())) } - implicits = append(implicits, headerJars...) + copy(headerJars[0], snapshotPath(javaStubFilePathFor(m))) - exportedAidlIncludeDirs := m.AidlIncludeDirs() - for _, dir := range exportedAidlIncludeDirs { - // Using tar to copy with the directory structure + for _, dir := range m.AidlIncludeDirs() { // TODO(jiyong): copy parcelable declarations only - sh.printfln("find %s -name \"*.aidl\" | tar cf - -T - | (cd %s; tar xf -)", - dir.String(), snapshotPath(aidlIncludeDir)) + aidlFiles, _ := ctx.GlobWithDeps(dir.String()+"/**/*.aidl", nil) + for _, file := range aidlFiles { + copy(android.PathForSource(ctx, file), snapshotPath(aidlIncludeDir, file)) + } } - - copyTarget := snapshotPath(javaStubFilePathFor(m)) - sh.printfln("mkdir -p %s && cp %s %s", - filepath.Dir(copyTarget), headerJars[0].String(), copyTarget) } + // copy exported header files and stub *.so files nativeLibInfos := s.nativeMemberInfos(ctx) for _, info := range nativeLibInfos { @@ -409,26 +396,32 @@ func (s *sdk) buildScript(ctx android.ModuleContext, version string) android.Out return } for _, dir := range includeDirs { - gen := strings.HasPrefix(dir.String(), buildDir) - targetDir := nativeIncludeDir - if gen { - targetDir = nativeGeneratedIncludeDir + if _, gen := dir.(android.WritablePath); gen { + // generated headers are copied via exportedDeps. See below. + continue } + targetDir := nativeIncludeDir if info.hasArchSpecificFlags { targetDir = filepath.Join(lib.archType, targetDir) } - targetDir = snapshotPath(targetDir) - - sourceDirRoot := "." - sourceDirRel := dir.String() - if gen { - // ex) out/soong/.intermediate/foo/bar/gen/aidl - sourceDirRoot = strings.TrimSuffix(dir.String(), dir.Rel()) - sourceDirRel = dir.Rel() - } + // TODO(jiyong) copy headers having other suffixes - sh.printfln("(cd %s; find %s -name \"*.h\" | tar cf - -T - ) | (cd %s; tar xf -)", - sourceDirRoot, sourceDirRel, targetDir) + headers, _ := ctx.GlobWithDeps(dir.String()+"/**/*.h", nil) + for _, file := range headers { + src := android.PathForSource(ctx, file) + dest := snapshotPath(targetDir, file) + copy(src, dest) + } + } + + genHeaders := lib.exportedDeps + for _, file := range genHeaders { + targetDir := nativeGeneratedIncludeDir + if info.hasArchSpecificFlags { + targetDir = filepath.Join(lib.archType, targetDir) + } + dest := snapshotPath(targetDir, lib.name, file.Rel()) + copy(file, dest) } } @@ -438,10 +431,7 @@ func (s *sdk) buildScript(ctx android.ModuleContext, version string) android.Out // for each architecture for _, av := range info.archVariants { - stub := av.outputFile - implicits = append(implicits, stub) - copiedStub := snapshotPath(nativeStubFilePathFor(av)) - sh.printfln("cp %s %s", stub.String(), copiedStub) + copy(av.outputFile, snapshotPath(nativeStubFilePathFor(av))) if info.hasArchSpecificFlags { printExportedDirCopyCommandsForNativeLibs(av) @@ -449,69 +439,19 @@ func (s *sdk) buildScript(ctx android.ModuleContext, version string) android.Out } } - bp := s.buildAndroidBp(ctx, version) - implicits = append(implicits, bp) - sh.printfln("cp %s %s", bp.String(), snapshotPath("Android.bp")) + // generate Android.bp + bp := s.buildAndroidBp(ctx, "current") + filesToZip = append(filesToZip, bp) - sh.printfln("popd > /dev/null") - sh.printfln("rm -- \"$0\"") // self deleting so that stale script is not used - sh.printfln("echo Done") - - sh.build(pctx, ctx, implicits) - return sh.path -} - -func (s *sdk) buildSnapshotGenerationScripts(ctx android.ModuleContext) { - if s.snapshot() { - // we don't need a script for sdk_snapshot.. as they are frozen - return - } - - // script to update the 'current' snapshot - s.updateScript = s.buildScript(ctx, "current") - - versions := s.frozenVersions(ctx) - newVersion := "1" - if len(versions) >= 1 { - lastVersion := versions[len(versions)-1] - lastVersionNum, err := strconv.Atoi(lastVersion) - if err != nil { - panic(err) - return - } - newVersion = strconv.Itoa(lastVersionNum + 1) - } - // script to create a new frozen version of snapshot - s.freezeScript = s.buildScript(ctx, newVersion) -} - -func (s *sdk) androidMkEntriesForScript() android.AndroidMkEntries { - if s.snapshot() { - // we don't need a script for sdk_snapshot.. as they are frozen - return android.AndroidMkEntries{} - } + // zip them all + zipFile := android.PathForModuleOut(ctx, ctx.ModuleName()+"-current.zip").OutputPath + rb := android.NewRuleBuilder() + rb.Command(). + BuiltTool(ctx, "soong_zip"). + FlagWithArg("-C ", snapshotPath().String()). + FlagWithRspFileInputList("-l ", filesToZip). + FlagWithOutput("-o ", zipFile) + rb.Build(pctx, ctx, "snapshot", "Building snapshot for "+ctx.ModuleName()) - entries := android.AndroidMkEntries{ - Class: "FAKE", - // TODO(jiyong): remove this? but androidmk.go expects OutputFile to be specified anyway - OutputFile: android.OptionalPathForPath(s.updateScript), - Include: "$(BUILD_SYSTEM)/base_rules.mk", - ExtraEntries: []android.AndroidMkExtraEntriesFunc{ - func(entries *android.AndroidMkEntries) { - entries.AddStrings("LOCAL_ADDITIONAL_DEPENDENCIES", - s.updateScript.String(), s.freezeScript.String()) - }, - }, - ExtraFooters: []android.AndroidMkExtraFootersFunc{ - func(w io.Writer, name, prefix, moduleDir string, entries *android.AndroidMkEntries) { - fmt.Fprintln(w, "$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)") - fmt.Fprintln(w, " touch $@") - fmt.Fprintln(w, " echo ##################################################") - fmt.Fprintln(w, " echo To update current SDK: execute", filepath.Join("\\$$ANDROID_BUILD_TOP", s.updateScript.String())) - fmt.Fprintln(w, " echo To freeze current SDK: execute", filepath.Join("\\$$ANDROID_BUILD_TOP", s.freezeScript.String())) - fmt.Fprintln(w, " echo ##################################################") - }, - }, - } - return entries + return zipFile } diff --git a/ui/build/config.go b/ui/build/config.go index 919b9ce83..686ca3e76 100644 --- a/ui/build/config.go +++ b/ui/build/config.go @@ -219,10 +219,10 @@ func NewConfig(ctx Context, args ...string) Config { if override, ok := ret.environ.Get("OVERRIDE_ANDROID_JAVA_HOME"); ok { return override } - if toolchain11, ok := ret.environ.Get("EXPERIMENTAL_USE_OPENJDK11_TOOLCHAIN"); ok && toolchain11 == "true" { - return java11Home + if toolchain9, ok := ret.environ.Get("EXPERIMENTAL_USE_OPENJDK11_TOOLCHAIN"); ok && toolchain9 == "false" { + return java9Home } - return java9Home + return java11Home }() absJavaHome := absPath(ctx, javaHome) |