blob: 3b26d465484fc1da2d0e270be2c32695192c5462 [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",
Neill Kapron761019c2024-11-21 18:00:01 +0000161 // Flag to assist with the transition to libbpf
162 "-DENABLE_LIBBPF",
Neill Kapron41efab72024-07-31 22:17:36 +0000163 "-isystem bionic/libc/include",
164 "-isystem bionic/libc/kernel/uapi",
165 // The architecture doesn't matter here, but asm/types.h is included by linux/types.h.
166 "-isystem bionic/libc/kernel/uapi/asm-arm64",
167 "-isystem bionic/libc/kernel/android/uapi",
168 "-I " + ctx.ModuleDir(),
169 "-g", //Libbpf builds require BTF data
170 }
171
172 if runtime.GOOS != "darwin" {
173 cflags = append(cflags, "-fdebug-prefix-map=/proc/self/cwd=")
174 }
175
176 ctx.VisitDirectDeps(func(dep android.Module) {
177 depTag := ctx.OtherModuleDependencyTag(dep)
178 if depTag == libbpfProgDepTag {
179 if genRule, ok := dep.(genrule.SourceFileGenerator); ok {
180 cFlagsDeps = append(cFlagsDeps, genRule.GeneratedDeps()...)
181 dirs := genRule.GeneratedHeaderDirs()
182 for _, dir := range dirs {
183 cflags = append(cflags, "-I "+dir.String())
184 }
185 } else {
186 depName := ctx.OtherModuleName(dep)
187 ctx.ModuleErrorf("module %q is not a genrule", depName)
188 }
Neill Kapron3cc44de2024-09-16 20:08:13 +0000189 } else if depTag == cc.HeaderDepTag() {
190 depExporterInfo, _ := android.OtherModuleProvider(ctx, dep, cc.FlagExporterInfoProvider)
191 for _, dir := range depExporterInfo.IncludeDirs {
192 cflags = append(cflags, "-I "+dir.String())
193 }
Neill Kapron41efab72024-07-31 22:17:36 +0000194 }
195 })
196
197 for _, dir := range android.PathsForModuleSrc(ctx, libbpf.properties.Local_include_dirs) {
198 cflags = append(cflags, "-I "+dir.String())
199 }
200
201 cflags = append(cflags, libbpf.properties.Cflags...)
202
203 srcs := android.PathsForModuleSrc(ctx, libbpf.properties.Srcs)
204
205 for _, src := range srcs {
206 if strings.ContainsRune(src.Base(), '_') {
207 ctx.ModuleErrorf("invalid character '_' in source name")
208 }
Neill Kapron83815b32024-11-15 23:41:13 +0000209 obj := android.ObjPathWithExt(ctx, "unstripped", src, "bpf")
Neill Kapron41efab72024-07-31 22:17:36 +0000210
211 ctx.Build(pctx, android.BuildParams{
212 Rule: libbpfProgCcRule,
213 Input: src,
214 Implicits: cFlagsDeps,
215 Output: obj,
216 Args: map[string]string{
217 "cFlags": strings.Join(cflags, " "),
218 "ccCmd": "${config.ClangBin}/clang",
219 },
220 })
221
Neill Kapron83815b32024-11-15 23:41:13 +0000222 objStripped := android.ObjPathWithExt(ctx, "", src, "bpf")
Neill Kapron41efab72024-07-31 22:17:36 +0000223 ctx.Build(pctx, android.BuildParams{
224 Rule: libbpfProgStripRule,
225 Input: obj,
226 Output: objStripped,
227 Args: map[string]string{
228 "stripCmd": "${config.ClangBin}/llvm-strip",
229 },
230 })
231 libbpf.objs = append(libbpf.objs, objStripped.WithoutRel())
232 }
233
Neill Kapron83815b32024-11-15 23:41:13 +0000234 installDir := android.PathForModuleInstall(ctx, "etc", "bpf")
Neill Kapron41efab72024-07-31 22:17:36 +0000235 if len(libbpf.properties.Relative_install_path) > 0 {
236 installDir = installDir.Join(ctx, libbpf.properties.Relative_install_path)
237 }
238 for _, obj := range libbpf.objs {
239 ctx.PackageFile(installDir, obj.Base(), obj)
240 }
241
242 android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: srcs.Strings()})
243
244 ctx.SetOutputFiles(libbpf.objs, "")
245}
246
247func (libbpf *libbpfProg) AndroidMk() android.AndroidMkData {
248 return android.AndroidMkData{
249 Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
250 var names []string
251 fmt.Fprintln(w)
252 fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
253 fmt.Fprintln(w)
254 var localModulePath string
Neill Kapron83815b32024-11-15 23:41:13 +0000255 localModulePath = "LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/bpf"
Neill Kapron41efab72024-07-31 22:17:36 +0000256 if len(libbpf.properties.Relative_install_path) > 0 {
257 localModulePath += "/" + libbpf.properties.Relative_install_path
258 }
259 for _, obj := range libbpf.objs {
260 objName := name + "_" + obj.Base()
261 names = append(names, objName)
262 fmt.Fprintln(w, "include $(CLEAR_VARS)", " # libbpf.libbpf.obj")
263 fmt.Fprintln(w, "LOCAL_MODULE := ", objName)
264 fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", obj.String())
265 fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", obj.Base())
266 fmt.Fprintln(w, "LOCAL_MODULE_CLASS := ETC")
267 fmt.Fprintln(w, localModulePath)
268 // AconfigUpdateAndroidMkData may have added elements to Extra. Process them here.
269 for _, extra := range data.Extra {
270 extra(w, nil)
271 }
272 fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
273 fmt.Fprintln(w)
274 }
275 fmt.Fprintln(w, "include $(CLEAR_VARS)", " # libbpf.libbpf")
276 fmt.Fprintln(w, "LOCAL_MODULE := ", name)
277 android.AndroidMkEmitAssignList(w, "LOCAL_REQUIRED_MODULES", names)
278 fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")
279 },
280 }
281}
282
Neill Kapron4f1f0492024-09-16 19:33:46 +0000283type Defaults struct {
284 android.ModuleBase
285 android.DefaultsModuleBase
286}
287
288func defaultsFactory() android.Module {
289 return DefaultsFactory()
290}
291
292func DefaultsFactory(props ...interface{}) android.Module {
293 module := &Defaults{}
294
295 module.AddProperties(props...)
296 module.AddProperties(&LibbpfProgProperties{})
297
298 android.InitDefaultsModule(module)
299
300 return module
301}
302
Neill Kapron41efab72024-07-31 22:17:36 +0000303func LibbpfProgFactory() android.Module {
304 module := &libbpfProg{}
305
306 module.AddProperties(&module.properties)
307 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
Neill Kapron4f1f0492024-09-16 19:33:46 +0000308 android.InitDefaultableModule(module)
309
Neill Kapron41efab72024-07-31 22:17:36 +0000310 return module
311}