blob: 1f72dce3f45f14688ff17ab602f2cf2dfc9eab43 [file] [log] [blame]
Jiyong Park6f0f6882020-11-12 13:14:30 +09001// Copyright (C) 2020 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 "fmt"
19
20 "android/soong/android"
Jiyong Park65b62242020-11-25 12:44:59 +090021
22 "github.com/google/blueprint"
Jiyong Park6f0f6882020-11-12 13:14:30 +090023)
24
25func init() {
26 android.RegisterModuleType("android_filesystem", filesystemFactory)
27}
28
29type filesystem struct {
30 android.ModuleBase
31 android.PackagingBase
Jiyong Park65c49f52020-11-24 14:23:26 +090032
33 output android.OutputPath
34 installDir android.InstallPath
Jiyong Park6f0f6882020-11-12 13:14:30 +090035}
36
Jiyong Park65c49f52020-11-24 14:23:26 +090037// android_filesystem packages a set of modules and their transitive dependencies into a filesystem
38// image. The filesystem images are expected to be mounted in the target device, which means the
39// modules in the filesystem image are built for the target device (i.e. Android, not Linux host).
40// The modules are placed in the filesystem image just like they are installed to the ordinary
41// partitions like system.img. For example, cc_library modules are placed under ./lib[64] directory.
Jiyong Park6f0f6882020-11-12 13:14:30 +090042func filesystemFactory() android.Module {
43 module := &filesystem{}
44 android.InitPackageModule(module)
45 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
46 return module
47}
48
Jiyong Park12a719c2021-01-07 15:31:24 +090049var dependencyTag = struct {
50 blueprint.BaseDependencyTag
51 android.InstallAlwaysNeededDependencyTag
52}{}
Jiyong Park65b62242020-11-25 12:44:59 +090053
Jiyong Park6f0f6882020-11-12 13:14:30 +090054func (f *filesystem) DepsMutator(ctx android.BottomUpMutatorContext) {
Jiyong Park65b62242020-11-25 12:44:59 +090055 f.AddDeps(ctx, dependencyTag)
Jiyong Park6f0f6882020-11-12 13:14:30 +090056}
57
Jiyong Park65c49f52020-11-24 14:23:26 +090058func (f *filesystem) installFileName() string {
59 return f.BaseModuleName() + ".img"
60}
61
Jiyong Park6f0f6882020-11-12 13:14:30 +090062var pctx = android.NewPackageContext("android/soong/filesystem")
63
64func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) {
65 zipFile := android.PathForModuleOut(ctx, "temp.zip").OutputPath
66 f.CopyDepsToZip(ctx, zipFile)
67
68 rootDir := android.PathForModuleOut(ctx, "root").OutputPath
Colin Crossf1a035e2020-11-16 17:32:30 -080069 builder := android.NewRuleBuilder(pctx, ctx)
Jiyong Park6f0f6882020-11-12 13:14:30 +090070 builder.Command().
Colin Crossf1a035e2020-11-16 17:32:30 -080071 BuiltTool("zipsync").
Jiyong Park6f0f6882020-11-12 13:14:30 +090072 FlagWithArg("-d ", rootDir.String()). // zipsync wipes this. No need to clear.
73 Input(zipFile)
74
Jiyong Park72678312021-01-18 17:29:49 +090075 propFile, toolDeps := f.buildPropFile(ctx)
Jiyong Park12a719c2021-01-07 15:31:24 +090076 f.output = android.PathForModuleOut(ctx, f.installFileName()).OutputPath
Colin Crossf1a035e2020-11-16 17:32:30 -080077 builder.Command().BuiltTool("build_image").
Jiyong Park6f0f6882020-11-12 13:14:30 +090078 Text(rootDir.String()). // input directory
79 Input(propFile).
Jiyong Park72678312021-01-18 17:29:49 +090080 Implicits(toolDeps).
Jiyong Park65c49f52020-11-24 14:23:26 +090081 Output(f.output).
Jiyong Park6f0f6882020-11-12 13:14:30 +090082 Text(rootDir.String()) // directory where to find fs_config_files|dirs
83
84 // rootDir is not deleted. Might be useful for quick inspection.
Colin Crossf1a035e2020-11-16 17:32:30 -080085 builder.Build("build_filesystem_image", fmt.Sprintf("Creating filesystem %s", f.BaseModuleName()))
Jiyong Park65c49f52020-11-24 14:23:26 +090086
87 f.installDir = android.PathForModuleInstall(ctx, "etc")
88 ctx.InstallFile(f.installDir, f.installFileName(), f.output)
89}
90
Jiyong Park72678312021-01-18 17:29:49 +090091func (f *filesystem) buildPropFile(ctx android.ModuleContext) (propFile android.OutputPath, toolDeps android.Paths) {
92 type prop struct {
93 name string
94 value string
95 }
96
97 var props []prop
98 var deps android.Paths
99 addStr := func(name string, value string) {
100 props = append(props, prop{name, value})
101 }
102 addPath := func(name string, path android.Path) {
103 props = append(props, prop{name, path.String()})
104 deps = append(deps, path)
105 }
106
107 // TODO(jiyong): support more filesystem types other than ext4
108 addStr("fs_type", "ext4")
109 addStr("mount_point", "system")
110 addStr("use_dynamic_partition_size", "true")
111 addPath("ext_mkuserimg", ctx.Config().HostToolPath(ctx, "mkuserimg_mke2fs"))
112 // b/177813163 deps of the host tools have to be added. Remove this.
113 for _, t := range []string{"mke2fs", "e2fsdroid", "tune2fs"} {
114 deps = append(deps, ctx.Config().HostToolPath(ctx, t))
115 }
116
117 propFile = android.PathForModuleOut(ctx, "prop").OutputPath
118 builder := android.NewRuleBuilder(pctx, ctx)
119 builder.Command().Text("rm").Flag("-rf").Output(propFile)
120 for _, p := range props {
121 builder.Command().
122 Text("echo").Flag("-e").
123 Flag(`"` + p.name + "=" + p.value + `"`).
124 Text(">>").Output(propFile)
125 }
126 builder.Build("build_filesystem_prop", fmt.Sprintf("Creating filesystem props for %s", f.BaseModuleName()))
127 return propFile, deps
128}
129
Jiyong Park65c49f52020-11-24 14:23:26 +0900130var _ android.AndroidMkEntriesProvider = (*filesystem)(nil)
131
132// Implements android.AndroidMkEntriesProvider
133func (f *filesystem) AndroidMkEntries() []android.AndroidMkEntries {
134 return []android.AndroidMkEntries{android.AndroidMkEntries{
135 Class: "ETC",
136 OutputFile: android.OptionalPathForPath(f.output),
137 ExtraEntries: []android.AndroidMkExtraEntriesFunc{
138 func(entries *android.AndroidMkEntries) {
139 entries.SetString("LOCAL_MODULE_PATH", f.installDir.ToMakePath().String())
140 entries.SetString("LOCAL_INSTALLED_MODULE_STEM", f.installFileName())
141 },
142 },
143 }}
Jiyong Park6f0f6882020-11-12 13:14:30 +0900144}
Jiyong Park12a719c2021-01-07 15:31:24 +0900145
146// Filesystem is the public interface for the filesystem struct. Currently, it's only for the apex
147// package to have access to the output file.
148type Filesystem interface {
149 android.Module
150 OutputPath() android.Path
151}
152
153var _ Filesystem = (*filesystem)(nil)
154
155func (f *filesystem) OutputPath() android.Path {
156 return f.output
157}