Merge "Add symlinks to sh_binary in soong"
diff --git a/android/hooks.go b/android/hooks.go
index 1e5ff21..604cb9c 100644
--- a/android/hooks.go
+++ b/android/hooks.go
@@ -75,7 +75,7 @@
type InstallHookContext interface {
ModuleContext
- Path() OutputPath
+ Path() InstallPath
Symlink() bool
}
@@ -89,11 +89,11 @@
type installHookContext struct {
ModuleContext
- path OutputPath
+ path InstallPath
symlink bool
}
-func (x *installHookContext) Path() OutputPath {
+func (x *installHookContext) Path() InstallPath {
return x.path
}
@@ -101,7 +101,7 @@
return x.symlink
}
-func (x *hooks) runInstallHooks(ctx ModuleContext, path OutputPath, symlink bool) {
+func (x *hooks) runInstallHooks(ctx ModuleContext, path InstallPath, symlink bool) {
if len(x.install) > 0 {
mctx := &installHookContext{
ModuleContext: ctx,
diff --git a/android/module.go b/android/module.go
index a1a01a5..6988ac0 100644
--- a/android/module.go
+++ b/android/module.go
@@ -147,16 +147,17 @@
ExpandSource(srcFile, prop string) Path
ExpandOptionalSource(srcFile *string, prop string) OptionalPath
- InstallExecutable(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
- InstallFile(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
- InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath
- InstallAbsoluteSymlink(installPath OutputPath, name string, absPath string) OutputPath
+ InstallExecutable(installPath InstallPath, name string, srcPath Path, deps ...Path) InstallPath
+ InstallFile(installPath InstallPath, name string, srcPath Path, deps ...Path) InstallPath
+ InstallSymlink(installPath InstallPath, name string, srcPath InstallPath) InstallPath
+ InstallAbsoluteSymlink(installPath InstallPath, name string, absPath string) InstallPath
CheckbuildFile(srcPath Path)
InstallInData() bool
InstallInTestcases() bool
InstallInSanitizerDir() bool
InstallInRecovery() bool
+ InstallInRoot() bool
InstallBypassMake() bool
RequiredModuleNames() []string
@@ -196,6 +197,7 @@
InstallInTestcases() bool
InstallInSanitizerDir() bool
InstallInRecovery() bool
+ InstallInRoot() bool
InstallBypassMake() bool
SkipInstall()
ExportedToMake() bool
@@ -846,6 +848,10 @@
return Bool(m.commonProperties.Recovery)
}
+func (m *ModuleBase) InstallInRoot() bool {
+ return false
+}
+
func (m *ModuleBase) InstallBypassMake() bool {
return false
}
@@ -1183,6 +1189,12 @@
func (m *moduleContext) Rule(pctx PackageContext, name string, params blueprint.RuleParams,
argNames ...string) blueprint.Rule {
+ if m.config.UseGoma() && params.Pool == nil {
+ // When USE_GOMA=true is set and the rule is not supported by goma, restrict jobs to the
+ // local parallelism value
+ params.Pool = localPool
+ }
+
rule := m.bp.Rule(pctx.PackageContext, name, params, argNames...)
if m.config.captureBuild {
@@ -1522,11 +1534,15 @@
return m.module.InstallInRecovery()
}
+func (m *moduleContext) InstallInRoot() bool {
+ return m.module.InstallInRoot()
+}
+
func (m *moduleContext) InstallBypassMake() bool {
return m.module.InstallBypassMake()
}
-func (m *moduleContext) skipInstall(fullInstallPath OutputPath) bool {
+func (m *moduleContext) skipInstall(fullInstallPath InstallPath) bool {
if m.module.base().commonProperties.SkipInstall {
return true
}
@@ -1551,18 +1567,18 @@
return false
}
-func (m *moduleContext) InstallFile(installPath OutputPath, name string, srcPath Path,
- deps ...Path) OutputPath {
+func (m *moduleContext) InstallFile(installPath InstallPath, name string, srcPath Path,
+ deps ...Path) InstallPath {
return m.installFile(installPath, name, srcPath, Cp, deps)
}
-func (m *moduleContext) InstallExecutable(installPath OutputPath, name string, srcPath Path,
- deps ...Path) OutputPath {
+func (m *moduleContext) InstallExecutable(installPath InstallPath, name string, srcPath Path,
+ deps ...Path) InstallPath {
return m.installFile(installPath, name, srcPath, CpExecutable, deps)
}
-func (m *moduleContext) installFile(installPath OutputPath, name string, srcPath Path,
- rule blueprint.Rule, deps []Path) OutputPath {
+func (m *moduleContext) installFile(installPath InstallPath, name string, srcPath Path,
+ rule blueprint.Rule, deps []Path) InstallPath {
fullInstallPath := installPath.Join(m, name)
m.module.base().hooks.runInstallHooks(m, fullInstallPath, false)
@@ -1597,7 +1613,7 @@
return fullInstallPath
}
-func (m *moduleContext) InstallSymlink(installPath OutputPath, name string, srcPath OutputPath) OutputPath {
+func (m *moduleContext) InstallSymlink(installPath InstallPath, name string, srcPath InstallPath) InstallPath {
fullInstallPath := installPath.Join(m, name)
m.module.base().hooks.runInstallHooks(m, fullInstallPath, true)
@@ -1626,7 +1642,7 @@
// installPath/name -> absPath where absPath might be a path that is available only at runtime
// (e.g. /apex/...)
-func (m *moduleContext) InstallAbsoluteSymlink(installPath OutputPath, name string, absPath string) OutputPath {
+func (m *moduleContext) InstallAbsoluteSymlink(installPath InstallPath, name string, absPath string) InstallPath {
fullInstallPath := installPath.Join(m, name)
m.module.base().hooks.runInstallHooks(m, fullInstallPath, true)
diff --git a/android/notices.go b/android/notices.go
index 7b61d65..bf273b5 100644
--- a/android/notices.go
+++ b/android/notices.go
@@ -60,7 +60,7 @@
})
}
-func BuildNoticeOutput(ctx ModuleContext, installPath OutputPath, installFilename string,
+func BuildNoticeOutput(ctx ModuleContext, installPath InstallPath, installFilename string,
noticePaths []Path) NoticeOutputs {
// Merge all NOTICE files into one.
// TODO(jungjw): We should just produce a well-formatted NOTICE.html file in a single pass.
diff --git a/android/package_ctx.go b/android/package_ctx.go
index 00b99ff..548450e 100644
--- a/android/package_ctx.go
+++ b/android/package_ctx.go
@@ -104,7 +104,8 @@
}
// RuleFunc wraps blueprint.PackageContext.RuleFunc, converting the interface{} config
-// argument to a Context that supports Config().
+// argument to a Context that supports Config(), and provides a default Pool if none is
+// specified.
func (p PackageContext) RuleFunc(name string,
f func(PackageRuleContext) blueprint.RuleParams, argNames ...string) blueprint.Rule {
@@ -114,6 +115,11 @@
if len(ctx.errors) > 0 {
return params, ctx.errors[0]
}
+ if ctx.Config().UseGoma() && params.Pool == nil {
+ // When USE_GOMA=true is set and the rule is not supported by goma, restrict jobs to the
+ // local parallelism value
+ params.Pool = localPool
+ }
return params, nil
}, argNames...)
}
@@ -234,10 +240,16 @@
})
}
-// AndroidStaticRule wraps blueprint.StaticRule and provides a default Pool if none is specified
+// AndroidStaticRule is an alias for StaticRule.
func (p PackageContext) AndroidStaticRule(name string, params blueprint.RuleParams,
argNames ...string) blueprint.Rule {
- return p.AndroidRuleFunc(name, func(PackageRuleContext) blueprint.RuleParams {
+ return p.StaticRule(name, params, argNames...)
+}
+
+// StaticRule wraps blueprint.StaticRule and provides a default Pool if none is specified.
+func (p PackageContext) StaticRule(name string, params blueprint.RuleParams,
+ argNames ...string) blueprint.Rule {
+ return p.RuleFunc(name, func(PackageRuleContext) blueprint.RuleParams {
return params
}, argNames...)
}
@@ -245,18 +257,6 @@
// AndroidGomaStaticRule wraps blueprint.StaticRule but uses goma's parallelism if goma is enabled
func (p PackageContext) AndroidGomaStaticRule(name string, params blueprint.RuleParams,
argNames ...string) blueprint.Rule {
- return p.StaticRule(name, params, argNames...)
-}
-
-func (p PackageContext) AndroidRuleFunc(name string,
- f func(PackageRuleContext) blueprint.RuleParams, argNames ...string) blueprint.Rule {
- return p.RuleFunc(name, func(ctx PackageRuleContext) blueprint.RuleParams {
- params := f(ctx)
- if ctx.Config().UseGoma() && params.Pool == nil {
- // When USE_GOMA=true is set and the rule is not supported by goma, restrict jobs to the
- // local parallelism value
- params.Pool = localPool
- }
- return params
- }, argNames...)
+ // bypass android.PackageContext.StaticRule so that Pool does not get set to local_pool.
+ return p.PackageContext.StaticRule(name, params, argNames...)
}
diff --git a/android/paths.go b/android/paths.go
index 8bd2c61..8dbb086 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -47,6 +47,7 @@
InstallInTestcases() bool
InstallInSanitizerDir() bool
InstallInRecovery() bool
+ InstallInRoot() bool
InstallBypassMake() bool
}
@@ -792,7 +793,7 @@
return OptionalPathForPath(PathForSource(ctx, relPath))
}
-// OutputPath is a Path representing a file path rooted from the build directory
+// OutputPath is a Path representing an intermediates file path rooted from the build directory
type OutputPath struct {
basePath
}
@@ -820,17 +821,6 @@
return OutputPath{basePath{path, ctx.Config(), ""}}
}
-// pathForInstallInMakeDir is used by PathForModuleInstall when the module returns true
-// for InstallBypassMake to produce an OutputPath that installs to $OUT_DIR instead of
-// $OUT_DIR/soong.
-func pathForInstallInMakeDir(ctx PathContext, pathComponents ...string) OutputPath {
- path, err := validatePath(pathComponents...)
- if err != nil {
- reportPathError(ctx, err)
- }
- return OutputPath{basePath{"../" + path, ctx.Config(), ""}}
-}
-
// PathsForOutput returns Paths rooted from buildDir
func PathsForOutput(ctx PathContext, paths []string) WritablePaths {
ret := make(WritablePaths, len(paths))
@@ -846,10 +836,6 @@
return filepath.Join(p.config.buildDir, p.path)
}
-func (p OutputPath) RelPathString() string {
- return p.path
-}
-
// Join creates a new OutputPath with paths... joined with the current path. The
// provided paths... may not use '..' to escape from the current path.
func (p OutputPath) Join(ctx PathContext, paths ...string) OutputPath {
@@ -1118,9 +1104,44 @@
return ModuleResPath{PathForModuleOut(ctx, "res", p)}
}
+// InstallPath is a Path representing a installed file path rooted from the build directory
+type InstallPath struct {
+ basePath
+
+ baseDir string // "../" for Make paths to convert "out/soong" to "out", "" for Soong paths
+}
+
+func (p InstallPath) writablePath() {}
+
+func (p InstallPath) String() string {
+ return filepath.Join(p.config.buildDir, p.baseDir, p.path)
+}
+
+// Join creates a new InstallPath with paths... joined with the current path. The
+// provided paths... may not use '..' to escape from the current path.
+func (p InstallPath) Join(ctx PathContext, paths ...string) InstallPath {
+ path, err := validatePath(paths...)
+ if err != nil {
+ reportPathError(ctx, err)
+ }
+ return p.withRel(path)
+}
+
+func (p InstallPath) withRel(rel string) InstallPath {
+ p.basePath = p.basePath.withRel(rel)
+ return p
+}
+
+// ToMakePath returns a new InstallPath that points to Make's install directory instead of Soong's,
+// i.e. out/ instead of out/soong/.
+func (p InstallPath) ToMakePath() InstallPath {
+ p.baseDir = "../"
+ return p
+}
+
// PathForModuleInstall returns a Path representing the install path for the
// module appended with paths...
-func PathForModuleInstall(ctx ModuleInstallPathContext, pathComponents ...string) OutputPath {
+func PathForModuleInstall(ctx ModuleInstallPathContext, pathComponents ...string) InstallPath {
var outPaths []string
if ctx.Device() {
partition := modulePartition(ctx)
@@ -1140,13 +1161,30 @@
outPaths = append([]string{"debug"}, outPaths...)
}
outPaths = append(outPaths, pathComponents...)
- if ctx.InstallBypassMake() && ctx.Config().EmbeddedInMake() {
- return pathForInstallInMakeDir(ctx, outPaths...)
+
+ path, err := validatePath(outPaths...)
+ if err != nil {
+ reportPathError(ctx, err)
}
- return PathForOutput(ctx, outPaths...)
+
+ ret := InstallPath{basePath{path, ctx.Config(), ""}, ""}
+ if ctx.InstallBypassMake() && ctx.Config().EmbeddedInMake() {
+ ret = ret.ToMakePath()
+ }
+
+ return ret
}
-func InstallPathToOnDevicePath(ctx PathContext, path OutputPath) string {
+func PathForNdkInstall(ctx PathContext, paths ...string) InstallPath {
+ paths = append([]string{"ndk"}, paths...)
+ path, err := validatePath(paths...)
+ if err != nil {
+ reportPathError(ctx, err)
+ }
+ return InstallPath{basePath{path, ctx.Config(), ""}, ""}
+}
+
+func InstallPathToOnDevicePath(ctx PathContext, path InstallPath) string {
rel := Rel(ctx, PathForOutput(ctx, "target", "product", ctx.Config().DeviceName()).String(), path.String())
return "/" + rel
@@ -1159,8 +1197,12 @@
} else if ctx.InstallInTestcases() {
partition = "testcases"
} else if ctx.InstallInRecovery() {
- // the layout of recovery partion is the same as that of system partition
- partition = "recovery/root/system"
+ if ctx.InstallInRoot() {
+ partition = "recovery/root"
+ } else {
+ // the layout of recovery partion is the same as that of system partition
+ partition = "recovery/root/system"
+ }
} else if ctx.SocSpecific() {
partition = ctx.DeviceConfig().VendorPath()
} else if ctx.DeviceSpecific() {
@@ -1169,6 +1211,8 @@
partition = ctx.DeviceConfig().ProductPath()
} else if ctx.SystemExtSpecific() {
partition = ctx.DeviceConfig().SystemExtPath()
+ } else if ctx.InstallInRoot() {
+ partition = "root"
} else {
partition = "system"
}
diff --git a/android/paths_test.go b/android/paths_test.go
index b66eb1e..2e67272 100644
--- a/android/paths_test.go
+++ b/android/paths_test.go
@@ -204,6 +204,7 @@
inTestcases bool
inSanitizerDir bool
inRecovery bool
+ inRoot bool
}
func (moduleInstallPathContextImpl) Fs() pathtools.FileSystem {
@@ -232,6 +233,10 @@
return m.inRecovery
}
+func (m moduleInstallPathContextImpl) InstallInRoot() bool {
+ return m.inRoot
+}
+
func (m moduleInstallPathContextImpl) InstallBypassMake() bool {
return false
}
@@ -313,6 +318,40 @@
in: []string{"bin", "my_test"},
out: "target/product/test_device/system_ext/bin/my_test",
},
+ {
+ name: "root binary",
+ ctx: &moduleInstallPathContextImpl{
+ baseModuleContext: baseModuleContext{
+ target: deviceTarget,
+ },
+ inRoot: true,
+ },
+ in: []string{"my_test"},
+ out: "target/product/test_device/root/my_test",
+ },
+ {
+ name: "recovery binary",
+ ctx: &moduleInstallPathContextImpl{
+ baseModuleContext: baseModuleContext{
+ target: deviceTarget,
+ },
+ inRecovery: true,
+ },
+ in: []string{"bin/my_test"},
+ out: "target/product/test_device/recovery/root/system/bin/my_test",
+ },
+ {
+ name: "recovery root binary",
+ ctx: &moduleInstallPathContextImpl{
+ baseModuleContext: baseModuleContext{
+ target: deviceTarget,
+ },
+ inRecovery: true,
+ inRoot: true,
+ },
+ in: []string{"my_test"},
+ out: "target/product/test_device/recovery/root/my_test",
+ },
{
name: "system native test binary",
diff --git a/android/prebuilt_etc.go b/android/prebuilt_etc.go
index d29ed16..6c4813b 100644
--- a/android/prebuilt_etc.go
+++ b/android/prebuilt_etc.go
@@ -65,7 +65,7 @@
installDirBase string
// The base install location when soc_specific property is set to true, e.g. "firmware" for prebuilt_firmware.
socInstallDirBase string
- installDirPath OutputPath
+ installDirPath InstallPath
additionalDependencies *Paths
}
@@ -91,7 +91,7 @@
return PathForModuleSrc(ctx, String(p.properties.Src))
}
-func (p *PrebuiltEtc) InstallDirPath() OutputPath {
+func (p *PrebuiltEtc) InstallDirPath() InstallPath {
return p.installDirPath
}
@@ -158,7 +158,7 @@
ExtraEntries: []AndroidMkExtraEntriesFunc{
func(entries *AndroidMkEntries) {
entries.SetString("LOCAL_MODULE_TAGS", "optional")
- entries.SetString("LOCAL_MODULE_PATH", "$(OUT_DIR)/"+p.installDirPath.RelPathString())
+ entries.SetString("LOCAL_MODULE_PATH", p.installDirPath.ToMakePath().String())
entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.outputFilePath.Base())
entries.SetString("LOCAL_UNINSTALLABLE_MODULE", strconv.FormatBool(!p.Installable()))
if p.additionalDependencies != nil {
diff --git a/android/prebuilt_etc_test.go b/android/prebuilt_etc_test.go
index 0a2c7a4..f675ea3 100644
--- a/android/prebuilt_etc_test.go
+++ b/android/prebuilt_etc_test.go
@@ -182,9 +182,9 @@
`)
p := ctx.ModuleForTests("foo.conf", "android_arm64_armv8-a_core").Module().(*PrebuiltEtc)
- expected := "target/product/test_device/system/usr/share/bar"
- if p.installDirPath.RelPathString() != expected {
- t.Errorf("expected %q, got %q", expected, p.installDirPath.RelPathString())
+ expected := buildDir + "/target/product/test_device/system/usr/share/bar"
+ if p.installDirPath.String() != expected {
+ t.Errorf("expected %q, got %q", expected, p.installDirPath.String())
}
}
@@ -199,9 +199,9 @@
buildOS := BuildOs.String()
p := ctx.ModuleForTests("foo.conf", buildOS+"_common").Module().(*PrebuiltEtc)
- expected := filepath.Join("host", config.PrebuiltOS(), "usr", "share", "bar")
- if p.installDirPath.RelPathString() != expected {
- t.Errorf("expected %q, got %q", expected, p.installDirPath.RelPathString())
+ expected := filepath.Join(buildDir, "host", config.PrebuiltOS(), "usr", "share", "bar")
+ if p.installDirPath.String() != expected {
+ t.Errorf("expected %q, got %q", expected, p.installDirPath.String())
}
}
@@ -214,14 +214,14 @@
`)
p := ctx.ModuleForTests("foo.conf", "android_arm64_armv8-a_core").Module().(*PrebuiltEtc)
- expected := "target/product/test_device/system/fonts"
- if p.installDirPath.RelPathString() != expected {
- t.Errorf("expected %q, got %q", expected, p.installDirPath.RelPathString())
+ expected := buildDir + "/target/product/test_device/system/fonts"
+ if p.installDirPath.String() != expected {
+ t.Errorf("expected %q, got %q", expected, p.installDirPath.String())
}
}
func TestPrebuiltFirmwareDirPath(t *testing.T) {
- targetPath := "target/product/test_device"
+ targetPath := buildDir + "/target/product/test_device"
tests := []struct {
description string
config string
@@ -249,7 +249,7 @@
t.Run(tt.description, func(t *testing.T) {
ctx, _ := testPrebuiltEtc(t, tt.config)
p := ctx.ModuleForTests("foo.conf", "android_arm64_armv8-a_core").Module().(*PrebuiltEtc)
- if p.installDirPath.RelPathString() != tt.expectedPath {
+ if p.installDirPath.String() != tt.expectedPath {
t.Errorf("expected %q, got %q", tt.expectedPath, p.installDirPath)
}
})
diff --git a/android/singleton.go b/android/singleton.go
index a59d54a..7f9c216 100644
--- a/android/singleton.go
+++ b/android/singleton.go
@@ -127,6 +127,11 @@
}
func (s *singletonContextAdaptor) Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule {
+ if s.Config().UseGoma() && params.Pool == nil {
+ // When USE_GOMA=true is set and the rule is not supported by goma, restrict jobs to the
+ // local parallelism value
+ params.Pool = localPool
+ }
rule := s.SingletonContext.Rule(pctx.PackageContext, name, params, argNames...)
if s.Config().captureBuild {
s.ruleParams[rule] = params
diff --git a/apex/apex.go b/apex/apex.go
index 2feaa42..81660d5 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -222,12 +222,14 @@
if ab.IsNativeBridgeSupported() {
mctx.PropertyErrorf("native_bridge_supported", "%q doesn't support native bridge binary.", mctx.ModuleType())
}
- vndkVersion := proptools.StringDefault(ab.vndkProperties.Vndk_version, mctx.DeviceConfig().PlatformVndkVersion())
+
+ vndkVersion := proptools.String(ab.vndkProperties.Vndk_version)
+
vndkApexListMutex.Lock()
defer vndkApexListMutex.Unlock()
vndkApexList := vndkApexList(mctx.Config())
if other, ok := vndkApexList[vndkVersion]; ok {
- mctx.PropertyErrorf("vndk_version", "%v is already defined in %q", vndkVersion, other.Name())
+ mctx.PropertyErrorf("vndk_version", "%v is already defined in %q", vndkVersion, other.BaseModuleName())
}
vndkApexList[vndkVersion] = ab
}
@@ -561,8 +563,8 @@
bundleModuleFile android.WritablePath
outputFiles map[apexPackaging]android.WritablePath
- flattenedOutput android.OutputPath
- installDir android.OutputPath
+ flattenedOutput android.InstallPath
+ installDir android.InstallPath
prebuiltFileToDelete string
@@ -1625,8 +1627,8 @@
proptools.StringDefault(a.properties.Apex_name, name), fi.installDir)
if a.properties.Flattened && apexType.image() {
// /system/apex/<name>/{lib|framework|...}
- fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", filepath.Join("$(OUT_DIR)",
- a.installDir.RelPathString(), name, fi.installDir))
+ fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", filepath.Join(a.installDir.ToMakePath().String(),
+ name, fi.installDir))
if !a.isFlattenedVariant() {
fmt.Fprintln(w, "LOCAL_SOONG_SYMBOL_PATH :=", pathWhenActivated)
}
@@ -1735,7 +1737,7 @@
fmt.Fprintln(w, "LOCAL_MODULE :=", name)
fmt.Fprintln(w, "LOCAL_MODULE_CLASS := ETC") // do we need a new class?
fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", a.outputFiles[apexType].String())
- fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", filepath.Join("$(OUT_DIR)", a.installDir.RelPathString()))
+ fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", a.installDir.ToMakePath().String())
fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", name+apexType.suffix())
fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE :=", !a.installable())
if len(moduleNames) > 0 {
@@ -1746,7 +1748,7 @@
}
if a.prebuiltFileToDelete != "" {
fmt.Fprintln(w, "LOCAL_POST_INSTALL_CMD :=", "rm -rf "+
- filepath.Join("$(OUT_DIR)", a.installDir.RelPathString(), a.prebuiltFileToDelete))
+ filepath.Join(a.installDir.ToMakePath().String(), a.prebuiltFileToDelete))
}
fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
@@ -1801,6 +1803,15 @@
}{
proptools.StringPtr("both"),
})
+
+ vndkVersion := proptools.StringDefault(bundle.vndkProperties.Vndk_version, "current")
+ if vndkVersion == "current" {
+ vndkVersion = ctx.DeviceConfig().PlatformVndkVersion()
+ bundle.vndkProperties.Vndk_version = proptools.StringPtr(vndkVersion)
+ }
+
+ // Ensure VNDK APEX mount point is formatted as com.android.vndk.v###
+ bundle.properties.Apex_name = proptools.StringPtr("com.android.vndk.v" + vndkVersion)
})
return bundle
}
@@ -1840,7 +1851,7 @@
properties PrebuiltProperties
inputApex android.Path
- installDir android.OutputPath
+ installDir android.InstallPath
installFilename string
outputApex android.WritablePath
}
@@ -1987,7 +1998,7 @@
Include: "$(BUILD_PREBUILT)",
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(entries *android.AndroidMkEntries) {
- entries.SetString("LOCAL_MODULE_PATH", filepath.Join("$(OUT_DIR)", p.installDir.RelPathString()))
+ entries.SetString("LOCAL_MODULE_PATH", p.installDir.ToMakePath().String())
entries.SetString("LOCAL_MODULE_STEM", p.installFilename)
entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", !p.installable())
entries.AddStrings("LOCAL_OVERRIDES_PACKAGES", p.properties.Overrides...)
diff --git a/apex/apex_test.go b/apex/apex_test.go
index ecfa46f..413d084 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -1382,6 +1382,7 @@
vndk: {
enabled: true,
},
+ target_arch: "arm64",
srcs: ["libvndk27.so"],
}
`, withFiles(map[string][]byte{
@@ -1441,6 +1442,37 @@
}))
}
+func TestVndkApexNameRule(t *testing.T) {
+ ctx, _ := testApex(t, `
+ apex_vndk {
+ name: "myapex",
+ key: "myapex.key",
+ file_contexts: "myapex",
+ }
+ apex_vndk {
+ name: "myapex_v28",
+ key: "myapex.key",
+ file_contexts: "myapex",
+ vndk_version: "28",
+ }
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }`)
+
+ assertApexName := func(expected, moduleName string) {
+ bundle := ctx.ModuleForTests(moduleName, "android_common_"+moduleName).Module().(*apexBundle)
+ actual := proptools.String(bundle.properties.Apex_name)
+ if !reflect.DeepEqual(actual, expected) {
+ t.Errorf("Got '%v', expected '%v'", actual, expected)
+ }
+ }
+
+ assertApexName("com.android.vndk.vVER", "myapex")
+ assertApexName("com.android.vndk.v28", "myapex_v28")
+}
+
func TestVndkApexSkipsNativeBridgeSupportedModules(t *testing.T) {
ctx, _ := testApex(t, `
apex_vndk {
@@ -1864,8 +1896,8 @@
`)
apex := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(*apexBundle)
- expected := "target/product/test_device/product/apex"
- actual := apex.installDir.RelPathString()
+ expected := buildDir + "/target/product/test_device/product/apex"
+ actual := apex.installDir.String()
if actual != expected {
t.Errorf("wrong install path. expected %q. actual %q", expected, actual)
}
diff --git a/cc/androidmk.go b/cc/androidmk.go
index aab4edd..f1d329f 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -350,11 +350,10 @@
}
ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
- path := installer.path.RelPathString()
- dir, file := filepath.Split(path)
+ path, file := filepath.Split(installer.path.ToMakePath().String())
stem, suffix, _ := android.SplitFileExt(file)
fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+suffix)
- fmt.Fprintln(w, "LOCAL_MODULE_PATH := $(OUT_DIR)/"+filepath.Clean(dir))
+ fmt.Fprintln(w, "LOCAL_MODULE_PATH := "+path)
fmt.Fprintln(w, "LOCAL_MODULE_STEM := "+stem)
})
}
@@ -395,12 +394,11 @@
ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
c.libraryDecorator.androidMkWriteExportedFlags(w)
- path := c.path.RelPathString()
- dir, file := filepath.Split(path)
+ path, file := filepath.Split(c.path.ToMakePath().String())
stem, suffix, ext := android.SplitFileExt(file)
fmt.Fprintln(w, "LOCAL_BUILT_MODULE_STEM := $(LOCAL_MODULE)"+ext)
fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+suffix)
- fmt.Fprintln(w, "LOCAL_MODULE_PATH := $(OUT_DIR)/"+filepath.Clean(dir))
+ fmt.Fprintln(w, "LOCAL_MODULE_PATH := "+path)
fmt.Fprintln(w, "LOCAL_MODULE_STEM := "+stem)
})
}
diff --git a/cc/builder.go b/cc/builder.go
index c4f65da..0760dd4 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -195,7 +195,7 @@
_ = pctx.SourcePathVariable("sAbiDiffer", "prebuilts/clang-tools/${config.HostPrebuiltTag}/bin/header-abi-diff")
- sAbiDiff = pctx.AndroidRuleFunc("sAbiDiff",
+ sAbiDiff = pctx.RuleFunc("sAbiDiff",
func(ctx android.PackageRuleContext) blueprint.RuleParams {
// TODO(b/78139997): Add -check-all-apis back
commandStr := "($sAbiDiffer ${allowFlags} -lib ${libName} -arch ${arch} -o ${out} -new ${in} -old ${referenceDump})"
diff --git a/cc/installer.go b/cc/installer.go
index a52ccf1..610252c 100644
--- a/cc/installer.go
+++ b/cc/installer.go
@@ -52,7 +52,7 @@
relative string
location installLocation
- path android.OutputPath
+ path android.InstallPath
}
var _ installer = (*baseInstaller)(nil)
@@ -61,7 +61,7 @@
return []interface{}{&installer.Properties}
}
-func (installer *baseInstaller) installDir(ctx ModuleContext) android.OutputPath {
+func (installer *baseInstaller) installDir(ctx ModuleContext) android.InstallPath {
dir := installer.dir
if ctx.toolchain().Is64Bit() && installer.dir64 != "" {
dir = installer.dir64
diff --git a/cc/library.go b/cc/library.go
index a41ddc2..d8c9b90 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -791,9 +791,7 @@
// Optimize out relinking against shared libraries whose interface hasn't changed by
// depending on a table of contents file instead of the library itself.
- tocPath := outputFile.RelPathString()
- tocPath = pathtools.ReplaceExtension(tocPath, flags.Toolchain.ShlibSuffix()[1:]+".toc")
- tocFile := android.PathForOutput(ctx, tocPath)
+ tocFile := outputFile.ReplaceExtension(ctx, flags.Toolchain.ShlibSuffix()[1:]+".toc")
library.tocFile = android.OptionalPathForPath(tocFile)
TransformSharedObjectToToc(ctx, outputFile, tocFile, builderFlags)
diff --git a/cc/ndk_headers.go b/cc/ndk_headers.go
index 4065128..b8423be 100644
--- a/cc/ndk_headers.go
+++ b/cc/ndk_headers.go
@@ -48,7 +48,7 @@
}
// Returns the NDK base include path for use with sdk_version current. Usable with -I.
-func getCurrentIncludePath(ctx android.ModuleContext) android.OutputPath {
+func getCurrentIncludePath(ctx android.ModuleContext) android.InstallPath {
return getNdkSysrootBase(ctx).Join(ctx, "usr/include")
}
@@ -94,7 +94,7 @@
}
func getHeaderInstallDir(ctx android.ModuleContext, header android.Path, from string,
- to string) android.OutputPath {
+ to string) android.InstallPath {
// Output path is the sysroot base + "usr/include" + to directory + directory component
// of the file without the leading from directory stripped.
//
diff --git a/cc/ndk_sysroot.go b/cc/ndk_sysroot.go
index e39bae5..f6de4ef 100644
--- a/cc/ndk_sysroot.go
+++ b/cc/ndk_sysroot.go
@@ -66,12 +66,12 @@
pctx.Import("android/soong/android")
}
-func getNdkInstallBase(ctx android.PathContext) android.OutputPath {
- return android.PathForOutput(ctx, "ndk")
+func getNdkInstallBase(ctx android.PathContext) android.InstallPath {
+ return android.PathForNdkInstall(ctx)
}
// Returns the main install directory for the NDK sysroot. Usable with --sysroot.
-func getNdkSysrootBase(ctx android.PathContext) android.OutputPath {
+func getNdkSysrootBase(ctx android.PathContext) android.InstallPath {
return getNdkInstallBase(ctx).Join(ctx, "sysroot")
}
diff --git a/cc/stl.go b/cc/stl.go
index 458129c..aa34240 100644
--- a/cc/stl.go
+++ b/cc/stl.go
@@ -221,13 +221,13 @@
if !ctx.toolchain().Bionic() {
flags.CppFlags = append(flags.CppFlags, "-nostdinc++")
- flags.extraLibFlags = append(flags.extraLibFlags, "-nodefaultlibs")
- if ctx.staticBinary() {
- flags.extraLibFlags = append(flags.extraLibFlags, hostStaticGccLibs[ctx.Os()]...)
- } else {
- flags.extraLibFlags = append(flags.extraLibFlags, hostDynamicGccLibs[ctx.Os()]...)
- }
+ flags.extraLibFlags = append(flags.extraLibFlags, "-nostdlib++")
if ctx.Windows() {
+ if stl.Properties.SelectedStl == "libc++_static" {
+ // These are transitively needed by libc++_static.
+ flags.extraLibFlags = append(flags.extraLibFlags,
+ "-lmsvcrt", "-lucrt")
+ }
// Use SjLj exceptions for 32-bit. libgcc_eh implements SjLj
// exception model for 32-bit.
if ctx.Arch().ArchType == android.X86 {
@@ -260,12 +260,7 @@
// None or error.
if !ctx.toolchain().Bionic() {
flags.CppFlags = append(flags.CppFlags, "-nostdinc++")
- flags.extraLibFlags = append(flags.extraLibFlags, "-nodefaultlibs")
- if ctx.staticBinary() {
- flags.extraLibFlags = append(flags.extraLibFlags, hostStaticGccLibs[ctx.Os()]...)
- } else {
- flags.extraLibFlags = append(flags.extraLibFlags, hostDynamicGccLibs[ctx.Os()]...)
- }
+ flags.extraLibFlags = append(flags.extraLibFlags, "-nostdlib++")
}
default:
panic(fmt.Errorf("Unknown stl: %q", stl.Properties.SelectedStl))
@@ -273,22 +268,3 @@
return flags
}
-
-var hostDynamicGccLibs, hostStaticGccLibs map[android.OsType][]string
-
-func init() {
- hostDynamicGccLibs = map[android.OsType][]string{
- android.Fuchsia: []string{"-lc", "-lunwind"},
- android.Linux: []string{"-lgcc_s", "-lgcc", "-lc", "-lgcc_s", "-lgcc"},
- android.Darwin: []string{"-lc", "-lSystem"},
- android.Windows: []string{"-Wl,--start-group", "-lmingw32", "-lgcc", "-lgcc_eh",
- "-lmoldname", "-lmingwex", "-lmsvcrt", "-lucrt", "-lpthread",
- "-ladvapi32", "-lshell32", "-luser32", "-lkernel32", "-lpsapi",
- "-Wl,--end-group"},
- }
- hostStaticGccLibs = map[android.OsType][]string{
- android.Linux: []string{"-Wl,--start-group", "-lgcc", "-lgcc_eh", "-lc", "-Wl,--end-group"},
- android.Darwin: []string{"NO_STATIC_HOST_BINARIES_ON_DARWIN"},
- android.Windows: []string{"NO_STATIC_HOST_BINARIES_ON_WINDOWS"},
- }
-}
diff --git a/cc/vndk_prebuilt.go b/cc/vndk_prebuilt.go
index 8126e4a..2cebb6d 100644
--- a/cc/vndk_prebuilt.go
+++ b/cc/vndk_prebuilt.go
@@ -129,6 +129,18 @@
func (p *vndkPrebuiltLibraryDecorator) link(ctx ModuleContext,
flags Flags, deps PathDeps, objs Objects) android.Path {
+
+ arches := ctx.DeviceConfig().Arches()
+ if len(arches) == 0 || arches[0].ArchType.String() != p.arch() {
+ ctx.Module().SkipInstall()
+ return nil
+ }
+
+ if ctx.DeviceConfig().BinderBitness() != p.binderBit() {
+ ctx.Module().SkipInstall()
+ return nil
+ }
+
if len(p.properties.Srcs) > 0 && p.shared() {
p.libraryDecorator.exportIncludes(ctx)
p.libraryDecorator.reexportSystemDirs(p.properties.Export_system_include_dirs...)
@@ -136,6 +148,8 @@
// current VNDK prebuilts are only shared libs.
return p.singleSourcePath(ctx)
}
+
+ ctx.Module().SkipInstall()
return nil
}
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index c378f09..40644a3 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -248,7 +248,7 @@
odexPath := module.BuildPath.InSameDir(ctx, "oat", arch.String(), pathtools.ReplaceExtension(base, "odex"))
odexInstallPath := toOdexPath(module.DexLocation)
if odexOnSystemOther(module, global) {
- odexInstallPath = strings.Replace(odexInstallPath, SystemPartition, SystemOtherPartition, 1)
+ odexInstallPath = filepath.Join(SystemOtherPartition, odexInstallPath)
}
vdexPath := odexPath.ReplaceExtension(ctx, "vdex")
diff --git a/dexpreopt/dexpreopt_test.go b/dexpreopt/dexpreopt_test.go
index 78f2f3f..aca5e63 100644
--- a/dexpreopt/dexpreopt_test.go
+++ b/dexpreopt/dexpreopt_test.go
@@ -117,7 +117,7 @@
{
patterns: []string{"app/%"},
moduleTests: []moduleTest{
- {module: systemModule, expectedPartition: "system_other"},
+ {module: systemModule, expectedPartition: "system_other/system"},
{module: systemProductModule, expectedPartition: "system/product"},
{module: productModule, expectedPartition: "product"},
},
@@ -126,8 +126,8 @@
{
patterns: []string{"app/%", "product/app/%"},
moduleTests: []moduleTest{
- {module: systemModule, expectedPartition: "system_other"},
- {module: systemProductModule, expectedPartition: "system_other/product"},
+ {module: systemModule, expectedPartition: "system_other/system"},
+ {module: systemProductModule, expectedPartition: "system_other/system/product"},
{module: productModule, expectedPartition: "product"},
},
},
diff --git a/java/app.go b/java/app.go
index 3ee8b8d..e033661 100644
--- a/java/app.go
+++ b/java/app.go
@@ -126,7 +126,7 @@
// the install APK name is normally the same as the module name, but can be overridden with PRODUCT_PACKAGE_NAME_OVERRIDES.
installApkName string
- installDir android.OutputPath
+ installDir android.InstallPath
onDeviceDir string
@@ -773,7 +773,7 @@
usesLibrary usesLibrary
- installPath android.OutputPath
+ installPath android.InstallPath
}
type AndroidAppImportProperties struct {
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 6214dac..db6b455 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -22,7 +22,7 @@
type dexpreopter struct {
dexpreoptProperties DexpreoptProperties
- installPath android.OutputPath
+ installPath android.InstallPath
uncompressedDex bool
isSDKLibrary bool
isTest bool
@@ -94,7 +94,7 @@
return false
}
-func odexOnSystemOther(ctx android.ModuleContext, installPath android.OutputPath) bool {
+func odexOnSystemOther(ctx android.ModuleContext, installPath android.InstallPath) bool {
return dexpreopt.OdexOnSystemOtherByName(ctx.ModuleName(), android.InstallPathToOnDevicePath(ctx, installPath), dexpreoptGlobalConfig(ctx))
}
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 1d5331e..aab61c5 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -461,14 +461,14 @@
flags droiddocBuilderFlags) android.Paths {
outSrcFiles := make(android.Paths, 0, len(srcFiles))
+ var aidlSrcs android.Paths
aidlIncludeFlags := genAidlIncludeFlags(srcFiles)
for _, srcFile := range srcFiles {
switch srcFile.Ext() {
case ".aidl":
- javaFile := genAidl(ctx, srcFile, flags.aidlFlags+aidlIncludeFlags, flags.aidlDeps)
- outSrcFiles = append(outSrcFiles, javaFile)
+ aidlSrcs = append(aidlSrcs, srcFile)
case ".logtags":
javaFile := genLogtags(ctx, srcFile)
outSrcFiles = append(outSrcFiles, javaFile)
@@ -477,6 +477,12 @@
}
}
+ // Process all aidl files together to support sharding them into one or more rules that produce srcjars.
+ if len(aidlSrcs) > 0 {
+ srcJarFiles := genAidl(ctx, aidlSrcs, flags.aidlFlags+aidlIncludeFlags, flags.aidlDeps)
+ outSrcFiles = append(outSrcFiles, srcJarFiles...)
+ }
+
return outSrcFiles
}
diff --git a/java/gen.go b/java/gen.go
index b840b60..d50a665 100644
--- a/java/gen.go
+++ b/java/gen.go
@@ -15,9 +15,11 @@
package java
import (
+ "strconv"
"strings"
"github.com/google/blueprint"
+ "github.com/google/blueprint/pathtools"
"android/soong/android"
)
@@ -29,13 +31,6 @@
}
var (
- aidl = pctx.AndroidStaticRule("aidl",
- blueprint.RuleParams{
- Command: "${config.AidlCmd} -d$depFile $aidlFlags $in $out",
- CommandDeps: []string{"${config.AidlCmd}"},
- },
- "depFile", "aidlFlags")
-
logtags = pctx.AndroidStaticRule("logtags",
blueprint.RuleParams{
Command: "$logtagsCmd -o $out $in",
@@ -49,23 +44,64 @@
})
)
-func genAidl(ctx android.ModuleContext, aidlFile android.Path, aidlFlags string, deps android.Paths) android.Path {
- javaFile := android.GenPathWithExt(ctx, "aidl", aidlFile, "java")
- depFile := javaFile.String() + ".d"
+func genAidl(ctx android.ModuleContext, aidlFiles android.Paths, aidlFlags string, deps android.Paths) android.Paths {
+ // Shard aidl files into groups of 50 to avoid having to recompile all of them if one changes and to avoid
+ // hitting command line length limits.
+ shards := android.ShardPaths(aidlFiles, 50)
- ctx.Build(pctx, android.BuildParams{
- Rule: aidl,
- Description: "aidl " + aidlFile.Rel(),
- Output: javaFile,
- Input: aidlFile,
- Implicits: deps,
- Args: map[string]string{
- "depFile": depFile,
- "aidlFlags": aidlFlags,
- },
- })
+ srcJarFiles := make(android.Paths, 0, len(shards))
- return javaFile
+ for i, shard := range shards {
+ srcJarFile := android.PathForModuleGen(ctx, "aidl", "aidl"+strconv.Itoa(i)+".srcjar")
+ srcJarFiles = append(srcJarFiles, srcJarFile)
+
+ outDir := srcJarFile.ReplaceExtension(ctx, "tmp")
+
+ rule := android.NewRuleBuilder()
+
+ rule.Command().Text("rm -rf").Flag(outDir.String())
+ rule.Command().Text("mkdir -p").Flag(outDir.String())
+ rule.Command().Text("FLAGS=' " + aidlFlags + "'")
+
+ for _, aidlFile := range shard {
+ depFile := srcJarFile.InSameDir(ctx, aidlFile.String()+".d")
+ javaFile := outDir.Join(ctx, pathtools.ReplaceExtension(aidlFile.String(), "java"))
+ rule.Command().
+ Tool(ctx.Config().HostToolPath(ctx, "aidl")).
+ FlagWithDepFile("-d", depFile).
+ Flag("$FLAGS").
+ Input(aidlFile).
+ Output(javaFile).
+ Implicits(deps)
+ rule.Temporary(javaFile)
+ }
+
+ rule.Command().
+ Tool(ctx.Config().HostToolPath(ctx, "soong_zip")).
+ // TODO(b/124333557): this can't use -srcjar for now, aidl on parcelables generates java files
+ // without a package statement, which causes -srcjar to put them in the top level of the zip file.
+ // Once aidl skips parcelables we can use -srcjar.
+ //Flag("-srcjar").
+ Flag("-write_if_changed").
+ FlagWithOutput("-o ", srcJarFile).
+ FlagWithArg("-C ", outDir.String()).
+ FlagWithArg("-D ", outDir.String())
+
+ rule.Command().Text("rm -rf").Flag(outDir.String())
+
+ rule.Restat()
+
+ ruleName := "aidl"
+ ruleDesc := "aidl"
+ if len(shards) > 1 {
+ ruleName += "_" + strconv.Itoa(i)
+ ruleDesc += " " + strconv.Itoa(i)
+ }
+
+ rule.Build(pctx, ctx, ruleName, ruleDesc)
+ }
+
+ return srcJarFiles
}
func genLogtags(ctx android.ModuleContext, logtagsFile android.Path) android.Path {
@@ -98,26 +134,38 @@
flags javaBuilderFlags) android.Paths {
outSrcFiles := make(android.Paths, 0, len(srcFiles))
+ var protoSrcs android.Paths
+ var aidlSrcs android.Paths
aidlIncludeFlags := genAidlIncludeFlags(srcFiles)
for _, srcFile := range srcFiles {
switch srcFile.Ext() {
case ".aidl":
- javaFile := genAidl(ctx, srcFile, flags.aidlFlags+aidlIncludeFlags, flags.aidlDeps)
- outSrcFiles = append(outSrcFiles, javaFile)
+ aidlSrcs = append(aidlSrcs, srcFile)
case ".logtags":
j.logtagsSrcs = append(j.logtagsSrcs, srcFile)
javaFile := genLogtags(ctx, srcFile)
outSrcFiles = append(outSrcFiles, javaFile)
case ".proto":
- srcJarFile := genProto(ctx, srcFile, flags.proto)
- outSrcFiles = append(outSrcFiles, srcJarFile)
+ protoSrcs = append(protoSrcs, srcFile)
default:
outSrcFiles = append(outSrcFiles, srcFile)
}
}
+ // Process all proto files together to support sharding them into one or more rules that produce srcjars.
+ if len(protoSrcs) > 0 {
+ srcJarFiles := genProto(ctx, protoSrcs, flags.proto)
+ outSrcFiles = append(outSrcFiles, srcJarFiles...)
+ }
+
+ // Process all aidl files together to support sharding them into one or more rules that produce srcjars.
+ if len(aidlSrcs) > 0 {
+ srcJarFiles := genAidl(ctx, aidlSrcs, flags.aidlFlags+aidlIncludeFlags, flags.aidlDeps)
+ outSrcFiles = append(outSrcFiles, srcJarFiles...)
+ }
+
return outSrcFiles
}
diff --git a/java/java.go b/java/java.go
index f7b0f53..4264ba9 100644
--- a/java/java.go
+++ b/java/java.go
@@ -1795,7 +1795,7 @@
isWrapperVariant bool
wrapperFile android.Path
- binaryFile android.OutputPath
+ binaryFile android.InstallPath
}
func (j *Binary) HostToolPath() android.OptionalPath {
diff --git a/java/java_test.go b/java/java_test.go
index a932319..f0cb6f8 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -18,6 +18,7 @@
"io/ioutil"
"os"
"path/filepath"
+ "reflect"
"strconv"
"strings"
"testing"
@@ -811,19 +812,22 @@
}
`)
- inputs := ctx.ModuleForTests("bar-doc", "android_common").Rule("javadoc").Inputs
+ barDoc := ctx.ModuleForTests("bar-doc", "android_common").Rule("javadoc")
var javaSrcs []string
- for _, i := range inputs {
+ for _, i := range barDoc.Inputs {
javaSrcs = append(javaSrcs, i.Base())
}
- if len(javaSrcs) != 3 || javaSrcs[0] != "a.java" || javaSrcs[1] != "IFoo.java" || javaSrcs[2] != "IBar.java" {
- t.Errorf("inputs of bar-doc must be []string{\"a.java\", \"IFoo.java\", \"IBar.java\", but was %#v.", javaSrcs)
+ if len(javaSrcs) != 1 || javaSrcs[0] != "a.java" {
+ t.Errorf("inputs of bar-doc must be []string{\"a.java\"}, but was %#v.", javaSrcs)
}
- aidlRule := ctx.ModuleForTests("bar-doc", "android_common").Output(inputs[2].String())
- aidlFlags := aidlRule.Args["aidlFlags"]
- if !strings.Contains(aidlFlags, "-Ibar-doc") {
- t.Errorf("aidl flags for IBar.aidl should contain \"-Ibar-doc\", but was %q", aidlFlags)
+ aidl := ctx.ModuleForTests("bar-doc", "android_common").Rule("aidl")
+ if g, w := barDoc.Implicits.Strings(), aidl.Output.String(); !inList(w, g) {
+ t.Errorf("implicits of bar-doc must contain %q, but was %q.", w, g)
+ }
+
+ if g, w := aidl.Implicits.Strings(), []string{"bar-doc/IBar.aidl", "bar-doc/IFoo.aidl"}; !reflect.DeepEqual(w, g) {
+ t.Errorf("aidl inputs must be %q, but was %q", w, g)
}
}
diff --git a/java/platform_compat_config.go b/java/platform_compat_config.go
index 3d46077..23ba2b0 100644
--- a/java/platform_compat_config.go
+++ b/java/platform_compat_config.go
@@ -30,7 +30,7 @@
android.ModuleBase
properties platformCompatConfigProperties
- installDirPath android.OutputPath
+ installDirPath android.InstallPath
configFile android.OutputPath
}
@@ -78,7 +78,7 @@
Include: "$(BUILD_PREBUILT)",
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(entries *android.AndroidMkEntries) {
- entries.SetString("LOCAL_MODULE_PATH", "$(OUT_DIR)/"+p.installDirPath.RelPathString())
+ entries.SetString("LOCAL_MODULE_PATH", p.installDirPath.ToMakePath().String())
entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.configFile.Base())
},
},
diff --git a/java/proto.go b/java/proto.go
index f5c233c..e013bb4 100644
--- a/java/proto.go
+++ b/java/proto.go
@@ -15,36 +15,61 @@
package java
import (
+ "path/filepath"
+ "strconv"
+
"android/soong/android"
)
-func genProto(ctx android.ModuleContext, protoFile android.Path, flags android.ProtoFlags) android.Path {
- srcJarFile := android.GenPathWithExt(ctx, "proto", protoFile, "srcjar")
+func genProto(ctx android.ModuleContext, protoFiles android.Paths, flags android.ProtoFlags) android.Paths {
+ // Shard proto files into groups of 100 to avoid having to recompile all of them if one changes and to avoid
+ // hitting command line length limits.
+ shards := android.ShardPaths(protoFiles, 100)
- outDir := srcJarFile.ReplaceExtension(ctx, "tmp")
- depFile := srcJarFile.ReplaceExtension(ctx, "srcjar.d")
+ srcJarFiles := make(android.Paths, 0, len(shards))
- rule := android.NewRuleBuilder()
+ for i, shard := range shards {
+ srcJarFile := android.PathForModuleGen(ctx, "proto", "proto"+strconv.Itoa(i)+".srcjar")
+ srcJarFiles = append(srcJarFiles, srcJarFile)
- rule.Command().Text("rm -rf").Flag(outDir.String())
- rule.Command().Text("mkdir -p").Flag(outDir.String())
+ outDir := srcJarFile.ReplaceExtension(ctx, "tmp")
- android.ProtoRule(ctx, rule, protoFile, flags, flags.Deps, outDir, depFile, nil)
+ rule := android.NewRuleBuilder()
- // Proto generated java files have an unknown package name in the path, so package the entire output directory
- // into a srcjar.
- rule.Command().
- BuiltTool(ctx, "soong_zip").
- Flag("-jar").
- FlagWithOutput("-o ", srcJarFile).
- FlagWithArg("-C ", outDir.String()).
- FlagWithArg("-D ", outDir.String())
+ rule.Command().Text("rm -rf").Flag(outDir.String())
+ rule.Command().Text("mkdir -p").Flag(outDir.String())
- rule.Command().Text("rm -rf").Flag(outDir.String())
+ for _, protoFile := range shard {
+ depFile := srcJarFile.InSameDir(ctx, protoFile.String()+".d")
+ rule.Command().Text("mkdir -p").Flag(filepath.Dir(depFile.String()))
+ android.ProtoRule(ctx, rule, protoFile, flags, flags.Deps, outDir, depFile, nil)
+ }
- rule.Build(pctx, ctx, "protoc_"+protoFile.Rel(), "protoc "+protoFile.Rel())
+ // Proto generated java files have an unknown package name in the path, so package the entire output directory
+ // into a srcjar.
+ rule.Command().
+ BuiltTool(ctx, "soong_zip").
+ Flag("-jar").
+ Flag("-write_if_changed").
+ FlagWithOutput("-o ", srcJarFile).
+ FlagWithArg("-C ", outDir.String()).
+ FlagWithArg("-D ", outDir.String())
- return srcJarFile
+ rule.Command().Text("rm -rf").Flag(outDir.String())
+
+ rule.Restat()
+
+ ruleName := "protoc"
+ ruleDesc := "protoc"
+ if len(shards) > 1 {
+ ruleName += "_" + strconv.Itoa(i)
+ ruleDesc += " " + strconv.Itoa(i)
+ }
+
+ rule.Build(pctx, ctx, ruleName, ruleDesc)
+ }
+
+ return srcJarFiles
}
func protoDeps(ctx android.BottomUpMutatorContext, p *android.ProtoProperties) {
diff --git a/java/sdk_test.go b/java/sdk_test.go
index 88e21d7..5001b47 100644
--- a/java/sdk_test.go
+++ b/java/sdk_test.go
@@ -250,7 +250,10 @@
}
checkClasspath := func(t *testing.T, ctx *android.TestContext) {
- javac := ctx.ModuleForTests("foo", variant).Rule("javac")
+ foo := ctx.ModuleForTests("foo", variant)
+ javac := foo.Rule("javac")
+
+ aidl := foo.MaybeRule("aidl")
got := javac.Args["bootClasspath"]
if got != bc {
@@ -263,6 +266,9 @@
}
var deps []string
+ if aidl.Rule != nil {
+ deps = append(deps, aidl.Output.String())
+ }
if len(bootclasspath) > 0 && bootclasspath[0] != `""` {
deps = append(deps, bootclasspath...)
}
@@ -290,12 +296,8 @@
if testcase.host != android.Host {
aidl := ctx.ModuleForTests("foo", variant).Rule("aidl")
- aidlFlags := aidl.Args["aidlFlags"]
- // Trim trailing "-I." to avoid having to specify it in every test
- aidlFlags = strings.TrimSpace(strings.TrimSuffix(aidlFlags, "-I."))
-
- if g, w := aidlFlags, testcase.aidl; g != w {
- t.Errorf("want aidl flags %q, got %q", w, g)
+ if g, w := aidl.RuleParams.Command, testcase.aidl+" -I."; !strings.Contains(g, w) {
+ t.Errorf("want aidl command to contain %q, got %q", w, g)
}
}
})
diff --git a/makedeps/deps.go b/makedeps/deps.go
index e64e6f7..db49532 100644
--- a/makedeps/deps.go
+++ b/makedeps/deps.go
@@ -57,10 +57,12 @@
return nil, fmt.Errorf("%sunsupported variable expansion: %v", pos(node), x.Target.Dump())
}
outputs := x.Target.Words()
- if len(outputs) == 0 {
- return nil, fmt.Errorf("%smissing output: %v", pos(node), x)
+ if len(outputs) > 0 {
+ ret.Output = outputs[0].Value(nil)
+ } else {
+ // TODO(b/141372861): put this back
+ //return nil, fmt.Errorf("%smissing output: %v", pos(node), x)
}
- ret.Output = outputs[0].Value(nil)
if !x.Prerequisites.Const() {
return nil, fmt.Errorf("%sunsupported variable expansion: %v", pos(node), x.Prerequisites.Dump())
diff --git a/makedeps/deps_test.go b/makedeps/deps_test.go
index a32df65..ac2f699 100644
--- a/makedeps/deps_test.go
+++ b/makedeps/deps_test.go
@@ -147,6 +147,20 @@
},
},
},
+ {
+ // TODO(b/141372861): remove this
+ // AIDL produces a dep file with no output file for a parcelable (b/
+ name: "AIDL parcelable",
+ input: ` : \
+ frameworks/base/tests/net/integration/src/com/android/server/net/integrationtests/HttpResponse.aidl
+`,
+ output: Deps{
+ Output: "",
+ Inputs: []string{
+ "frameworks/base/tests/net/integration/src/com/android/server/net/integrationtests/HttpResponse.aidl",
+ },
+ },
+ },
}
for _, tc := range testCases {
diff --git a/python/androidmk.go b/python/androidmk.go
index 1e51e7b..aae7ced 100644
--- a/python/androidmk.go
+++ b/python/androidmk.go
@@ -89,12 +89,11 @@
ret.Required = append(ret.Required, "libc++")
ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
- path := installer.path.RelPathString()
- dir, file := filepath.Split(path)
+ path, file := filepath.Split(installer.path.ToMakePath().String())
stem := strings.TrimSuffix(file, filepath.Ext(file))
fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+filepath.Ext(file))
- fmt.Fprintln(w, "LOCAL_MODULE_PATH := $(OUT_DIR)/"+filepath.Clean(dir))
+ fmt.Fprintln(w, "LOCAL_MODULE_PATH := "+path)
fmt.Fprintln(w, "LOCAL_MODULE_STEM := "+stem)
fmt.Fprintln(w, "LOCAL_SHARED_LIBRARIES := "+strings.Join(installer.androidMkSharedLibs, " "))
})
diff --git a/python/installer.go b/python/installer.go
index 62f36f4..b0a25b9 100644
--- a/python/installer.go
+++ b/python/installer.go
@@ -33,7 +33,7 @@
dir64 string
relative string
- path android.OutputPath
+ path android.InstallPath
androidMkSharedLibs []string
}
@@ -47,7 +47,7 @@
var _ installer = (*pythonInstaller)(nil)
-func (installer *pythonInstaller) installDir(ctx android.ModuleContext) android.OutputPath {
+func (installer *pythonInstaller) installDir(ctx android.ModuleContext) android.InstallPath {
dir := installer.dir
if ctx.Arch().ArchType.Multilib == "lib64" && installer.dir64 != "" {
dir = installer.dir64
diff --git a/rust/androidmk.go b/rust/androidmk.go
index 107959f..a6208db 100644
--- a/rust/androidmk.go
+++ b/rust/androidmk.go
@@ -116,11 +116,10 @@
ret.OutputFile = android.OptionalPathForPath(compiler.path)
}
ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
- path := compiler.path.RelPathString()
- dir, file := filepath.Split(path)
+ path, file := filepath.Split(compiler.path.ToMakePath().String())
stem, suffix, _ := android.SplitFileExt(file)
fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+suffix)
- fmt.Fprintln(w, "LOCAL_MODULE_PATH := $(OUT_DIR)/"+filepath.Clean(dir))
+ fmt.Fprintln(w, "LOCAL_MODULE_PATH := "+path)
fmt.Fprintln(w, "LOCAL_MODULE_STEM := "+stem)
})
}
diff --git a/rust/compiler.go b/rust/compiler.go
index 3bfef76..6d74010 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -20,16 +20,22 @@
"android/soong/android"
"android/soong/rust/config"
+ "github.com/google/blueprint/proptools"
)
+func getEdition(compiler *baseCompiler) string {
+ return proptools.StringDefault(compiler.Properties.Edition, config.DefaultEdition)
+}
+
+func getDenyWarnings(compiler *baseCompiler) bool {
+ return BoolDefault(compiler.Properties.Deny_warnings, config.DefaultDenyWarnings)
+}
+
func NewBaseCompiler(dir, dir64 string) *baseCompiler {
return &baseCompiler{
- Properties: BaseCompilerProperties{
- Edition: &config.DefaultEdition,
- Deny_warnings: config.DefaultDenyWarnings,
- },
- dir: dir,
- dir64: dir64,
+ Properties: BaseCompilerProperties{},
+ dir: dir,
+ dir64: dir64,
}
}
@@ -94,7 +100,7 @@
dir64 string
subDir string
relative string
- path android.OutputPath
+ path android.InstallPath
}
var _ compiler = (*baseCompiler)(nil)
@@ -113,12 +119,12 @@
func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags) Flags {
- if Bool(compiler.Properties.Deny_warnings) {
+ if getDenyWarnings(compiler) {
flags.RustFlags = append(flags.RustFlags, "-D warnings")
}
flags.RustFlags = append(flags.RustFlags, compiler.Properties.Flags...)
flags.RustFlags = append(flags.RustFlags, compiler.featuresToFlags(compiler.Properties.Features)...)
- flags.RustFlags = append(flags.RustFlags, "--edition="+*compiler.Properties.Edition)
+ flags.RustFlags = append(flags.RustFlags, "--edition="+getEdition(compiler))
flags.LinkFlags = append(flags.LinkFlags, compiler.Properties.Ld_flags...)
flags.GlobalRustFlags = append(flags.GlobalRustFlags, config.GlobalRustFlags...)
flags.GlobalRustFlags = append(flags.GlobalRustFlags, ctx.toolchain().ToolchainRustFlags())
@@ -173,7 +179,7 @@
return compiler.Properties.Crate_name
}
-func (compiler *baseCompiler) installDir(ctx ModuleContext) android.OutputPath {
+func (compiler *baseCompiler) installDir(ctx ModuleContext) android.InstallPath {
dir := compiler.dir
if ctx.toolchain().Is64Bit() && compiler.dir64 != "" {
dir = compiler.dir64
diff --git a/rust/config/global.go b/rust/config/global.go
index ae50804..7846d21 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -17,8 +17,6 @@
import (
"strings"
- "github.com/google/blueprint/proptools"
-
"android/soong/android"
_ "android/soong/cc/config"
)
@@ -35,7 +33,7 @@
"libtest",
}
- DefaultDenyWarnings = proptools.BoolPtr(true)
+ DefaultDenyWarnings = true
GlobalRustFlags = []string{
"--remap-path-prefix $$(pwd)=",
diff --git a/xml/xml_test.go b/xml/xml_test.go
index ae3e9fe..f2a440f 100644
--- a/xml/xml_test.go
+++ b/xml/xml_test.go
@@ -15,15 +15,40 @@
package xml
import (
- "android/soong/android"
"io/ioutil"
"os"
"testing"
+
+ "android/soong/android"
)
+var buildDir string
+
+func setUp() {
+ var err error
+ buildDir, err = ioutil.TempDir("", "soong_xml_test")
+ if err != nil {
+ panic(err)
+ }
+}
+
+func tearDown() {
+ os.RemoveAll(buildDir)
+}
+
+func TestMain(m *testing.M) {
+ run := func() int {
+ setUp()
+ defer tearDown()
+
+ return m.Run()
+ }
+
+ os.Exit(run())
+}
+
func testXml(t *testing.T, bp string) *android.TestContext {
- config, buildDir := setup(t)
- defer teardown(buildDir)
+ config := android.TestArchConfig(buildDir, nil)
ctx := android.NewTestArchContext()
ctx.RegisterModuleType("prebuilt_etc", android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory))
ctx.RegisterModuleType("prebuilt_etc_xml", android.ModuleFactoryAdaptor(PrebuiltEtcXmlFactory))
@@ -45,21 +70,6 @@
return ctx
}
-func setup(t *testing.T) (config android.Config, buildDir string) {
- buildDir, err := ioutil.TempDir("", "soong_xml_test")
- if err != nil {
- t.Fatal(err)
- }
-
- config = android.TestArchConfig(buildDir, nil)
-
- return
-}
-
-func teardown(buildDir string) {
- os.RemoveAll(buildDir)
-}
-
func assertEqual(t *testing.T, name, expected, actual string) {
t.Helper()
if expected != actual {
@@ -103,5 +113,5 @@
}
m := ctx.ModuleForTests("foo.xml", "android_arm64_armv8-a").Module().(*prebuiltEtcXml)
- assertEqual(t, "installDir", "target/product/test_device/system/etc", m.InstallDirPath().RelPathString())
+ assertEqual(t, "installDir", buildDir+"/target/product/test_device/system/etc", m.InstallDirPath().String())
}