diff --git a/Android.bp b/Android.bp index d6260b400..b5ddaa4e4 100644 --- a/Android.bp +++ b/Android.bp @@ -62,6 +62,7 @@ toolchain_library { }, }, notice: ":mingw-libwinpthread-notice", + licenses: ["winpthreads_license"], } kernel_headers { diff --git a/android/androidmk.go b/android/androidmk.go index 967c550d6..feaef1f69 100644 --- a/android/androidmk.go +++ b/android/androidmk.go @@ -836,6 +836,7 @@ func translateAndroidModule(ctx SingletonContext, w io.Writer, mod blueprint.Mod 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 327e6ae20..02706eccb 100644 --- a/android/module.go +++ b/android/module.go @@ -2818,11 +2818,13 @@ func (m *moduleContext) PackageFile(installPath InstallPath, name string, srcPat } 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 b8517a986..9098a718e 100644 --- a/android/neverallow.go +++ b/android/neverallow.go @@ -150,6 +150,7 @@ func createTrebleRules() []Rule { 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 07cf3e4d0..d8cfaf2a1 100644 --- a/android/notices.go +++ b/android/notices.go @@ -100,3 +100,56 @@ func BuildNoticeOutput(ctx ModuleContext, installPath InstallPath, installFilena 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 906582667..e3a0b54be 100644 --- a/android/packaging.go +++ b/android/packaging.go @@ -38,6 +38,8 @@ type PackagingSpec struct { // Whether relPathInPackage should be marked as executable or not executable bool + + effectiveLicenseFiles *Paths } // Get file name of installed package @@ -54,6 +56,17 @@ func (p *PackagingSpec) RelPathInPackage() string { 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 @@ func (p *PackagingBase) GatherPackagingSpecs(ctx ModuleContext) map[string]Packa 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 @@ func (p *PackagingBase) CopyDepsToZip(ctx ModuleContext, zipOut WritablePath) (e } } + 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 4a82f23d3..5c54e9436 100644 --- a/android/variable.go +++ b/android/variable.go @@ -40,6 +40,7 @@ type variableProperties struct { Platform_sdk_version struct { Asflags []string Cflags []string + Cmd *string } Platform_sdk_version_or_codename struct { @@ -50,6 +51,10 @@ type variableProperties struct { 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 000000000..e686d59ff --- /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 000000000..a76da8b45 --- /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 000000000..0688921f4 --- /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 ba104916b..69639e0ea 100644 --- a/cc/config/global.go +++ b/cc/config/global.go @@ -366,28 +366,12 @@ func init() { 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 @@ func init() { } 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 0bb1a816e..ecdcbde15 100644 --- a/cc/config/x86_darwin_host.go +++ b/cc/config/x86_darwin_host.go @@ -113,6 +113,10 @@ func init() { 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 @@ type macPlatformTools struct { 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 @@ func getMacTools(ctx android.PackageVarContext) *macPlatformTools { 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 537159ef3..eca5caacb 100644 --- a/java/androidmk.go +++ b/java/androidmk.go @@ -60,6 +60,11 @@ func (library *Library) AndroidMkEntriesHostDex() android.AndroidMkEntries { 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 (prebuilt *AARImport) AndroidMkEntries() []android.AndroidMkEntries { } 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 39fb04a8e..4abdcc6e9 100644 --- a/java/device_host_converter.go +++ b/java/device_host_converter.go @@ -118,7 +118,7 @@ func (d *DeviceHostConverter) GenerateAndroidBuildActions(ctx android.ModuleCont 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 @@ func (d *DeviceHostConverter) GenerateAndroidBuildActions(ctx android.ModuleCont 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 @@ func (d *DeviceHostConverter) AndroidMk() android.AndroidMkData { 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 287bcfaeb..7f7d88f7c 100644 --- a/java/java.go +++ b/java/java.go @@ -565,10 +565,6 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { 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 @@ func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) { 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) {