1// Copyright (C) 2021 The Android Open Source Project 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package filesystem 16 17import ( 18 "android/soong/android" 19 "android/soong/cc" 20 "android/soong/linkerconfig" 21 22 "strings" 23 24 "github.com/google/blueprint/proptools" 25) 26 27type systemImage struct { 28 filesystem 29} 30 31var _ filesystemBuilder = (*systemImage)(nil) 32 33// android_system_image is a specialization of android_filesystem for the 'system' partition. 34// Currently, the only difference is the inclusion of linker.config.pb file which specifies 35// the provided and the required libraries to and from APEXes. 36func SystemImageFactory() android.Module { 37 module := &systemImage{} 38 module.filesystemBuilder = module 39 initFilesystemModule(module, &module.filesystem) 40 return module 41} 42 43func (s systemImage) FsProps() FilesystemProperties { 44 return s.filesystem.properties 45} 46 47func (s *systemImage) BuildLinkerConfigFile( 48 ctx android.ModuleContext, 49 builder *android.RuleBuilder, 50 rebasedDir android.OutputPath, 51 fullInstallPaths *[]FullInstallPathInfo, 52) { 53 if !proptools.Bool(s.filesystem.properties.Linker_config.Gen_linker_config) { 54 return 55 } 56 57 output := rebasedDir.Join(ctx, "etc", "linker.config.pb") 58 if s.filesystem.properties.Linker_config.Linker_config_srcs != nil { 59 provideModules, requireModules := s.getLibsForLinkerConfig(ctx) 60 intermediateOutput := android.PathForModuleOut(ctx, "linker.config.pb") 61 linkerconfig.BuildLinkerConfig(ctx, android.PathsForModuleSrc(ctx, s.filesystem.properties.Linker_config.Linker_config_srcs), provideModules, requireModules, intermediateOutput) 62 builder.Command().Text("cp").Input(intermediateOutput).Output(output) 63 64 *fullInstallPaths = append(*fullInstallPaths, FullInstallPathInfo{ 65 FullInstallPath: android.PathForModuleInPartitionInstall(ctx, s.PartitionType(), "etc", "linker.config.pb"), 66 SourcePath: intermediateOutput, 67 }) 68 } else { 69 // TODO: This branch is the logic that make uses for the linker config file, which is 70 // different than linkerconfig.BuildLinkerConfig used above. Keeping both branches for now 71 // because microdroid uses the other method and is in theory happy with it. But we should 72 // consider deduping them. 73 stubLibraries := cc.StubLibrariesFile(ctx) 74 llndkMovedToApexLibraries := cc.MovedToApexLlndkLibrariesFile(ctx) 75 outputStep1 := android.PathForModuleOut(ctx, "linker.config.pb.step1") 76 builder.Command(). 77 BuiltTool("conv_linker_config"). 78 Text("proto --force"). 79 FlagWithInput("-s ", android.PathForSource(ctx, "system/core/rootdir/etc/linker.config.json")). 80 FlagWithOutput("-o ", outputStep1) 81 builder.Temporary(outputStep1) 82 builder.Command(). 83 BuiltTool("conv_linker_config"). 84 Text("systemprovide"). 85 FlagWithInput("--source ", outputStep1). 86 FlagWithArg("--output ", output.String()). 87 Textf(`--value "$(cat %s)"`, stubLibraries). 88 Implicit(stubLibraries). 89 FlagWithArg("--system ", rebasedDir.String()) 90 builder.Command(). 91 BuiltTool("conv_linker_config"). 92 Text("append"). 93 FlagWithArg("--source ", output.String()). 94 FlagWithOutput("--output ", output). 95 FlagWithArg("--key ", "requireLibs"). 96 Textf(`--value "$(cat %s)"`, llndkMovedToApexLibraries). 97 Implicit(llndkMovedToApexLibraries) 98 // TODO: Make also supports adding an extra append command with PRODUCT_EXTRA_STUB_LIBRARIES, 99 // but that variable appears to have no usages. 100 101 *fullInstallPaths = append(*fullInstallPaths, FullInstallPathInfo{ 102 FullInstallPath: android.PathForModuleInPartitionInstall(ctx, s.PartitionType(), "etc", "linker.config.pb"), 103 SourcePath: output, 104 }) 105 } 106 107 s.appendToEntry(ctx, output) 108} 109 110// Filter the result of GatherPackagingSpecs to discard items targeting outside "system" / "root" 111// partition. Note that "apex" module installs its contents to "apex"(fake partition) as well 112// for symbol lookup by imitating "activated" paths. 113func (s *systemImage) FilterPackagingSpec(ps android.PackagingSpec) bool { 114 return !ps.SkipInstall() && 115 (ps.Partition() == "system" || ps.Partition() == "root" || 116 strings.HasPrefix(ps.Partition(), "system/")) 117} 118 119func (s *systemImage) ShouldUseVintfFragmentModuleOnly() bool { 120 return true 121} 122