summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cc/stub_library.go4
-rw-r--r--filesystem/Android.bp2
-rw-r--r--filesystem/filesystem.go39
-rw-r--r--filesystem/filesystem_test.go34
-rw-r--r--filesystem/system_image.go68
-rw-r--r--linkerconfig/Android.bp1
-rw-r--r--linkerconfig/linkerconfig.go65
7 files changed, 192 insertions, 21 deletions
diff --git a/cc/stub_library.go b/cc/stub_library.go
index 76d236ce6..81c8be783 100644
--- a/cc/stub_library.go
+++ b/cc/stub_library.go
@@ -30,7 +30,7 @@ type stubLibraries struct {
}
// Check if the module defines stub, or itself is stub
-func isStubTarget(m *Module) bool {
+func IsStubTarget(m *Module) bool {
if m.IsStubs() || m.HasStubsVariants() {
return true
}
@@ -61,7 +61,7 @@ func (s *stubLibraries) GenerateBuildActions(ctx android.SingletonContext) {
// Visit all generated soong modules and store stub library file names.
ctx.VisitAllModules(func(module android.Module) {
if m, ok := module.(*Module); ok {
- if isStubTarget(m) {
+ if IsStubTarget(m) {
if name := getInstalledFileName(m); name != "" {
s.stubLibraryMap[name] = true
}
diff --git a/filesystem/Android.bp b/filesystem/Android.bp
index 3cdaa6418..38684d3b2 100644
--- a/filesystem/Android.bp
+++ b/filesystem/Android.bp
@@ -9,11 +9,13 @@ bootstrap_go_package {
"blueprint",
"soong",
"soong-android",
+ "soong-linkerconfig",
],
srcs: [
"bootimg.go",
"filesystem.go",
"logical_partition.go",
+ "system_image.go",
"vbmeta.go",
"testing.go",
],
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index cf9871701..b2caa51d2 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -31,6 +31,7 @@ func init() {
func registerBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterModuleType("android_filesystem", filesystemFactory)
+ ctx.RegisterModuleType("android_system_image", systemImageFactory)
}
type filesystem struct {
@@ -39,6 +40,9 @@ type filesystem struct {
properties filesystemProperties
+ // Function that builds extra files under the root directory and returns the files
+ buildExtraFiles func(ctx android.ModuleContext, root android.OutputPath) android.OutputPaths
+
output android.OutputPath
installDir android.InstallPath
}
@@ -87,10 +91,14 @@ type filesystemProperties struct {
// partitions like system.img. For example, cc_library modules are placed under ./lib[64] directory.
func filesystemFactory() android.Module {
module := &filesystem{}
+ initFilesystemModule(module)
+ return module
+}
+
+func initFilesystemModule(module *filesystem) {
module.AddProperties(&module.properties)
android.InitPackageModule(module)
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
- return module
}
var dependencyTag = struct {
@@ -148,7 +156,7 @@ func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) {
ctx.InstallFile(f.installDir, f.installFileName(), f.output)
}
-// root zip will contain stuffs like dirs or symlinks.
+// root zip will contain extra files/dirs that are not from the `deps` property.
func (f *filesystem) buildRootZip(ctx android.ModuleContext) android.OutputPath {
rootDir := android.PathForModuleGen(ctx, "root").OutputPath
builder := android.NewRuleBuilder(pctx, ctx)
@@ -182,15 +190,34 @@ func (f *filesystem) buildRootZip(ctx android.ModuleContext) android.OutputPath
builder.Command().Text("ln -sf").Text(proptools.ShellEscape(target)).Text(dst.String())
}
- zipOut := android.PathForModuleGen(ctx, "root.zip").OutputPath
+ // create extra files if there's any
+ rootForExtraFiles := android.PathForModuleGen(ctx, "root-extra").OutputPath
+ var extraFiles android.OutputPaths
+ if f.buildExtraFiles != nil {
+ extraFiles = f.buildExtraFiles(ctx, rootForExtraFiles)
+ for _, f := range extraFiles {
+ rel, _ := filepath.Rel(rootForExtraFiles.String(), f.String())
+ if strings.HasPrefix(rel, "..") {
+ panic(fmt.Errorf("%q is not under %q\n", f, rootForExtraFiles))
+ }
+ }
+ }
- builder.Command().
- BuiltTool("soong_zip").
- FlagWithOutput("-o ", zipOut).
+ // Zip them all
+ zipOut := android.PathForModuleGen(ctx, "root.zip").OutputPath
+ zipCommand := builder.Command().BuiltTool("soong_zip")
+ zipCommand.FlagWithOutput("-o ", zipOut).
FlagWithArg("-C ", rootDir.String()).
Flag("-L 0"). // no compression because this will be unzipped soon
FlagWithArg("-D ", rootDir.String()).
Flag("-d") // include empty directories
+ if len(extraFiles) > 0 {
+ zipCommand.FlagWithArg("-C ", rootForExtraFiles.String())
+ for _, f := range extraFiles {
+ zipCommand.FlagWithInput("-f ", f)
+ }
+ }
+
builder.Command().Text("rm -rf").Text(rootDir.String())
builder.Build("zip_root", fmt.Sprintf("zipping root contents for %s", ctx.ModuleName()))
diff --git a/filesystem/filesystem_test.go b/filesystem/filesystem_test.go
index 880b17741..e78fdffde 100644
--- a/filesystem/filesystem_test.go
+++ b/filesystem/filesystem_test.go
@@ -19,6 +19,7 @@ import (
"testing"
"android/soong/android"
+ "android/soong/cc"
)
func TestMain(m *testing.M) {
@@ -27,6 +28,7 @@ func TestMain(m *testing.M) {
var fixture = android.GroupFixturePreparers(
android.PrepareForIntegrationTestWithAndroid,
+ cc.PrepareForIntegrationTestWithCc,
PrepareForTestWithFilesystemBuildComponents,
)
@@ -40,3 +42,35 @@ func TestFileSystemDeps(t *testing.T) {
// produces "myfilesystem.img"
result.ModuleForTests("myfilesystem", "android_common").Output("myfilesystem.img")
}
+
+func TestFileSystemFillsLinkerConfigWithStubLibs(t *testing.T) {
+ result := fixture.RunTestWithBp(t, `
+ android_system_image {
+ name: "myfilesystem",
+ deps: [
+ "libfoo",
+ "libbar",
+ ],
+ linker_config_src: "linker.config.json",
+ }
+
+ cc_library {
+ name: "libfoo",
+ stubs: {
+ symbol_file: "libfoo.map.txt",
+ },
+ }
+
+ cc_library {
+ name: "libbar",
+ }
+ `)
+
+ module := result.ModuleForTests("myfilesystem", "android_common")
+ output := module.Output("system/etc/linker.config.pb")
+
+ android.AssertStringDoesContain(t, "linker.config.pb should have libfoo",
+ output.RuleParams.Command, "libfoo.so")
+ android.AssertStringDoesNotContain(t, "linker.config.pb should not have libbar",
+ output.RuleParams.Command, "libbar.so")
+}
diff --git a/filesystem/system_image.go b/filesystem/system_image.go
new file mode 100644
index 000000000..a7c914395
--- /dev/null
+++ b/filesystem/system_image.go
@@ -0,0 +1,68 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package filesystem
+
+import (
+ "android/soong/android"
+ "android/soong/linkerconfig"
+)
+
+type systemImage struct {
+ filesystem
+
+ properties systemImageProperties
+}
+
+type systemImageProperties struct {
+ // Path to the input linker config json file.
+ Linker_config_src *string
+}
+
+// android_system_image is a specialization of android_filesystem for the 'system' partition.
+// Currently, the only difference is the inclusion of linker.config.pb file which specifies
+// the provided and the required libraries to and from APEXes.
+func systemImageFactory() android.Module {
+ module := &systemImage{}
+ module.AddProperties(&module.properties)
+ module.filesystem.buildExtraFiles = module.buildExtraFiles
+ initFilesystemModule(&module.filesystem)
+ return module
+}
+
+func (s *systemImage) buildExtraFiles(ctx android.ModuleContext, root android.OutputPath) android.OutputPaths {
+ lc := s.buildLinkerConfigFile(ctx, root)
+ // Add more files if needed
+ return []android.OutputPath{lc}
+}
+
+func (s *systemImage) buildLinkerConfigFile(ctx android.ModuleContext, root android.OutputPath) android.OutputPath {
+ input := android.PathForModuleSrc(ctx, android.String(s.properties.Linker_config_src))
+ output := root.Join(ctx, "system", "etc", "linker.config.pb")
+ var otherModules []android.Module
+ ctx.WalkDeps(func(child, parent android.Module) bool {
+ // Don't track direct dependencies that aren't not packaged
+ if parent == s {
+ if pi, ok := ctx.OtherModuleDependencyTag(child).(android.PackagingItem); !ok || !pi.IsPackagingItem() {
+ return false
+ }
+ }
+ otherModules = append(otherModules, child)
+ return true
+ })
+ builder := android.NewRuleBuilder(pctx, ctx)
+ linkerconfig.BuildLinkerConfig(ctx, builder, input, otherModules, output)
+ builder.Build("conv_linker_config", "Generate linker config protobuf "+output.String())
+ return output
+}
diff --git a/linkerconfig/Android.bp b/linkerconfig/Android.bp
index 9161f0eb5..76a632517 100644
--- a/linkerconfig/Android.bp
+++ b/linkerconfig/Android.bp
@@ -9,6 +9,7 @@ bootstrap_go_package {
"blueprint",
"soong",
"soong-android",
+ "soong-cc",
"soong-etc",
],
srcs: [
diff --git a/linkerconfig/linkerconfig.go b/linkerconfig/linkerconfig.go
index 241cac691..8d0ad7cf2 100644
--- a/linkerconfig/linkerconfig.go
+++ b/linkerconfig/linkerconfig.go
@@ -15,11 +15,15 @@
package linkerconfig
import (
- "android/soong/android"
- "android/soong/etc"
"fmt"
+ "sort"
+ "strings"
"github.com/google/blueprint/proptools"
+
+ "android/soong/android"
+ "android/soong/cc"
+ "android/soong/etc"
)
var (
@@ -81,24 +85,59 @@ func (l *linkerConfig) OutputFiles(tag string) (android.Paths, error) {
}
func (l *linkerConfig) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- inputFile := android.PathForModuleSrc(ctx, android.String(l.properties.Src))
- l.outputFilePath = android.PathForModuleOut(ctx, "linker.config.pb").OutputPath
- l.installDirPath = android.PathForModuleInstall(ctx, "etc")
- linkerConfigRule := android.NewRuleBuilder(pctx, ctx)
- linkerConfigRule.Command().
- BuiltTool("conv_linker_config").
- Flag("proto").
- FlagWithInput("-s ", inputFile).
- FlagWithOutput("-o ", l.outputFilePath)
- linkerConfigRule.Build("conv_linker_config",
- "Generate linker config protobuf "+l.outputFilePath.String())
+ input := android.PathForModuleSrc(ctx, android.String(l.properties.Src))
+ output := android.PathForModuleOut(ctx, "linker.config.pb").OutputPath
+
+ builder := android.NewRuleBuilder(pctx, ctx)
+ BuildLinkerConfig(ctx, builder, input, nil, output)
+ builder.Build("conv_linker_config", "Generate linker config protobuf "+output.String())
+ l.outputFilePath = output
+ l.installDirPath = android.PathForModuleInstall(ctx, "etc")
if !proptools.BoolDefault(l.properties.Installable, true) {
l.SkipInstall()
}
ctx.InstallFile(l.installDirPath, l.outputFilePath.Base(), l.outputFilePath)
}
+func BuildLinkerConfig(ctx android.ModuleContext, builder *android.RuleBuilder,
+ input android.Path, otherModules []android.Module, output android.OutputPath) {
+
+ // First, convert the input json to protobuf format
+ interimOutput := android.PathForModuleOut(ctx, "temp.pb")
+ builder.Command().
+ BuiltTool("conv_linker_config").
+ Flag("proto").
+ FlagWithInput("-s ", input).
+ FlagWithOutput("-o ", interimOutput)
+
+ // Secondly, if there's provideLibs gathered from otherModules, append them
+ var provideLibs []string
+ for _, m := range otherModules {
+ if c, ok := m.(*cc.Module); ok && cc.IsStubTarget(c) {
+ for _, ps := range c.PackagingSpecs() {
+ provideLibs = append(provideLibs, ps.FileName())
+ }
+ }
+ }
+ provideLibs = android.FirstUniqueStrings(provideLibs)
+ sort.Strings(provideLibs)
+ if len(provideLibs) > 0 {
+ builder.Command().
+ BuiltTool("conv_linker_config").
+ Flag("append").
+ FlagWithInput("-s ", interimOutput).
+ FlagWithOutput("-o ", output).
+ FlagWithArg("--key ", "provideLibs").
+ FlagWithArg("--value ", proptools.ShellEscapeIncludingSpaces(strings.Join(provideLibs, " ")))
+ } else {
+ // If nothing to add, just cp to the final output
+ builder.Command().Text("cp").Input(interimOutput).Output(output)
+ }
+ builder.Temporary(interimOutput)
+ builder.DeleteTemporaryFiles()
+}
+
// linker_config generates protobuf file from json file. This protobuf file will be used from
// linkerconfig while generating ld.config.txt. Format of this file can be found from
// https://android.googlesource.com/platform/system/linkerconfig/+/master/README.md