blob: e89cc4ec8a94b507d6149b8e173ebe5cf447b7b7 [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"
Colin Cross38406592018-05-17 11:17:01 -070021 "strings"
22
23 "android/soong/android"
Colin Cross38406592018-05-17 11:17:01 -070024
25 "github.com/google/blueprint"
Connor O'Brien25739652021-12-02 20:09:45 -080026 "github.com/google/blueprint/proptools"
Colin Cross38406592018-05-17 11:17:01 -070027)
28
29func init() {
Paul Duffin12c7eb82021-02-24 18:51:54 +000030 registerBpfBuildComponents(android.InitRegistrationContext)
Colin Cross38406592018-05-17 11:17:01 -070031 pctx.Import("android/soong/cc/config")
32}
33
34var (
35 pctx = android.NewPackageContext("android/soong/bpf")
36
Ramy Medhat8ea054a2020-01-27 14:19:44 -050037 ccRule = pctx.AndroidRemoteStaticRule("ccRule", android.RemoteRuleSupports{Goma: true},
Colin Cross38406592018-05-17 11:17:01 -070038 blueprint.RuleParams{
39 Depfile: "${out}.d",
40 Deps: blueprint.DepsGCC,
41 Command: "$ccCmd --target=bpf -c $cFlags -MD -MF ${out}.d -o $out $in",
42 CommandDeps: []string{"$ccCmd"},
43 },
44 "ccCmd", "cFlags")
Connor O'Brien25739652021-12-02 20:09:45 -080045
46 stripRule = pctx.AndroidStaticRule("stripRule",
47 blueprint.RuleParams{
48 Command: `$stripCmd --strip-unneeded --remove-section=.rel.BTF ` +
49 `--remove-section=.rel.BTF.ext --remove-section=.BTF.ext $in -o $out`,
50 CommandDeps: []string{"$stripCmd"},
51 },
52 "stripCmd")
Colin Cross38406592018-05-17 11:17:01 -070053)
54
Paul Duffin12c7eb82021-02-24 18:51:54 +000055func registerBpfBuildComponents(ctx android.RegistrationContext) {
56 ctx.RegisterModuleType("bpf", BpfFactory)
57}
58
59var PrepareForTestWithBpf = android.FixtureRegisterWithContext(registerBpfBuildComponents)
60
markchien2f59ec92020-09-02 16:23:38 +080061// BpfModule interface is used by the apex package to gather information from a bpf module.
62type BpfModule interface {
63 android.Module
64
65 OutputFiles(tag string) (android.Paths, error)
Ken Chenfad7f9d2021-11-10 22:02:57 +080066
67 // Returns the sub install directory if the bpf module is included by apex.
68 SubDir() string
markchien2f59ec92020-09-02 16:23:38 +080069}
70
Colin Cross38406592018-05-17 11:17:01 -070071type BpfProperties struct {
Zi Wang4877c722022-08-11 18:05:13 +000072 // source paths to the files.
73 Srcs []string `android:"path"`
74
75 // additional cflags that should be used to build the bpf variant of
76 // the C/C++ module.
77 Cflags []string
78
79 // directories (relative to the root of the source tree) that will
80 // be added to the include paths using -I.
Colin Cross38406592018-05-17 11:17:01 -070081 Include_dirs []string
Zi Wang4877c722022-08-11 18:05:13 +000082
83 // optional subdirectory under which this module is installed into.
84 Sub_dir string
85
86 // if set to true, generate BTF debug info for maps & programs.
87 Btf *bool
88
Steven Moreland606c5e92019-12-12 14:23:42 -080089 Vendor *bool
90
91 VendorInternal bool `blueprint:"mutated"`
Colin Cross38406592018-05-17 11:17:01 -070092}
93
94type bpf struct {
95 android.ModuleBase
96
97 properties BpfProperties
98
99 objs android.Paths
100}
101
Steven Moreland606c5e92019-12-12 14:23:42 -0800102var _ android.ImageInterface = (*bpf)(nil)
103
104func (bpf *bpf) ImageMutatorBegin(ctx android.BaseModuleContext) {}
105
106func (bpf *bpf) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
107 return !proptools.Bool(bpf.properties.Vendor)
108}
109
110func (bpf *bpf) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
111 return false
112}
113
114func (bpf *bpf) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
115 return false
116}
117
118func (bpf *bpf) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
119 return false
120}
121
122func (bpf *bpf) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
123 return false
124}
125
126func (bpf *bpf) ExtraImageVariations(ctx android.BaseModuleContext) []string {
127 if proptools.Bool(bpf.properties.Vendor) {
128 return []string{"vendor"}
129 }
130 return nil
131}
132
133func (bpf *bpf) SetImageVariation(ctx android.BaseModuleContext, variation string, module android.Module) {
134 bpf.properties.VendorInternal = variation == "vendor"
135}
136
Colin Cross38406592018-05-17 11:17:01 -0700137func (bpf *bpf) GenerateAndroidBuildActions(ctx android.ModuleContext) {
138 cflags := []string{
139 "-nostdlibinc",
Kousik Kumarfb0e2512020-03-25 15:01:27 -0700140
141 // Make paths in deps files relative
142 "-no-canonical-prefixes",
143
Colin Cross38406592018-05-17 11:17:01 -0700144 "-O2",
145 "-isystem bionic/libc/include",
146 "-isystem bionic/libc/kernel/uapi",
147 // The architecture doesn't matter here, but asm/types.h is included by linux/types.h.
148 "-isystem bionic/libc/kernel/uapi/asm-arm64",
149 "-isystem bionic/libc/kernel/android/uapi",
Ken Chenfd264442021-12-20 18:22:55 +0800150 "-I frameworks/libs/net/common/native/bpf_headers/include/bpf",
Maciej Żenczykowski79f6f752020-02-18 15:38:36 -0800151 // TODO(b/149785767): only give access to specific file with AID_* constants
152 "-I system/core/libcutils/include",
Colin Cross38406592018-05-17 11:17:01 -0700153 "-I " + ctx.ModuleDir(),
154 }
155
156 for _, dir := range android.PathsForSource(ctx, bpf.properties.Include_dirs) {
157 cflags = append(cflags, "-I "+dir.String())
158 }
159
160 cflags = append(cflags, bpf.properties.Cflags...)
161
Connor O'Brien25739652021-12-02 20:09:45 -0800162 if proptools.Bool(bpf.properties.Btf) {
163 cflags = append(cflags, "-g")
164 }
165
Colin Cross8a497952019-03-05 22:25:09 -0800166 srcs := android.PathsForModuleSrc(ctx, bpf.properties.Srcs)
Colin Cross38406592018-05-17 11:17:01 -0700167
168 for _, src := range srcs {
Ken Chen5372a242022-07-07 17:48:06 +0800169 if strings.ContainsRune(filepath.Base(src.String()), '_') {
170 ctx.ModuleErrorf("invalid character '_' in source name")
171 }
Connor O'Brien25739652021-12-02 20:09:45 -0800172 obj := android.ObjPathWithExt(ctx, "unstripped", src, "o")
Colin Cross38406592018-05-17 11:17:01 -0700173
174 ctx.Build(pctx, android.BuildParams{
Colin Cross815daf92019-05-14 16:05:20 -0700175 Rule: ccRule,
Colin Cross38406592018-05-17 11:17:01 -0700176 Input: src,
177 Output: obj,
178 Args: map[string]string{
179 "cFlags": strings.Join(cflags, " "),
180 "ccCmd": "${config.ClangBin}/clang",
181 },
182 })
183
Connor O'Brien25739652021-12-02 20:09:45 -0800184 if proptools.Bool(bpf.properties.Btf) {
185 objStripped := android.ObjPathWithExt(ctx, "", src, "o")
186 ctx.Build(pctx, android.BuildParams{
Steven Moreland606c5e92019-12-12 14:23:42 -0800187 Rule: stripRule,
188 Input: obj,
Connor O'Brien25739652021-12-02 20:09:45 -0800189 Output: objStripped,
190 Args: map[string]string{
191 "stripCmd": "${config.ClangBin}/llvm-strip",
192 },
193 })
194 bpf.objs = append(bpf.objs, objStripped.WithoutRel())
195 } else {
196 bpf.objs = append(bpf.objs, obj.WithoutRel())
197 }
198
Colin Cross38406592018-05-17 11:17:01 -0700199 }
200}
201
Colin Cross38406592018-05-17 11:17:01 -0700202func (bpf *bpf) AndroidMk() android.AndroidMkData {
203 return android.AndroidMkData{
204 Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
205 var names []string
206 fmt.Fprintln(w)
207 fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
208 fmt.Fprintln(w)
Steven Moreland606c5e92019-12-12 14:23:42 -0800209 var localModulePath string
210 if bpf.properties.VendorInternal {
211 localModulePath = "LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_ETC)/bpf"
212 } else {
213 localModulePath = "LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/bpf"
214 }
Ken Chenfad7f9d2021-11-10 22:02:57 +0800215 if len(bpf.properties.Sub_dir) > 0 {
216 localModulePath += "/" + bpf.properties.Sub_dir
217 }
Colin Cross38406592018-05-17 11:17:01 -0700218 for _, obj := range bpf.objs {
219 objName := name + "_" + obj.Base()
220 names = append(names, objName)
221 fmt.Fprintln(w, "include $(CLEAR_VARS)")
222 fmt.Fprintln(w, "LOCAL_MODULE := ", objName)
Bob Badourb4999222021-01-07 03:34:31 +0000223 data.Entries.WriteLicenseVariables(w)
Colin Cross38406592018-05-17 11:17:01 -0700224 fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", obj.String())
225 fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", obj.Base())
226 fmt.Fprintln(w, "LOCAL_MODULE_CLASS := ETC")
Ken Chenfad7f9d2021-11-10 22:02:57 +0800227 fmt.Fprintln(w, localModulePath)
Colin Cross38406592018-05-17 11:17:01 -0700228 fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
229 fmt.Fprintln(w)
230 }
231 fmt.Fprintln(w, "include $(CLEAR_VARS)")
232 fmt.Fprintln(w, "LOCAL_MODULE := ", name)
Bob Badourb4999222021-01-07 03:34:31 +0000233 data.Entries.WriteLicenseVariables(w)
Colin Cross38406592018-05-17 11:17:01 -0700234 fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES :=", strings.Join(names, " "))
235 fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")
236 },
237 }
238}
239
Colin Cross41955e82019-05-29 14:40:35 -0700240// Implements OutputFileFileProducer interface so that the obj output can be used in the data property
Jaewoong Jung5f3fb4b2018-12-13 15:01:46 -0800241// of other modules.
Colin Cross41955e82019-05-29 14:40:35 -0700242func (bpf *bpf) OutputFiles(tag string) (android.Paths, error) {
243 switch tag {
244 case "":
245 return bpf.objs, nil
246 default:
247 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
248 }
Jaewoong Jung5f3fb4b2018-12-13 15:01:46 -0800249}
250
Ken Chenfad7f9d2021-11-10 22:02:57 +0800251func (bpf *bpf) SubDir() string {
252 return bpf.properties.Sub_dir
253}
254
Colin Cross41955e82019-05-29 14:40:35 -0700255var _ android.OutputFileProducer = (*bpf)(nil)
Jaewoong Jung5f3fb4b2018-12-13 15:01:46 -0800256
markchien2f59ec92020-09-02 16:23:38 +0800257func BpfFactory() android.Module {
Colin Cross38406592018-05-17 11:17:01 -0700258 module := &bpf{}
259
260 module.AddProperties(&module.properties)
261
262 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
263 return module
264}