Merge "Fallback to /tmp when socket address is longer than max length."
diff --git a/android/config.go b/android/config.go
index a1e97c9..dd622e5 100644
--- a/android/config.go
+++ b/android/config.go
@@ -35,6 +35,7 @@
var Bool = proptools.Bool
var String = proptools.String
+var StringDefault = proptools.StringDefault
const FutureApiLevel = 10000
@@ -958,6 +959,10 @@
return String(c.config.productVariables.DeviceVndkVersion)
}
+func (c *deviceConfig) CurrentApiLevelForVendorModules() string {
+ return StringDefault(c.config.productVariables.DeviceCurrentApiLevelForVendorModules, "current")
+}
+
func (c *deviceConfig) PlatformVndkVersion() string {
return String(c.config.productVariables.Platform_vndk_version)
}
@@ -1393,7 +1398,7 @@
if len(pair) == 2 {
return pair[0], pair[1]
} else {
- reportPathErrorf(ctx, "malformed (apex, jar) pair: '%s', expected format: <apex>:<jar>", str)
+ ReportPathErrorf(ctx, "malformed (apex, jar) pair: '%s', expected format: <apex>:<jar>", str)
return "error-apex", "error-jar"
}
}
diff --git a/android/module.go b/android/module.go
index b689a87..17bc205 100644
--- a/android/module.go
+++ b/android/module.go
@@ -2246,7 +2246,7 @@
return nil
}
if len(paths) > 1 {
- reportPathErrorf(ctx, "got multiple output files from module %q, expected exactly one",
+ ReportPathErrorf(ctx, "got multiple output files from module %q, expected exactly one",
pathContextName(ctx, module))
return nil
}
diff --git a/android/paths.go b/android/paths.go
index 65f129c..6b603ba 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -86,13 +86,13 @@
// attempts ctx.ModuleErrorf for a better error message first, then falls
// back to ctx.Errorf.
func reportPathError(ctx PathContext, err error) {
- reportPathErrorf(ctx, "%s", err.Error())
+ ReportPathErrorf(ctx, "%s", err.Error())
}
-// reportPathErrorf will register an error with the attached context. It
+// ReportPathErrorf will register an error with the attached context. It
// attempts ctx.ModuleErrorf for a better error message first, then falls
// back to ctx.Errorf.
-func reportPathErrorf(ctx PathContext, format string, args ...interface{}) {
+func ReportPathErrorf(ctx PathContext, format string, args ...interface{}) {
if mctx, ok := ctx.(moduleErrorf); ok {
mctx.ModuleErrorf(format, args...)
} else if ectx, ok := ctx.(errorfContext); ok {
@@ -155,7 +155,7 @@
if path, ok := p.(genPathProvider); ok {
return path.genPathWithExt(ctx, subdir, ext)
}
- reportPathErrorf(ctx, "Tried to create generated file from unsupported path: %s(%s)", reflect.TypeOf(p).Name(), p)
+ ReportPathErrorf(ctx, "Tried to create generated file from unsupported path: %s(%s)", reflect.TypeOf(p).Name(), p)
return PathForModuleGen(ctx)
}
@@ -165,7 +165,7 @@
if path, ok := p.(objPathProvider); ok {
return path.objPathWithExt(ctx, subdir, ext)
}
- reportPathErrorf(ctx, "Tried to create object file from unsupported path: %s (%s)", reflect.TypeOf(p).Name(), p)
+ ReportPathErrorf(ctx, "Tried to create object file from unsupported path: %s (%s)", reflect.TypeOf(p).Name(), p)
return PathForModuleObj(ctx)
}
@@ -176,7 +176,7 @@
if path, ok := p.(resPathProvider); ok {
return path.resPathWithName(ctx, name)
}
- reportPathErrorf(ctx, "Tried to create res file from unsupported path: %s (%s)", reflect.TypeOf(p).Name(), p)
+ ReportPathErrorf(ctx, "Tried to create res file from unsupported path: %s (%s)", reflect.TypeOf(p).Name(), p)
return PathForModuleRes(ctx)
}
@@ -416,9 +416,9 @@
} else {
p := pathForModuleSrc(ctx, s)
if exists, _, err := ctx.Config().fs.Exists(p.String()); err != nil {
- reportPathErrorf(ctx, "%s: %s", p, err.Error())
+ ReportPathErrorf(ctx, "%s: %s", p, err.Error())
} else if !exists && !ctx.Config().testAllowNonExistentPaths {
- reportPathErrorf(ctx, "module source path %q does not exist", p)
+ ReportPathErrorf(ctx, "module source path %q does not exist", p)
}
if InList(p.String(), expandedExcludes) {
@@ -445,7 +445,7 @@
}
path := filepath.Clean(p)
if !strings.HasPrefix(path, prefix) {
- reportPathErrorf(ctx, "Path %q is not in module source directory %q", p, prefix)
+ ReportPathErrorf(ctx, "Path %q is not in module source directory %q", p, prefix)
continue
}
@@ -801,7 +801,7 @@
}
if pathtools.IsGlob(path.String()) {
- reportPathErrorf(ctx, "path may not contain a glob: %s", path.String())
+ ReportPathErrorf(ctx, "path may not contain a glob: %s", path.String())
}
if modCtx, ok := ctx.(ModuleContext); ok && ctx.Config().AllowMissingDependencies() {
@@ -813,9 +813,9 @@
modCtx.AddMissingDependencies([]string{path.String()})
}
} else if exists, _, err := ctx.Config().fs.Exists(path.String()); err != nil {
- reportPathErrorf(ctx, "%s: %s", path, err.Error())
+ ReportPathErrorf(ctx, "%s: %s", path, err.Error())
} else if !exists && !ctx.Config().testAllowNonExistentPaths {
- reportPathErrorf(ctx, "source path %q does not exist", path)
+ ReportPathErrorf(ctx, "source path %q does not exist", path)
}
return path
}
@@ -831,7 +831,7 @@
}
if pathtools.IsGlob(path.String()) {
- reportPathErrorf(ctx, "path may not contain a glob: %s", path.String())
+ ReportPathErrorf(ctx, "path may not contain a glob: %s", path.String())
return OptionalPath{}
}
@@ -876,17 +876,17 @@
if srcPath, ok := path.(SourcePath); ok {
relDir = srcPath.path
} else {
- reportPathErrorf(ctx, "Cannot find relative path for %s(%s)", reflect.TypeOf(path).Name(), path)
+ ReportPathErrorf(ctx, "Cannot find relative path for %s(%s)", reflect.TypeOf(path).Name(), path)
return OptionalPath{}
}
dir := filepath.Join(p.config.srcDir, p.path, relDir)
// Use Glob so that we are run again if the directory is added.
if pathtools.IsGlob(dir) {
- reportPathErrorf(ctx, "Path may not contain a glob: %s", dir)
+ ReportPathErrorf(ctx, "Path may not contain a glob: %s", dir)
}
paths, err := ctx.GlobWithDeps(dir, nil)
if err != nil {
- reportPathErrorf(ctx, "glob: %s", err.Error())
+ ReportPathErrorf(ctx, "glob: %s", err.Error())
return OptionalPath{}
}
if len(paths) == 0 {
@@ -977,7 +977,7 @@
// ReplaceExtension creates a new OutputPath with the extension replaced with ext.
func (p OutputPath) ReplaceExtension(ctx PathContext, ext string) OutputPath {
if strings.Contains(ext, "/") {
- reportPathErrorf(ctx, "extension %q cannot contain /", ext)
+ ReportPathErrorf(ctx, "extension %q cannot contain /", ext)
}
ret := PathForOutput(ctx, pathtools.ReplaceExtension(p.path, ext))
ret.rel = pathtools.ReplaceExtension(p.rel, ext)
@@ -1030,10 +1030,10 @@
}
return nil
} else if len(paths) == 0 {
- reportPathErrorf(ctx, "%q produced no files, expected exactly one", p)
+ ReportPathErrorf(ctx, "%q produced no files, expected exactly one", p)
return nil
} else if len(paths) > 1 {
- reportPathErrorf(ctx, "%q produced %d files, expected exactly one", p, len(paths))
+ ReportPathErrorf(ctx, "%q produced %d files, expected exactly one", p, len(paths))
}
return paths[0]
}
@@ -1447,7 +1447,7 @@
func PathForPhony(ctx PathContext, phony string) WritablePath {
if strings.ContainsAny(phony, "$/") {
- reportPathErrorf(ctx, "Phony target contains invalid character ($ or /): %s", phony)
+ ReportPathErrorf(ctx, "Phony target contains invalid character ($ or /): %s", phony)
}
return PhonyPath{basePath{phony, ctx.Config(), ""}}
}
@@ -1513,7 +1513,7 @@
func Rel(ctx PathContext, basePath string, targetPath string) string {
rel, isRel := MaybeRel(ctx, basePath, targetPath)
if !isRel {
- reportPathErrorf(ctx, "path %q is not under path %q", targetPath, basePath)
+ ReportPathErrorf(ctx, "path %q is not under path %q", targetPath, basePath)
return ""
}
return rel
diff --git a/android/testing.go b/android/testing.go
index 8a9134c..8ea4168 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -187,19 +187,21 @@
}
}
-func maybeBuildParamsFromRule(provider testBuildProvider, rule string) TestingBuildParams {
+func maybeBuildParamsFromRule(provider testBuildProvider, rule string) (TestingBuildParams, []string) {
+ var searchedRules []string
for _, p := range provider.BuildParamsForTests() {
+ searchedRules = append(searchedRules, p.Rule.String())
if strings.Contains(p.Rule.String(), rule) {
- return newTestingBuildParams(provider, p)
+ return newTestingBuildParams(provider, p), searchedRules
}
}
- return TestingBuildParams{}
+ return TestingBuildParams{}, searchedRules
}
func buildParamsFromRule(provider testBuildProvider, rule string) TestingBuildParams {
- p := maybeBuildParamsFromRule(provider, rule)
+ p, searchRules := maybeBuildParamsFromRule(provider, rule)
if p.Rule == nil {
- panic(fmt.Errorf("couldn't find rule %q", rule))
+ panic(fmt.Errorf("couldn't find rule %q.\nall rules: %v", rule, searchRules))
}
return p
}
@@ -275,7 +277,8 @@
// MaybeRule finds a call to ctx.Build with BuildParams.Rule set to a rule with the given name. Returns an empty
// BuildParams if no rule is found.
func (m TestingModule) MaybeRule(rule string) TestingBuildParams {
- return maybeBuildParamsFromRule(m.module, rule)
+ r, _ := maybeBuildParamsFromRule(m.module, rule)
+ return r
}
// Rule finds a call to ctx.Build with BuildParams.Rule set to a rule with the given name. Panics if no rule is found.
@@ -328,7 +331,8 @@
// MaybeRule finds a call to ctx.Build with BuildParams.Rule set to a rule with the given name. Returns an empty
// BuildParams if no rule is found.
func (s TestingSingleton) MaybeRule(rule string) TestingBuildParams {
- return maybeBuildParamsFromRule(s.provider, rule)
+ r, _ := maybeBuildParamsFromRule(s.provider, rule)
+ return r
}
// Rule finds a call to ctx.Build with BuildParams.Rule set to a rule with the given name. Panics if no rule is found.
diff --git a/android/variable.go b/android/variable.go
index 1f21f34..53f081e 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -166,13 +166,14 @@
Platform_min_supported_target_sdk_version *string `json:",omitempty"`
Platform_base_os *string `json:",omitempty"`
- DeviceName *string `json:",omitempty"`
- DeviceArch *string `json:",omitempty"`
- DeviceArchVariant *string `json:",omitempty"`
- DeviceCpuVariant *string `json:",omitempty"`
- DeviceAbi []string `json:",omitempty"`
- DeviceVndkVersion *string `json:",omitempty"`
- DeviceSystemSdkVersions []string `json:",omitempty"`
+ DeviceName *string `json:",omitempty"`
+ DeviceArch *string `json:",omitempty"`
+ DeviceArchVariant *string `json:",omitempty"`
+ DeviceCpuVariant *string `json:",omitempty"`
+ DeviceAbi []string `json:",omitempty"`
+ DeviceVndkVersion *string `json:",omitempty"`
+ DeviceCurrentApiLevelForVendorModules *string `json:",omitempty"`
+ DeviceSystemSdkVersions []string `json:",omitempty"`
DeviceSecondaryArch *string `json:",omitempty"`
DeviceSecondaryArchVariant *string `json:",omitempty"`
diff --git a/apex/apex.go b/apex/apex.go
index 84a1e75..f3699b0 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -41,6 +41,9 @@
imageApexType = "image"
zipApexType = "zip"
flattenedApexType = "flattened"
+
+ ext4FsType = "ext4"
+ f2fsFsType = "f2fs"
)
type dependencyTag struct {
@@ -747,18 +750,6 @@
if am, ok := mctx.Module().(android.ApexModule); ok {
availableToPlatform := am.AvailableFor(android.AvailableToPlatform)
- // In a rare case when a lib is marked as available only to an apex
- // but the apex doesn't exist. This can happen in a partial manifest branch
- // like master-art. Currently, libstatssocket in the stats APEX is causing
- // this problem.
- // Include the lib in platform because the module SDK that ought to provide
- // it doesn't exist, so it would otherwise be left out completely.
- // TODO(b/154888298) remove this by adding those libraries in module SDKS and skipping
- // this check for libraries provided by SDKs.
- if !availableToPlatform && !android.InAnyApex(am.Name()) {
- availableToPlatform = true
- }
-
// If any of the dep is not available to platform, this module is also considered
// as being not available to platform even if it has "//apex_available:platform"
mctx.VisitDirectDeps(func(child android.Module) {
@@ -1040,6 +1031,10 @@
// Should be only used in non-system apexes (e.g. vendor: true).
// Default is false.
Use_vndk_as_stable *bool
+
+ // The type of filesystem to use for an image apex. Either 'ext4' or 'f2fs'.
+ // Default 'ext4'.
+ Payload_fs_type *string
}
type apexTargetBundleProperties struct {
@@ -1247,6 +1242,24 @@
return false
}
+type fsType int
+
+const (
+ ext4 fsType = iota
+ f2fs
+)
+
+func (f fsType) string() string {
+ switch f {
+ case ext4:
+ return ext4FsType
+ case f2fs:
+ return f2fsFsType
+ default:
+ panic(fmt.Errorf("unknown APEX payload type %d", f))
+ }
+}
+
type apexBundle struct {
android.ModuleBase
android.DefaultableModuleBase
@@ -1312,6 +1325,8 @@
// Optional list of lint report zip files for apexes that contain java or app modules
lintReports android.Paths
+
+ payloadFsType fsType
}
func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext,
@@ -2284,6 +2299,15 @@
a.installDir = android.PathForModuleInstall(ctx, "apex")
a.filesInfo = filesInfo
+ switch proptools.StringDefault(a.properties.Payload_fs_type, ext4FsType) {
+ case ext4FsType:
+ a.payloadFsType = ext4
+ case f2fsFsType:
+ a.payloadFsType = f2fs
+ default:
+ ctx.PropertyErrorf("payload_fs_type", "%q is not a valid filesystem for apex [ext4, f2fs]", *a.properties.Payload_fs_type)
+ }
+
// Optimization. If we are building bundled APEX, for the files that are gathered due to the
// transitive dependencies, don't place them inside the APEX, but place a symlink pointing
// the same library in the system partition, thus effectively sharing the same libraries
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 70464fc..e9843fc 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -5399,29 +5399,6 @@
}
}
-func TestApexWithJniLibs_Errors(t *testing.T) {
- testApexError(t, `jni_libs: "xxx" is not a cc_library`, `
- apex {
- name: "myapex",
- key: "myapex.key",
- jni_libs: ["xxx"],
- }
-
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
-
- prebuilt_etc {
- name: "xxx",
- src: "xxx",
- }
- `, withFiles(map[string][]byte{
- "xxx": nil,
- }))
-}
-
func TestAppBundle(t *testing.T) {
ctx, _ := testApex(t, `
apex {
diff --git a/apex/builder.go b/apex/builder.go
index 0a1ec3e..22cd69b 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -63,6 +63,8 @@
pctx.HostBinToolVariable("jsonmodify", "jsonmodify")
pctx.HostBinToolVariable("conv_apex_manifest", "conv_apex_manifest")
pctx.HostBinToolVariable("extract_apks", "extract_apks")
+ pctx.HostBinToolVariable("make_f2fs", "make_f2fs")
+ pctx.HostBinToolVariable("sload_f2fs", "sload_f2fs")
}
var (
@@ -116,12 +118,12 @@
`--payload_type image ` +
`--key ${key} ${opt_flags} ${image_dir} ${out} `,
CommandDeps: []string{"${apexer}", "${avbtool}", "${e2fsdroid}", "${merge_zips}",
- "${mke2fs}", "${resize2fs}", "${sefcontext_compile}",
+ "${mke2fs}", "${resize2fs}", "${sefcontext_compile}", "${make_f2fs}", "${sload_f2fs}",
"${soong_zip}", "${zipalign}", "${aapt2}", "prebuilts/sdk/current/public/android.jar"},
Rspfile: "${out}.copy_commands",
RspfileContent: "${copy_commands}",
Description: "APEX ${image_dir} => ${out}",
- }, "tool_path", "image_dir", "copy_commands", "file_contexts", "canned_fs_config", "key", "opt_flags", "manifest")
+ }, "tool_path", "image_dir", "copy_commands", "file_contexts", "canned_fs_config", "key", "opt_flags", "manifest", "payload_fs_type")
zipApexRule = pctx.StaticRule("zipApexRule", blueprint.RuleParams{
Command: `rm -rf ${image_dir} && mkdir -p ${image_dir} && ` +
@@ -193,7 +195,7 @@
// collect jniLibs. Notice that a.filesInfo is already sorted
var jniLibs []string
for _, fi := range a.filesInfo {
- if fi.isJniLib {
+ if fi.isJniLib && !android.InList(fi.Stem(), jniLibs) {
jniLibs = append(jniLibs, fi.Stem())
}
}
@@ -582,6 +584,8 @@
optFlags = append(optFlags, "--manifest_json "+a.manifestJsonOut.String())
}
+ optFlags = append(optFlags, "--payload_fs_type "+a.payloadFsType.string())
+
ctx.Build(pctx, android.BuildParams{
Rule: apexRule,
Implicits: implicitInputs,
diff --git a/cc/binary.go b/cc/binary.go
index 6769fa7..b3ce5ff 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -83,7 +83,7 @@
type binaryDecorator struct {
*baseLinker
*baseInstaller
- stripper
+ stripper Stripper
Properties BinaryLinkerProperties
@@ -317,14 +317,14 @@
}
builderFlags := flagsToBuilderFlags(flags)
-
- if binary.stripper.needsStrip(ctx) {
+ stripFlags := flagsToStripFlags(flags)
+ if binary.stripper.NeedsStrip(ctx) {
if ctx.Darwin() {
- builderFlags.stripUseGnuStrip = true
+ stripFlags.StripUseGnuStrip = true
}
strippedOutputFile := outputFile
outputFile = android.PathForModuleOut(ctx, "unstripped", fileName)
- binary.stripper.stripExecutableOrSharedLib(ctx, outputFile, strippedOutputFile, builderFlags)
+ binary.stripper.StripExecutableOrSharedLib(ctx, outputFile, strippedOutputFile, stripFlags)
}
binary.unstrippedOutputFile = outputFile
@@ -333,7 +333,7 @@
afterPrefixSymbols := outputFile
outputFile = android.PathForModuleOut(ctx, "unprefixed", fileName)
TransformBinaryPrefixSymbols(ctx, String(binary.Properties.Prefix_symbols), outputFile,
- flagsToBuilderFlags(flags), afterPrefixSymbols)
+ builderFlags, afterPrefixSymbols)
}
outputFile = maybeInjectBoringSSLHash(ctx, outputFile, binary.Properties.Inject_bssl_hash, fileName)
@@ -347,10 +347,10 @@
versionedOutputFile := android.PathForModuleOut(ctx, "versioned", fileName)
binary.distFiles = android.MakeDefaultDistFiles(versionedOutputFile)
- if binary.stripper.needsStrip(ctx) {
+ if binary.stripper.NeedsStrip(ctx) {
out := android.PathForModuleOut(ctx, "versioned-stripped", fileName)
binary.distFiles = android.MakeDefaultDistFiles(out)
- binary.stripper.stripExecutableOrSharedLib(ctx, versionedOutputFile, out, builderFlags)
+ binary.stripper.StripExecutableOrSharedLib(ctx, versionedOutputFile, out, stripFlags)
}
binary.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
@@ -445,7 +445,7 @@
// The original path becomes a symlink to the corresponding file in the
// runtime APEX.
translatedArch := ctx.Target().NativeBridge == android.NativeBridgeEnabled
- if InstallToBootstrap(ctx.baseModuleName(), ctx.Config()) && !translatedArch && ctx.apexVariationName() == "" && !ctx.inRamdisk() && !ctx.inRecovery() {
+ if android.DirectlyInAnyApex(ctx, ctx.ModuleName()) && InstallToBootstrap(ctx.baseModuleName(), ctx.Config()) && !translatedArch && ctx.apexVariationName() == "" && !ctx.inRamdisk() && !ctx.inRecovery() {
if ctx.Device() && isBionic(ctx.baseModuleName()) {
binary.installSymlinkToRuntimeApex(ctx, file)
}
diff --git a/cc/builder.go b/cc/builder.go
index f2bab8c..81d2f1e 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -69,12 +69,12 @@
&remoteexec.REParams{
Labels: map[string]string{"type": "link", "tool": "clang"},
ExecStrategy: "${config.RECXXLinksExecStrategy}",
- Inputs: []string{"${out}.rsp"},
+ Inputs: []string{"${out}.rsp", "$implicitInputs"},
RSPFile: "${out}.rsp",
OutputFiles: []string{"${out}", "$implicitOutputs"},
ToolchainInputs: []string{"$ldCmd"},
Platform: map[string]string{remoteexec.PoolKey: "${config.RECXXLinksPool}"},
- }, []string{"ldCmd", "crtBegin", "libFlags", "crtEnd", "ldFlags", "extraLibFlags"}, []string{"implicitOutputs"})
+ }, []string{"ldCmd", "crtBegin", "libFlags", "crtEnd", "ldFlags", "extraLibFlags"}, []string{"implicitInputs", "implicitOutputs"})
partialLd, partialLdRE = remoteexec.StaticRules(pctx, "partialLd",
blueprint.RuleParams{
@@ -83,12 +83,13 @@
Command: "$reTemplate$ldCmd -fuse-ld=lld -nostdlib -no-pie -Wl,-r ${in} -o ${out} ${ldFlags}",
CommandDeps: []string{"$ldCmd"},
}, &remoteexec.REParams{
- Labels: map[string]string{"type": "link", "tool": "clang"},
- ExecStrategy: "${config.RECXXLinksExecStrategy}", Inputs: []string{"$inCommaList"},
+ Labels: map[string]string{"type": "link", "tool": "clang"},
+ ExecStrategy: "${config.RECXXLinksExecStrategy}",
+ Inputs: []string{"$inCommaList", "$implicitInputs"},
OutputFiles: []string{"${out}", "$implicitOutputs"},
ToolchainInputs: []string{"$ldCmd"},
Platform: map[string]string{remoteexec.PoolKey: "${config.RECXXLinksPool}"},
- }, []string{"ldCmd", "ldFlags"}, []string{"inCommaList", "implicitOutputs"})
+ }, []string{"ldCmd", "ldFlags"}, []string{"implicitInputs", "inCommaList", "implicitOutputs"})
ar = pctx.AndroidStaticRule("ar",
blueprint.RuleParams{
@@ -236,12 +237,12 @@
}, &remoteexec.REParams{
Labels: map[string]string{"type": "tool", "name": "abi-linker"},
ExecStrategy: "${config.REAbiLinkerExecStrategy}",
- Inputs: []string{"$sAbiLinkerLibs", "${out}.rsp", "$implicits"},
+ Inputs: []string{"$sAbiLinkerLibs", "${out}.rsp", "$implicitInputs"},
RSPFile: "${out}.rsp",
OutputFiles: []string{"$out"},
ToolchainInputs: []string{"$sAbiLinker"},
Platform: map[string]string{remoteexec.PoolKey: "${config.RECXXPool}"},
- }, []string{"symbolFilter", "arch", "exportedHeaderFlags"}, []string{"implicits"})
+ }, []string{"symbolFilter", "arch", "exportedHeaderFlags"}, []string{"implicitInputs"})
_ = pctx.SourcePathVariable("sAbiDiffer", "prebuilts/clang-tools/${config.HostPrebuiltTag}/bin/header-abi-diff")
@@ -349,18 +350,22 @@
groupStaticLibs bool
- stripKeepSymbols bool
- stripKeepSymbolsList string
- stripKeepSymbolsAndDebugFrame bool
- stripKeepMiniDebugInfo bool
- stripAddGnuDebuglink bool
- stripUseGnuStrip bool
-
proto android.ProtoFlags
protoC bool
protoOptionsFile bool
yacc *YaccProperties
+ lex *LexProperties
+}
+
+type StripFlags struct {
+ Toolchain config.Toolchain
+ StripKeepSymbols bool
+ StripKeepSymbolsList string
+ StripKeepSymbolsAndDebugFrame bool
+ StripKeepMiniDebugInfo bool
+ StripAddGnuDebuglink bool
+ StripUseGnuStrip bool
}
type Objects struct {
@@ -743,6 +748,7 @@
if ctx.Config().IsEnvTrue("RBE_CXX_LINKS") {
rule = ldRE
args["implicitOutputs"] = strings.Join(implicitOutputs.Strings(), ",")
+ args["implicitInputs"] = strings.Join(deps.Strings(), ",")
}
ctx.Build(pctx, android.BuildParams{
@@ -792,7 +798,7 @@
rbeImplicits = append(rbeImplicits, p[2:])
}
}
- args["implicits"] = strings.Join(rbeImplicits, ",")
+ args["implicitInputs"] = strings.Join(rbeImplicits, ",")
}
ctx.Build(pctx, android.BuildParams{
Rule: rule,
@@ -909,6 +915,7 @@
if ctx.Config().IsEnvTrue("RBE_CXX_LINKS") {
rule = partialLdRE
args["inCommaList"] = strings.Join(objFiles.Strings(), ",")
+ args["implicitInputs"] = strings.Join(deps.Strings(), ",")
}
ctx.Build(pctx, android.BuildParams{
Rule: rule,
@@ -939,26 +946,26 @@
}
func TransformStrip(ctx android.ModuleContext, inputFile android.Path,
- outputFile android.WritablePath, flags builderFlags) {
+ outputFile android.WritablePath, flags StripFlags) {
- crossCompile := gccCmd(flags.toolchain, "")
+ crossCompile := gccCmd(flags.Toolchain, "")
args := ""
- if flags.stripAddGnuDebuglink {
+ if flags.StripAddGnuDebuglink {
args += " --add-gnu-debuglink"
}
- if flags.stripKeepMiniDebugInfo {
+ if flags.StripKeepMiniDebugInfo {
args += " --keep-mini-debug-info"
}
- if flags.stripKeepSymbols {
+ if flags.StripKeepSymbols {
args += " --keep-symbols"
}
- if flags.stripKeepSymbolsList != "" {
- args += " -k" + flags.stripKeepSymbolsList
+ if flags.StripKeepSymbolsList != "" {
+ args += " -k" + flags.StripKeepSymbolsList
}
- if flags.stripKeepSymbolsAndDebugFrame {
+ if flags.StripKeepSymbolsAndDebugFrame {
args += " --keep-symbols-and-debug-frame"
}
- if flags.stripUseGnuStrip {
+ if flags.StripUseGnuStrip {
args += " --use-gnu-strip"
}
diff --git a/cc/cc.go b/cc/cc.go
index 9bf9c84..9196d47 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -210,6 +210,7 @@
protoOptionsFile bool // Whether to look for a .options file next to the .proto
Yacc *YaccProperties
+ Lex *LexProperties
}
// Properties used to compile all C or C++ modules
diff --git a/cc/compiler.go b/cc/compiler.go
index e06243b..f504c38 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -111,6 +111,7 @@
Gnu_extensions *bool
Yacc *YaccProperties
+ Lex *LexProperties
Aidl struct {
// list of directories that will be added to the aidl include paths.
@@ -189,8 +190,14 @@
// Build and link with OpenMP
Openmp *bool `android:"arch_variant"`
+ // Deprecated.
// Adds __ANDROID_APEX_<APEX_MODULE_NAME>__ macro defined for apex variants in addition to __ANDROID_APEX__
Use_apex_name_macro *bool
+
+ // Adds two macros for apex variants in addition to __ANDROID_APEX__
+ // * __ANDROID_APEX_COM_ANDROID_FOO__
+ // * __ANDROID_APEX_NAME__="com.android.foo"
+ UseApexNameMacro bool `blueprint:"mutated"`
}
func NewBaseCompiler() *baseCompiler {
@@ -254,6 +261,10 @@
return deps
}
+func (compiler *baseCompiler) useApexNameMacro() bool {
+ return Bool(compiler.Properties.Use_apex_name_macro) || compiler.Properties.UseApexNameMacro
+}
+
// Return true if the module is in the WarningAllowedProjects.
func warningsAreAllowed(subdir string) bool {
subdir += "/"
@@ -289,6 +300,7 @@
flags.Local.YasmFlags = append(flags.Local.YasmFlags, esc(compiler.Properties.Asflags)...)
flags.Yacc = compiler.Properties.Yacc
+ flags.Lex = compiler.Properties.Lex
// Include dir cflags
localIncludeDirs := android.PathsForModuleSrc(ctx, compiler.Properties.Local_include_dirs)
@@ -337,8 +349,9 @@
if ctx.apexVariationName() != "" {
flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_APEX__")
- if Bool(compiler.Properties.Use_apex_name_macro) {
+ if compiler.useApexNameMacro() {
flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_APEX_"+makeDefineString(ctx.apexVariationName())+"__")
+ flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_APEX_NAME__='\""+ctx.apexVariationName()+"\"'")
}
if ctx.Device() {
flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_SDK_VERSION__="+strconv.Itoa(ctx.apexSdkVersion()))
@@ -557,7 +570,7 @@
}
func (compiler *baseCompiler) uniqueApexVariations() bool {
- return Bool(compiler.Properties.Use_apex_name_macro)
+ return compiler.useApexNameMacro()
}
// makeDefineString transforms a name of an APEX module into a value to be used as value for C define
diff --git a/cc/gen.go b/cc/gen.go
index b0aadc6..ccc3d0e 100644
--- a/cc/gen.go
+++ b/cc/gen.go
@@ -34,9 +34,9 @@
var (
lex = pctx.AndroidStaticRule("lex",
blueprint.RuleParams{
- Command: "M4=$m4Cmd $lexCmd -o$out $in",
+ Command: "M4=$m4Cmd $lexCmd $flags -o$out $in",
CommandDeps: []string{"$lexCmd", "$m4Cmd"},
- })
+ }, "flags")
sysprop = pctx.AndroidStaticRule("sysprop",
blueprint.RuleParams{
@@ -153,12 +153,23 @@
}
}
-func genLex(ctx android.ModuleContext, lexFile android.Path, outFile android.ModuleGenPath) {
+type LexProperties struct {
+ // list of module-specific flags that will be used for .l and .ll compiles
+ Flags []string
+}
+
+func genLex(ctx android.ModuleContext, lexFile android.Path, outFile android.ModuleGenPath, props *LexProperties) {
+ var flags []string
+ if props != nil {
+ flags = props.Flags
+ }
+ flagsString := strings.Join(flags[:], " ")
ctx.Build(pctx, android.BuildParams{
Rule: lex,
Description: "lex " + lexFile.Rel(),
Output: outFile,
Input: lexFile,
+ Args: map[string]string{"flags": flagsString},
})
}
@@ -235,11 +246,11 @@
case ".l":
cFile := android.GenPathWithExt(ctx, "lex", srcFile, "c")
srcFiles[i] = cFile
- genLex(ctx, srcFile, cFile)
+ genLex(ctx, srcFile, cFile, buildFlags.lex)
case ".ll":
cppFile := android.GenPathWithExt(ctx, "lex", srcFile, "cpp")
srcFiles[i] = cppFile
- genLex(ctx, srcFile, cppFile)
+ genLex(ctx, srcFile, cppFile, buildFlags.lex)
case ".proto":
ccFile, headerFile := genProto(ctx, srcFile, buildFlags)
srcFiles[i] = ccFile
diff --git a/cc/library.go b/cc/library.go
index 1c2b1ee..92853b5 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -336,7 +336,7 @@
tocFile android.OptionalPath
flagExporter
- stripper
+ stripper Stripper
// If we're used as a whole_static_lib, our missing dependencies need
// to be given
@@ -955,13 +955,14 @@
library.tocFile = android.OptionalPathForPath(tocFile)
TransformSharedObjectToToc(ctx, outputFile, tocFile, builderFlags)
- if library.stripper.needsStrip(ctx) {
+ stripFlags := flagsToStripFlags(flags)
+ if library.stripper.NeedsStrip(ctx) {
if ctx.Darwin() {
- builderFlags.stripUseGnuStrip = true
+ stripFlags.StripUseGnuStrip = true
}
strippedOutputFile := outputFile
outputFile = android.PathForModuleOut(ctx, "unstripped", fileName)
- library.stripper.stripExecutableOrSharedLib(ctx, outputFile, strippedOutputFile, builderFlags)
+ library.stripper.StripExecutableOrSharedLib(ctx, outputFile, strippedOutputFile, stripFlags)
}
library.unstrippedOutputFile = outputFile
@@ -976,10 +977,10 @@
versionedOutputFile := android.PathForModuleOut(ctx, "versioned", fileName)
library.distFile = versionedOutputFile
- if library.stripper.needsStrip(ctx) {
+ if library.stripper.NeedsStrip(ctx) {
out := android.PathForModuleOut(ctx, "versioned-stripped", fileName)
library.distFile = out
- library.stripper.stripExecutableOrSharedLib(ctx, versionedOutputFile, out, builderFlags)
+ library.stripper.StripExecutableOrSharedLib(ctx, versionedOutputFile, out, stripFlags)
}
library.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
@@ -1027,6 +1028,10 @@
return library.unstrippedOutputFile
}
+func (library *libraryDecorator) disableStripping() {
+ library.stripper.StripProperties.Strip.None = BoolPtr(true)
+}
+
func (library *libraryDecorator) nativeCoverage() bool {
if library.header() || library.buildStubs() {
return false
diff --git a/cc/llndk_library.go b/cc/llndk_library.go
index 71c9204..b3f9d61 100644
--- a/cc/llndk_library.go
+++ b/cc/llndk_library.go
@@ -179,7 +179,7 @@
library.BuildOnlyShared()
module.stl = nil
module.sanitize = nil
- library.StripProperties.Strip.None = BoolPtr(true)
+ library.disableStripping()
stub := &llndkStubDecorator{
libraryDecorator: library,
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index 58e742e..fe3efc0 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -405,7 +405,7 @@
library.BuildOnlyShared()
module.stl = nil
module.sanitize = nil
- library.StripProperties.Strip.None = BoolPtr(true)
+ library.disableStripping()
stub := &stubDecorator{
libraryDecorator: library,
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index baf43ce..3af65d6 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -125,9 +125,10 @@
outputFile := android.PathForModuleOut(ctx, libName)
var implicits android.Paths
- if p.needsStrip(ctx) {
+ if p.stripper.NeedsStrip(ctx) {
+ stripFlags := flagsToStripFlags(flags)
stripped := android.PathForModuleOut(ctx, "stripped", libName)
- p.stripExecutableOrSharedLib(ctx, in, stripped, builderFlags)
+ p.stripper.StripExecutableOrSharedLib(ctx, in, stripped, stripFlags)
in = stripped
}
@@ -331,16 +332,16 @@
flags Flags, deps PathDeps, objs Objects) android.Path {
// TODO(ccross): verify shared library dependencies
if len(p.properties.Srcs) > 0 {
- builderFlags := flagsToBuilderFlags(flags)
+ stripFlags := flagsToStripFlags(flags)
fileName := p.getStem(ctx) + flags.Toolchain.ExecutableSuffix()
in := p.Prebuilt.SingleSourcePath(ctx)
p.unstrippedOutputFile = in
- if p.needsStrip(ctx) {
+ if p.stripper.NeedsStrip(ctx) {
stripped := android.PathForModuleOut(ctx, "stripped", fileName)
- p.stripExecutableOrSharedLib(ctx, in, stripped, builderFlags)
+ p.stripper.StripExecutableOrSharedLib(ctx, in, stripped, stripFlags)
in = stripped
}
diff --git a/cc/strip.go b/cc/strip.go
index 7e560ec..18150dc 100644
--- a/cc/strip.go
+++ b/cc/strip.go
@@ -30,42 +30,42 @@
} `android:"arch_variant"`
}
-type stripper struct {
+type Stripper struct {
StripProperties StripProperties
}
-func (stripper *stripper) needsStrip(ctx ModuleContext) bool {
+func (stripper *Stripper) NeedsStrip(actx android.ModuleContext) bool {
// TODO(ccross): enable host stripping when embedded in make? Make never had support for stripping host binaries.
- return (!ctx.Config().EmbeddedInMake() || ctx.Device()) && !Bool(stripper.StripProperties.Strip.None)
+ return (!actx.Config().EmbeddedInMake() || actx.Device()) && !Bool(stripper.StripProperties.Strip.None)
}
-func (stripper *stripper) strip(ctx ModuleContext, in android.Path, out android.ModuleOutPath,
- flags builderFlags, isStaticLib bool) {
- if ctx.Darwin() {
- TransformDarwinStrip(ctx, in, out)
+func (stripper *Stripper) strip(actx android.ModuleContext, in android.Path, out android.ModuleOutPath,
+ flags StripFlags, isStaticLib bool) {
+ if actx.Darwin() {
+ TransformDarwinStrip(actx, in, out)
} else {
if Bool(stripper.StripProperties.Strip.Keep_symbols) {
- flags.stripKeepSymbols = true
+ flags.StripKeepSymbols = true
} else if Bool(stripper.StripProperties.Strip.Keep_symbols_and_debug_frame) {
- flags.stripKeepSymbolsAndDebugFrame = true
+ flags.StripKeepSymbolsAndDebugFrame = true
} else if len(stripper.StripProperties.Strip.Keep_symbols_list) > 0 {
- flags.stripKeepSymbolsList = strings.Join(stripper.StripProperties.Strip.Keep_symbols_list, ",")
+ flags.StripKeepSymbolsList = strings.Join(stripper.StripProperties.Strip.Keep_symbols_list, ",")
} else if !Bool(stripper.StripProperties.Strip.All) {
- flags.stripKeepMiniDebugInfo = true
+ flags.StripKeepMiniDebugInfo = true
}
- if ctx.Config().Debuggable() && !flags.stripKeepMiniDebugInfo && !isStaticLib {
- flags.stripAddGnuDebuglink = true
+ if actx.Config().Debuggable() && !flags.StripKeepMiniDebugInfo && !isStaticLib {
+ flags.StripAddGnuDebuglink = true
}
- TransformStrip(ctx, in, out, flags)
+ TransformStrip(actx, in, out, flags)
}
}
-func (stripper *stripper) stripExecutableOrSharedLib(ctx ModuleContext, in android.Path,
- out android.ModuleOutPath, flags builderFlags) {
- stripper.strip(ctx, in, out, flags, false)
+func (stripper *Stripper) StripExecutableOrSharedLib(actx android.ModuleContext, in android.Path,
+ out android.ModuleOutPath, flags StripFlags) {
+ stripper.strip(actx, in, out, flags, false)
}
-func (stripper *stripper) stripStaticLib(ctx ModuleContext, in android.Path, out android.ModuleOutPath,
- flags builderFlags) {
- stripper.strip(ctx, in, out, flags, true)
+func (stripper *Stripper) StripStaticLib(actx android.ModuleContext, in android.Path, out android.ModuleOutPath,
+ flags StripFlags) {
+ stripper.strip(actx, in, out, flags, true)
}
diff --git a/cc/toolchain_library.go b/cc/toolchain_library.go
index 042e012..19f5ea4 100644
--- a/cc/toolchain_library.go
+++ b/cc/toolchain_library.go
@@ -36,8 +36,7 @@
type toolchainLibraryDecorator struct {
*libraryDecorator
-
- stripper
+ stripper Stripper
Properties toolchainLibraryProperties
}
@@ -89,8 +88,8 @@
if library.stripper.StripProperties.Strip.Keep_symbols_list != nil {
fileName := ctx.ModuleName() + staticLibraryExtension
outputFile := android.PathForModuleOut(ctx, fileName)
- buildFlags := flagsToBuilderFlags(flags)
- library.stripper.stripStaticLib(ctx, srcPath, outputFile, buildFlags)
+ stripFlags := flagsToStripFlags(flags)
+ library.stripper.StripStaticLib(ctx, srcPath, outputFile, stripFlags)
return outputFile
}
diff --git a/cc/util.go b/cc/util.go
index af26268..40374bf 100644
--- a/cc/util.go
+++ b/cc/util.go
@@ -97,9 +97,14 @@
protoOptionsFile: in.protoOptionsFile,
yacc: in.Yacc,
+ lex: in.Lex,
}
}
+func flagsToStripFlags(in Flags) StripFlags {
+ return StripFlags{Toolchain: in.Toolchain}
+}
+
func addPrefix(list []string, prefix string) []string {
for i := range list {
list[i] = prefix + list[i]
diff --git a/cc/vendor_public_library.go b/cc/vendor_public_library.go
index e9d1c73..85f514c 100644
--- a/cc/vendor_public_library.go
+++ b/cc/vendor_public_library.go
@@ -144,7 +144,7 @@
library.BuildOnlyShared()
module.stl = nil
module.sanitize = nil
- library.StripProperties.Strip.None = BoolPtr(true)
+ library.disableStripping()
stub := &vendorPublicLibraryStubDecorator{
libraryDecorator: library,
diff --git a/cc/vendor_snapshot.go b/cc/vendor_snapshot.go
index e17a6d0..93aece4 100644
--- a/cc/vendor_snapshot.go
+++ b/cc/vendor_snapshot.go
@@ -264,7 +264,7 @@
module.stl = nil
module.sanitize = nil
- library.StripProperties.Strip.None = BoolPtr(true)
+ library.disableStripping()
prebuilt := &vendorSnapshotLibraryDecorator{
libraryDecorator: library,
@@ -340,12 +340,12 @@
}
in := android.PathForModuleSrc(ctx, *p.properties.Src)
- builderFlags := flagsToBuilderFlags(flags)
+ stripFlags := flagsToStripFlags(flags)
p.unstrippedOutputFile = in
binName := in.Base()
- if p.needsStrip(ctx) {
+ if p.stripper.NeedsStrip(ctx) {
stripped := android.PathForModuleOut(ctx, "stripped", binName)
- p.stripExecutableOrSharedLib(ctx, in, stripped, builderFlags)
+ p.stripper.StripExecutableOrSharedLib(ctx, in, stripped, stripFlags)
in = stripped
}
diff --git a/cc/vndk_prebuilt.go b/cc/vndk_prebuilt.go
index 5a44c46..9484760 100644
--- a/cc/vndk_prebuilt.go
+++ b/cc/vndk_prebuilt.go
@@ -142,9 +142,10 @@
builderFlags := flagsToBuilderFlags(flags)
p.unstrippedOutputFile = in
libName := in.Base()
- if p.needsStrip(ctx) {
+ if p.stripper.NeedsStrip(ctx) {
+ stripFlags := flagsToStripFlags(flags)
stripped := android.PathForModuleOut(ctx, "stripped", libName)
- p.stripExecutableOrSharedLib(ctx, in, stripped, builderFlags)
+ p.stripper.StripExecutableOrSharedLib(ctx, in, stripped, stripFlags)
in = stripped
}
@@ -213,7 +214,7 @@
library.BuildOnlyShared()
module.stl = nil
module.sanitize = nil
- library.StripProperties.Strip.None = BoolPtr(true)
+ library.disableStripping()
prebuilt := &vndkPrebuiltLibraryDecorator{
libraryDecorator: library,
diff --git a/dexpreopt/config.go b/dexpreopt/config.go
index 78f91df..f22ee47 100644
--- a/dexpreopt/config.go
+++ b/dexpreopt/config.go
@@ -111,12 +111,9 @@
// LibraryPaths is a map from library name to on-host and on-device paths to its DEX jar.
type LibraryPaths map[string]*LibraryPath
-// Add a new path to the map of library paths, unless a path for this library already exists.
-func (libPaths LibraryPaths) AddLibraryPath(ctx android.PathContext, lib *string, hostPath, installPath android.Path) {
- if lib == nil {
- return
- }
- if _, present := libPaths[*lib]; !present {
+// Add a new library path to the map, unless a path for this library already exists.
+func (libPaths LibraryPaths) addLibraryPath(ctx android.PathContext, lib string, hostPath, installPath android.Path) {
+ if _, present := libPaths[lib]; !present {
var devicePath string
if installPath != nil {
devicePath = android.InstallPathToOnDevicePath(ctx, installPath.(android.InstallPath))
@@ -127,9 +124,30 @@
// but we cannot use if for dexpreopt.
devicePath = UnknownInstallLibraryPath
}
- libPaths[*lib] = &LibraryPath{hostPath, devicePath}
+ libPaths[lib] = &LibraryPath{hostPath, devicePath}
}
- return
+}
+
+// Add a new library path to the map. Ensure that the build path to the library exists.
+func (libPaths LibraryPaths) AddLibraryPath(ctx android.PathContext, lib string, hostPath, installPath android.Path) {
+ if hostPath != nil {
+ // Add a library only if the build path to it is known.
+ libPaths.addLibraryPath(ctx, lib, hostPath, installPath)
+ } else if !ctx.Config().AllowMissingDependencies() {
+ // Error on libraries with unknown build paths, unless missing dependencies are allowed.
+ android.ReportPathErrorf(ctx, "unknown build path to <uses-library> '%s'", lib)
+ } else {
+ // Not adding a library to the map will likely result in disabling dexpreopt.
+ }
+}
+
+// Add a new library path to the map, if the library exists (name is not nil).
+func (libPaths LibraryPaths) MaybeAddLibraryPath(ctx android.PathContext, lib *string, hostPath, installPath android.Path) {
+ if lib != nil {
+ // Don't check the build paths, add in any case. Some libraries may be missing from the
+ // build, but their names still need to be added to <uses-library> tags in the manifest.
+ libPaths.addLibraryPath(ctx, *lib, hostPath, installPath)
+ }
}
// Add library paths from the second map to the first map (do not override existing entries).
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index 8deb0a3..4dbda49 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -81,15 +81,14 @@
}
if !dexpreoptDisabled(ctx, global, module) {
- // Don't preopt individual boot jars, they will be preopted together.
- if !global.BootJars.ContainsJar(module.Name) {
+ if clc := genClassLoaderContext(ctx, global, module); clc != nil {
appImage := (generateProfile || module.ForceCreateAppImage || global.DefaultAppImages) &&
!module.NoCreateAppImage
generateDM := shouldGenerateDM(module, global)
for archIdx, _ := range module.Archs {
- dexpreoptCommand(ctx, globalSoong, global, module, rule, archIdx, profile, appImage, generateDM)
+ dexpreoptCommand(ctx, globalSoong, global, module, rule, archIdx, *clc, profile, appImage, generateDM)
}
}
}
@@ -102,6 +101,11 @@
return true
}
+ // Don't preopt individual boot jars, they will be preopted together.
+ if global.BootJars.ContainsJar(module.Name) {
+ return true
+ }
+
// Don't preopt system server jars that are updatable.
if global.UpdatableSystemServerJars.ContainsJar(module.Name) {
return true
@@ -214,13 +218,17 @@
return m[sdkVer]
}
-func (m classLoaderContextMap) addLibs(sdkVer int, module *ModuleConfig, libs ...string) {
+func (m classLoaderContextMap) addLibs(sdkVer int, module *ModuleConfig, libs ...string) bool {
clc := m.getValue(sdkVer)
for _, lib := range libs {
- p := pathForLibrary(module, lib)
- clc.Host = append(clc.Host, p.Host)
- clc.Target = append(clc.Target, p.Device)
+ if p := pathForLibrary(module, lib); p != nil {
+ clc.Host = append(clc.Host, p.Host)
+ clc.Target = append(clc.Target, p.Device)
+ } else {
+ return false
+ }
}
+ return true
}
func (m classLoaderContextMap) addSystemServerLibs(sdkVer int, ctx android.PathContext, module *ModuleConfig, libs ...string) {
@@ -231,9 +239,79 @@
}
}
+// genClassLoaderContext generates host and target class loader context to be passed to the dex2oat
+// command for the dexpreopted module. There are three possible cases:
+//
+// 1. System server jars. They have a special class loader context that includes other system
+// server jars.
+//
+// 2. Library jars or APKs which have precise list of their <uses-library> libs. Their class loader
+// context includes build and on-device paths to these libs. In some cases it may happen that
+// the path to a <uses-library> is unknown (e.g. the dexpreopted module may depend on stubs
+// library, whose implementation library is missing from the build altogether). In such case
+// dexpreopting with the <uses-library> is impossible, and dexpreopting without it is pointless,
+// as the runtime classpath won't match and the dexpreopted code will be discarded. Therefore in
+// such cases the function returns nil, which disables dexpreopt.
+//
+// 2. All other library jars or APKs for which the exact <uses-library> list is unknown. They use
+// the unsafe &-classpath workaround that means empty class loader context and absence of runtime
+// check that the class loader context provided by the PackageManager agrees with the stored
+// class loader context recorded in the .odex file.
+//
+func genClassLoaderContext(ctx android.PathContext, global *GlobalConfig, module *ModuleConfig) *classLoaderContextMap {
+ classLoaderContexts := make(classLoaderContextMap)
+ systemServerJars := NonUpdatableSystemServerJars(ctx, global)
+
+ if jarIndex := android.IndexList(module.Name, systemServerJars); jarIndex >= 0 {
+ // System server jars should be dexpreopted together: class loader context of each jar
+ // should include all preceding jars on the system server classpath.
+ classLoaderContexts.addSystemServerLibs(anySdkVersion, ctx, module, systemServerJars[:jarIndex]...)
+
+ } else if module.EnforceUsesLibraries {
+ // Unconditional class loader context.
+ usesLibs := append(copyOf(module.UsesLibraries), module.OptionalUsesLibraries...)
+ if !classLoaderContexts.addLibs(anySdkVersion, module, usesLibs...) {
+ return nil
+ }
+
+ // Conditional class loader context for API version < 28.
+ const httpLegacy = "org.apache.http.legacy"
+ if !contains(usesLibs, httpLegacy) {
+ if !classLoaderContexts.addLibs(28, module, httpLegacy) {
+ return nil
+ }
+ }
+
+ // Conditional class loader context for API version < 29.
+ usesLibs29 := []string{
+ "android.hidl.base-V1.0-java",
+ "android.hidl.manager-V1.0-java",
+ }
+ if !classLoaderContexts.addLibs(29, module, usesLibs29...) {
+ return nil
+ }
+
+ // Conditional class loader context for API version < 30.
+ const testBase = "android.test.base"
+ if !contains(usesLibs, testBase) {
+ if !classLoaderContexts.addLibs(30, module, testBase) {
+ return nil
+ }
+ }
+
+ } else {
+ // Pass special class loader context to skip the classpath and collision check.
+ // This will get removed once LOCAL_USES_LIBRARIES is enforced.
+ // Right now LOCAL_USES_LIBRARIES is opt in, for the case where it's not specified we still default
+ // to the &.
+ }
+
+ return &classLoaderContexts
+}
+
func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, global *GlobalConfig,
- module *ModuleConfig, rule *android.RuleBuilder, archIdx int, profile android.WritablePath,
- appImage bool, generateDM bool) {
+ module *ModuleConfig, rule *android.RuleBuilder, archIdx int, classLoaderContexts classLoaderContextMap,
+ profile android.WritablePath, appImage bool, generateDM bool) {
arch := module.Archs[archIdx]
@@ -264,17 +342,12 @@
invocationPath := odexPath.ReplaceExtension(ctx, "invocation")
- classLoaderContexts := make(classLoaderContextMap)
systemServerJars := NonUpdatableSystemServerJars(ctx, global)
rule.Command().FlagWithArg("mkdir -p ", filepath.Dir(odexPath.String()))
rule.Command().FlagWithOutput("rm -f ", odexPath)
if jarIndex := android.IndexList(module.Name, systemServerJars); jarIndex >= 0 {
- // System server jars should be dexpreopted together: class loader context of each jar
- // should include all preceding jars on the system server classpath.
- classLoaderContexts.addSystemServerLibs(anySdkVersion, ctx, module, systemServerJars[:jarIndex]...)
-
// Copy the system server jar to a predefined location where dex2oat will find it.
dexPathHost := SystemServerDexJarHostPath(ctx, module.Name)
rule.Command().Text("mkdir -p").Flag(filepath.Dir(dexPathHost.String()))
@@ -288,29 +361,6 @@
Implicits(clc.Host).
Text("stored_class_loader_context_arg=--stored-class-loader-context=PCL[" + strings.Join(clc.Target, ":") + "]")
} else if module.EnforceUsesLibraries {
- // Unconditional class loader context.
- usesLibs := append(copyOf(module.UsesLibraries), module.OptionalUsesLibraries...)
- classLoaderContexts.addLibs(anySdkVersion, module, usesLibs...)
-
- // Conditional class loader context for API version < 28.
- const httpLegacy = "org.apache.http.legacy"
- if !contains(usesLibs, httpLegacy) {
- classLoaderContexts.addLibs(28, module, httpLegacy)
- }
-
- // Conditional class loader context for API version < 29.
- usesLibs29 := []string{
- "android.hidl.base-V1.0-java",
- "android.hidl.manager-V1.0-java",
- }
- classLoaderContexts.addLibs(29, module, usesLibs29...)
-
- // Conditional class loader context for API version < 30.
- const testBase = "android.test.base"
- if !contains(usesLibs, testBase) {
- classLoaderContexts.addLibs(30, module, testBase)
- }
-
// Generate command that saves target SDK version in a shell variable.
if module.ManifestPath != nil {
rule.Command().Text(`target_sdk_version="$(`).
@@ -540,11 +590,11 @@
}
func pathForLibrary(module *ModuleConfig, lib string) *LibraryPath {
- path, ok := module.LibraryPaths[lib]
- if !ok {
- panic(fmt.Errorf("unknown library path for %q", lib))
+ if path, ok := module.LibraryPaths[lib]; ok && path.Host != nil && path.Device != "error" {
+ return path
+ } else {
+ return nil
}
- return path
}
func makefileMatch(pattern, s string) bool {
diff --git a/java/aar.go b/java/aar.go
index 5c19a9c..0f5e30d 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -390,7 +390,7 @@
// (including the java_sdk_library) itself then append any implicit sdk library
// names to the list of sdk libraries to be added to the manifest.
if component, ok := module.(SdkLibraryComponentDependency); ok {
- sdkLibraries.AddLibraryPath(ctx, component.OptionalImplicitSdkLibrary(),
+ sdkLibraries.MaybeAddLibraryPath(ctx, component.OptionalImplicitSdkLibrary(),
component.DexJarBuildPath(), component.DexJarInstallPath())
}
diff --git a/java/app.go b/java/app.go
index 5e3a9d9..34f96dd 100755
--- a/java/app.go
+++ b/java/app.go
@@ -586,7 +586,7 @@
return android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
}
-func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) android.Path {
+func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext, sdkLibs dexpreopt.LibraryPaths) android.Path {
a.dexpreopter.installPath = a.installPath(ctx)
if a.dexProperties.Uncompress_dex == nil {
// If the value was not force-set by the user, use reasonable default based on the module.
@@ -597,6 +597,7 @@
a.dexpreopter.usesLibs = a.usesLibrary.usesLibraryProperties.Uses_libs
a.dexpreopter.optionalUsesLibs = a.usesLibrary.presentOptionalUsesLibs(ctx)
a.dexpreopter.libraryPaths = a.usesLibrary.usesLibraryPaths(ctx)
+ a.dexpreopter.libraryPaths.AddLibraryPaths(sdkLibs)
a.dexpreopter.manifestFile = a.mergedManifestFile
a.exportedSdkLibs = make(dexpreopt.LibraryPaths)
@@ -767,6 +768,15 @@
// Process all building blocks, from AAPT to certificates.
a.aaptBuildActions(ctx)
+ // The decision to enforce <uses-library> checks is made before adding implicit SDK libraries.
+ a.usesLibrary.freezeEnforceUsesLibraries()
+
+ // Add implicit SDK libraries to <uses-library> list.
+ for _, usesLib := range android.SortedStringKeys(a.aapt.sdkLibraries) {
+ a.usesLibrary.addLib(usesLib, inList(usesLib, optionalUsesLibs))
+ }
+
+ // Check that the <uses-library> list is coherent with the manifest.
if a.usesLibrary.enforceUsesLibraries() {
manifestCheckFile := a.usesLibrary.verifyUsesLibrariesManifest(ctx, a.mergedManifestFile)
apkDeps = append(apkDeps, manifestCheckFile)
@@ -779,7 +789,7 @@
a.linter.resources = a.aapt.resourceFiles
a.linter.buildModuleReportZip = ctx.Config().UnbundledBuildApps()
- dexJarFile := a.dexBuildActions(ctx)
+ dexJarFile := a.dexBuildActions(ctx, a.aapt.sdkLibraries)
jniLibs, certificateDeps := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), !Bool(a.appProperties.Jni_uses_platform_apis))
jniJarFile := a.jniBuildActions(jniLibs, ctx)
@@ -1888,6 +1898,16 @@
usesLibraryProperties UsesLibraryProperties
}
+func (u *usesLibrary) addLib(lib string, optional bool) {
+ if !android.InList(lib, u.usesLibraryProperties.Uses_libs) && !android.InList(lib, u.usesLibraryProperties.Optional_uses_libs) {
+ if optional {
+ u.usesLibraryProperties.Optional_uses_libs = append(u.usesLibraryProperties.Optional_uses_libs, lib)
+ } else {
+ u.usesLibraryProperties.Uses_libs = append(u.usesLibraryProperties.Uses_libs, lib)
+ }
+ }
+}
+
func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, hasFrameworkLibs bool) {
if !ctx.Config().UnbundledBuild() {
ctx.AddVariationDependencies(nil, usesLibTag, u.usesLibraryProperties.Uses_libs...)
@@ -1960,6 +1980,12 @@
return BoolDefault(u.usesLibraryProperties.Enforce_uses_libs, defaultEnforceUsesLibs)
}
+// Freeze the value of `enforce_uses_libs` based on the current values of `uses_libs` and `optional_uses_libs`.
+func (u *usesLibrary) freezeEnforceUsesLibraries() {
+ enforce := u.enforceUsesLibraries()
+ u.usesLibraryProperties.Enforce_uses_libs = &enforce
+}
+
// verifyUsesLibrariesManifest checks the <uses-library> tags in an AndroidManifest.xml against the ones specified
// in the uses_libs and optional_uses_libs properties. It returns the path to a copy of the manifest.
func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, manifest android.Path) android.Path {
diff --git a/java/app_test.go b/java/app_test.go
index 6b27124..b8d8616 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -1038,6 +1038,35 @@
}
}
+func checkSdkVersion(t *testing.T, config android.Config, expectedSdkVersion string) {
+ ctx := testContext()
+
+ run(t, ctx, config)
+
+ foo := ctx.ModuleForTests("foo", "android_common")
+ link := foo.Output("package-res.apk")
+ linkFlags := strings.Split(link.Args["flags"], " ")
+ min := android.IndexList("--min-sdk-version", linkFlags)
+ target := android.IndexList("--target-sdk-version", linkFlags)
+
+ if min == -1 || target == -1 || min == len(linkFlags)-1 || target == len(linkFlags)-1 {
+ t.Fatalf("missing --min-sdk-version or --target-sdk-version in link flags: %q", linkFlags)
+ }
+
+ gotMinSdkVersion := linkFlags[min+1]
+ gotTargetSdkVersion := linkFlags[target+1]
+
+ if gotMinSdkVersion != expectedSdkVersion {
+ t.Errorf("incorrect --min-sdk-version, expected %q got %q",
+ expectedSdkVersion, gotMinSdkVersion)
+ }
+
+ if gotTargetSdkVersion != expectedSdkVersion {
+ t.Errorf("incorrect --target-sdk-version, expected %q got %q",
+ expectedSdkVersion, gotTargetSdkVersion)
+ }
+}
+
func TestAppSdkVersion(t *testing.T) {
testCases := []struct {
name string
@@ -1107,38 +1136,85 @@
config.TestProductVariables.Platform_sdk_version = &test.platformSdkInt
config.TestProductVariables.Platform_sdk_codename = &test.platformSdkCodename
config.TestProductVariables.Platform_sdk_final = &test.platformSdkFinal
+ checkSdkVersion(t, config, test.expectedMinSdkVersion)
- ctx := testContext()
-
- run(t, ctx, config)
-
- foo := ctx.ModuleForTests("foo", "android_common")
- link := foo.Output("package-res.apk")
- linkFlags := strings.Split(link.Args["flags"], " ")
- min := android.IndexList("--min-sdk-version", linkFlags)
- target := android.IndexList("--target-sdk-version", linkFlags)
-
- if min == -1 || target == -1 || min == len(linkFlags)-1 || target == len(linkFlags)-1 {
- t.Fatalf("missing --min-sdk-version or --target-sdk-version in link flags: %q", linkFlags)
- }
-
- gotMinSdkVersion := linkFlags[min+1]
- gotTargetSdkVersion := linkFlags[target+1]
-
- if gotMinSdkVersion != test.expectedMinSdkVersion {
- t.Errorf("incorrect --min-sdk-version, expected %q got %q",
- test.expectedMinSdkVersion, gotMinSdkVersion)
- }
-
- if gotTargetSdkVersion != test.expectedMinSdkVersion {
- t.Errorf("incorrect --target-sdk-version, expected %q got %q",
- test.expectedMinSdkVersion, gotTargetSdkVersion)
- }
})
}
}
}
+func TestVendorAppSdkVersion(t *testing.T) {
+ testCases := []struct {
+ name string
+ sdkVersion string
+ platformSdkInt int
+ platformSdkCodename string
+ platformSdkFinal bool
+ deviceCurrentApiLevelForVendorModules string
+ expectedMinSdkVersion string
+ }{
+ {
+ name: "current final SDK",
+ sdkVersion: "current",
+ platformSdkInt: 29,
+ platformSdkCodename: "REL",
+ platformSdkFinal: true,
+ deviceCurrentApiLevelForVendorModules: "29",
+ expectedMinSdkVersion: "29",
+ },
+ {
+ name: "current final SDK",
+ sdkVersion: "current",
+ platformSdkInt: 29,
+ platformSdkCodename: "REL",
+ platformSdkFinal: true,
+ deviceCurrentApiLevelForVendorModules: "28",
+ expectedMinSdkVersion: "28",
+ },
+ {
+ name: "current final SDK",
+ sdkVersion: "current",
+ platformSdkInt: 29,
+ platformSdkCodename: "Q",
+ platformSdkFinal: false,
+ deviceCurrentApiLevelForVendorModules: "current",
+ expectedMinSdkVersion: "Q",
+ },
+ {
+ name: "current final SDK",
+ sdkVersion: "current",
+ platformSdkInt: 29,
+ platformSdkCodename: "Q",
+ platformSdkFinal: false,
+ deviceCurrentApiLevelForVendorModules: "28",
+ expectedMinSdkVersion: "28",
+ },
+ }
+
+ for _, moduleType := range []string{"android_app", "android_library"} {
+ for _, sdkKind := range []string{"", "system_"} {
+ for _, test := range testCases {
+ t.Run(moduleType+" "+test.name, func(t *testing.T) {
+ bp := fmt.Sprintf(`%s {
+ name: "foo",
+ srcs: ["a.java"],
+ sdk_version: "%s%s",
+ vendor: true,
+ }`, moduleType, sdkKind, test.sdkVersion)
+
+ config := testAppConfig(nil, bp, nil)
+ config.TestProductVariables.Platform_sdk_version = &test.platformSdkInt
+ config.TestProductVariables.Platform_sdk_codename = &test.platformSdkCodename
+ config.TestProductVariables.Platform_sdk_final = &test.platformSdkFinal
+ config.TestProductVariables.DeviceCurrentApiLevelForVendorModules = &test.deviceCurrentApiLevelForVendorModules
+ config.TestProductVariables.DeviceSystemSdkVersions = []string{"28", "29"}
+ checkSdkVersion(t, config, test.expectedMinSdkVersion)
+ })
+ }
+ }
+ }
+}
+
func TestJNIABI(t *testing.T) {
ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
cc_library {
@@ -2542,6 +2618,19 @@
android_app {
name: "app",
srcs: ["a.java"],
+ libs: ["qux", "quuz"],
+ static_libs: ["static-runtime-helper"],
+ uses_libs: ["foo"],
+ sdk_version: "current",
+ optional_uses_libs: [
+ "bar",
+ "baz",
+ ],
+ }
+
+ android_app {
+ name: "app_with_stub_deps",
+ srcs: ["a.java"],
libs: ["qux", "quuz.stubs"],
static_libs: ["static-runtime-helper"],
uses_libs: ["foo"],
@@ -2572,6 +2661,7 @@
run(t, ctx, config)
app := ctx.ModuleForTests("app", "android_common")
+ appWithStubDeps := ctx.ModuleForTests("app_with_stub_deps", "android_common")
prebuilt := ctx.ModuleForTests("prebuilt", "android_common")
// Test that implicit dependencies on java_sdk_library instances are passed to the manifest.
@@ -2602,15 +2692,24 @@
t.Errorf("wanted %q in %q", w, cmd)
}
- // Test that only present libraries are preopted
+ // Test that all present libraries are preopted, including implicit SDK dependencies
cmd = app.Rule("dexpreopt").RuleParams.Command
-
- if w := `--target-classpath-for-sdk any /system/framework/foo.jar:/system/framework/bar.jar`; !strings.Contains(cmd, w) {
+ w := `--target-classpath-for-sdk any` +
+ ` /system/framework/foo.jar` +
+ `:/system/framework/quuz.jar` +
+ `:/system/framework/qux.jar` +
+ `:/system/framework/runtime-library.jar` +
+ `:/system/framework/bar.jar`
+ if !strings.Contains(cmd, w) {
t.Errorf("wanted %q in %q", w, cmd)
}
- cmd = prebuilt.Rule("dexpreopt").RuleParams.Command
+ // TODO(skvadrik) fix dexpreopt for stub libraries for which the implementation is present
+ if appWithStubDeps.MaybeRule("dexpreopt").RuleParams.Command != "" {
+ t.Errorf("dexpreopt should be disabled for apps with dependencies on stub libraries")
+ }
+ cmd = prebuilt.Rule("dexpreopt").RuleParams.Command
if w := `--target-classpath-for-sdk any /system/framework/foo.jar:/system/framework/bar.jar`; !strings.Contains(cmd, w) {
t.Errorf("wanted %q in %q", w, cmd)
}
diff --git a/java/java.go b/java/java.go
index 4d7d568..27e425d 100644
--- a/java/java.go
+++ b/java/java.go
@@ -991,7 +991,7 @@
case libTag:
deps.classpath = append(deps.classpath, dep.SdkHeaderJars(ctx, j.sdkVersion())...)
// names of sdk libs that are directly depended are exported
- j.exportedSdkLibs.AddLibraryPath(ctx, dep.OptionalImplicitSdkLibrary(), dep.DexJarBuildPath(), dep.DexJarInstallPath())
+ j.exportedSdkLibs.MaybeAddLibraryPath(ctx, dep.OptionalImplicitSdkLibrary(), dep.DexJarBuildPath(), dep.DexJarInstallPath())
case staticLibTag:
ctx.ModuleErrorf("dependency on java_sdk_library %q can only be in libs", otherName)
}
@@ -1970,7 +1970,7 @@
// add the name of that java_sdk_library to the exported sdk libs to make sure
// that, if necessary, a <uses-library> element for that java_sdk_library is
// added to the Android manifest.
- j.exportedSdkLibs.AddLibraryPath(ctx, j.OptionalImplicitSdkLibrary(), j.DexJarBuildPath(), j.DexJarInstallPath())
+ j.exportedSdkLibs.MaybeAddLibraryPath(ctx, j.OptionalImplicitSdkLibrary(), j.DexJarBuildPath(), j.DexJarInstallPath())
j.distFiles = j.GenerateTaggedDistFiles(ctx)
}
@@ -2608,7 +2608,7 @@
switch tag {
case libTag:
// names of sdk libs that are directly depended are exported
- j.exportedSdkLibs.AddLibraryPath(ctx, &otherName, dep.DexJarBuildPath(), dep.DexJarInstallPath())
+ j.exportedSdkLibs.AddLibraryPath(ctx, otherName, dep.DexJarBuildPath(), dep.DexJarInstallPath())
}
}
})
@@ -2623,7 +2623,7 @@
// add the name of that java_sdk_library to the exported sdk libs to make sure
// that, if necessary, a <uses-library> element for that java_sdk_library is
// added to the Android manifest.
- j.exportedSdkLibs.AddLibraryPath(ctx, j.OptionalImplicitSdkLibrary(), outputFile, installFile)
+ j.exportedSdkLibs.MaybeAddLibraryPath(ctx, j.OptionalImplicitSdkLibrary(), outputFile, installFile)
j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.properties.Aidl.Export_include_dirs)
}
diff --git a/java/sdk.go b/java/sdk.go
index b44cd8e1..56fa12b 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -191,6 +191,26 @@
return s.kind != sdkPrivate && s.kind != sdkNone && s.kind != sdkCorePlatform
}
+func (s sdkSpec) forVendorPartition(ctx android.EarlyModuleContext) sdkSpec {
+ // If BOARD_CURRENT_API_LEVEL_FOR_VENDOR_MODULES has a numeric value,
+ // use it instead of "current" for the vendor partition.
+ currentSdkVersion := ctx.DeviceConfig().CurrentApiLevelForVendorModules()
+ if currentSdkVersion == "current" {
+ return s
+ }
+
+ if s.kind == sdkPublic || s.kind == sdkSystem {
+ if s.version.isCurrent() {
+ if i, err := strconv.Atoi(currentSdkVersion); err == nil {
+ version := sdkVersion(i)
+ return sdkSpec{s.kind, version, s.raw}
+ }
+ panic(fmt.Errorf("BOARD_CURRENT_API_LEVEL_FOR_VENDOR_MODULES must be either \"current\" or a number, but was %q", currentSdkVersion))
+ }
+ }
+ return s
+}
+
// usePrebuilt determines whether prebuilt SDK should be used for this sdkSpec with the given context.
func (s sdkSpec) usePrebuilt(ctx android.EarlyModuleContext) bool {
if s.version.isCurrent() {
@@ -216,6 +236,10 @@
if !s.valid() {
return s.version, fmt.Errorf("invalid sdk version %q", s.raw)
}
+
+ if ctx.DeviceSpecific() || ctx.SocSpecific() {
+ s = s.forVendorPartition(ctx)
+ }
if s.version.isNumbered() {
return s.version, nil
}
@@ -330,6 +354,10 @@
return sdkDep{}
}
+ if ctx.DeviceSpecific() || ctx.SocSpecific() {
+ sdkVersion = sdkVersion.forVendorPartition(ctx)
+ }
+
if !sdkVersion.validateSystemSdk(ctx) {
return sdkDep{}
}
diff --git a/java/testing.go b/java/testing.go
index 1e725fa..1db6ef2 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -44,6 +44,9 @@
"prebuilts/sdk/17/public/android.jar": nil,
"prebuilts/sdk/17/public/framework.aidl": nil,
"prebuilts/sdk/17/system/android.jar": nil,
+ "prebuilts/sdk/28/public/android.jar": nil,
+ "prebuilts/sdk/28/public/framework.aidl": nil,
+ "prebuilts/sdk/28/system/android.jar": nil,
"prebuilts/sdk/29/public/android.jar": nil,
"prebuilts/sdk/29/public/framework.aidl": nil,
"prebuilts/sdk/29/system/android.jar": nil,
diff --git a/rust/Android.bp b/rust/Android.bp
index bbeb28d..8618207 100644
--- a/rust/Android.bp
+++ b/rust/Android.bp
@@ -19,7 +19,9 @@
"prebuilt.go",
"proc_macro.go",
"project_json.go",
+ "protobuf.go",
"rust.go",
+ "strip.go",
"source_provider.go",
"test.go",
"testing.go",
@@ -33,6 +35,7 @@
"coverage_test.go",
"library_test.go",
"project_json_test.go",
+ "protobuf_test.go",
"rust_test.go",
"source_provider_test.go",
"test_test.go",
diff --git a/rust/androidmk.go b/rust/androidmk.go
index fda0a25..edae0e6 100644
--- a/rust/androidmk.go
+++ b/rust/androidmk.go
@@ -96,7 +96,6 @@
ret.Class = "EXECUTABLES"
ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
- fmt.Fprintln(w, "LOCAL_SOONG_UNSTRIPPED_BINARY :=", binary.unstrippedOutputFile.String())
if binary.coverageOutputZipFile.Valid() {
fmt.Fprintln(w, "LOCAL_PREBUILT_COVERAGE_ARCHIVE := "+binary.coverageOutputZipFile.String())
}
@@ -139,9 +138,6 @@
}
ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
- if !library.rlib() {
- fmt.Fprintln(w, "LOCAL_SOONG_UNSTRIPPED_BINARY :=", library.unstrippedOutputFile.String())
- }
if library.coverageOutputZipFile.Valid() {
fmt.Fprintln(w, "LOCAL_PREBUILT_COVERAGE_ARCHIVE := "+library.coverageOutputZipFile.String())
}
@@ -169,23 +165,32 @@
stem, suffix, _ := android.SplitFileExt(file)
fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+suffix)
fmt.Fprintln(w, "LOCAL_MODULE_STEM := "+stem)
+ fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true")
})
}
func (bindgen *bindgenDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
ctx.SubAndroidMk(ret, bindgen.BaseSourceProvider)
- ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
- fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true")
- })
+}
+
+func (proto *protobufDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
+ ctx.SubAndroidMk(ret, proto.BaseSourceProvider)
}
func (compiler *baseCompiler) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
+ var unstrippedOutputFile android.OptionalPath
// Soong installation is only supported for host modules. Have Make
// installation trigger Soong installation.
if ctx.Target().Os.Class == android.Host {
ret.OutputFile = android.OptionalPathForPath(compiler.path)
+ } else if compiler.strippedOutputFile.Valid() {
+ unstrippedOutputFile = ret.OutputFile
+ ret.OutputFile = compiler.strippedOutputFile
}
ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
+ if compiler.strippedOutputFile.Valid() {
+ fmt.Fprintln(w, "LOCAL_SOONG_UNSTRIPPED_BINARY :=", unstrippedOutputFile)
+ }
path, file := filepath.Split(compiler.path.ToMakePath().String())
stem, suffix, _ := android.SplitFileExt(file)
fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+suffix)
diff --git a/rust/binary.go b/rust/binary.go
index f750186..1d02453 100644
--- a/rust/binary.go
+++ b/rust/binary.go
@@ -28,6 +28,7 @@
type binaryDecorator struct {
*baseCompiler
+ stripper Stripper
Properties BinaryCompilerProperties
}
@@ -86,7 +87,8 @@
func (binary *binaryDecorator) compilerProps() []interface{} {
return append(binary.baseCompiler.compilerProps(),
- &binary.Properties)
+ &binary.Properties,
+ &binary.stripper.StripProperties)
}
func (binary *binaryDecorator) nativeCoverage() bool {
@@ -95,15 +97,20 @@
func (binary *binaryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
fileName := binary.getStem(ctx) + ctx.toolchain().ExecutableSuffix()
-
srcPath, _ := srcPathFromModuleSrcs(ctx, binary.baseCompiler.Properties.Srcs)
-
outputFile := android.PathForModuleOut(ctx, fileName)
- binary.unstrippedOutputFile = outputFile
flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
+ flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects...)
outputs := TransformSrcToBinary(ctx, srcPath, deps, flags, outputFile, deps.linkDirs)
+
+ if binary.stripper.NeedsStrip(ctx) {
+ strippedOutputFile := android.PathForModuleOut(ctx, "stripped", fileName)
+ binary.stripper.StripExecutableOrSharedLib(ctx, outputFile, strippedOutputFile)
+ binary.strippedOutputFile = android.OptionalPathForPath(strippedOutputFile)
+ }
+
binary.coverageFile = outputs.coverageFile
var coverageFiles android.Paths
diff --git a/rust/binary_test.go b/rust/binary_test.go
index 5c9bd65..cfef57a 100644
--- a/rust/binary_test.go
+++ b/rust/binary_test.go
@@ -78,3 +78,51 @@
t.Errorf("extra --test flag, rustcFlags: %#v", flags)
}
}
+
+func TestLinkObjects(t *testing.T) {
+ ctx := testRust(t, `
+ rust_binary {
+ name: "fizz-buzz",
+ srcs: ["foo.rs"],
+ shared_libs: ["libfoo"],
+ }
+ cc_library {
+ name: "libfoo",
+ }`)
+
+ fizzBuzz := ctx.ModuleForTests("fizz-buzz", "android_arm64_armv8-a").Output("fizz-buzz")
+ linkFlags := fizzBuzz.Args["linkFlags"]
+ if !strings.Contains(linkFlags, "/libfoo.so") {
+ t.Errorf("missing shared dependency 'libfoo.so' in linkFlags: %#v", linkFlags)
+ }
+}
+
+// Test that stripped versions are correctly generated and used.
+func TestStrippedBinary(t *testing.T) {
+ ctx := testRust(t, `
+ rust_binary {
+ name: "foo",
+ srcs: ["foo.rs"],
+ }
+ rust_binary {
+ name: "bar",
+ srcs: ["foo.rs"],
+ strip: {
+ none: true
+ }
+ }
+ `)
+
+ foo := ctx.ModuleForTests("foo", "android_arm64_armv8-a")
+ foo.Output("stripped/foo")
+ // Check that the `cp` rules is using the stripped version as input.
+ cp := foo.Rule("android.Cp")
+ if !strings.HasSuffix(cp.Input.String(), "stripped/foo") {
+ t.Errorf("installed binary not based on stripped version: %v", cp.Input)
+ }
+
+ fizzBar := ctx.ModuleForTests("bar", "android_arm64_armv8-a").MaybeOutput("stripped/bar")
+ if fizzBar.Rule != nil {
+ t.Errorf("stripped version of bar has been generated")
+ }
+}
diff --git a/rust/bindgen.go b/rust/bindgen.go
index 9b09e61..0336308 100644
--- a/rust/bindgen.go
+++ b/rust/bindgen.go
@@ -21,7 +21,6 @@
"github.com/google/blueprint/proptools"
"android/soong/android"
- ccConfig "android/soong/cc/config"
)
var (
@@ -34,9 +33,9 @@
//TODO(b/160803703) Use a prebuilt bindgen instead of the built bindgen.
_ = pctx.SourcePathVariable("bindgenCmd", "out/host/${config.HostPrebuiltTag}/bin/bindgen")
_ = pctx.SourcePathVariable("bindgenClang",
- "${ccConfig.ClangBase}/${config.HostPrebuiltTag}/"+bindgenClangVersion+"/bin/clang")
+ "${cc_config.ClangBase}/${config.HostPrebuiltTag}/"+bindgenClangVersion+"/bin/clang")
_ = pctx.SourcePathVariable("bindgenLibClang",
- "${ccConfig.ClangBase}/${config.HostPrebuiltTag}/"+bindgenClangVersion+"/lib64/libclang.so."+bindgenLibClangSoGit)
+ "${cc_config.ClangBase}/${config.HostPrebuiltTag}/"+bindgenClangVersion+"/lib64/libclang.so."+bindgenLibClangSoGit)
//TODO(ivanlozano) Switch this to RuleBuilder
bindgen = pctx.AndroidStaticRule("bindgen",
@@ -92,8 +91,8 @@
Properties BindgenProperties
}
-func (b *bindgenDecorator) GenerateSource(ctx android.ModuleContext, deps PathDeps) android.Path {
- ccToolchain := ccConfig.FindToolchain(ctx.Os(), ctx.Arch())
+func (b *bindgenDecorator) GenerateSource(ctx ModuleContext, deps PathDeps) android.Path {
+ ccToolchain := ctx.RustModule().ccToolchain(ctx)
var cflags []string
var implicits android.Paths
@@ -102,14 +101,14 @@
implicits = append(implicits, deps.depSystemIncludePaths...)
// Default clang flags
- cflags = append(cflags, "${ccConfig.CommonClangGlobalCflags}")
+ cflags = append(cflags, "${cc_config.CommonClangGlobalCflags}")
if ctx.Device() {
- cflags = append(cflags, "${ccConfig.DeviceClangGlobalCflags}")
+ cflags = append(cflags, "${cc_config.DeviceClangGlobalCflags}")
}
// Toolchain clang flags
cflags = append(cflags, "-target "+ccToolchain.ClangTriple())
- cflags = append(cflags, strings.ReplaceAll(ccToolchain.ToolchainClangCflags(), "${config.", "${ccConfig."))
+ cflags = append(cflags, strings.ReplaceAll(ccToolchain.ToolchainClangCflags(), "${config.", "${cc_config."))
// Dependency clang flags and include paths
cflags = append(cflags, deps.depClangFlags...)
diff --git a/rust/compiler.go b/rust/compiler.go
index 2600f4d..ddf1fac 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -129,8 +129,9 @@
location installLocation
coverageOutputZipFile android.OptionalPath
- unstrippedOutputFile android.Path
distFile android.OptionalPath
+ // Stripped output file. If Valid(), this file will be installed instead of outputFile.
+ strippedOutputFile android.OptionalPath
}
func (compiler *baseCompiler) Disabled() bool {
@@ -269,8 +270,12 @@
return false
}
-func (compiler *baseCompiler) install(ctx ModuleContext, file android.Path) {
- compiler.path = ctx.InstallFile(compiler.installDir(ctx), file.Base(), file)
+func (compiler *baseCompiler) install(ctx ModuleContext) {
+ path := ctx.RustModule().outputFile
+ if compiler.strippedOutputFile.Valid() {
+ path = compiler.strippedOutputFile
+ }
+ compiler.path = ctx.InstallFile(compiler.installDir(ctx), path.Path().Base(), path.Path())
}
func (compiler *baseCompiler) getStem(ctx ModuleContext) string {
diff --git a/rust/config/global.go b/rust/config/global.go
index 97de676..2f4d930 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -52,10 +52,11 @@
"-Wl,--fatal-warnings",
"-Wl,--pack-dyn-relocs=android+relr",
+ "-Wl,--use-android-relr-tags",
"-Wl,--no-undefined",
"-Wl,--hash-style=gnu",
- "-B${ccConfig.ClangBin}",
+ "-B${cc_config.ClangBin}",
"-fuse-ld=lld",
}
)
@@ -81,8 +82,8 @@
pctx.StaticVariable("RustPath", "${RustBase}/${HostPrebuiltTag}/${RustVersion}")
pctx.StaticVariable("RustBin", "${RustPath}/bin")
- pctx.ImportAs("ccConfig", "android/soong/cc/config")
- pctx.StaticVariable("RustLinker", "${ccConfig.ClangBin}/clang++")
+ pctx.ImportAs("cc_config", "android/soong/cc/config")
+ pctx.StaticVariable("RustLinker", "${cc_config.ClangBin}/clang++")
pctx.StaticVariable("RustLinkerArgs", "")
pctx.StaticVariable("DeviceGlobalLinkFlags", strings.Join(deviceGlobalLinkFlags, " "))
diff --git a/rust/config/x86_darwin_host.go b/rust/config/x86_darwin_host.go
index 4104400..a13a9a6 100644
--- a/rust/config/x86_darwin_host.go
+++ b/rust/config/x86_darwin_host.go
@@ -23,7 +23,7 @@
var (
DarwinRustFlags = []string{}
DarwinRustLinkFlags = []string{
- "-B${ccConfig.MacToolPath}",
+ "-B${cc_config.MacToolPath}",
}
darwinX8664Rustflags = []string{}
darwinX8664Linkflags = []string{}
diff --git a/rust/config/x86_linux_host.go b/rust/config/x86_linux_host.go
index acc99e1..b55b2f2 100644
--- a/rust/config/x86_linux_host.go
+++ b/rust/config/x86_linux_host.go
@@ -23,7 +23,7 @@
var (
LinuxRustFlags = []string{}
LinuxRustLinkFlags = []string{
- "-B${ccConfig.ClangBin}",
+ "-B${cc_config.ClangBin}",
"-fuse-ld=lld",
}
linuxX86Rustflags = []string{}
diff --git a/rust/library.go b/rust/library.go
index 91fbe0f..a442933 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -78,6 +78,7 @@
type libraryDecorator struct {
*baseCompiler
*flagExporter
+ stripper Stripper
Properties LibraryCompilerProperties
MutatedProperties LibraryMutatedProperties
@@ -338,7 +339,8 @@
func (library *libraryDecorator) compilerProps() []interface{} {
return append(library.baseCompiler.compilerProps(),
&library.Properties,
- &library.MutatedProperties)
+ &library.MutatedProperties,
+ &library.stripper.StripProperties)
}
func (library *libraryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps {
@@ -371,7 +373,8 @@
}
func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
- var outputFile android.WritablePath
+ var outputFile android.ModuleOutPath
+ var fileName string
var srcPath android.Path
if library.sourceProvider != nil {
@@ -381,6 +384,7 @@
}
flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
+ flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects...)
if library.dylib() {
// We need prefer-dynamic for now to avoid linking in the static stdlib. See:
@@ -390,31 +394,37 @@
}
if library.rlib() {
- fileName := library.getStem(ctx) + ctx.toolchain().RlibSuffix()
+ fileName = library.getStem(ctx) + ctx.toolchain().RlibSuffix()
outputFile = android.PathForModuleOut(ctx, fileName)
outputs := TransformSrctoRlib(ctx, srcPath, deps, flags, outputFile, deps.linkDirs)
library.coverageFile = outputs.coverageFile
} else if library.dylib() {
- fileName := library.getStem(ctx) + ctx.toolchain().DylibSuffix()
+ fileName = library.getStem(ctx) + ctx.toolchain().DylibSuffix()
outputFile = android.PathForModuleOut(ctx, fileName)
outputs := TransformSrctoDylib(ctx, srcPath, deps, flags, outputFile, deps.linkDirs)
library.coverageFile = outputs.coverageFile
} else if library.static() {
- fileName := library.getStem(ctx) + ctx.toolchain().StaticLibSuffix()
+ fileName = library.getStem(ctx) + ctx.toolchain().StaticLibSuffix()
outputFile = android.PathForModuleOut(ctx, fileName)
outputs := TransformSrctoStatic(ctx, srcPath, deps, flags, outputFile, deps.linkDirs)
library.coverageFile = outputs.coverageFile
} else if library.shared() {
- fileName := library.sharedLibFilename(ctx)
+ fileName = library.sharedLibFilename(ctx)
outputFile = android.PathForModuleOut(ctx, fileName)
outputs := TransformSrctoShared(ctx, srcPath, deps, flags, outputFile, deps.linkDirs)
library.coverageFile = outputs.coverageFile
}
+ if !library.rlib() && library.stripper.NeedsStrip(ctx) {
+ strippedOutputFile := android.PathForModuleOut(ctx, "stripped", fileName)
+ library.stripper.StripExecutableOrSharedLib(ctx, outputFile, strippedOutputFile)
+ library.strippedOutputFile = android.OptionalPathForPath(strippedOutputFile)
+ }
+
var coverageFiles android.Paths
if library.coverageFile != nil {
coverageFiles = append(coverageFiles, library.coverageFile)
@@ -427,8 +437,8 @@
if library.rlib() || library.dylib() {
library.exportLinkDirs(deps.linkDirs...)
library.exportDepFlags(deps.depFlags...)
+ library.exportLinkObjects(deps.linkObjects...)
}
- library.unstrippedOutputFile = outputFile
return outputFile
}
diff --git a/rust/library_test.go b/rust/library_test.go
index 0fd9e32..f1bc050 100644
--- a/rust/library_test.go
+++ b/rust/library_test.go
@@ -206,3 +206,35 @@
}
}
+
+// Test that stripped versions are correctly generated and used.
+func TestStrippedLibrary(t *testing.T) {
+ ctx := testRust(t, `
+ rust_library_dylib {
+ name: "libfoo",
+ crate_name: "foo",
+ srcs: ["foo.rs"],
+ }
+ rust_library_dylib {
+ name: "libbar",
+ crate_name: "bar",
+ srcs: ["foo.rs"],
+ strip: {
+ none: true
+ }
+ }
+ `)
+
+ foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_dylib")
+ foo.Output("stripped/libfoo.dylib.so")
+ // Check that the `cp` rule is using the stripped version as input.
+ cp := foo.Rule("android.Cp")
+ if !strings.HasSuffix(cp.Input.String(), "stripped/libfoo.dylib.so") {
+ t.Errorf("installed binary not based on stripped version: %v", cp.Input)
+ }
+
+ fizzBar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_dylib").MaybeOutput("stripped/libbar.dylib.so")
+ if fizzBar.Rule != nil {
+ t.Errorf("stripped version of bar has been generated")
+ }
+}
diff --git a/rust/prebuilt.go b/rust/prebuilt.go
index 3d081c1..f9c8934 100644
--- a/rust/prebuilt.go
+++ b/rust/prebuilt.go
@@ -99,9 +99,6 @@
if len(paths) > 0 {
ctx.PropertyErrorf("srcs", "prebuilt libraries can only have one entry in srcs (the prebuilt path)")
}
-
- prebuilt.unstrippedOutputFile = srcPath
-
return srcPath
}
diff --git a/rust/proc_macro.go b/rust/proc_macro.go
index 748879c..0c6ec99 100644
--- a/rust/proc_macro.go
+++ b/rust/proc_macro.go
@@ -66,9 +66,6 @@
outputFile := android.PathForModuleOut(ctx, fileName)
srcPath, _ := srcPathFromModuleSrcs(ctx, procMacro.baseCompiler.Properties.Srcs)
-
- procMacro.unstrippedOutputFile = outputFile
-
TransformSrctoProcMacro(ctx, srcPath, deps, flags, outputFile, deps.linkDirs)
return outputFile
}
diff --git a/rust/protobuf.go b/rust/protobuf.go
new file mode 100644
index 0000000..897300f
--- /dev/null
+++ b/rust/protobuf.go
@@ -0,0 +1,109 @@
+// Copyright 2020 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 rust
+
+import (
+ "android/soong/android"
+)
+
+var (
+ defaultProtobufFlags = []string{""}
+)
+
+func init() {
+ android.RegisterModuleType("rust_protobuf", RustProtobufFactory)
+ android.RegisterModuleType("rust_protobuf_host", RustProtobufHostFactory)
+}
+
+var _ SourceProvider = (*protobufDecorator)(nil)
+
+type ProtobufProperties struct {
+ // Path to the proto file that will be used to generate the source
+ Proto *string `android:"path,arch_variant"`
+
+ // List of additional flags to pass to aprotoc
+ Proto_flags []string `android:"arch_variant"`
+}
+
+type protobufDecorator struct {
+ *BaseSourceProvider
+
+ Properties ProtobufProperties
+}
+
+func (proto *protobufDecorator) GenerateSource(ctx ModuleContext, deps PathDeps) android.Path {
+ var protoFlags android.ProtoFlags
+ pluginPath := ctx.Config().HostToolPath(ctx, "protoc-gen-rust")
+
+ protoFlags.OutTypeFlag = "--rust_out"
+
+ protoFlags.Flags = append(protoFlags.Flags, " --plugin="+pluginPath.String())
+ protoFlags.Flags = append(protoFlags.Flags, defaultProtobufFlags...)
+ protoFlags.Flags = append(protoFlags.Flags, proto.Properties.Proto_flags...)
+
+ protoFlags.Deps = append(protoFlags.Deps, pluginPath)
+
+ protoFile := android.OptionalPathForModuleSrc(ctx, proto.Properties.Proto)
+ if !protoFile.Valid() {
+ ctx.PropertyErrorf("proto", "invalid path to proto file")
+ }
+
+ outDir := android.PathForModuleOut(ctx)
+ depFile := android.PathForModuleOut(ctx, proto.BaseSourceProvider.getStem(ctx)+".d")
+ outputs := android.WritablePaths{android.PathForModuleOut(ctx, proto.BaseSourceProvider.getStem(ctx)+".rs")}
+
+ rule := android.NewRuleBuilder()
+ android.ProtoRule(ctx, rule, protoFile.Path(), protoFlags, protoFlags.Deps, outDir, depFile, outputs)
+ rule.Build(pctx, ctx, "protoc_"+protoFile.Path().Rel(), "protoc "+protoFile.Path().Rel())
+
+ proto.BaseSourceProvider.OutputFile = outputs[0]
+ return outputs[0]
+}
+
+func (proto *protobufDecorator) SourceProviderProps() []interface{} {
+ return append(proto.BaseSourceProvider.SourceProviderProps(), &proto.Properties)
+}
+
+func (proto *protobufDecorator) SourceProviderDeps(ctx DepsContext, deps Deps) Deps {
+ deps = proto.BaseSourceProvider.SourceProviderDeps(ctx, deps)
+ deps.Rustlibs = append(deps.Rustlibs, "libprotobuf")
+ return deps
+}
+
+// rust_protobuf generates protobuf rust code from the provided proto file. This uses the protoc-gen-rust plugin for
+// protoc. Additional flags to the protoc command can be passed via the proto_flags property. This module type will
+// create library variants that can be used as a crate dependency by adding it to the rlibs, dylibs, and rustlibs
+// properties of other modules.
+func RustProtobufFactory() android.Module {
+ module, _ := NewRustProtobuf(android.HostAndDeviceSupported)
+ return module.Init()
+}
+
+// A host-only variant of rust_protobuf. Refer to rust_protobuf for more details.
+func RustProtobufHostFactory() android.Module {
+ module, _ := NewRustProtobuf(android.HostSupported)
+ return module.Init()
+}
+
+func NewRustProtobuf(hod android.HostOrDeviceSupported) (*Module, *protobufDecorator) {
+ protobuf := &protobufDecorator{
+ BaseSourceProvider: NewSourceProvider(),
+ Properties: ProtobufProperties{},
+ }
+
+ module := NewSourceProviderModule(hod, protobuf, false)
+
+ return module, protobuf
+}
diff --git a/rust/protobuf_test.go b/rust/protobuf_test.go
new file mode 100644
index 0000000..a9dbf39
--- /dev/null
+++ b/rust/protobuf_test.go
@@ -0,0 +1,39 @@
+// Copyright 2020 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 rust
+
+import (
+ "android/soong/android"
+ "testing"
+)
+
+func TestRustProtobuf(t *testing.T) {
+ ctx := testRust(t, `
+ rust_protobuf {
+ name: "librust_proto",
+ proto: "buf.proto",
+ crate_name: "rust_proto",
+ source_stem: "buf",
+ }
+ `)
+ // Check that there's a rule to generate the expected output
+ _ = ctx.ModuleForTests("librust_proto", "android_arm64_armv8-a_dylib").Output("buf.rs")
+
+ // Check that libprotobuf is added as a dependency.
+ librust_proto := ctx.ModuleForTests("librust_proto", "android_arm64_armv8-a_dylib").Module().(*Module)
+ if !android.InList("libprotobuf", librust_proto.Properties.AndroidMkDylibs) {
+ t.Errorf("libprotobuf dependency missing for rust_protobuf (dependency missing from AndroidMkDylibs)")
+ }
+}
diff --git a/rust/rust.go b/rust/rust.go
index 80fe622..5c6cdb7 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -23,6 +23,7 @@
"android/soong/android"
"android/soong/cc"
+ cc_config "android/soong/cc/config"
"android/soong/rust/config"
)
@@ -42,7 +43,7 @@
ctx.BottomUp("rust_begin", BeginMutator).Parallel()
})
pctx.Import("android/soong/rust/config")
- pctx.ImportAs("ccConfig", "android/soong/cc/config")
+ pctx.ImportAs("cc_config", "android/soong/cc/config")
}
type Flags struct {
@@ -244,13 +245,14 @@
}
type PathDeps struct {
- DyLibs RustLibraries
- RLibs RustLibraries
- SharedLibs android.Paths
- StaticLibs android.Paths
- ProcMacros RustLibraries
- linkDirs []string
- depFlags []string
+ DyLibs RustLibraries
+ RLibs RustLibraries
+ SharedLibs android.Paths
+ StaticLibs android.Paths
+ ProcMacros RustLibraries
+ linkDirs []string
+ depFlags []string
+ linkObjects []string
//ReexportedDeps android.Paths
// Used by bindgen modules which call clang
@@ -282,7 +284,7 @@
crateName() string
inData() bool
- install(ctx ModuleContext, path android.Path)
+ install(ctx ModuleContext)
relativeInstallPath() string
nativeCoverage() bool
@@ -296,13 +298,16 @@
type exportedFlagsProducer interface {
exportedLinkDirs() []string
exportedDepFlags() []string
+ exportedLinkObjects() []string
exportLinkDirs(...string)
exportDepFlags(...string)
+ exportLinkObjects(...string)
}
type flagExporter struct {
- depFlags []string
- linkDirs []string
+ depFlags []string
+ linkDirs []string
+ linkObjects []string
}
func (flagExporter *flagExporter) exportedLinkDirs() []string {
@@ -313,6 +318,10 @@
return flagExporter.depFlags
}
+func (flagExporter *flagExporter) exportedLinkObjects() []string {
+ return flagExporter.linkObjects
+}
+
func (flagExporter *flagExporter) exportLinkDirs(dirs ...string) {
flagExporter.linkDirs = android.FirstUniqueStrings(append(flagExporter.linkDirs, dirs...))
}
@@ -321,12 +330,17 @@
flagExporter.depFlags = android.FirstUniqueStrings(append(flagExporter.depFlags, flags...))
}
+func (flagExporter *flagExporter) exportLinkObjects(flags ...string) {
+ flagExporter.linkObjects = android.FirstUniqueStrings(append(flagExporter.linkObjects, flags...))
+}
+
var _ exportedFlagsProducer = (*flagExporter)(nil)
func NewFlagExporter() *flagExporter {
return &flagExporter{
- depFlags: []string{},
- linkDirs: []string{},
+ depFlags: []string{},
+ linkDirs: []string{},
+ linkObjects: []string{},
}
}
@@ -643,6 +657,10 @@
return mod.cachedToolchain
}
+func (mod *Module) ccToolchain(ctx android.BaseModuleContext) cc_config.Toolchain {
+ return cc_config.FindToolchain(ctx.Os(), ctx.Arch())
+}
+
func (d *Defaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
}
@@ -686,7 +704,7 @@
mod.outputFile = android.OptionalPathForPath(outputFile)
if mod.outputFile.Valid() && !mod.Properties.PreventInstall {
- mod.compiler.install(ctx, mod.outputFile.Path())
+ mod.compiler.install(ctx)
}
}
}
@@ -813,6 +831,7 @@
if lib, ok := rustDep.compiler.(exportedFlagsProducer); ok && depTag != procMacroDepTag {
depPaths.linkDirs = append(depPaths.linkDirs, lib.exportedLinkDirs()...)
depPaths.depFlags = append(depPaths.depFlags, lib.exportedDepFlags()...)
+ depPaths.linkObjects = append(depPaths.linkObjects, lib.exportedLinkObjects()...)
}
if depTag == dylibDepTag || depTag == rlibDepTag || depTag == procMacroDepTag {
@@ -840,21 +859,18 @@
return
}
}
- linkFile := ccDep.OutputFile()
- linkPath := linkPathFromFilePath(linkFile.Path())
- libName := libNameFromFilePath(linkFile.Path())
- depFlag := "-l" + libName
+ linkObject := ccDep.OutputFile()
+ linkPath := linkPathFromFilePath(linkObject.Path())
- if !linkFile.Valid() {
+ if !linkObject.Valid() {
ctx.ModuleErrorf("Invalid output file when adding dep %q to %q", depName, ctx.ModuleName())
}
exportDep := false
switch {
case cc.IsStaticDepTag(depTag):
- depFlag = "-lstatic=" + libName
depPaths.linkDirs = append(depPaths.linkDirs, linkPath)
- depPaths.depFlags = append(depPaths.depFlags, depFlag)
+ depPaths.linkObjects = append(depPaths.linkObjects, linkObject.String())
depPaths.depIncludePaths = append(depPaths.depIncludePaths, ccDep.IncludeDirs()...)
if mod, ok := ccDep.(*cc.Module); ok {
depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, mod.ExportedSystemIncludeDirs()...)
@@ -864,9 +880,8 @@
directStaticLibDeps = append(directStaticLibDeps, ccDep)
mod.Properties.AndroidMkStaticLibs = append(mod.Properties.AndroidMkStaticLibs, depName)
case cc.IsSharedDepTag(depTag):
- depFlag = "-ldylib=" + libName
depPaths.linkDirs = append(depPaths.linkDirs, linkPath)
- depPaths.depFlags = append(depPaths.depFlags, depFlag)
+ depPaths.linkObjects = append(depPaths.linkObjects, linkObject.String())
depPaths.depIncludePaths = append(depPaths.depIncludePaths, ccDep.IncludeDirs()...)
if mod, ok := ccDep.(*cc.Module); ok {
depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, mod.ExportedSystemIncludeDirs()...)
@@ -876,15 +891,15 @@
mod.Properties.AndroidMkSharedLibs = append(mod.Properties.AndroidMkSharedLibs, depName)
exportDep = true
case depTag == cc.CrtBeginDepTag:
- depPaths.CrtBegin = linkFile
+ depPaths.CrtBegin = linkObject
case depTag == cc.CrtEndDepTag:
- depPaths.CrtEnd = linkFile
+ depPaths.CrtEnd = linkObject
}
// Make sure these dependencies are propagated
if lib, ok := mod.compiler.(exportedFlagsProducer); ok && exportDep {
lib.exportLinkDirs(linkPath)
- lib.exportDepFlags(depFlag)
+ lib.exportLinkObjects(linkObject.String())
}
}
@@ -958,14 +973,6 @@
return strings.Split(filepath.String(), filepath.Base())[0]
}
-func libNameFromFilePath(filepath android.Path) string {
- libName := strings.TrimSuffix(filepath.Base(), filepath.Ext())
- if strings.HasPrefix(libName, "lib") {
- libName = libName[3:]
- }
- return libName
-}
-
func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
ctx := &depsContext{
BottomUpMutatorContext: actx,
diff --git a/rust/rust_test.go b/rust/rust_test.go
index 04de48b..89ce359 100644
--- a/rust/rust_test.go
+++ b/rust/rust_test.go
@@ -62,6 +62,7 @@
"foo.c": nil,
"src/bar.rs": nil,
"src/any.h": nil,
+ "buf.proto": nil,
"liby.so": nil,
"libz.so": nil,
}
@@ -132,25 +133,6 @@
t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
}
-// Test that we can extract the lib name from a lib path.
-func TestLibNameFromFilePath(t *testing.T) {
- libBarPath := android.PathForTesting("out/soong/.intermediates/external/libbar/libbar/linux_glibc_x86_64_shared/libbar.so.so")
- libLibPath := android.PathForTesting("out/soong/.intermediates/external/libbar/libbar/linux_glibc_x86_64_shared/liblib.dylib.so")
-
- libBarName := libNameFromFilePath(libBarPath)
- libLibName := libNameFromFilePath(libLibPath)
-
- expectedResult := "bar.so"
- if libBarName != expectedResult {
- t.Errorf("libNameFromFilePath returned the wrong name; expected '%#v', got '%#v'", expectedResult, libBarName)
- }
-
- expectedResult = "lib.dylib"
- if libLibName != expectedResult {
- t.Errorf("libNameFromFilePath returned the wrong name; expected '%#v', got '%#v'", expectedResult, libLibPath)
- }
-}
-
// Test that we can extract the link path from a lib path.
func TestLinkPathFromFilePath(t *testing.T) {
barPath := android.PathForTesting("out/soong/.intermediates/external/libbar/libbar/linux_glibc_x86_64_shared/libbar.so")
diff --git a/rust/source_provider.go b/rust/source_provider.go
index e168718..755a369 100644
--- a/rust/source_provider.go
+++ b/rust/source_provider.go
@@ -38,7 +38,7 @@
var _ SourceProvider = (*BaseSourceProvider)(nil)
type SourceProvider interface {
- GenerateSource(ctx android.ModuleContext, deps PathDeps) android.Path
+ GenerateSource(ctx ModuleContext, deps PathDeps) android.Path
Srcs() android.Paths
SourceProviderProps() []interface{}
SourceProviderDeps(ctx DepsContext, deps Deps) Deps
@@ -49,7 +49,7 @@
return android.Paths{sp.OutputFile}
}
-func (sp *BaseSourceProvider) GenerateSource(ctx android.ModuleContext, deps PathDeps) android.Path {
+func (sp *BaseSourceProvider) GenerateSource(ctx ModuleContext, deps PathDeps) android.Path {
panic("BaseSourceProviderModule does not implement GenerateSource()")
}
diff --git a/rust/strip.go b/rust/strip.go
new file mode 100644
index 0000000..d1bbba6
--- /dev/null
+++ b/rust/strip.go
@@ -0,0 +1,30 @@
+// Copyright 2020 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 rust
+
+import (
+ "android/soong/android"
+ "android/soong/cc"
+)
+
+// Stripper encapsulates cc.Stripper.
+type Stripper struct {
+ cc.Stripper
+}
+
+func (s *Stripper) StripExecutableOrSharedLib(ctx ModuleContext, in android.Path, out android.ModuleOutPath) {
+ ccFlags := cc.StripFlags{Toolchain: ctx.RustModule().ccToolchain(ctx)}
+ s.Stripper.StripExecutableOrSharedLib(ctx, in, out, ccFlags)
+}
diff --git a/rust/test.go b/rust/test.go
index 19802e3..d93fc31 100644
--- a/rust/test.go
+++ b/rust/test.go
@@ -88,7 +88,7 @@
return append(test.binaryDecorator.compilerProps(), &test.Properties)
}
-func (test *testDecorator) install(ctx ModuleContext, file android.Path) {
+func (test *testDecorator) install(ctx ModuleContext) {
test.testConfig = tradefed.AutoGenRustTestConfig(ctx,
test.Properties.Test_config,
test.Properties.Test_config_template,
@@ -103,7 +103,7 @@
ctx.PropertyErrorf("no_named_install_directory", "Module install directory may only be disabled if relative_install_path is set")
}
- test.binaryDecorator.install(ctx, file)
+ test.binaryDecorator.install(ctx)
}
func (test *testDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {
diff --git a/rust/testing.go b/rust/testing.go
index 80e4148..0144c82 100644
--- a/rust/testing.go
+++ b/rust/testing.go
@@ -91,6 +91,12 @@
host_supported: true,
native_coverage: false,
}
+ rust_library {
+ name: "libprotobuf",
+ crate_name: "protobuf",
+ srcs: ["foo.rs"],
+ host_supported: true,
+ }
` + cc.GatherRequiredDepsForTest(android.NoOsType)
return bp
@@ -120,6 +126,8 @@
ctx.RegisterModuleType("rust_ffi_host_shared", RustFFISharedHostFactory)
ctx.RegisterModuleType("rust_ffi_host_static", RustFFIStaticHostFactory)
ctx.RegisterModuleType("rust_proc_macro", ProcMacroFactory)
+ ctx.RegisterModuleType("rust_protobuf", RustProtobufFactory)
+ ctx.RegisterModuleType("rust_protobuf_host", RustProtobufHostFactory)
ctx.RegisterModuleType("rust_prebuilt_library", PrebuiltLibraryFactory)
ctx.RegisterModuleType("rust_prebuilt_dylib", PrebuiltDylibFactory)
ctx.RegisterModuleType("rust_prebuilt_rlib", PrebuiltRlibFactory)
diff --git a/sh/sh_binary.go b/sh/sh_binary.go
index 217a4e1..f3f4a4a 100644
--- a/sh/sh_binary.go
+++ b/sh/sh_binary.go
@@ -64,6 +64,12 @@
// install symlinks to the binary
Symlinks []string `android:"arch_variant"`
+
+ // Make this module available when building for ramdisk.
+ Ramdisk_available *bool
+
+ // Make this module available when building for recovery.
+ Recovery_available *bool
}
type TestProperties struct {
@@ -158,6 +164,29 @@
return s.properties.Symlinks
}
+var _ android.ImageInterface = (*ShBinary)(nil)
+
+func (s *ShBinary) ImageMutatorBegin(ctx android.BaseModuleContext) {}
+
+func (s *ShBinary) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
+ return !s.ModuleBase.InstallInRecovery() && !s.ModuleBase.InstallInRamdisk()
+}
+
+func (s *ShBinary) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+ return proptools.Bool(s.properties.Ramdisk_available) || s.ModuleBase.InstallInRamdisk()
+}
+
+func (s *ShBinary) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
+ return proptools.Bool(s.properties.Recovery_available) || s.ModuleBase.InstallInRecovery()
+}
+
+func (s *ShBinary) ExtraImageVariations(ctx android.BaseModuleContext) []string {
+ return nil
+}
+
+func (s *ShBinary) SetImageVariation(ctx android.BaseModuleContext, variation string, module android.Module) {
+}
+
func (s *ShBinary) generateAndroidBuildActions(ctx android.ModuleContext) {
s.sourceFilePath = android.PathForModuleSrc(ctx, proptools.String(s.properties.Src))
filename := proptools.String(s.properties.Filename)