Support multiple sources for prebuilt_etc
Keep the Src attribute for compatibility. The new attribute (Srcs) is mutually exclusive with Src. Keep SourceFilePath and OutputFile for compatibility with other modules. These can be removed in a follow up change. Bug: 328313691 Test: presubmit Test: m blueprint_tests Test: prebuilts/build-tools/build-prebuilts.sh (on build-tools branch) Change-Id: I5d5b2657715a7180a829c7ed0f501872d561b662
This commit is contained in:
15
apex/apex.go
15
apex/apex.go
@@ -1648,10 +1648,9 @@ func apexFileForShBinary(ctx android.BaseModuleContext, sh *sh.ShBinary) apexFil
|
||||
return af
|
||||
}
|
||||
|
||||
func apexFileForPrebuiltEtc(ctx android.BaseModuleContext, prebuilt prebuilt_etc.PrebuiltEtcModule, depName string) apexFile {
|
||||
func apexFileForPrebuiltEtc(ctx android.BaseModuleContext, prebuilt prebuilt_etc.PrebuiltEtcModule, outputFile android.Path) apexFile {
|
||||
dirInApex := filepath.Join(prebuilt.BaseDir(), prebuilt.SubDir())
|
||||
fileToCopy := prebuilt.OutputFile()
|
||||
return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, prebuilt)
|
||||
return newApexFile(ctx, outputFile, outputFile.Base(), dirInApex, etc, prebuilt)
|
||||
}
|
||||
|
||||
func apexFileForCompatConfig(ctx android.BaseModuleContext, config java.PlatformCompatConfigIntf, depName string) apexFile {
|
||||
@@ -2120,7 +2119,10 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext,
|
||||
}
|
||||
case prebuiltTag:
|
||||
if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
|
||||
vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
|
||||
filesToCopy, _ := prebuilt.OutputFiles("")
|
||||
for _, etcFile := range filesToCopy {
|
||||
vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, etcFile))
|
||||
}
|
||||
addAconfigFiles(vctx, ctx, child)
|
||||
} else {
|
||||
ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName)
|
||||
@@ -2263,7 +2265,10 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext,
|
||||
// Because APK-in-APEX embeds jni_libs transitively, we don't need to track transitive deps
|
||||
} else if java.IsXmlPermissionsFileDepTag(depTag) {
|
||||
if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
|
||||
vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
|
||||
filesToCopy, _ := prebuilt.OutputFiles("")
|
||||
for _, etcFile := range filesToCopy {
|
||||
vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, etcFile))
|
||||
}
|
||||
}
|
||||
} else if rust.IsDylibDepTag(depTag) {
|
||||
if rustm, ok := child.(*rust.Module); ok && rustm.IsInstallableToApex() {
|
||||
|
@@ -71,10 +71,15 @@ var PrepareForTestWithPrebuiltEtc = android.FixtureRegisterWithContext(RegisterP
|
||||
|
||||
type prebuiltEtcProperties struct {
|
||||
// Source file of this prebuilt. Can reference a genrule type module with the ":module" syntax.
|
||||
// Mutually exclusive with srcs.
|
||||
Src *string `android:"path,arch_variant"`
|
||||
|
||||
// Source files of this prebuilt. Can reference a genrule type module with the ":module" syntax.
|
||||
// Mutually exclusive with src. When used, filename_from_src is set to true.
|
||||
Srcs []string `android:"path,arch_variant"`
|
||||
|
||||
// Optional name for the installed file. If unspecified, name of the module is used as the file
|
||||
// name.
|
||||
// name. Only available when using a single source (src).
|
||||
Filename *string `android:"arch_variant"`
|
||||
|
||||
// When set to true, and filename property is not set, the name for the installed file
|
||||
@@ -127,9 +132,9 @@ type PrebuiltEtcModule interface {
|
||||
// Returns the sub install directory relative to BaseDir().
|
||||
SubDir() string
|
||||
|
||||
// Returns an android.OutputPath to the intermeidate file, which is the renamed prebuilt source
|
||||
// Returns an android.OutputPath to the intermediate file, which is the renamed prebuilt source
|
||||
// file.
|
||||
OutputFile() android.OutputPath
|
||||
OutputFiles(tag string) (android.Paths, error)
|
||||
}
|
||||
|
||||
type PrebuiltEtc struct {
|
||||
@@ -142,8 +147,8 @@ type PrebuiltEtc struct {
|
||||
properties prebuiltEtcProperties
|
||||
subdirProperties prebuiltSubdirProperties
|
||||
|
||||
sourceFilePath android.Path
|
||||
outputFilePath android.OutputPath
|
||||
sourceFilePaths android.Paths
|
||||
outputFilePaths android.OutputPaths
|
||||
// The base install location, e.g. "etc" for prebuilt_etc, "usr/share" for prebuilt_usr_share.
|
||||
installDirBase string
|
||||
installDirBase64 string
|
||||
@@ -246,6 +251,9 @@ func (p *PrebuiltEtc) SetImageVariation(ctx android.BaseModuleContext, variation
|
||||
}
|
||||
|
||||
func (p *PrebuiltEtc) SourceFilePath(ctx android.ModuleContext) android.Path {
|
||||
if len(p.properties.Srcs) > 0 {
|
||||
panic(fmt.Errorf("SourceFilePath not available on multi-source prebuilt %q", p.Name()))
|
||||
}
|
||||
return android.PathForModuleSrc(ctx, proptools.String(p.properties.Src))
|
||||
}
|
||||
|
||||
@@ -260,7 +268,10 @@ func (p *PrebuiltEtc) SetAdditionalDependencies(paths android.Paths) {
|
||||
}
|
||||
|
||||
func (p *PrebuiltEtc) OutputFile() android.OutputPath {
|
||||
return p.outputFilePath
|
||||
if len(p.properties.Srcs) > 0 {
|
||||
panic(fmt.Errorf("OutputFile not available on multi-source prebuilt %q", p.Name()))
|
||||
}
|
||||
return p.outputFilePaths[0]
|
||||
}
|
||||
|
||||
var _ android.OutputFileProducer = (*PrebuiltEtc)(nil)
|
||||
@@ -268,7 +279,7 @@ var _ android.OutputFileProducer = (*PrebuiltEtc)(nil)
|
||||
func (p *PrebuiltEtc) OutputFiles(tag string) (android.Paths, error) {
|
||||
switch tag {
|
||||
case "":
|
||||
return android.Paths{p.outputFilePath}, nil
|
||||
return p.outputFilePaths.Paths(), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported module reference tag %q", tag)
|
||||
}
|
||||
@@ -301,50 +312,7 @@ func (p *PrebuiltEtc) ExcludeFromRecoverySnapshot() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *PrebuiltEtc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||
filename := proptools.String(p.properties.Filename)
|
||||
filenameFromSrc := proptools.Bool(p.properties.Filename_from_src)
|
||||
if p.properties.Src != nil {
|
||||
p.sourceFilePath = android.PathForModuleSrc(ctx, proptools.String(p.properties.Src))
|
||||
|
||||
// Determine the output file basename.
|
||||
// If Filename is set, use the name specified by the property.
|
||||
// If Filename_from_src is set, use the source file name.
|
||||
// Otherwise use the module name.
|
||||
if filename != "" {
|
||||
if filenameFromSrc {
|
||||
ctx.PropertyErrorf("filename_from_src", "filename is set. filename_from_src can't be true")
|
||||
return
|
||||
}
|
||||
} else if filenameFromSrc {
|
||||
filename = p.sourceFilePath.Base()
|
||||
} else {
|
||||
filename = ctx.ModuleName()
|
||||
}
|
||||
} else if ctx.Config().AllowMissingDependencies() {
|
||||
// If no srcs was set and AllowMissingDependencies is enabled then
|
||||
// mark the module as missing dependencies and set a fake source path
|
||||
// and file name.
|
||||
ctx.AddMissingDependencies([]string{"MISSING_PREBUILT_SRC_FILE"})
|
||||
p.sourceFilePath = android.PathForModuleSrc(ctx)
|
||||
if filename == "" {
|
||||
filename = ctx.ModuleName()
|
||||
}
|
||||
} else {
|
||||
ctx.PropertyErrorf("src", "missing prebuilt source file")
|
||||
return
|
||||
}
|
||||
|
||||
if strings.Contains(filename, "/") {
|
||||
ctx.PropertyErrorf("filename", "filename cannot contain separator '/'")
|
||||
return
|
||||
}
|
||||
|
||||
// Check that `sub_dir` and `relative_install_path` are not set at the same time.
|
||||
if p.subdirProperties.Sub_dir != nil && p.subdirProperties.Relative_install_path != nil {
|
||||
ctx.PropertyErrorf("sub_dir", "relative_install_path is set. Cannot set sub_dir")
|
||||
}
|
||||
|
||||
func (p *PrebuiltEtc) installBaseDir(ctx android.ModuleContext) string {
|
||||
// If soc install dir was specified and SOC specific is set, set the installDirPath to the
|
||||
// specified socInstallDirBase.
|
||||
installBaseDir := p.installDirBase
|
||||
@@ -357,47 +325,138 @@ func (p *PrebuiltEtc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||
if p.installAvoidMultilibConflict && !ctx.Host() && ctx.Config().HasMultilibConflict(ctx.Arch().ArchType) {
|
||||
installBaseDir = filepath.Join(installBaseDir, ctx.Arch().ArchType.String())
|
||||
}
|
||||
return installBaseDir
|
||||
}
|
||||
|
||||
p.installDirPath = android.PathForModuleInstall(ctx, installBaseDir, p.SubDir())
|
||||
func (p *PrebuiltEtc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||
var installs []installProperties
|
||||
|
||||
if p.properties.Src != nil && len(p.properties.Srcs) > 0 {
|
||||
ctx.PropertyErrorf("src", "src is set. Cannot set srcs")
|
||||
}
|
||||
|
||||
// Check that `sub_dir` and `relative_install_path` are not set at the same time.
|
||||
if p.subdirProperties.Sub_dir != nil && p.subdirProperties.Relative_install_path != nil {
|
||||
ctx.PropertyErrorf("sub_dir", "relative_install_path is set. Cannot set sub_dir")
|
||||
}
|
||||
p.installDirPath = android.PathForModuleInstall(ctx, p.installBaseDir(ctx), p.SubDir())
|
||||
|
||||
filename := proptools.String(p.properties.Filename)
|
||||
filenameFromSrc := proptools.Bool(p.properties.Filename_from_src)
|
||||
if p.properties.Src != nil {
|
||||
p.sourceFilePaths = android.PathsForModuleSrc(ctx, []string{proptools.String(p.properties.Src)})
|
||||
// If the source was not found, set a fake source path to
|
||||
// support AllowMissingDependencies executions.
|
||||
if len(p.sourceFilePaths) == 0 {
|
||||
p.sourceFilePaths = android.Paths{android.PathForModuleSrc(ctx)}
|
||||
}
|
||||
|
||||
// Determine the output file basename.
|
||||
// If Filename is set, use the name specified by the property.
|
||||
// If Filename_from_src is set, use the source file name.
|
||||
// Otherwise use the module name.
|
||||
if filename != "" {
|
||||
if filenameFromSrc {
|
||||
ctx.PropertyErrorf("filename_from_src", "filename is set. filename_from_src can't be true")
|
||||
return
|
||||
}
|
||||
} else if filenameFromSrc {
|
||||
filename = p.sourceFilePaths[0].Base()
|
||||
} else {
|
||||
filename = ctx.ModuleName()
|
||||
}
|
||||
if strings.Contains(filename, "/") {
|
||||
ctx.PropertyErrorf("filename", "filename cannot contain separator '/'")
|
||||
return
|
||||
}
|
||||
p.outputFilePaths = android.OutputPaths{android.PathForModuleOut(ctx, filename).OutputPath}
|
||||
|
||||
// Call InstallFile even when uninstallable to make the module included in the package
|
||||
ip := installProperties{
|
||||
installable: p.Installable(),
|
||||
filename: filename,
|
||||
sourceFilePath: p.sourceFilePath,
|
||||
sourceFilePath: p.sourceFilePaths[0],
|
||||
outputFilePath: p.outputFilePaths[0],
|
||||
installDirPath: p.installDirPath,
|
||||
symlinks: p.properties.Symlinks,
|
||||
}
|
||||
p.addInstallRules(ctx, ip)
|
||||
installs = append(installs, ip)
|
||||
} else if len(p.properties.Srcs) > 0 {
|
||||
if filename != "" {
|
||||
ctx.PropertyErrorf("filename", "filename cannot be set when using srcs")
|
||||
}
|
||||
if len(p.properties.Symlinks) > 0 {
|
||||
ctx.PropertyErrorf("symlinks", "symlinks cannot be set when using srcs")
|
||||
}
|
||||
if p.properties.Filename_from_src != nil {
|
||||
ctx.PropertyErrorf("filename_from_src", "filename_from_src is implicitly set to true when using srcs")
|
||||
}
|
||||
p.sourceFilePaths = android.PathsForModuleSrc(ctx, p.properties.Srcs)
|
||||
for _, src := range p.sourceFilePaths {
|
||||
filename := src.Base()
|
||||
output := android.PathForModuleOut(ctx, filename).OutputPath
|
||||
ip := installProperties{
|
||||
filename: filename,
|
||||
sourceFilePath: src,
|
||||
outputFilePath: output,
|
||||
installDirPath: p.installDirPath,
|
||||
}
|
||||
p.outputFilePaths = append(p.outputFilePaths, output)
|
||||
installs = append(installs, ip)
|
||||
}
|
||||
} else if ctx.Config().AllowMissingDependencies() {
|
||||
// If no srcs was set and AllowMissingDependencies is enabled then
|
||||
// mark the module as missing dependencies and set a fake source path
|
||||
// and file name.
|
||||
ctx.AddMissingDependencies([]string{"MISSING_PREBUILT_SRC_FILE"})
|
||||
p.sourceFilePaths = android.Paths{android.PathForModuleSrc(ctx)}
|
||||
if filename == "" {
|
||||
filename = ctx.ModuleName()
|
||||
}
|
||||
p.outputFilePaths = android.OutputPaths{android.PathForModuleOut(ctx, filename).OutputPath}
|
||||
ip := installProperties{
|
||||
filename: filename,
|
||||
sourceFilePath: p.sourceFilePaths[0],
|
||||
outputFilePath: p.outputFilePaths[0],
|
||||
installDirPath: p.installDirPath,
|
||||
}
|
||||
installs = append(installs, ip)
|
||||
} else {
|
||||
ctx.PropertyErrorf("src", "missing prebuilt source file")
|
||||
return
|
||||
}
|
||||
|
||||
// Call InstallFile even when uninstallable to make the module included in the package.
|
||||
if !p.Installable() {
|
||||
p.SkipInstall()
|
||||
}
|
||||
for _, ip := range installs {
|
||||
ip.addInstallRules(ctx)
|
||||
}
|
||||
android.CollectDependencyAconfigFiles(ctx, &p.mergedAconfigFiles)
|
||||
}
|
||||
|
||||
type installProperties struct {
|
||||
installable bool
|
||||
filename string
|
||||
sourceFilePath android.Path
|
||||
outputFilePath android.OutputPath
|
||||
installDirPath android.InstallPath
|
||||
symlinks []string
|
||||
}
|
||||
|
||||
// utility function to add install rules to the build graph.
|
||||
// Reduces code duplication between Soong and Mixed build analysis
|
||||
func (p *PrebuiltEtc) addInstallRules(ctx android.ModuleContext, ip installProperties) {
|
||||
if !ip.installable {
|
||||
p.SkipInstall()
|
||||
}
|
||||
|
||||
func (ip *installProperties) addInstallRules(ctx android.ModuleContext) {
|
||||
// Copy the file from src to a location in out/ with the correct `filename`
|
||||
// This ensures that outputFilePath has the correct name for others to
|
||||
// use, as the source file may have a different name.
|
||||
p.outputFilePath = android.PathForModuleOut(ctx, ip.filename).OutputPath
|
||||
ctx.Build(pctx, android.BuildParams{
|
||||
Rule: android.Cp,
|
||||
Output: p.outputFilePath,
|
||||
Output: ip.outputFilePath,
|
||||
Input: ip.sourceFilePath,
|
||||
})
|
||||
|
||||
installPath := ctx.InstallFile(p.installDirPath, ip.filename, p.outputFilePath)
|
||||
installPath := ctx.InstallFile(ip.installDirPath, ip.filename, ip.outputFilePath)
|
||||
for _, sl := range ip.symlinks {
|
||||
ctx.InstallSymlink(p.installDirPath, sl, installPath)
|
||||
ctx.InstallSymlink(ip.installDirPath, sl, installPath)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -421,15 +480,15 @@ func (p *PrebuiltEtc) AndroidMkEntries() []android.AndroidMkEntries {
|
||||
class = "ETC"
|
||||
}
|
||||
|
||||
return []android.AndroidMkEntries{android.AndroidMkEntries{
|
||||
return []android.AndroidMkEntries{{
|
||||
Class: class,
|
||||
SubName: nameSuffix,
|
||||
OutputFile: android.OptionalPathForPath(p.outputFilePath),
|
||||
OutputFile: android.OptionalPathForPath(p.outputFilePaths[0]),
|
||||
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
|
||||
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
|
||||
entries.SetString("LOCAL_MODULE_TAGS", "optional")
|
||||
entries.SetString("LOCAL_MODULE_PATH", p.installDirPath.String())
|
||||
entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.outputFilePath.Base())
|
||||
entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.outputFilePaths[0].Base())
|
||||
if len(p.properties.Symlinks) > 0 {
|
||||
entries.AddStrings("LOCAL_MODULE_SYMLINKS", p.properties.Symlinks...)
|
||||
}
|
||||
@@ -700,7 +759,11 @@ func generatePrebuiltSnapshot(s snapshot.SnapshotSingleton, ctx android.Singleto
|
||||
targetArch := "arch-" + m.Target().Arch.ArchType.String()
|
||||
|
||||
snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, "etc", m.BaseModuleName())
|
||||
snapshotOutputs = append(snapshotOutputs, copyFile(ctx, m.OutputFile(), snapshotLibOut, s.Fake))
|
||||
outputs, _ := m.OutputFiles("")
|
||||
for _, output := range outputs {
|
||||
cp := copyFile(ctx, output, snapshotLibOut, s.Fake)
|
||||
snapshotOutputs = append(snapshotOutputs, cp)
|
||||
}
|
||||
|
||||
prop := snapshot.SnapshotJsonFlags{}
|
||||
propOut := snapshotLibOut + ".json"
|
||||
|
@@ -96,7 +96,7 @@ func TestPrebuiltEtcOutputPath(t *testing.T) {
|
||||
`)
|
||||
|
||||
p := result.Module("foo.conf", "android_arm64_armv8-a").(*PrebuiltEtc)
|
||||
android.AssertStringEquals(t, "output file path", "foo.installed.conf", p.outputFilePath.Base())
|
||||
android.AssertStringEquals(t, "output file path", "foo.installed.conf", p.outputFilePaths[0].Base())
|
||||
}
|
||||
|
||||
func TestPrebuiltEtcGlob(t *testing.T) {
|
||||
@@ -113,10 +113,24 @@ func TestPrebuiltEtcGlob(t *testing.T) {
|
||||
`)
|
||||
|
||||
p := result.Module("my_foo", "android_arm64_armv8-a").(*PrebuiltEtc)
|
||||
android.AssertStringEquals(t, "my_foo output file path", "my_foo", p.outputFilePath.Base())
|
||||
android.AssertStringEquals(t, "my_foo output file path", "my_foo", p.outputFilePaths[0].Base())
|
||||
|
||||
p = result.Module("my_bar", "android_arm64_armv8-a").(*PrebuiltEtc)
|
||||
android.AssertStringEquals(t, "my_bar output file path", "bar.conf", p.outputFilePath.Base())
|
||||
android.AssertStringEquals(t, "my_bar output file path", "bar.conf", p.outputFilePaths[0].Base())
|
||||
}
|
||||
|
||||
func TestPrebuiltEtcMultipleSrcs(t *testing.T) {
|
||||
result := prepareForPrebuiltEtcTest.RunTestWithBp(t, `
|
||||
prebuilt_etc {
|
||||
name: "foo",
|
||||
srcs: ["*.conf"],
|
||||
}
|
||||
`)
|
||||
|
||||
p := result.Module("foo", "android_arm64_armv8-a").(*PrebuiltEtc)
|
||||
android.AssertStringEquals(t, "output file path", "bar.conf", p.outputFilePaths[0].Base())
|
||||
android.AssertStringEquals(t, "output file path", "baz.conf", p.outputFilePaths[1].Base())
|
||||
android.AssertStringEquals(t, "output file path", "foo.conf", p.outputFilePaths[2].Base())
|
||||
}
|
||||
|
||||
func TestPrebuiltEtcAndroidMk(t *testing.T) {
|
||||
|
@@ -30,6 +30,7 @@ import (
|
||||
|
||||
"android/soong/android"
|
||||
"android/soong/dexpreopt"
|
||||
"android/soong/etc"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -3163,10 +3164,12 @@ func (module *sdkLibraryXml) SubDir() string {
|
||||
}
|
||||
|
||||
// from android.PrebuiltEtcModule
|
||||
func (module *sdkLibraryXml) OutputFile() android.OutputPath {
|
||||
return module.outputFilePath
|
||||
func (module *sdkLibraryXml) OutputFiles(tag string) (android.Paths, error) {
|
||||
return android.OutputPaths{module.outputFilePath}.Paths(), nil
|
||||
}
|
||||
|
||||
var _ etc.PrebuiltEtcModule = (*sdkLibraryXml)(nil)
|
||||
|
||||
// from android.ApexModule
|
||||
func (module *sdkLibraryXml) AvailableFor(what string) bool {
|
||||
return true
|
||||
|
Reference in New Issue
Block a user