Merge "Add android_sdk_repo_host to build platform-tools&build-tools"
This commit is contained in:
commit
adf2b3e68f
15 changed files with 586 additions and 45 deletions
|
@ -62,6 +62,7 @@ toolchain_library {
|
|||
},
|
||||
},
|
||||
notice: ":mingw-libwinpthread-notice",
|
||||
licenses: ["winpthreads_license"],
|
||||
}
|
||||
|
||||
kernel_headers {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
effectiveLicenseFiles: &licenseFiles,
|
||||
}
|
||||
m.packagingSpecs = append(m.packagingSpecs, spec)
|
||||
return spec
|
||||
|
|
|
@ -150,6 +150,7 @@ func createTrebleRules() []Rule {
|
|||
|
||||
func createJavaDeviceForHostRules() []Rule {
|
||||
javaDeviceForHostProjectsAllowedList := []string{
|
||||
"development/build",
|
||||
"external/guava",
|
||||
"external/robolectric-shadows",
|
||||
"frameworks/layoutlib",
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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 {
|
||||
|
|
22
android_sdk/Android.bp
Normal file
22
android_sdk/Android.bp
Normal file
|
@ -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"],
|
||||
}
|
295
android_sdk/sdk_repo_host.go
Normal file
295
android_sdk/sdk_repo_host.go
Normal file
|
@ -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:]
|
||||
}
|
124
android_sdk/sdk_repo_host_test.go
Normal file
124
android_sdk/sdk_repo_host_test.go
Normal file
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -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,6 +174,8 @@ func (d *DeviceHostConverter) AndroidMk() android.AndroidMkData {
|
|||
return android.AndroidMkData{
|
||||
Class: "JAVA_LIBRARIES",
|
||||
OutputFile: android.OptionalPathForPath(d.combinedImplementationJar),
|
||||
// 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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue