blob: 18e03a5e770e39919c8feeca31f8dc9175fa46ed [file] [log] [blame]
Neill Kapron41efab72024-07-31 22:17:36 +00001// Copyright (C) 2024 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 libbpf_prog
16
17import (
18 "fmt"
19 "io"
20 "runtime"
21 "strings"
22
23 "android/soong/android"
24 "android/soong/cc"
25 "android/soong/genrule"
26
27 "github.com/google/blueprint"
28)
29
30type libbpfProgDepType struct {
31 blueprint.BaseDependencyTag
32}
33
34func init() {
35 registerLibbpfProgBuildComponents(android.InitRegistrationContext)
36 pctx.Import("android/soong/cc/config")
37 pctx.StaticVariable("relPwd", cc.PwdPrefix())
38}
39
40var (
41 pctx = android.NewPackageContext("android/soong/bpf/libbpf_prog")
42
43 libbpfProgCcRule = pctx.AndroidStaticRule("libbpfProgCcRule",
44 blueprint.RuleParams{
45 Depfile: "${out}.d",
46 Deps: blueprint.DepsGCC,
47 Command: "$relPwd $ccCmd --target=bpf -c $cFlags -MD -MF ${out}.d -o $out $in",
48 CommandDeps: []string{"$ccCmd"},
49 },
50 "ccCmd", "cFlags")
51
52 libbpfProgStripRule = pctx.AndroidStaticRule("libbpfProgStripRule",
53 blueprint.RuleParams{
54 Command: `$stripCmd --strip-unneeded --remove-section=.rel.BTF ` +
55 `--remove-section=.rel.BTF.ext --remove-section=.BTF.ext $in -o $out`,
56 CommandDeps: []string{"$stripCmd"},
57 },
58 "stripCmd")
59
60 libbpfProgDepTag = libbpfProgDepType{}
61)
62
63func registerLibbpfProgBuildComponents(ctx android.RegistrationContext) {
Neill Kapron4f1f0492024-09-16 19:33:46 +000064 ctx.RegisterModuleType("libbpf_defaults", defaultsFactory)
Neill Kapron41efab72024-07-31 22:17:36 +000065 ctx.RegisterModuleType("libbpf_prog", LibbpfProgFactory)
66}
67
68var PrepareForTestWithLibbpfProg = android.GroupFixturePreparers(
69 android.FixtureRegisterWithContext(registerLibbpfProgBuildComponents),
70 android.FixtureAddFile("libbpf_headers/Foo.h", nil),
71 android.FixtureAddFile("libbpf_headers/Android.bp", []byte(`
72 genrule {
73 name: "libbpf_headers",
74 out: ["foo.h",],
75 }
76 `)),
77 genrule.PrepareForTestWithGenRuleBuildComponents,
78)
79
80type LibbpfProgProperties struct {
81 // source paths to the files.
82 Srcs []string `android:"path"`
83
84 // additional cflags that should be used to build the libbpf variant of
85 // the C/C++ module.
86 Cflags []string `android:"arch_variant"`
87
88 // list of directories relative to the Blueprint file that will
89 // be added to the include path using -I
90 Local_include_dirs []string `android:"arch_variant"`
91
Neill Kapron3cc44de2024-09-16 20:08:13 +000092 Header_libs []string `android:"arch_variant"`
93
Neill Kapron41efab72024-07-31 22:17:36 +000094 // optional subdirectory under which this module is installed into.
95 Relative_install_path string
96}
97
98type libbpfProg struct {
99 android.ModuleBase
Neill Kapron4f1f0492024-09-16 19:33:46 +0000100 android.DefaultableModuleBase
Neill Kapron41efab72024-07-31 22:17:36 +0000101 properties LibbpfProgProperties
Neill Kapron4f1f0492024-09-16 19:33:46 +0000102 objs android.Paths
Neill Kapron41efab72024-07-31 22:17:36 +0000103}
104
105var _ android.ImageInterface = (*libbpfProg)(nil)
106
Cole Faustfa6e0fd2024-10-15 15:22:57 -0700107func (libbpf *libbpfProg) ImageMutatorBegin(ctx android.ImageInterfaceContext) {}
Neill Kapron41efab72024-07-31 22:17:36 +0000108
Cole Faustfa6e0fd2024-10-15 15:22:57 -0700109func (libbpf *libbpfProg) VendorVariantNeeded(ctx android.ImageInterfaceContext) bool {
Neill Kapron41efab72024-07-31 22:17:36 +0000110 return false
111}
112
Cole Faustfa6e0fd2024-10-15 15:22:57 -0700113func (libbpf *libbpfProg) ProductVariantNeeded(ctx android.ImageInterfaceContext) bool {
Neill Kapron41efab72024-07-31 22:17:36 +0000114 return false
115}
116
Cole Faustfa6e0fd2024-10-15 15:22:57 -0700117func (libbpf *libbpfProg) CoreVariantNeeded(ctx android.ImageInterfaceContext) bool {
Neill Kapron41efab72024-07-31 22:17:36 +0000118 return true
119}
120
Cole Faustfa6e0fd2024-10-15 15:22:57 -0700121func (libbpf *libbpfProg) RamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
Neill Kapron41efab72024-07-31 22:17:36 +0000122 return false
123}
124
Cole Faustfa6e0fd2024-10-15 15:22:57 -0700125func (libbpf *libbpfProg) VendorRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
Neill Kapron41efab72024-07-31 22:17:36 +0000126 return false
127}
128
Cole Faustfa6e0fd2024-10-15 15:22:57 -0700129func (libbpf *libbpfProg) DebugRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
Neill Kapron41efab72024-07-31 22:17:36 +0000130 return false
131}
132
Cole Faustfa6e0fd2024-10-15 15:22:57 -0700133func (libbpf *libbpfProg) RecoveryVariantNeeded(ctx android.ImageInterfaceContext) bool {
Neill Kapron41efab72024-07-31 22:17:36 +0000134 return false
135}
136
Cole Faustfa6e0fd2024-10-15 15:22:57 -0700137func (libbpf *libbpfProg) ExtraImageVariations(ctx android.ImageInterfaceContext) []string {
Neill Kapron41efab72024-07-31 22:17:36 +0000138 return nil
139}
140
Cole Faustfa6e0fd2024-10-15 15:22:57 -0700141func (libbpf *libbpfProg) SetImageVariation(ctx android.ImageInterfaceContext, variation string) {
Neill Kapron41efab72024-07-31 22:17:36 +0000142}
143
144func (libbpf *libbpfProg) DepsMutator(ctx android.BottomUpMutatorContext) {
145 ctx.AddDependency(ctx.Module(), libbpfProgDepTag, "libbpf_headers")
Neill Kapron3cc44de2024-09-16 20:08:13 +0000146 ctx.AddVariationDependencies(nil, cc.HeaderDepTag(), libbpf.properties.Header_libs...)
Neill Kapron41efab72024-07-31 22:17:36 +0000147}
148
149func (libbpf *libbpfProg) GenerateAndroidBuildActions(ctx android.ModuleContext) {
150 var cFlagsDeps android.Paths
151 cflags := []string{
152 "-nostdlibinc",
153
154 // Make paths in deps files relative
155 "-no-canonical-prefixes",
156
157 "-O2",
158 "-Wall",
159 "-Werror",
160 "-Wextra",
161
162 "-isystem bionic/libc/include",
163 "-isystem bionic/libc/kernel/uapi",
164 // The architecture doesn't matter here, but asm/types.h is included by linux/types.h.
165 "-isystem bionic/libc/kernel/uapi/asm-arm64",
166 "-isystem bionic/libc/kernel/android/uapi",
167 "-I " + ctx.ModuleDir(),
168 "-g", //Libbpf builds require BTF data
169 }
170
171 if runtime.GOOS != "darwin" {
172 cflags = append(cflags, "-fdebug-prefix-map=/proc/self/cwd=")
173 }
174
175 ctx.VisitDirectDeps(func(dep android.Module) {
176 depTag := ctx.OtherModuleDependencyTag(dep)
177 if depTag == libbpfProgDepTag {
178 if genRule, ok := dep.(genrule.SourceFileGenerator); ok {
179 cFlagsDeps = append(cFlagsDeps, genRule.GeneratedDeps()...)
180 dirs := genRule.GeneratedHeaderDirs()
181 for _, dir := range dirs {
182 cflags = append(cflags, "-I "+dir.String())
183 }
184 } else {
185 depName := ctx.OtherModuleName(dep)
186 ctx.ModuleErrorf("module %q is not a genrule", depName)
187 }
Neill Kapron3cc44de2024-09-16 20:08:13 +0000188 } else if depTag == cc.HeaderDepTag() {
189 depExporterInfo, _ := android.OtherModuleProvider(ctx, dep, cc.FlagExporterInfoProvider)
190 for _, dir := range depExporterInfo.IncludeDirs {
191 cflags = append(cflags, "-I "+dir.String())
192 }
Neill Kapron41efab72024-07-31 22:17:36 +0000193 }
194 })
195
196 for _, dir := range android.PathsForModuleSrc(ctx, libbpf.properties.Local_include_dirs) {
197 cflags = append(cflags, "-I "+dir.String())
198 }
199
200 cflags = append(cflags, libbpf.properties.Cflags...)
201
202 srcs := android.PathsForModuleSrc(ctx, libbpf.properties.Srcs)
203
204 for _, src := range srcs {
205 if strings.ContainsRune(src.Base(), '_') {
206 ctx.ModuleErrorf("invalid character '_' in source name")
207 }
Neill Kapron83815b32024-11-15 23:41:13 +0000208 obj := android.ObjPathWithExt(ctx, "unstripped", src, "bpf")
Neill Kapron41efab72024-07-31 22:17:36 +0000209
210 ctx.Build(pctx, android.BuildParams{
211 Rule: libbpfProgCcRule,
212 Input: src,
213 Implicits: cFlagsDeps,
214 Output: obj,
215 Args: map[string]string{
216 "cFlags": strings.Join(cflags, " "),
217 "ccCmd": "${config.ClangBin}/clang",
218 },
219 })
220
Neill Kapron83815b32024-11-15 23:41:13 +0000221 objStripped := android.ObjPathWithExt(ctx, "", src, "bpf")
Neill Kapron41efab72024-07-31 22:17:36 +0000222 ctx.Build(pctx, android.BuildParams{
223 Rule: libbpfProgStripRule,
224 Input: obj,
225 Output: objStripped,
226 Args: map[string]string{
227 "stripCmd": "${config.ClangBin}/llvm-strip",
228 },
229 })
230 libbpf.objs = append(libbpf.objs, objStripped.WithoutRel())
231 }
232
Neill Kapron83815b32024-11-15 23:41:13 +0000233 installDir := android.PathForModuleInstall(ctx, "etc", "bpf")
Neill Kapron41efab72024-07-31 22:17:36 +0000234 if len(libbpf.properties.Relative_install_path) > 0 {
235 installDir = installDir.Join(ctx, libbpf.properties.Relative_install_path)
236 }
237 for _, obj := range libbpf.objs {
238 ctx.PackageFile(installDir, obj.Base(), obj)
239 }
240
241 android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: srcs.Strings()})
242
243 ctx.SetOutputFiles(libbpf.objs, "")
244}
245
246func (libbpf *libbpfProg) AndroidMk() android.AndroidMkData {
247 return android.AndroidMkData{
248 Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
249 var names []string
250 fmt.Fprintln(w)
251 fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
252 fmt.Fprintln(w)
253 var localModulePath string
Neill Kapron83815b32024-11-15 23:41:13 +0000254 localModulePath = "LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/bpf"
Neill Kapron41efab72024-07-31 22:17:36 +0000255 if len(libbpf.properties.Relative_install_path) > 0 {
256 localModulePath += "/" + libbpf.properties.Relative_install_path
257 }
258 for _, obj := range libbpf.objs {
259 objName := name + "_" + obj.Base()
260 names = append(names, objName)
261 fmt.Fprintln(w, "include $(CLEAR_VARS)", " # libbpf.libbpf.obj")
262 fmt.Fprintln(w, "LOCAL_MODULE := ", objName)
263 fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", obj.String())
264 fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", obj.Base())
265 fmt.Fprintln(w, "LOCAL_MODULE_CLASS := ETC")
266 fmt.Fprintln(w, localModulePath)
267 // AconfigUpdateAndroidMkData may have added elements to Extra. Process them here.
268 for _, extra := range data.Extra {
269 extra(w, nil)
270 }
271 fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
272 fmt.Fprintln(w)
273 }
274 fmt.Fprintln(w, "include $(CLEAR_VARS)", " # libbpf.libbpf")
275 fmt.Fprintln(w, "LOCAL_MODULE := ", name)
276 android.AndroidMkEmitAssignList(w, "LOCAL_REQUIRED_MODULES", names)
277 fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")
278 },
279 }
280}
281
Neill Kapron4f1f0492024-09-16 19:33:46 +0000282type Defaults struct {
283 android.ModuleBase
284 android.DefaultsModuleBase
285}
286
287func defaultsFactory() android.Module {
288 return DefaultsFactory()
289}
290
291func DefaultsFactory(props ...interface{}) android.Module {
292 module := &Defaults{}
293
294 module.AddProperties(props...)
295 module.AddProperties(&LibbpfProgProperties{})
296
297 android.InitDefaultsModule(module)
298
299 return module
300}
301
Neill Kapron41efab72024-07-31 22:17:36 +0000302func LibbpfProgFactory() android.Module {
303 module := &libbpfProg{}
304
305 module.AddProperties(&module.properties)
306 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
Neill Kapron4f1f0492024-09-16 19:33:46 +0000307 android.InitDefaultableModule(module)
308
Neill Kapron41efab72024-07-31 22:17:36 +0000309 return module
310}