Merge "Make all the PrebuiltEtc modules defaultable."
diff --git a/Android.bp b/Android.bp
index d6260b4..b5ddaa4 100644
--- a/Android.bp
+++ b/Android.bp
@@ -62,6 +62,7 @@
},
},
notice: ":mingw-libwinpthread-notice",
+ licenses: ["winpthreads_license"],
}
kernel_headers {
diff --git a/android/androidmk.go b/android/androidmk.go
index 967c550..feaef1f 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -836,6 +836,7 @@
case "*aidl.aidlApi": // writes non-custom before adding .phony
case "*aidl.aidlMapping": // writes non-custom before adding .phony
case "*android.customModule": // appears in tests only
+ case "*android_sdk.sdkRepoHost": // doesn't go through base_rules
case "*apex.apexBundle": // license properties written
case "*bpf.bpf": // license properties written (both for module and objs)
case "*genrule.Module": // writes non-custom before adding .phony
diff --git a/android/arch.go b/android/arch.go
index ce4ba9b..5e3e920 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -1587,10 +1587,12 @@
return PrefixInList(arch.Abi, "arm")
}
-// hasArmArch returns true if targets has at least non-native_bridge arm Android arch
+// hasArmAndroidArch returns true if targets has at least
+// one arm Android arch (possibly native bridged)
func hasArmAndroidArch(targets []Target) bool {
for _, target := range targets {
- if target.Os == Android && target.Arch.ArchType == Arm {
+ if target.Os == Android &&
+ (target.Arch.ArchType == Arm || target.Arch.ArchType == Arm64) {
return true
}
}
diff --git a/android/bazel.go b/android/bazel.go
index 6aba759..e4eaa37 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -182,8 +182,8 @@
"external/boringssl": Bp2BuildDefaultTrueRecursively,
"external/brotli": Bp2BuildDefaultTrue,
"external/fmtlib": Bp2BuildDefaultTrueRecursively,
- "external/googletest/googletest": Bp2BuildDefaultTrueRecursively,
"external/google-benchmark": Bp2BuildDefaultTrueRecursively,
+ "external/googletest/googletest": Bp2BuildDefaultTrueRecursively,
"external/gwp_asan": Bp2BuildDefaultTrueRecursively,
"external/jemalloc_new": Bp2BuildDefaultTrueRecursively,
"external/jsoncpp": Bp2BuildDefaultTrueRecursively,
@@ -191,10 +191,15 @@
"external/libcxx": Bp2BuildDefaultTrueRecursively,
"external/libcxxabi": Bp2BuildDefaultTrueRecursively,
"external/lz4/lib": Bp2BuildDefaultTrue,
+ "external/mdnsresponder": Bp2BuildDefaultTrueRecursively,
+ "external/minijail": Bp2BuildDefaultTrueRecursively,
+ "external/pcre": Bp2BuildDefaultTrueRecursively,
"external/protobuf": Bp2BuildDefaultTrueRecursively,
"external/python/six": Bp2BuildDefaultTrueRecursively,
"external/scudo": Bp2BuildDefaultTrueRecursively,
+ "external/selinux/libselinux": Bp2BuildDefaultTrueRecursively,
"external/zlib": Bp2BuildDefaultTrueRecursively,
+ "external/zstd": Bp2BuildDefaultTrueRecursively,
"frameworks/native/libs/adbd_auth": Bp2BuildDefaultTrueRecursively,
"packages/modules/adb": Bp2BuildDefaultTrue,
"packages/modules/adb/crypto": Bp2BuildDefaultTrueRecursively,
@@ -208,6 +213,7 @@
"system/core/libasyncio": Bp2BuildDefaultTrue,
"system/core/libcrypto_utils": Bp2BuildDefaultTrueRecursively,
"system/core/libcutils": Bp2BuildDefaultTrueRecursively,
+ "system/core/libpackagelistparser": Bp2BuildDefaultTrueRecursively,
"system/core/libprocessgroup": Bp2BuildDefaultTrue,
"system/core/libprocessgroup/cgrouprc": Bp2BuildDefaultTrue,
"system/core/libprocessgroup/cgrouprc_format": Bp2BuildDefaultTrue,
@@ -241,6 +247,8 @@
"libcap", // http://b/198595332, depends on _makenames, a cc_binary
"cap_names.h", // http://b/198596102, depends on _makenames, a cc_binary
+ "libminijail", // depends on unconverted modules: libcap
+
// Tests. Handle later.
"libbionic_tests_headers_posix", // http://b/186024507, cc_library_static, sched.h, time.h not found
"libjemalloc5_integrationtest",
@@ -282,7 +290,7 @@
"libseccomp_policy_app_zygote_sources", // http://b/200899432, bazel-built cc_genrule does not work in mixed build when it is a dependency of another soong module.
"libseccomp_policy_app_sources", // http://b/200899432, bazel-built cc_genrule does not work in mixed build when it is a dependency of another soong module.
"libseccomp_policy_system_sources", // http://b/200899432, bazel-built cc_genrule does not work in mixed build when it is a dependency of another soong module.
-
+ "minijail_constants_json", // http://b/200899432, bazel-built cc_genrule does not work in mixed build when it is a dependency of another soong module.
}
// Used for quicker lookups
diff --git a/android/module.go b/android/module.go
index 327e6ae..02706ec 100644
--- a/android/module.go
+++ b/android/module.go
@@ -2818,11 +2818,13 @@
}
func (m *moduleContext) packageFile(fullInstallPath InstallPath, srcPath Path, executable bool) PackagingSpec {
+ licenseFiles := m.Module().EffectiveLicenseFiles()
spec := PackagingSpec{
- relPathInPackage: Rel(m, fullInstallPath.PartitionDir(), fullInstallPath.String()),
- srcPath: srcPath,
- symlinkTarget: "",
- executable: executable,
+ relPathInPackage: Rel(m, fullInstallPath.PartitionDir(), fullInstallPath.String()),
+ srcPath: srcPath,
+ symlinkTarget: "",
+ executable: executable,
+ effectiveLicenseFiles: &licenseFiles,
}
m.packagingSpecs = append(m.packagingSpecs, spec)
return spec
diff --git a/android/neverallow.go b/android/neverallow.go
index b8517a9..9098a71 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -150,6 +150,7 @@
func createJavaDeviceForHostRules() []Rule {
javaDeviceForHostProjectsAllowedList := []string{
+ "development/build",
"external/guava",
"external/robolectric-shadows",
"frameworks/layoutlib",
diff --git a/android/notices.go b/android/notices.go
index 07cf3e4..d8cfaf2 100644
--- a/android/notices.go
+++ b/android/notices.go
@@ -100,3 +100,56 @@
HtmlGzOutput: OptionalPathForPath(htmlGzOutput),
}
}
+
+// BuildNotices merges the supplied NOTICE files into a single file that lists notices
+// for every key in noticeMap (which would normally be installed files).
+func BuildNotices(ctx ModuleContext, noticeMap map[string]Paths) NoticeOutputs {
+ // TODO(jungjw): We should just produce a well-formatted NOTICE.html file in a single pass.
+ //
+ // generate-notice-files.py, which processes the merged NOTICE file, has somewhat strict rules
+ // about input NOTICE file paths.
+ // 1. Their relative paths to the src root become their NOTICE index titles. We want to use
+ // on-device paths as titles, and so output the merged NOTICE file the corresponding location.
+ // 2. They must end with .txt extension. Otherwise, they're ignored.
+
+ mergeTool := PathForSource(ctx, "build/soong/scripts/mergenotice.py")
+ generateNoticeTool := PathForSource(ctx, "build/soong/scripts/generate-notice-files.py")
+
+ outputDir := PathForModuleOut(ctx, "notices")
+ builder := NewRuleBuilder(pctx, ctx).
+ Sbox(outputDir, PathForModuleOut(ctx, "notices.sbox.textproto"))
+ for _, installPath := range SortedStringKeys(noticeMap) {
+ noticePath := outputDir.Join(ctx, installPath+".txt")
+ // It would be nice if sbox created directories for temporaries, but until then
+ // this is simple enough.
+ builder.Command().
+ Text("(cd").OutputDir().Text("&&").
+ Text("mkdir -p").Text(filepath.Dir(installPath)).Text(")")
+ builder.Temporary(noticePath)
+ builder.Command().
+ Tool(mergeTool).
+ Flag("--output").Output(noticePath).
+ Inputs(noticeMap[installPath])
+ }
+
+ // Transform the merged NOTICE file into a gzipped HTML file.
+ txtOutput := outputDir.Join(ctx, "NOTICE.txt")
+ htmlOutput := outputDir.Join(ctx, "NOTICE.html")
+ htmlGzOutput := outputDir.Join(ctx, "NOTICE.html.gz")
+ title := "\"Notices for " + ctx.ModuleName() + "\""
+ builder.Command().Tool(generateNoticeTool).
+ FlagWithOutput("--text-output ", txtOutput).
+ FlagWithOutput("--html-output ", htmlOutput).
+ FlagWithArg("-t ", title).
+ Flag("-s").OutputDir()
+ builder.Command().BuiltTool("minigzip").
+ FlagWithInput("-c ", htmlOutput).
+ FlagWithOutput("> ", htmlGzOutput)
+ builder.Build("build_notices", "generate notice output")
+
+ return NoticeOutputs{
+ TxtOutput: OptionalPathForPath(txtOutput),
+ HtmlOutput: OptionalPathForPath(htmlOutput),
+ HtmlGzOutput: OptionalPathForPath(htmlGzOutput),
+ }
+}
diff --git a/android/packaging.go b/android/packaging.go
index 9065826..e3a0b54 100644
--- a/android/packaging.go
+++ b/android/packaging.go
@@ -38,6 +38,8 @@
// Whether relPathInPackage should be marked as executable or not
executable bool
+
+ effectiveLicenseFiles *Paths
}
// Get file name of installed package
@@ -54,6 +56,17 @@
return p.relPathInPackage
}
+func (p *PackagingSpec) SetRelPathInPackage(relPathInPackage string) {
+ p.relPathInPackage = relPathInPackage
+}
+
+func (p *PackagingSpec) EffectiveLicenseFiles() Paths {
+ if p.effectiveLicenseFiles == nil {
+ return Paths{}
+ }
+ return *p.effectiveLicenseFiles
+}
+
type PackageModule interface {
Module
packagingBase() *PackagingBase
@@ -214,15 +227,9 @@
return m
}
-// See PackageModule.CopyDepsToZip
-func (p *PackagingBase) CopyDepsToZip(ctx ModuleContext, zipOut WritablePath) (entries []string) {
- m := p.GatherPackagingSpecs(ctx)
- builder := NewRuleBuilder(pctx, ctx)
-
- dir := PathForModuleOut(ctx, ".zip")
- builder.Command().Text("rm").Flag("-rf").Text(dir.String())
- builder.Command().Text("mkdir").Flag("-p").Text(dir.String())
-
+// CopySpecsToDir is a helper that will add commands to the rule builder to copy the PackagingSpec
+// entries into the specified directory.
+func (p *PackagingBase) CopySpecsToDir(ctx ModuleContext, builder *RuleBuilder, m map[string]PackagingSpec, dir ModuleOutPath) (entries []string) {
seenDir := make(map[string]bool)
for _, k := range SortedStringKeys(m) {
ps := m[k]
@@ -243,6 +250,19 @@
}
}
+ return entries
+}
+
+// See PackageModule.CopyDepsToZip
+func (p *PackagingBase) CopyDepsToZip(ctx ModuleContext, zipOut WritablePath) (entries []string) {
+ m := p.GatherPackagingSpecs(ctx)
+ builder := NewRuleBuilder(pctx, ctx)
+
+ dir := PathForModuleOut(ctx, ".zip")
+ builder.Command().Text("rm").Flag("-rf").Text(dir.String())
+ builder.Command().Text("mkdir").Flag("-p").Text(dir.String())
+ entries = p.CopySpecsToDir(ctx, builder, m, dir)
+
builder.Command().
BuiltTool("soong_zip").
FlagWithOutput("-o ", zipOut).
diff --git a/android/variable.go b/android/variable.go
index 4a82f23..5c54e94 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -40,6 +40,7 @@
Platform_sdk_version struct {
Asflags []string
Cflags []string
+ Cmd *string
}
Platform_sdk_version_or_codename struct {
@@ -50,6 +51,10 @@
Cmd *string
}
+ Platform_version_name struct {
+ Base_dir *string
+ }
+
// unbundled_build is a catch-all property to annotate modules that don't build in one or
// more unbundled branches, usually due to dependencies missing from the manifest.
Unbundled_build struct {
diff --git a/android_sdk/Android.bp b/android_sdk/Android.bp
new file mode 100644
index 0000000..e686d59
--- /dev/null
+++ b/android_sdk/Android.bp
@@ -0,0 +1,22 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+bootstrap_go_package {
+ name: "soong-android-sdk",
+ pkgPath: "android/soong/android_sdk",
+ deps: [
+ "blueprint",
+ "soong",
+ "soong-android",
+ "soong-cc",
+ "soong-cc-config",
+ ],
+ srcs: [
+ "sdk_repo_host.go",
+ ],
+ testSrcs: [
+ "sdk_repo_host_test.go",
+ ],
+ pluginFor: ["soong_build"],
+}
diff --git a/android_sdk/sdk_repo_host.go b/android_sdk/sdk_repo_host.go
new file mode 100644
index 0000000..a76da8b
--- /dev/null
+++ b/android_sdk/sdk_repo_host.go
@@ -0,0 +1,295 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package android_sdk
+
+import (
+ "fmt"
+ "io"
+ "path/filepath"
+ "strings"
+
+ "github.com/google/blueprint"
+ "github.com/google/blueprint/pathtools"
+ "github.com/google/blueprint/proptools"
+
+ "android/soong/android"
+ "android/soong/cc/config"
+)
+
+var pctx = android.NewPackageContext("android/soong/android_sdk")
+
+func init() {
+ registerBuildComponents(android.InitRegistrationContext)
+}
+
+func registerBuildComponents(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("android_sdk_repo_host", SdkRepoHostFactory)
+}
+
+type sdkRepoHost struct {
+ android.ModuleBase
+ android.PackagingBase
+
+ properties sdkRepoHostProperties
+
+ outputBaseName string
+ outputFile android.OptionalPath
+}
+
+type remapProperties struct {
+ From string
+ To string
+}
+
+type sdkRepoHostProperties struct {
+ // The top level directory to use for the SDK repo.
+ Base_dir *string
+
+ // List of src:dst mappings to rename files from `deps`.
+ Deps_remap []remapProperties `android:"arch_variant"`
+
+ // List of zip files to merge into the SDK repo.
+ Merge_zips []string `android:"arch_variant,path"`
+
+ // List of sources to include into the SDK repo. These are usually raw files, filegroups,
+ // or genrules, as most built modules should be referenced via `deps`.
+ Srcs []string `android:"arch_variant,path"`
+
+ // List of files to strip. This should be a list of files, not modules. This happens after
+ // `deps_remap` and `merge_zips` are applied, but before the `base_dir` is added.
+ Strip_files []string `android:"arch_variant"`
+}
+
+// android_sdk_repo_host defines an Android SDK repo containing host tools.
+//
+// This implementation is trying to be a faithful reproduction of how these sdk-repos were produced
+// in the Make system, which may explain some of the oddities (like `strip_files` not being
+// automatic)
+func SdkRepoHostFactory() android.Module {
+ return newSdkRepoHostModule()
+}
+
+func newSdkRepoHostModule() *sdkRepoHost {
+ s := &sdkRepoHost{}
+ s.AddProperties(&s.properties)
+ android.InitPackageModule(s)
+ android.InitAndroidMultiTargetsArchModule(s, android.HostSupported, android.MultilibCommon)
+ return s
+}
+
+type dependencyTag struct {
+ blueprint.BaseDependencyTag
+ android.PackagingItemAlwaysDepTag
+}
+
+// TODO(b/201696252): Evaluate whether licenses should be propagated through this dependency.
+func (d dependencyTag) PropagateLicenses() bool {
+ return false
+}
+
+var depTag = dependencyTag{}
+
+func (s *sdkRepoHost) DepsMutator(ctx android.BottomUpMutatorContext) {
+ s.AddDeps(ctx, depTag)
+}
+
+func (s *sdkRepoHost) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ dir := android.PathForModuleOut(ctx, "zip")
+ builder := android.NewRuleBuilder(pctx, ctx).
+ Sbox(dir, android.PathForModuleOut(ctx, "out.sbox.textproto")).
+ SandboxInputs()
+
+ // Get files from modules listed in `deps`
+ packageSpecs := s.GatherPackagingSpecs(ctx)
+
+ // Handle `deps_remap` renames
+ err := remapPackageSpecs(packageSpecs, s.properties.Deps_remap)
+ if err != nil {
+ ctx.PropertyErrorf("deps_remap", "%s", err.Error())
+ }
+
+ s.CopySpecsToDir(ctx, builder, packageSpecs, dir)
+
+ // Collect licenses to write into NOTICE.txt
+ noticeMap := map[string]android.Paths{}
+ for path, pkgSpec := range packageSpecs {
+ licenseFiles := pkgSpec.EffectiveLicenseFiles()
+ if len(licenseFiles) > 0 {
+ noticeMap[path] = pkgSpec.EffectiveLicenseFiles()
+ }
+ }
+ notices := android.BuildNotices(ctx, noticeMap)
+ builder.Command().Text("cp").
+ Input(notices.TxtOutput.Path()).
+ Text(filepath.Join(dir.String(), "NOTICE.txt"))
+
+ // Handle `merge_zips` by extracting their contents into our tmpdir
+ for _, zip := range android.PathsForModuleSrc(ctx, s.properties.Merge_zips) {
+ builder.Command().
+ Text("unzip").
+ Flag("-DD").
+ Flag("-q").
+ FlagWithArg("-d ", dir.String()).
+ Input(zip)
+ }
+
+ // Copy files from `srcs` into our tmpdir
+ for _, src := range android.PathsForModuleSrc(ctx, s.properties.Srcs) {
+ builder.Command().
+ Text("cp").Input(src).Flag(dir.Join(ctx, src.Rel()).String())
+ }
+
+ // Handle `strip_files` by calling the necessary strip commands
+ //
+ // Note: this stripping logic was copied over from the old Make implementation
+ // It's not using the same flags as the regular stripping support, nor does it
+ // support the array of per-module stripping options. It would be nice if we
+ // pulled the stripped versions from the CC modules, but that doesn't exist
+ // for host tools today. (And not all the things we strip are CC modules today)
+ if ctx.Darwin() {
+ macStrip := config.MacStripPath(ctx)
+ for _, strip := range s.properties.Strip_files {
+ builder.Command().
+ Text(macStrip).Flag("-x").
+ Flag(dir.Join(ctx, strip).String())
+ }
+ } else {
+ llvmStrip := config.ClangPath(ctx, "bin/llvm-strip")
+ llvmLib := config.ClangPath(ctx, "lib64/libc++.so.1")
+ for _, strip := range s.properties.Strip_files {
+ cmd := builder.Command().Tool(llvmStrip).ImplicitTool(llvmLib)
+ if !ctx.Windows() {
+ cmd.Flag("-x")
+ }
+ cmd.Flag(dir.Join(ctx, strip).String())
+ }
+ }
+
+ // Fix up the line endings of all text files. This also removes executable permissions.
+ builder.Command().
+ Text("find").
+ Flag(dir.String()).
+ Flag("-name '*.aidl' -o -name '*.css' -o -name '*.html' -o -name '*.java'").
+ Flag("-o -name '*.js' -o -name '*.prop' -o -name '*.template'").
+ Flag("-o -name '*.txt' -o -name '*.windows' -o -name '*.xml' -print0").
+ // Using -n 500 for xargs to limit the max number of arguments per call to line_endings
+ // to 500. This avoids line_endings failing with "arguments too long".
+ Text("| xargs -0 -n 500 ").
+ BuiltTool("line_endings").
+ Flag("unix")
+
+ // Exclude some file types (roughly matching sdk.exclude.atree)
+ builder.Command().
+ Text("find").
+ Flag(dir.String()).
+ Flag("'('").
+ Flag("-name '.*' -o -name '*~' -o -name 'Makefile' -o -name 'Android.mk' -o").
+ Flag("-name '.*.swp' -o -name '.DS_Store' -o -name '*.pyc' -o -name 'OWNERS' -o").
+ Flag("-name 'MODULE_LICENSE_*' -o -name '*.ezt' -o -name 'Android.bp'").
+ Flag("')' -print0").
+ Text("| xargs -0 -r rm -rf")
+ builder.Command().
+ Text("find").
+ Flag(dir.String()).
+ Flag("-name '_*' ! -name '__*' -print0").
+ Text("| xargs -0 -r rm -rf")
+
+ if ctx.Windows() {
+ // Fix EOL chars to make window users happy
+ builder.Command().
+ Text("find").
+ Flag(dir.String()).
+ Flag("-maxdepth 2 -name '*.bat' -type f -print0").
+ Text("| xargs -0 -r unix2dos")
+ }
+
+ // Zip up our temporary directory as the sdk-repo
+ outputZipFile := dir.Join(ctx, "output.zip")
+ builder.Command().
+ BuiltTool("soong_zip").
+ FlagWithOutput("-o ", outputZipFile).
+ FlagWithArg("-P ", proptools.StringDefault(s.properties.Base_dir, ".")).
+ FlagWithArg("-C ", dir.String()).
+ FlagWithArg("-D ", dir.String())
+ builder.Command().Text("rm").Flag("-rf").Text(dir.String())
+
+ builder.Build("build_sdk_repo", "Creating sdk-repo-"+s.BaseModuleName())
+
+ osName := ctx.Os().String()
+ if osName == "linux_glibc" {
+ osName = "linux"
+ }
+ name := fmt.Sprintf("sdk-repo-%s-%s", osName, s.BaseModuleName())
+
+ s.outputBaseName = name
+ s.outputFile = android.OptionalPathForPath(outputZipFile)
+ ctx.InstallFile(android.PathForModuleInstall(ctx, "sdk-repo"), name+".zip", outputZipFile)
+}
+
+func (s *sdkRepoHost) AndroidMk() android.AndroidMkData {
+ return android.AndroidMkData{
+ Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
+ // TODO: per-OS PHONY
+ fmt.Fprintln(w, ".PHONY:", name, "sdk_repo", "sdk-repo-"+name)
+ fmt.Fprintln(w, "sdk_repo", "sdk-repo-"+name+":", strings.Join(s.FilesToInstall().Strings(), " "))
+
+ fmt.Fprintf(w, "$(call dist-for-goals,sdk_repo sdk-repo-%s,%s:new_%s-$(FILE_NAME_TAG).zip)\n\n", s.BaseModuleName(), s.outputFile.String(), s.outputBaseName)
+ },
+ }
+}
+
+func remapPackageSpecs(specs map[string]android.PackagingSpec, remaps []remapProperties) error {
+ for _, remap := range remaps {
+ for path, spec := range specs {
+ if match, err := pathtools.Match(remap.From, path); err != nil {
+ return fmt.Errorf("Error parsing %q: %v", remap.From, err)
+ } else if match {
+ newPath := remap.To
+ if pathtools.IsGlob(remap.From) {
+ rel, err := filepath.Rel(constantPartOfPattern(remap.From), path)
+ if err != nil {
+ return fmt.Errorf("Error handling %q", path)
+ }
+ newPath = filepath.Join(remap.To, rel)
+ }
+ delete(specs, path)
+ spec.SetRelPathInPackage(newPath)
+ specs[newPath] = spec
+ }
+ }
+ }
+ return nil
+}
+
+func constantPartOfPattern(pattern string) string {
+ ret := ""
+ for pattern != "" {
+ var first string
+ first, pattern = splitFirst(pattern)
+ if pathtools.IsGlob(first) {
+ return ret
+ }
+ ret = filepath.Join(ret, first)
+ }
+ return ret
+}
+
+func splitFirst(path string) (string, string) {
+ i := strings.IndexRune(path, filepath.Separator)
+ if i < 0 {
+ return path, ""
+ }
+ return path[:i], path[i+1:]
+}
diff --git a/android_sdk/sdk_repo_host_test.go b/android_sdk/sdk_repo_host_test.go
new file mode 100644
index 0000000..0688921
--- /dev/null
+++ b/android_sdk/sdk_repo_host_test.go
@@ -0,0 +1,124 @@
+// Copyright 2021 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package android_sdk
+
+import (
+ "fmt"
+ "runtime"
+ "sort"
+ "testing"
+
+ "android/soong/android"
+ "android/soong/cc"
+
+ "github.com/google/blueprint/pathtools"
+)
+
+var fixture = android.GroupFixturePreparers(
+ android.PrepareForIntegrationTestWithAndroid,
+ cc.PrepareForIntegrationTestWithCc,
+ android.FixtureRegisterWithContext(registerBuildComponents),
+)
+
+func TestSdkRepoHostDeps(t *testing.T) {
+ if runtime.GOOS != "linux" {
+ t.Skipf("Skipping sdk_repo_host testing that is only supported on linux not %s", runtime.GOOS)
+ }
+
+ result := fixture.RunTestWithBp(t, `
+ android_sdk_repo_host {
+ name: "platform-tools",
+ }
+ `)
+
+ // produces "sdk-repo-{OS}-platform-tools.zip"
+ result.ModuleForTests("platform-tools", "linux_glibc_common").Output("sdk-repo-linux-platform-tools.zip")
+}
+
+func TestRemapPackageSpecs(t *testing.T) {
+ testcases := []struct {
+ name string
+ input []string
+ remaps []remapProperties
+ output []string
+ err string
+ }{
+ {
+ name: "basic remap",
+ input: []string{"a", "c"},
+ remaps: []remapProperties{
+ {From: "a", To: "b"},
+ },
+ output: []string{"b", "c"},
+ },
+ {
+ name: "non-matching remap",
+ input: []string{"a"},
+ remaps: []remapProperties{
+ {From: "b", To: "c"},
+ },
+ output: []string{"a"},
+ },
+ {
+ name: "glob",
+ input: []string{"bin/d", "liba.so", "libb.so", "lib/c.so"},
+ remaps: []remapProperties{
+ {From: "lib*.so", To: "lib/"},
+ },
+ output: []string{"bin/d", "lib/c.so", "lib/liba.so", "lib/libb.so"},
+ },
+ {
+ name: "bad glob",
+ input: []string{"a"},
+ remaps: []remapProperties{
+ {From: "**", To: "./"},
+ },
+ err: fmt.Sprintf("Error parsing \"**\": %v", pathtools.GlobLastRecursiveErr.Error()),
+ },
+ {
+ name: "globbed dirs",
+ input: []string{"a/b/c"},
+ remaps: []remapProperties{
+ {From: "a/*/c", To: "./"},
+ },
+ output: []string{"b/c"},
+ },
+ }
+
+ for _, test := range testcases {
+ t.Run(test.name, func(t *testing.T) {
+ specs := map[string]android.PackagingSpec{}
+ for _, input := range test.input {
+ spec := android.PackagingSpec{}
+ spec.SetRelPathInPackage(input)
+ specs[input] = spec
+ }
+
+ err := remapPackageSpecs(specs, test.remaps)
+
+ if test.err != "" {
+ android.AssertErrorMessageEquals(t, "", test.err, err)
+ } else {
+ outputs := []string{}
+ for path, spec := range specs {
+ android.AssertStringEquals(t, "path does not match rel path", path, spec.RelPathInPackage())
+ outputs = append(outputs, path)
+ }
+ sort.Strings(outputs)
+ android.AssertArrayString(t, "outputs mismatch", test.output, outputs)
+ }
+ })
+ }
+}
diff --git a/androidmk/androidmk/android.go b/androidmk/androidmk/android.go
index 963e905..f3ad152 100644
--- a/androidmk/androidmk/android.go
+++ b/androidmk/androidmk/android.go
@@ -639,6 +639,12 @@
if len(val.Variables) == 1 && varLiteralName(val.Variables[0]) != "" && len(val.Strings) == 2 && val.Strings[0] == "" {
fixed = val.Strings[1]
varname = val.Variables[0].Name.Strings[0]
+ // TARGET_OUT_OPTIONAL_EXECUTABLES puts the artifact in xbin, which is
+ // deprecated. TARGET_OUT_DATA_APPS install location will be handled
+ // automatically by Soong
+ if varname == "TARGET_OUT_OPTIONAL_EXECUTABLES" || varname == "TARGET_OUT_DATA_APPS" {
+ return nil
+ }
} else if len(val.Variables) == 2 && varLiteralName(val.Variables[0]) == "PRODUCT_OUT" && varLiteralName(val.Variables[1]) == "TARGET_COPY_OUT_VENDOR" &&
len(val.Strings) == 3 && val.Strings[0] == "" && val.Strings[1] == "/" {
fixed = val.Strings[2]
diff --git a/androidmk/androidmk/androidmk_test.go b/androidmk/androidmk/androidmk_test.go
index 9fd4ff9..775a9a8 100644
--- a/androidmk/androidmk/androidmk_test.go
+++ b/androidmk/androidmk/androidmk_test.go
@@ -1516,7 +1516,23 @@
],
}
`,
- },
+ }, {
+ desc: "Obsolete LOCAL_MODULE_PATH",
+ in: `
+include $(CLEAR_VARS)
+LOCAL_MODULE := foo
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_CTS_TEST_PACKAGE := bar
+LOCAL_USE_AAPT2 := blah
+include $(BUILD_PACKAGE)
+`,
+ expected: `
+android_app {
+ name: "foo",
+
+}
+`},
}
func TestEndToEnd(t *testing.T) {
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 4a5373f..78a6bb8 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -3183,7 +3183,6 @@
"myapex",
"otherapex",
],
- use_apex_name_macro: true,
recovery_available: true,
min_sdk_version: "29",
}
@@ -3198,13 +3197,11 @@
mylibCFlags = ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_apex10000").Rule("cc").Args["cFlags"]
ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__")
ensureContains(t, mylibCFlags, "-D__ANDROID_APEX_MIN_SDK_VERSION__=10000")
- ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MYAPEX__")
// APEX variant has __ANDROID_APEX__ and __ANDROID_APEX_SDK__ defined
mylibCFlags = ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_apex29").Rule("cc").Args["cFlags"]
ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__")
ensureContains(t, mylibCFlags, "-D__ANDROID_APEX_MIN_SDK_VERSION__=29")
- ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_OTHERAPEX__")
// When a cc_library sets use_apex_name_macro: true each apex gets a unique variant and
// each variant defines additional macros to distinguish which apex variant it is built for
@@ -3213,42 +3210,15 @@
mylibCFlags = ctx.ModuleForTests("mylib3", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__")
- // APEX variant has __ANDROID_APEX__ defined
- mylibCFlags = ctx.ModuleForTests("mylib3", "android_arm64_armv8-a_static_myapex").Rule("cc").Args["cFlags"]
- ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__")
- ensureContains(t, mylibCFlags, "-D__ANDROID_APEX_MYAPEX__")
- ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_OTHERAPEX__")
-
- // APEX variant has __ANDROID_APEX__ defined
- mylibCFlags = ctx.ModuleForTests("mylib3", "android_arm64_armv8-a_static_otherapex").Rule("cc").Args["cFlags"]
- ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__")
- ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MYAPEX__")
- ensureContains(t, mylibCFlags, "-D__ANDROID_APEX_OTHERAPEX__")
-
// recovery variant does not set __ANDROID_APEX_MIN_SDK_VERSION__
mylibCFlags = ctx.ModuleForTests("mylib3", "android_recovery_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__")
ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MIN_SDK_VERSION__")
- // When a dependency of a cc_library sets use_apex_name_macro: true each apex gets a unique
- // variant.
-
// non-APEX variant does not have __ANDROID_APEX__ defined
mylibCFlags = ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__")
- // APEX variant has __ANDROID_APEX__ defined
- mylibCFlags = ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static_myapex").Rule("cc").Args["cFlags"]
- ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__")
- ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MYAPEX__")
- ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_OTHERAPEX__")
-
- // APEX variant has __ANDROID_APEX__ defined
- mylibCFlags = ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static_otherapex").Rule("cc").Args["cFlags"]
- ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__")
- ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MYAPEX__")
- ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_OTHERAPEX__")
-
// recovery variant does not set __ANDROID_APEX_MIN_SDK_VERSION__
mylibCFlags = ctx.ModuleForTests("mylib2", "android_recovery_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__")
diff --git a/cc/cc.go b/cc/cc.go
index 87de1c8..1c65549 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -3249,16 +3249,6 @@
return c.Properties.Test_for
}
-func (c *Module) UniqueApexVariations() bool {
- if u, ok := c.compiler.(interface {
- uniqueApexVariations() bool
- }); ok {
- return u.uniqueApexVariations()
- } else {
- return false
- }
-}
-
func (c *Module) EverInstallable() bool {
return c.installer != nil &&
// Check to see whether the module is actually ever installable.
diff --git a/cc/compiler.go b/cc/compiler.go
index 4f96712..2ac7bf3 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -209,15 +209,6 @@
// Build and link with OpenMP
Openmp *bool `android:"arch_variant"`
-
- // Deprecated.
- // Adds __ANDROID_APEX_<APEX_MODULE_NAME>__ macro defined for apex variants in addition to __ANDROID_APEX__
- Use_apex_name_macro *bool
-
- // Adds two macros for apex variants in addition to __ANDROID_APEX__
- // * __ANDROID_APEX_COM_ANDROID_FOO__
- // * __ANDROID_APEX_NAME__="com.android.foo"
- UseApexNameMacro bool `blueprint:"mutated"`
}
func NewBaseCompiler() *baseCompiler {
@@ -291,10 +282,6 @@
return deps
}
-func (compiler *baseCompiler) useApexNameMacro() bool {
- return Bool(compiler.Properties.Use_apex_name_macro) || compiler.Properties.UseApexNameMacro
-}
-
// Return true if the module is in the WarningAllowedProjects.
func warningsAreAllowed(subdir string) bool {
subdir += "/"
@@ -405,10 +392,6 @@
if ctx.apexVariationName() != "" {
flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_APEX__")
- if compiler.useApexNameMacro() {
- flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_APEX_"+makeDefineString(ctx.apexVariationName())+"__")
- flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_APEX_NAME__='\""+ctx.apexVariationName()+"\"'")
- }
if ctx.Device() {
flags.Global.CommonFlags = append(flags.Global.CommonFlags,
fmt.Sprintf("-D__ANDROID_APEX_MIN_SDK_VERSION__=%d",
@@ -634,10 +617,6 @@
return false
}
-func (compiler *baseCompiler) uniqueApexVariations() bool {
- return compiler.useApexNameMacro()
-}
-
var invalidDefineCharRegex = regexp.MustCompile("[^a-zA-Z0-9_]")
// makeDefineString transforms a name of an APEX module into a value to be used as value for C define
diff --git a/cc/config/global.go b/cc/config/global.go
index ba10491..6108d3d 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -270,8 +270,8 @@
// prebuilts/clang default settings.
ClangDefaultBase = "prebuilts/clang/host"
- ClangDefaultVersion = "clang-r433403"
- ClangDefaultShortVersion = "13.0.2"
+ ClangDefaultVersion = "clang-r433403b"
+ ClangDefaultShortVersion = "13.0.3"
// Directories with warnings from Android.bp files.
WarningAllowedProjects = []string{
@@ -366,28 +366,12 @@
exportStringStaticVariable("CLANG_DEFAULT_VERSION", ClangDefaultVersion)
exportStringStaticVariable("CLANG_DEFAULT_SHORT_VERSION", ClangDefaultShortVersion)
- pctx.SourcePathVariable("ClangDefaultBase", ClangDefaultBase)
- pctx.VariableFunc("ClangBase", func(ctx android.PackageVarContext) string {
- if override := ctx.Config().Getenv("LLVM_PREBUILTS_BASE"); override != "" {
- return override
- }
- return "${ClangDefaultBase}"
- })
- pctx.VariableFunc("ClangVersion", func(ctx android.PackageVarContext) string {
- if override := ctx.Config().Getenv("LLVM_PREBUILTS_VERSION"); override != "" {
- return override
- }
- return ClangDefaultVersion
- })
+ pctx.StaticVariableWithEnvOverride("ClangBase", "LLVM_PREBUILTS_BASE", ClangDefaultBase)
+ pctx.StaticVariableWithEnvOverride("ClangVersion", "LLVM_PREBUILTS_VERSION", ClangDefaultVersion)
pctx.StaticVariable("ClangPath", "${ClangBase}/${HostPrebuiltTag}/${ClangVersion}")
pctx.StaticVariable("ClangBin", "${ClangPath}/bin")
- pctx.VariableFunc("ClangShortVersion", func(ctx android.PackageVarContext) string {
- if override := ctx.Config().Getenv("LLVM_RELEASE_VERSION"); override != "" {
- return override
- }
- return ClangDefaultShortVersion
- })
+ pctx.StaticVariableWithEnvOverride("ClangShortVersion", "LLVM_RELEASE_VERSION", ClangDefaultShortVersion)
pctx.StaticVariable("ClangAsanLibDir", "${ClangBase}/linux-x86/${ClangVersion}/lib64/clang/${ClangShortVersion}/lib/linux")
// These are tied to the version of LLVM directly in external/llvm, so they might trail the host prebuilts
@@ -421,3 +405,29 @@
}
var HostPrebuiltTag = pctx.VariableConfigMethod("HostPrebuiltTag", android.Config.PrebuiltOS)
+
+func ClangPath(ctx android.PathContext, file string) android.SourcePath {
+ type clangToolKey string
+
+ key := android.NewCustomOnceKey(clangToolKey(file))
+
+ return ctx.Config().OnceSourcePath(key, func() android.SourcePath {
+ return clangPath(ctx).Join(ctx, file)
+ })
+}
+
+var clangPathKey = android.NewOnceKey("clangPath")
+
+func clangPath(ctx android.PathContext) android.SourcePath {
+ return ctx.Config().OnceSourcePath(clangPathKey, func() android.SourcePath {
+ clangBase := ClangDefaultBase
+ if override := ctx.Config().Getenv("LLVM_PREBUILTS_BASE"); override != "" {
+ clangBase = override
+ }
+ clangVersion := ClangDefaultVersion
+ if override := ctx.Config().Getenv("LLVM_PREBUILTS_VERSION"); override != "" {
+ clangVersion = override
+ }
+ return android.PathForSource(ctx, clangBase, ctx.Config().PrebuiltOS(), clangVersion)
+ })
+}
diff --git a/cc/config/x86_darwin_host.go b/cc/config/x86_darwin_host.go
index 0bb1a81..ecdcbde 100644
--- a/cc/config/x86_darwin_host.go
+++ b/cc/config/x86_darwin_host.go
@@ -113,6 +113,10 @@
pctx.StaticVariable("DarwinYasmFlags", "-f macho -m amd64")
}
+func MacStripPath(ctx android.PathContext) string {
+ return getMacTools(ctx).stripPath
+}
+
type macPlatformTools struct {
once sync.Once
err error
@@ -125,7 +129,7 @@
var macTools = &macPlatformTools{}
-func getMacTools(ctx android.PackageVarContext) *macPlatformTools {
+func getMacTools(ctx android.PathContext) *macPlatformTools {
macTools.once.Do(func() {
xcrunTool := "/usr/bin/xcrun"
@@ -170,7 +174,7 @@
macTools.toolPath = filepath.Dir(xcrun("--find", "ld"))
})
if macTools.err != nil {
- ctx.Errorf("%q", macTools.err)
+ android.ReportPathErrorf(ctx, "%q", macTools.err)
}
return macTools
}
diff --git a/cc/lto.go b/cc/lto.go
index d9a0118..6d55579 100644
--- a/cc/lto.go
+++ b/cc/lto.go
@@ -49,8 +49,9 @@
// Dep properties indicate that this module needs to be built with LTO
// since it is an object dependency of an LTO module.
- FullDep bool `blueprint:"mutated"`
- ThinDep bool `blueprint:"mutated"`
+ FullDep bool `blueprint:"mutated"`
+ ThinDep bool `blueprint:"mutated"`
+ NoLtoDep bool `blueprint:"mutated"`
// Use clang lld instead of gnu ld.
Use_clang_lld *bool
@@ -70,15 +71,6 @@
func (lto *lto) begin(ctx BaseModuleContext) {
if ctx.Config().IsEnvTrue("DISABLE_LTO") {
lto.Properties.Lto.Never = proptools.BoolPtr(true)
- } else if ctx.Config().IsEnvTrue("GLOBAL_THINLTO") {
- staticLib := ctx.static() && !ctx.staticBinary()
- hostBin := ctx.Host()
- vndk := ctx.isVndk() // b/169217596
- if !staticLib && !hostBin && !vndk {
- if !lto.Never() && !lto.FullLTO() {
- lto.Properties.Lto.Thin = proptools.BoolPtr(true)
- }
- }
}
}
@@ -96,22 +88,27 @@
return flags
}
- if lto.LTO() {
- var ltoFlag string
+ if lto.LTO(ctx) {
+ var ltoCFlag string
+ var ltoLdFlag string
if lto.ThinLTO() {
- ltoFlag = "-flto=thin -fsplit-lto-unit"
+ ltoCFlag = "-flto=thin -fsplit-lto-unit"
+ } else if lto.FullLTO() {
+ ltoCFlag = "-flto"
} else {
- ltoFlag = "-flto"
+ ltoCFlag = "-flto=thin -fsplit-lto-unit"
+ ltoLdFlag = "-Wl,--lto-O0"
}
- flags.Local.CFlags = append(flags.Local.CFlags, ltoFlag)
- flags.Local.LdFlags = append(flags.Local.LdFlags, ltoFlag)
+ flags.Local.CFlags = append(flags.Local.CFlags, ltoCFlag)
+ flags.Local.LdFlags = append(flags.Local.LdFlags, ltoCFlag)
+ flags.Local.LdFlags = append(flags.Local.LdFlags, ltoLdFlag)
if Bool(lto.Properties.Whole_program_vtables) {
flags.Local.CFlags = append(flags.Local.CFlags, "-fwhole-program-vtables")
}
- if lto.ThinLTO() && ctx.Config().IsEnvTrue("USE_THINLTO_CACHE") && lto.useClangLld(ctx) {
+ if (lto.DefaultThinLTO(ctx) || lto.ThinLTO()) && ctx.Config().IsEnvTrue("USE_THINLTO_CACHE") && lto.useClangLld(ctx) {
// Set appropriate ThinLTO cache policy
cacheDirFormat := "-Wl,--thinlto-cache-dir="
cacheDir := android.PathForOutput(ctx, "thinlto-cache").String()
@@ -134,33 +131,40 @@
return flags
}
-// Can be called with a null receiver
-func (lto *lto) LTO() bool {
- if lto == nil || lto.Never() {
- return false
- }
+func (lto *lto) LTO(ctx BaseModuleContext) bool {
+ return lto.ThinLTO() || lto.FullLTO() || lto.DefaultThinLTO(ctx)
+}
- return lto.FullLTO() || lto.ThinLTO()
+func (lto *lto) DefaultThinLTO(ctx BaseModuleContext) bool {
+ host := ctx.Host()
+ vndk := ctx.isVndk() // b/169217596
+ return GlobalThinLTO(ctx) && !lto.Never() && !host && !vndk
}
func (lto *lto) FullLTO() bool {
- return Bool(lto.Properties.Lto.Full)
+ return lto != nil && Bool(lto.Properties.Lto.Full)
}
func (lto *lto) ThinLTO() bool {
- return Bool(lto.Properties.Lto.Thin)
+ return lto != nil && Bool(lto.Properties.Lto.Thin)
}
-// Is lto.never explicitly set to true?
func (lto *lto) Never() bool {
- return Bool(lto.Properties.Lto.Never)
+ return lto != nil && Bool(lto.Properties.Lto.Never)
+}
+
+func GlobalThinLTO(ctx android.BaseModuleContext) bool {
+ return ctx.Config().IsEnvTrue("GLOBAL_THINLTO")
}
// Propagate lto requirements down from binaries
func ltoDepsMutator(mctx android.TopDownMutatorContext) {
- if m, ok := mctx.Module().(*Module); ok && m.lto.LTO() {
+ globalThinLTO := GlobalThinLTO(mctx)
+
+ if m, ok := mctx.Module().(*Module); ok {
full := m.lto.FullLTO()
thin := m.lto.ThinLTO()
+ never := m.lto.Never()
if full && thin {
mctx.PropertyErrorf("LTO", "FullLTO and ThinLTO are mutually exclusive")
}
@@ -180,14 +184,16 @@
}
}
- if dep, ok := dep.(*Module); ok && dep.lto != nil &&
- !dep.lto.Never() {
+ if dep, ok := dep.(*Module); ok {
if full && !dep.lto.FullLTO() {
dep.lto.Properties.FullDep = true
}
- if thin && !dep.lto.ThinLTO() {
+ if !globalThinLTO && thin && !dep.lto.ThinLTO() {
dep.lto.Properties.ThinDep = true
}
+ if globalThinLTO && never && !dep.lto.Never() {
+ dep.lto.Properties.NoLtoDep = true
+ }
}
// Recursively walk static dependencies
@@ -198,6 +204,8 @@
// Create lto variants for modules that need them
func ltoMutator(mctx android.BottomUpMutatorContext) {
+ globalThinLTO := GlobalThinLTO(mctx)
+
if m, ok := mctx.Module().(*Module); ok && m.lto != nil {
// Create variations for LTO types required as static
// dependencies
@@ -205,18 +213,25 @@
if m.lto.Properties.FullDep && !m.lto.FullLTO() {
variationNames = append(variationNames, "lto-full")
}
- if m.lto.Properties.ThinDep && !m.lto.ThinLTO() {
+ if !globalThinLTO && m.lto.Properties.ThinDep && !m.lto.ThinLTO() {
variationNames = append(variationNames, "lto-thin")
}
+ if globalThinLTO && m.lto.Properties.NoLtoDep && !m.lto.Never() {
+ variationNames = append(variationNames, "lto-none")
+ }
// Use correct dependencies if LTO property is explicitly set
// (mutually exclusive)
if m.lto.FullLTO() {
mctx.SetDependencyVariation("lto-full")
}
- if m.lto.ThinLTO() {
+ if !globalThinLTO && m.lto.ThinLTO() {
mctx.SetDependencyVariation("lto-thin")
}
+ // Never must be the last, it overrides Thin or Full.
+ if globalThinLTO && m.lto.Never() {
+ mctx.SetDependencyVariation("lto-none")
+ }
if len(variationNames) > 1 {
modules := mctx.CreateVariations(variationNames...)
@@ -232,16 +247,18 @@
// LTO properties for dependencies
if name == "lto-full" {
variation.lto.Properties.Lto.Full = proptools.BoolPtr(true)
- variation.lto.Properties.Lto.Thin = proptools.BoolPtr(false)
}
if name == "lto-thin" {
- variation.lto.Properties.Lto.Full = proptools.BoolPtr(false)
variation.lto.Properties.Lto.Thin = proptools.BoolPtr(true)
}
+ if name == "lto-none" {
+ variation.lto.Properties.Lto.Never = proptools.BoolPtr(true)
+ }
variation.Properties.PreventInstall = true
variation.Properties.HideFromMake = true
variation.lto.Properties.FullDep = false
variation.lto.Properties.ThinDep = false
+ variation.lto.Properties.NoLtoDep = false
}
}
}
diff --git a/java/androidmk.go b/java/androidmk.go
index 537159e..eca5caa 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -60,6 +60,11 @@
func (library *Library) AndroidMkEntries() []android.AndroidMkEntries {
var entriesList []android.AndroidMkEntries
+ if library.Os() == android.Windows {
+ // Make does not support Windows Java modules
+ return nil
+ }
+
if library.hideApexVariantFromMake {
// For a java library built for an APEX, we don't need a Make module for itself. Otherwise, it
// will conflict with the platform variant because they have the same module name in the
@@ -250,6 +255,10 @@
}
func (binary *Binary) AndroidMkEntries() []android.AndroidMkEntries {
+ if binary.Os() == android.Windows {
+ // Make does not support Windows Java modules
+ return nil
+ }
if !binary.isWrapperVariant {
return []android.AndroidMkEntries{android.AndroidMkEntries{
diff --git a/java/device_host_converter.go b/java/device_host_converter.go
index 39fb04a..4abdcc6 100644
--- a/java/device_host_converter.go
+++ b/java/device_host_converter.go
@@ -118,7 +118,7 @@
TransformJarsToJar(ctx, outputFile, "combine", d.implementationAndResourceJars,
android.OptionalPath{}, false, nil, nil)
d.combinedImplementationJar = outputFile
- } else {
+ } else if len(d.implementationAndResourceJars) == 1 {
d.combinedImplementationJar = d.implementationAndResourceJars[0]
}
@@ -127,7 +127,7 @@
TransformJarsToJar(ctx, outputFile, "turbine combine", d.headerJars,
android.OptionalPath{}, false, nil, []string{"META-INF/TRANSITIVE"})
d.combinedHeaderJar = outputFile
- } else {
+ } else if len(d.headerJars) == 1 {
d.combinedHeaderJar = d.headerJars[0]
}
@@ -174,7 +174,9 @@
return android.AndroidMkData{
Class: "JAVA_LIBRARIES",
OutputFile: android.OptionalPathForPath(d.combinedImplementationJar),
- Include: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
+ // Make does not support Windows Java modules
+ Disabled: d.Os() == android.Windows,
+ Include: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
Extra: []android.AndroidMkExtraFunc{
func(w io.Writer, outputFile android.Path) {
fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true")
diff --git a/java/java.go b/java/java.go
index 287bcfa..29f31e5 100644
--- a/java/java.go
+++ b/java/java.go
@@ -532,6 +532,14 @@
return false
}
+// Sets `dexer.dexProperties.Uncompress_dex` to the proper value.
+func setUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter, dexer *dexer) {
+ if dexer.dexProperties.Uncompress_dex == nil {
+ // If the value was not force-set by the user, use reasonable default based on the module.
+ dexer.dexProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, dexpreopter))
+ }
+}
+
func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
j.sdkVersion = j.SdkVersion(ctx)
j.minSdkVersion = j.MinSdkVersion(ctx)
@@ -545,10 +553,7 @@
j.dexpreopter.installPath = j.dexpreopter.getInstallPath(
ctx, android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar"))
j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary
- if j.dexProperties.Uncompress_dex == nil {
- // If the value was not force-set by the user, use reasonable default based on the module.
- j.dexProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, &j.dexpreopter))
- }
+ setUncompressDex(ctx, &j.dexpreopter, &j.dexer)
j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex
j.classLoaderContexts = j.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
j.compile(ctx, nil)
@@ -565,10 +570,6 @@
j.installFile = ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
j.Stem()+".jar", j.outputFile, extraInstallDeps...)
}
-
- if ctx.Windows() {
- j.HideFromMake()
- }
}
func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) {
@@ -1135,10 +1136,6 @@
j.binaryFile = ctx.InstallExecutable(android.PathForModuleInstall(ctx, "bin"),
ctx.ModuleName()+ext, j.wrapperFile)
}
-
- if ctx.Windows() {
- j.HideFromMake()
- }
}
func (j *Binary) DepsMutator(ctx android.BottomUpMutatorContext) {
@@ -1401,16 +1398,13 @@
installPath := android.PathForModuleInPartitionInstall(ctx, "apex", ai.ApexVariationName, apexRootRelativePathToJavaLib(j.BaseModuleName()))
j.dexJarInstallFile = installPath
- // Initialize the hiddenapi structure.
- j.initHiddenAPI(ctx, dexJarFile, outputFile, nil)
-
j.dexpreopter.installPath = j.dexpreopter.getInstallPath(ctx, installPath)
- if j.dexProperties.Uncompress_dex == nil {
- // If the value was not force-set by the user, use reasonable default based on the module.
- j.dexProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, &j.dexpreopter))
- }
+ setUncompressDex(ctx, &j.dexpreopter, &j.dexer)
j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex
j.dexpreopt(ctx, dexOutputPath)
+
+ // Initialize the hiddenapi structure.
+ j.initHiddenAPI(ctx, dexJarFile, outputFile, j.dexProperties.Uncompress_dex)
} else {
// This should never happen as a variant for a prebuilt_apex is only created if the
// prebuilt_apex has been configured to export the java library dex file.
@@ -1430,10 +1424,7 @@
j.dexpreopter.installPath = j.dexpreopter.getInstallPath(
ctx, android.PathForModuleInstall(ctx, "framework", jarName))
- if j.dexProperties.Uncompress_dex == nil {
- // If the value was not force-set by the user, use reasonable default based on the module.
- j.dexProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, &j.dexpreopter))
- }
+ setUncompressDex(ctx, &j.dexpreopter, &j.dexer)
j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex
var dexOutputFile android.OutputPath
diff --git a/rust/compiler.go b/rust/compiler.go
index 1ce71f6..cada985 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -449,6 +449,10 @@
// Returns the Path for the main source file along with Paths for generated source files from modules listed in srcs.
func srcPathFromModuleSrcs(ctx ModuleContext, srcs []string) (android.Path, android.Paths) {
+ if len(srcs) == 0 {
+ ctx.PropertyErrorf("srcs", "srcs must not be empty")
+ }
+
// The srcs can contain strings with prefix ":".
// They are dependent modules of this module, with android.SourceDepTag.
// They are not the main source file compiled by rustc.
diff --git a/rust/compiler_test.go b/rust/compiler_test.go
index f589b69..ec6829a 100644
--- a/rust/compiler_test.go
+++ b/rust/compiler_test.go
@@ -98,6 +98,41 @@
}`)
}
+// Test that we reject _no_ source files.
+func TestEnforceMissingSourceFiles(t *testing.T) {
+
+ singleSrcError := "srcs must not be empty"
+
+ // Test libraries
+ testRustError(t, singleSrcError, `
+ rust_library_host {
+ name: "foo-bar-library",
+ crate_name: "foo",
+ }`)
+
+ // Test binaries
+ testRustError(t, singleSrcError, `
+ rust_binary_host {
+ name: "foo-bar-binary",
+ crate_name: "foo",
+ }`)
+
+ // Test proc_macros
+ testRustError(t, singleSrcError, `
+ rust_proc_macro {
+ name: "foo-bar-proc-macro",
+ crate_name: "foo",
+ }`)
+
+ // Test prebuilts
+ testRustError(t, singleSrcError, `
+ rust_prebuilt_dylib {
+ name: "foo-bar-prebuilt",
+ crate_name: "foo",
+ host_supported: true,
+ }`)
+}
+
// Test environment vars for Cargo compat are set.
func TestCargoCompat(t *testing.T) {
ctx := testRust(t, `