blob: 54ad10bfbcd3c697ba32d0a6f2f68bdd1a2f2367 [file] [log] [blame]
Jiyong Parka5f914a2019-01-20 21:02:00 +09001// Copyright (C) 2019 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 bionic
16
17import (
18 "fmt"
19 "io"
20 "strings"
21
Jiyong Parkacb4d212019-02-11 16:05:48 +090022 "github.com/google/blueprint"
Jiyong Parka5f914a2019-01-20 21:02:00 +090023 "github.com/google/blueprint/proptools"
24
25 "android/soong/android"
Jiyong Parkacb4d212019-02-11 16:05:48 +090026 "android/soong/cc"
Jiyong Parka5f914a2019-01-20 21:02:00 +090027)
28
29// bionic_mountpoint is a module type that is specialized to create
30// mount points for Bionic files (libc, libdl, libm, and linker).
31//
32// With following description,
33//
34// bionic_mountpoint {
35// name: "libc.mountpoint",
36// stem: "libc.so",
37// src: "dummy_mountpoint",
38// library: true,
39// symlinks: ["libc.so"],
40// }
41//
42// , the build system does following jobs:
43//
44// A mount point /bionic/lib[64]/libc.so is created. Its content
45// is from the file 'dummy_mountpoint'.
46//
47// Then a symlink is created at /system/lib[64]/libc.so which points to
48// the created mountpoint.
49//
50// At runtime, on the mount point, either bootstrap Bionic or default Bionic
51// (which is from the runtime APEX) is mounted by the init process. The
52// symlink exists to provide consistent legacy path for compatibility
53// reason.
54func init() {
55 android.RegisterModuleType("bionic_mountpoint", bionicMountpointFactory)
56}
57
58type bionicMountpoint struct {
59 android.ModuleBase
60 properties bionicMountpointProperties
61
62 outputFile android.Path
63 pathInPartition string
64 stem string
Jiyong Parkacb4d212019-02-11 16:05:48 +090065 unstrippedOutputFile android.Path
Jiyong Parka5f914a2019-01-20 21:02:00 +090066}
67
68type bionicMountpointProperties struct {
69 // The file that is installed as the mount point
70 Src *string
71
Jiyong Parkacb4d212019-02-11 16:05:48 +090072 // TODO(jiyong) remove these two properties (probably Stem and Suffix
73 // as well, as they can be inteffered from Mountsource
74
Jiyong Parka5f914a2019-01-20 21:02:00 +090075 // True if the mount point is for a Bionic library such libc.so
76 Library *bool
77 // True if the mount point is for a Bionic binary such as linker
78 Binary *bool
79
Jiyong Parkacb4d212019-02-11 16:05:48 +090080 // The module that this module is a mount point for
81 Mountsource *string
82
Jiyong Parka5f914a2019-01-20 21:02:00 +090083 // Base name of the mount point
84 Stem *string `android:"arch_variant"`
85
86 // Append to the name of the output
87 Suffix *string `android:"arch_variant"`
88
89 // Symlinks to the mountpoints from the system and recovery partitions
90 // Symlinks names will have the same suffix as the mount point
91 Symlinks []string
Jiyong Park88d03202019-02-15 12:15:27 +090092
93 // List of sanitizer names that this APEX is enabled for
94 SanitizerNames []string `blueprint:"mutated"`
Jiyong Parka5f914a2019-01-20 21:02:00 +090095}
96
Jiyong Parkacb4d212019-02-11 16:05:48 +090097type dependencyTag struct {
98 blueprint.BaseDependencyTag
99 name string
100}
101
102var mountsourceTag = dependencyTag{name: "mountsource"}
103
Jiyong Park88d03202019-02-15 12:15:27 +0900104
105func (m *bionicMountpoint) EnableSanitizer(sanitizerName string) {
106 if !android.InList(sanitizerName, m.properties.SanitizerNames) {
107 m.properties.SanitizerNames = append(m.properties.SanitizerNames, sanitizerName)
108 }
109}
110
111func (m *bionicMountpoint) IsSanitizerEnabled(ctx android.BaseModuleContext, sanitizerName string) bool {
112 if android.InList(sanitizerName, m.properties.SanitizerNames) {
113 return true
114 }
115
116 // Then follow the global setting
117 globalSanitizerNames := []string{}
118 if m.Host() {
119 globalSanitizerNames = ctx.Config().SanitizeHost()
120 } else {
121 arches := ctx.Config().SanitizeDeviceArch()
122 if len(arches) == 0 || android.InList(m.Arch().ArchType.Name, arches) {
123 globalSanitizerNames = ctx.Config().SanitizeDevice()
124 }
125 }
126 return android.InList(sanitizerName, globalSanitizerNames)
127}
128
Jiyong Parka5f914a2019-01-20 21:02:00 +0900129func (m *bionicMountpoint) DepsMutator(ctx android.BottomUpMutatorContext) {
130 if Bool(m.properties.Library) == Bool(m.properties.Binary) {
131 ctx.ModuleErrorf("either binary or library must be set to true")
132 return
133 }
134 if m.properties.Stem == nil {
135 ctx.PropertyErrorf("stem", "stem must be set")
136 return
137 }
138 if m.properties.Src == nil {
139 ctx.PropertyErrorf("src", "src must be set")
140 }
141 android.ExtractSourceDeps(ctx, m.properties.Src)
Jiyong Parkacb4d212019-02-11 16:05:48 +0900142
143 if m.properties.Mountsource == nil {
144 ctx.PropertyErrorf("mountsource", "mountsource must be set")
145 return
146 }
147
148 ctx.AddFarVariationDependencies([]blueprint.Variation{
149 {Mutator: "arch", Variation: ctx.Target().String()},
150 {Mutator: "image", Variation: "core"},
151 {Mutator: "link", Variation: "shared"},
152 }, mountsourceTag, String(m.properties.Mountsource))
Jiyong Parka5f914a2019-01-20 21:02:00 +0900153}
154
155func (m *bionicMountpoint) GenerateAndroidBuildActions(ctx android.ModuleContext) {
156 if Bool(m.properties.Library) {
157 m.pathInPartition = "lib"
158 if m.Arch().ArchType.Multilib == "lib64" {
159 m.pathInPartition = "lib64"
160 }
161 } else if Bool(m.properties.Binary) {
162 m.pathInPartition = "bin"
163 }
164
165 m.stem = String(m.properties.Stem) + String(m.properties.Suffix)
166
167 m.outputFile = ctx.ExpandSource(String(m.properties.Src), "src")
Jiyong Parkacb4d212019-02-11 16:05:48 +0900168
169 ctx.VisitDirectDepsWithTag(mountsourceTag, func(module android.Module) {
170 if cc, ok := module.(*cc.Module); ok {
171 m.unstrippedOutputFile = cc.UnstrippedOutputFile()
172 }
173 })
Jiyong Parka5f914a2019-01-20 21:02:00 +0900174}
175
176func (m *bionicMountpoint) AndroidMk() android.AndroidMkData {
177 return android.AndroidMkData {
178 Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
179 if !m.Arch().Native {
180 return
181 }
182 fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
183 fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
184 fmt.Fprintln(w, "LOCAL_MODULE :=", name)
185 fmt.Fprintln(w, "LOCAL_USE_CLANG_LLD := false")
186 fmt.Fprintln(w, "LOCAL_STRIP_MODULE := false")
187 if Bool(m.properties.Library) {
188 fmt.Fprintln(w, "LOCAL_MODULE_CLASS := SHARED_LIBRARIES")
189 } else if Bool(m.properties.Binary) {
190 fmt.Fprintln(w, "LOCAL_MODULE_CLASS := EXECUTABLES")
191 }
192 fmt.Fprintln(w, "LOCAL_MODULE_TAGS := optional")
193 fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", m.outputFile.String())
194 fmt.Fprintln(w, "LOCAL_MODULE_TARGET_ARCH :=", m.Arch().ArchType.String())
195 fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", "$(TARGET_ROOT_OUT)/bionic/" + m.pathInPartition)
196 fmt.Fprintln(w, "LOCAL_INSTALLED_MODULE_STEM :=", m.stem)
197
198 if len(m.properties.Symlinks) > 0 {
199 symlink_dir_in_system := "$(TARGET_OUT)/" + m.pathInPartition + "/"
200 symlink_dir_in_recovery := "$(TARGET_RECOVERY_ROOT_OUT)/system/" + m.pathInPartition + "/"
201 symlink_target := "/bionic/" + m.pathInPartition + "/" + m.stem
202 cmds := []string{}
203 cmds = append(cmds, "$(hide) mkdir -p " + symlink_dir_in_system)
204 cmds = append(cmds, "mkdir -p " + symlink_dir_in_recovery)
205 for _, s := range m.properties.Symlinks {
206 symlink := s + String(m.properties.Suffix)
207 cmds = append(cmds, "ln -sf " + symlink_target + " " + symlink_dir_in_system + symlink)
208 cmds = append(cmds, "ln -sf " + symlink_target + " " + symlink_dir_in_recovery + symlink)
209 }
210 fmt.Fprintln(w, "LOCAL_POST_INSTALL_CMD := " + strings.Join(cmds, " && "))
211 }
Jiyong Parkacb4d212019-02-11 16:05:48 +0900212 if m.unstrippedOutputFile != nil {
213 fmt.Fprintln(w, "LOCAL_SOONG_UNSTRIPPED_BINARY :=", m.unstrippedOutputFile.String())
214 }
215 fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_cc_prebuilt.mk")
Jiyong Parka5f914a2019-01-20 21:02:00 +0900216 },
217 }
218}
219
220func bionicMountpointFactory() android.Module {
221 m := &bionicMountpoint{}
222 m.AddProperties(&m.properties)
223 android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibBoth)
224 return m
225}
226
227var Bool = proptools.Bool
228var String = proptools.String