blob: e1b512f20256bbe48dad1dfbba6719d79b93d28a [file] [log] [blame]
Colin Cross38406592018-05-17 11:17:01 -07001// Copyright (C) 2018 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 bpf
16
17import (
18 "fmt"
19 "io"
Ken Chen5372a242022-07-07 17:48:06 +080020 "path/filepath"
Connor O'Brien3e739cf2022-08-17 15:45:52 -070021 "runtime"
Colin Cross38406592018-05-17 11:17:01 -070022 "strings"
23
24 "android/soong/android"
Connor O'Brien6a288bc2022-11-10 13:58:48 -080025 "android/soong/cc"
Colin Cross38406592018-05-17 11:17:01 -070026
27 "github.com/google/blueprint"
Connor O'Brien25739652021-12-02 20:09:45 -080028 "github.com/google/blueprint/proptools"
Colin Cross38406592018-05-17 11:17:01 -070029)
30
31func init() {
Paul Duffin12c7eb82021-02-24 18:51:54 +000032 registerBpfBuildComponents(android.InitRegistrationContext)
Colin Cross38406592018-05-17 11:17:01 -070033 pctx.Import("android/soong/cc/config")
Connor O'Brien6a288bc2022-11-10 13:58:48 -080034 pctx.StaticVariable("relPwd", cc.PwdPrefix())
Colin Cross38406592018-05-17 11:17:01 -070035}
36
37var (
38 pctx = android.NewPackageContext("android/soong/bpf")
39
Ramy Medhat8ea054a2020-01-27 14:19:44 -050040 ccRule = pctx.AndroidRemoteStaticRule("ccRule", android.RemoteRuleSupports{Goma: true},
Colin Cross38406592018-05-17 11:17:01 -070041 blueprint.RuleParams{
42 Depfile: "${out}.d",
43 Deps: blueprint.DepsGCC,
Connor O'Brien3e739cf2022-08-17 15:45:52 -070044 Command: "$relPwd $ccCmd --target=bpf -c $cFlags -MD -MF ${out}.d -o $out $in",
Colin Cross38406592018-05-17 11:17:01 -070045 CommandDeps: []string{"$ccCmd"},
46 },
47 "ccCmd", "cFlags")
Connor O'Brien25739652021-12-02 20:09:45 -080048
49 stripRule = pctx.AndroidStaticRule("stripRule",
50 blueprint.RuleParams{
51 Command: `$stripCmd --strip-unneeded --remove-section=.rel.BTF ` +
52 `--remove-section=.rel.BTF.ext --remove-section=.BTF.ext $in -o $out`,
53 CommandDeps: []string{"$stripCmd"},
54 },
55 "stripCmd")
Colin Cross38406592018-05-17 11:17:01 -070056)
57
Paul Duffin12c7eb82021-02-24 18:51:54 +000058func registerBpfBuildComponents(ctx android.RegistrationContext) {
59 ctx.RegisterModuleType("bpf", BpfFactory)
60}
61
62var PrepareForTestWithBpf = android.FixtureRegisterWithContext(registerBpfBuildComponents)
63
markchien2f59ec92020-09-02 16:23:38 +080064// BpfModule interface is used by the apex package to gather information from a bpf module.
65type BpfModule interface {
66 android.Module
67
68 OutputFiles(tag string) (android.Paths, error)
Ken Chenfad7f9d2021-11-10 22:02:57 +080069
70 // Returns the sub install directory if the bpf module is included by apex.
71 SubDir() string
markchien2f59ec92020-09-02 16:23:38 +080072}
73
Colin Cross38406592018-05-17 11:17:01 -070074type BpfProperties struct {
Zi Wang4877c722022-08-11 18:05:13 +000075 // source paths to the files.
76 Srcs []string `android:"path"`
77
78 // additional cflags that should be used to build the bpf variant of
79 // the C/C++ module.
80 Cflags []string
81
82 // directories (relative to the root of the source tree) that will
83 // be added to the include paths using -I.
Colin Cross38406592018-05-17 11:17:01 -070084 Include_dirs []string
Zi Wang4877c722022-08-11 18:05:13 +000085
86 // optional subdirectory under which this module is installed into.
87 Sub_dir string
88
89 // if set to true, generate BTF debug info for maps & programs.
90 Btf *bool
91
Steven Moreland606c5e92019-12-12 14:23:42 -080092 Vendor *bool
93
94 VendorInternal bool `blueprint:"mutated"`
Colin Cross38406592018-05-17 11:17:01 -070095}
96
97type bpf struct {
98 android.ModuleBase
99
100 properties BpfProperties
101
102 objs android.Paths
103}
104
Steven Moreland606c5e92019-12-12 14:23:42 -0800105var _ android.ImageInterface = (*bpf)(nil)
106
107func (bpf *bpf) ImageMutatorBegin(ctx android.BaseModuleContext) {}
108
109func (bpf *bpf) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
110 return !proptools.Bool(bpf.properties.Vendor)
111}
112
113func (bpf *bpf) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
114 return false
115}
116
117func (bpf *bpf) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
118 return false
119}
120
121func (bpf *bpf) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
122 return false
123}
124
125func (bpf *bpf) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
126 return false
127}
128
129func (bpf *bpf) ExtraImageVariations(ctx android.BaseModuleContext) []string {
130 if proptools.Bool(bpf.properties.Vendor) {
131 return []string{"vendor"}
132 }
133 return nil
134}
135
136func (bpf *bpf) SetImageVariation(ctx android.BaseModuleContext, variation string, module android.Module) {
137 bpf.properties.VendorInternal = variation == "vendor"
138}
139
Colin Cross38406592018-05-17 11:17:01 -0700140func (bpf *bpf) GenerateAndroidBuildActions(ctx android.ModuleContext) {
141 cflags := []string{
142 "-nostdlibinc",
Kousik Kumarfb0e2512020-03-25 15:01:27 -0700143
144 // Make paths in deps files relative
145 "-no-canonical-prefixes",
146
Colin Cross38406592018-05-17 11:17:01 -0700147 "-O2",
148 "-isystem bionic/libc/include",
149 "-isystem bionic/libc/kernel/uapi",
150 // The architecture doesn't matter here, but asm/types.h is included by linux/types.h.
151 "-isystem bionic/libc/kernel/uapi/asm-arm64",
152 "-isystem bionic/libc/kernel/android/uapi",
Motomu Utsumi44591552023-08-22 12:03:16 +0900153 "-I packages/modules/Connectivity/staticlibs/native/bpf_headers/include/bpf",
Maciej Żenczykowski79f6f752020-02-18 15:38:36 -0800154 // TODO(b/149785767): only give access to specific file with AID_* constants
155 "-I system/core/libcutils/include",
Colin Cross38406592018-05-17 11:17:01 -0700156 "-I " + ctx.ModuleDir(),
157 }
158
159 for _, dir := range android.PathsForSource(ctx, bpf.properties.Include_dirs) {
160 cflags = append(cflags, "-I "+dir.String())
161 }
162
163 cflags = append(cflags, bpf.properties.Cflags...)
164
Connor O'Brien25739652021-12-02 20:09:45 -0800165 if proptools.Bool(bpf.properties.Btf) {
166 cflags = append(cflags, "-g")
Connor O'Brien3e739cf2022-08-17 15:45:52 -0700167 if runtime.GOOS != "darwin" {
168 cflags = append(cflags, "-fdebug-prefix-map=/proc/self/cwd=")
169 }
Connor O'Brien25739652021-12-02 20:09:45 -0800170 }
171
Colin Cross8a497952019-03-05 22:25:09 -0800172 srcs := android.PathsForModuleSrc(ctx, bpf.properties.Srcs)
Colin Cross38406592018-05-17 11:17:01 -0700173
174 for _, src := range srcs {
Ken Chen5372a242022-07-07 17:48:06 +0800175 if strings.ContainsRune(filepath.Base(src.String()), '_') {
176 ctx.ModuleErrorf("invalid character '_' in source name")
177 }
Connor O'Brien25739652021-12-02 20:09:45 -0800178 obj := android.ObjPathWithExt(ctx, "unstripped", src, "o")
Colin Cross38406592018-05-17 11:17:01 -0700179
180 ctx.Build(pctx, android.BuildParams{
Colin Cross815daf92019-05-14 16:05:20 -0700181 Rule: ccRule,
Colin Cross38406592018-05-17 11:17:01 -0700182 Input: src,
183 Output: obj,
184 Args: map[string]string{
185 "cFlags": strings.Join(cflags, " "),
186 "ccCmd": "${config.ClangBin}/clang",
187 },
188 })
189
Connor O'Brien25739652021-12-02 20:09:45 -0800190 if proptools.Bool(bpf.properties.Btf) {
191 objStripped := android.ObjPathWithExt(ctx, "", src, "o")
192 ctx.Build(pctx, android.BuildParams{
Steven Moreland606c5e92019-12-12 14:23:42 -0800193 Rule: stripRule,
194 Input: obj,
Connor O'Brien25739652021-12-02 20:09:45 -0800195 Output: objStripped,
196 Args: map[string]string{
197 "stripCmd": "${config.ClangBin}/llvm-strip",
198 },
199 })
200 bpf.objs = append(bpf.objs, objStripped.WithoutRel())
201 } else {
202 bpf.objs = append(bpf.objs, obj.WithoutRel())
203 }
204
Colin Cross38406592018-05-17 11:17:01 -0700205 }
Colin Cross40213022023-12-13 15:19:49 -0800206 android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: srcs.Strings()})
Colin Cross38406592018-05-17 11:17:01 -0700207}
208
Colin Cross38406592018-05-17 11:17:01 -0700209func (bpf *bpf) AndroidMk() android.AndroidMkData {
210 return android.AndroidMkData{
211 Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
212 var names []string
213 fmt.Fprintln(w)
214 fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
215 fmt.Fprintln(w)
Steven Moreland606c5e92019-12-12 14:23:42 -0800216 var localModulePath string
217 if bpf.properties.VendorInternal {
218 localModulePath = "LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_ETC)/bpf"
219 } else {
220 localModulePath = "LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/bpf"
221 }
Ken Chenfad7f9d2021-11-10 22:02:57 +0800222 if len(bpf.properties.Sub_dir) > 0 {
223 localModulePath += "/" + bpf.properties.Sub_dir
224 }
Colin Cross38406592018-05-17 11:17:01 -0700225 for _, obj := range bpf.objs {
226 objName := name + "_" + obj.Base()
227 names = append(names, objName)
Sasha Smundak5c4729d2022-12-01 10:49:23 -0800228 fmt.Fprintln(w, "include $(CLEAR_VARS)", " # bpf.bpf.obj")
Colin Cross38406592018-05-17 11:17:01 -0700229 fmt.Fprintln(w, "LOCAL_MODULE := ", objName)
230 fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", obj.String())
231 fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", obj.Base())
232 fmt.Fprintln(w, "LOCAL_MODULE_CLASS := ETC")
Ken Chenfad7f9d2021-11-10 22:02:57 +0800233 fmt.Fprintln(w, localModulePath)
LaMont Jonesb5099382024-01-10 23:42:36 +0000234 // AconfigUpdateAndroidMkData may have added elements to Extra. Process them here.
235 for _, extra := range data.Extra {
236 extra(w, nil)
237 }
Colin Cross38406592018-05-17 11:17:01 -0700238 fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
239 fmt.Fprintln(w)
240 }
Sasha Smundak5c4729d2022-12-01 10:49:23 -0800241 fmt.Fprintln(w, "include $(CLEAR_VARS)", " # bpf.bpf")
Colin Cross38406592018-05-17 11:17:01 -0700242 fmt.Fprintln(w, "LOCAL_MODULE := ", name)
Sasha Smundakdcb61292022-12-08 10:41:33 -0800243 android.AndroidMkEmitAssignList(w, "LOCAL_REQUIRED_MODULES", names)
Colin Cross38406592018-05-17 11:17:01 -0700244 fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")
245 },
246 }
247}
248
Colin Cross41955e82019-05-29 14:40:35 -0700249// Implements OutputFileFileProducer interface so that the obj output can be used in the data property
Jaewoong Jung5f3fb4b2018-12-13 15:01:46 -0800250// of other modules.
Colin Cross41955e82019-05-29 14:40:35 -0700251func (bpf *bpf) OutputFiles(tag string) (android.Paths, error) {
252 switch tag {
253 case "":
254 return bpf.objs, nil
255 default:
256 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
257 }
Jaewoong Jung5f3fb4b2018-12-13 15:01:46 -0800258}
259
Ken Chenfad7f9d2021-11-10 22:02:57 +0800260func (bpf *bpf) SubDir() string {
261 return bpf.properties.Sub_dir
262}
263
Colin Cross41955e82019-05-29 14:40:35 -0700264var _ android.OutputFileProducer = (*bpf)(nil)
Jaewoong Jung5f3fb4b2018-12-13 15:01:46 -0800265
markchien2f59ec92020-09-02 16:23:38 +0800266func BpfFactory() android.Module {
Colin Cross38406592018-05-17 11:17:01 -0700267 module := &bpf{}
268
269 module.AddProperties(&module.properties)
270
271 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
272 return module
273}