blob: 3522acae8075b56adb960ade5eeb25fac51241a8 [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
22 "github.com/google/blueprint/proptools"
23
24 "android/soong/android"
25)
26
27// bionic_mountpoint is a module type that is specialized to create
28// mount points for Bionic files (libc, libdl, libm, and linker).
29//
30// With following description,
31//
32// bionic_mountpoint {
33// name: "libc.mountpoint",
34// stem: "libc.so",
35// src: "dummy_mountpoint",
36// library: true,
37// symlinks: ["libc.so"],
38// }
39//
40// , the build system does following jobs:
41//
42// A mount point /bionic/lib[64]/libc.so is created. Its content
43// is from the file 'dummy_mountpoint'.
44//
45// Then a symlink is created at /system/lib[64]/libc.so which points to
46// the created mountpoint.
47//
48// At runtime, on the mount point, either bootstrap Bionic or default Bionic
49// (which is from the runtime APEX) is mounted by the init process. The
50// symlink exists to provide consistent legacy path for compatibility
51// reason.
52func init() {
53 android.RegisterModuleType("bionic_mountpoint", bionicMountpointFactory)
54}
55
56type bionicMountpoint struct {
57 android.ModuleBase
58 properties bionicMountpointProperties
59
60 outputFile android.Path
61 pathInPartition string
62 stem string
63}
64
65type bionicMountpointProperties struct {
66 // The file that is installed as the mount point
67 Src *string
68
69 // True if the mount point is for a Bionic library such libc.so
70 Library *bool
71 // True if the mount point is for a Bionic binary such as linker
72 Binary *bool
73
74 // Base name of the mount point
75 Stem *string `android:"arch_variant"`
76
77 // Append to the name of the output
78 Suffix *string `android:"arch_variant"`
79
80 // Symlinks to the mountpoints from the system and recovery partitions
81 // Symlinks names will have the same suffix as the mount point
82 Symlinks []string
83}
84
85func (m *bionicMountpoint) DepsMutator(ctx android.BottomUpMutatorContext) {
86 if Bool(m.properties.Library) == Bool(m.properties.Binary) {
87 ctx.ModuleErrorf("either binary or library must be set to true")
88 return
89 }
90 if m.properties.Stem == nil {
91 ctx.PropertyErrorf("stem", "stem must be set")
92 return
93 }
94 if m.properties.Src == nil {
95 ctx.PropertyErrorf("src", "src must be set")
96 }
97 android.ExtractSourceDeps(ctx, m.properties.Src)
98}
99
100func (m *bionicMountpoint) GenerateAndroidBuildActions(ctx android.ModuleContext) {
101 if Bool(m.properties.Library) {
102 m.pathInPartition = "lib"
103 if m.Arch().ArchType.Multilib == "lib64" {
104 m.pathInPartition = "lib64"
105 }
106 } else if Bool(m.properties.Binary) {
107 m.pathInPartition = "bin"
108 }
109
110 m.stem = String(m.properties.Stem) + String(m.properties.Suffix)
111
112 m.outputFile = ctx.ExpandSource(String(m.properties.Src), "src")
113}
114
115func (m *bionicMountpoint) AndroidMk() android.AndroidMkData {
116 return android.AndroidMkData {
117 Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
118 if !m.Arch().Native {
119 return
120 }
121 fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
122 fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
123 fmt.Fprintln(w, "LOCAL_MODULE :=", name)
124 fmt.Fprintln(w, "LOCAL_USE_CLANG_LLD := false")
125 fmt.Fprintln(w, "LOCAL_STRIP_MODULE := false")
126 if Bool(m.properties.Library) {
127 fmt.Fprintln(w, "LOCAL_MODULE_CLASS := SHARED_LIBRARIES")
128 } else if Bool(m.properties.Binary) {
129 fmt.Fprintln(w, "LOCAL_MODULE_CLASS := EXECUTABLES")
130 }
131 fmt.Fprintln(w, "LOCAL_MODULE_TAGS := optional")
132 fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", m.outputFile.String())
133 fmt.Fprintln(w, "LOCAL_MODULE_TARGET_ARCH :=", m.Arch().ArchType.String())
134 fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", "$(TARGET_ROOT_OUT)/bionic/" + m.pathInPartition)
135 fmt.Fprintln(w, "LOCAL_INSTALLED_MODULE_STEM :=", m.stem)
136
137 if len(m.properties.Symlinks) > 0 {
138 symlink_dir_in_system := "$(TARGET_OUT)/" + m.pathInPartition + "/"
139 symlink_dir_in_recovery := "$(TARGET_RECOVERY_ROOT_OUT)/system/" + m.pathInPartition + "/"
140 symlink_target := "/bionic/" + m.pathInPartition + "/" + m.stem
141 cmds := []string{}
142 cmds = append(cmds, "$(hide) mkdir -p " + symlink_dir_in_system)
143 cmds = append(cmds, "mkdir -p " + symlink_dir_in_recovery)
144 for _, s := range m.properties.Symlinks {
145 symlink := s + String(m.properties.Suffix)
146 cmds = append(cmds, "ln -sf " + symlink_target + " " + symlink_dir_in_system + symlink)
147 cmds = append(cmds, "ln -sf " + symlink_target + " " + symlink_dir_in_recovery + symlink)
148 }
149 fmt.Fprintln(w, "LOCAL_POST_INSTALL_CMD := " + strings.Join(cmds, " && "))
150 }
151 fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
152 },
153 }
154}
155
156func bionicMountpointFactory() android.Module {
157 m := &bionicMountpoint{}
158 m.AddProperties(&m.properties)
159 android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibBoth)
160 return m
161}
162
163var Bool = proptools.Bool
164var String = proptools.String