blob: 93c24944f706101eddb3b0eeb203f3b1d43575b2 [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
92}
93
Jiyong Parkacb4d212019-02-11 16:05:48 +090094type dependencyTag struct {
95 blueprint.BaseDependencyTag
96 name string
97}
98
99var mountsourceTag = dependencyTag{name: "mountsource"}
100
Jiyong Parka5f914a2019-01-20 21:02:00 +0900101func (m *bionicMountpoint) DepsMutator(ctx android.BottomUpMutatorContext) {
102 if Bool(m.properties.Library) == Bool(m.properties.Binary) {
103 ctx.ModuleErrorf("either binary or library must be set to true")
104 return
105 }
106 if m.properties.Stem == nil {
107 ctx.PropertyErrorf("stem", "stem must be set")
108 return
109 }
110 if m.properties.Src == nil {
111 ctx.PropertyErrorf("src", "src must be set")
112 }
113 android.ExtractSourceDeps(ctx, m.properties.Src)
Jiyong Parkacb4d212019-02-11 16:05:48 +0900114
115 if m.properties.Mountsource == nil {
116 ctx.PropertyErrorf("mountsource", "mountsource must be set")
117 return
118 }
119
120 ctx.AddFarVariationDependencies([]blueprint.Variation{
121 {Mutator: "arch", Variation: ctx.Target().String()},
122 {Mutator: "image", Variation: "core"},
123 {Mutator: "link", Variation: "shared"},
124 }, mountsourceTag, String(m.properties.Mountsource))
Jiyong Parka5f914a2019-01-20 21:02:00 +0900125}
126
127func (m *bionicMountpoint) GenerateAndroidBuildActions(ctx android.ModuleContext) {
128 if Bool(m.properties.Library) {
129 m.pathInPartition = "lib"
130 if m.Arch().ArchType.Multilib == "lib64" {
131 m.pathInPartition = "lib64"
132 }
133 } else if Bool(m.properties.Binary) {
134 m.pathInPartition = "bin"
135 }
136
137 m.stem = String(m.properties.Stem) + String(m.properties.Suffix)
138
139 m.outputFile = ctx.ExpandSource(String(m.properties.Src), "src")
Jiyong Parkacb4d212019-02-11 16:05:48 +0900140
141 ctx.VisitDirectDepsWithTag(mountsourceTag, func(module android.Module) {
142 if cc, ok := module.(*cc.Module); ok {
143 m.unstrippedOutputFile = cc.UnstrippedOutputFile()
144 }
145 })
Jiyong Parka5f914a2019-01-20 21:02:00 +0900146}
147
148func (m *bionicMountpoint) AndroidMk() android.AndroidMkData {
149 return android.AndroidMkData {
150 Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
151 if !m.Arch().Native {
152 return
153 }
154 fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
155 fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
156 fmt.Fprintln(w, "LOCAL_MODULE :=", name)
157 fmt.Fprintln(w, "LOCAL_USE_CLANG_LLD := false")
158 fmt.Fprintln(w, "LOCAL_STRIP_MODULE := false")
159 if Bool(m.properties.Library) {
160 fmt.Fprintln(w, "LOCAL_MODULE_CLASS := SHARED_LIBRARIES")
161 } else if Bool(m.properties.Binary) {
162 fmt.Fprintln(w, "LOCAL_MODULE_CLASS := EXECUTABLES")
163 }
164 fmt.Fprintln(w, "LOCAL_MODULE_TAGS := optional")
165 fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", m.outputFile.String())
166 fmt.Fprintln(w, "LOCAL_MODULE_TARGET_ARCH :=", m.Arch().ArchType.String())
167 fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", "$(TARGET_ROOT_OUT)/bionic/" + m.pathInPartition)
168 fmt.Fprintln(w, "LOCAL_INSTALLED_MODULE_STEM :=", m.stem)
169
170 if len(m.properties.Symlinks) > 0 {
171 symlink_dir_in_system := "$(TARGET_OUT)/" + m.pathInPartition + "/"
172 symlink_dir_in_recovery := "$(TARGET_RECOVERY_ROOT_OUT)/system/" + m.pathInPartition + "/"
173 symlink_target := "/bionic/" + m.pathInPartition + "/" + m.stem
174 cmds := []string{}
175 cmds = append(cmds, "$(hide) mkdir -p " + symlink_dir_in_system)
176 cmds = append(cmds, "mkdir -p " + symlink_dir_in_recovery)
177 for _, s := range m.properties.Symlinks {
178 symlink := s + String(m.properties.Suffix)
179 cmds = append(cmds, "ln -sf " + symlink_target + " " + symlink_dir_in_system + symlink)
180 cmds = append(cmds, "ln -sf " + symlink_target + " " + symlink_dir_in_recovery + symlink)
181 }
182 fmt.Fprintln(w, "LOCAL_POST_INSTALL_CMD := " + strings.Join(cmds, " && "))
183 }
Jiyong Parkacb4d212019-02-11 16:05:48 +0900184 if m.unstrippedOutputFile != nil {
185 fmt.Fprintln(w, "LOCAL_SOONG_UNSTRIPPED_BINARY :=", m.unstrippedOutputFile.String())
186 }
187 fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_cc_prebuilt.mk")
Jiyong Parka5f914a2019-01-20 21:02:00 +0900188 },
189 }
190}
191
192func bionicMountpointFactory() android.Module {
193 m := &bionicMountpoint{}
194 m.AddProperties(&m.properties)
195 android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibBoth)
196 return m
197}
198
199var Bool = proptools.Bool
200var String = proptools.String