Add android_sdk_repo_host to build platform-tools&build-tools
The Android SDK has been built with Make up until now, monolithically,
then split up into several sdk-repo zip files for different purposes.
The Mac and Windows SDKs really only need to contain the platform-tools
and build-tools pieces, but due to this monolithic sdk zip, we had to
build the whole SDK first.
This adds an `android_sdk_repo_host` module that can build these
platform-tools and build-tools zips.
Bug: 187222815
Change-Id: I55809e1d7447dd65e22461f921b2b8abb6d5f822
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/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/cc/config/global.go b/cc/config/global.go
index ba10491..69639e0 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -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/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..7f7d88f 100644
--- a/java/java.go
+++ b/java/java.go
@@ -565,10 +565,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 +1131,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) {