blob: 14b2d84c544861f1d85e0fb7cf77646abe47d2dc [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"
20 "strings"
21
22 "android/soong/android"
Colin Cross38406592018-05-17 11:17:01 -070023
24 "github.com/google/blueprint"
Connor O'Brien25739652021-12-02 20:09:45 -080025 "github.com/google/blueprint/proptools"
Colin Cross38406592018-05-17 11:17:01 -070026)
27
28func init() {
Paul Duffin12c7eb82021-02-24 18:51:54 +000029 registerBpfBuildComponents(android.InitRegistrationContext)
Colin Cross38406592018-05-17 11:17:01 -070030 pctx.Import("android/soong/cc/config")
31}
32
33var (
34 pctx = android.NewPackageContext("android/soong/bpf")
35
Ramy Medhat8ea054a2020-01-27 14:19:44 -050036 ccRule = pctx.AndroidRemoteStaticRule("ccRule", android.RemoteRuleSupports{Goma: true},
Colin Cross38406592018-05-17 11:17:01 -070037 blueprint.RuleParams{
38 Depfile: "${out}.d",
39 Deps: blueprint.DepsGCC,
40 Command: "$ccCmd --target=bpf -c $cFlags -MD -MF ${out}.d -o $out $in",
41 CommandDeps: []string{"$ccCmd"},
42 },
43 "ccCmd", "cFlags")
Connor O'Brien25739652021-12-02 20:09:45 -080044
45 stripRule = pctx.AndroidStaticRule("stripRule",
46 blueprint.RuleParams{
47 Command: `$stripCmd --strip-unneeded --remove-section=.rel.BTF ` +
48 `--remove-section=.rel.BTF.ext --remove-section=.BTF.ext $in -o $out`,
49 CommandDeps: []string{"$stripCmd"},
50 },
51 "stripCmd")
Colin Cross38406592018-05-17 11:17:01 -070052)
53
Paul Duffin12c7eb82021-02-24 18:51:54 +000054func registerBpfBuildComponents(ctx android.RegistrationContext) {
55 ctx.RegisterModuleType("bpf", BpfFactory)
56}
57
58var PrepareForTestWithBpf = android.FixtureRegisterWithContext(registerBpfBuildComponents)
59
markchien2f59ec92020-09-02 16:23:38 +080060// BpfModule interface is used by the apex package to gather information from a bpf module.
61type BpfModule interface {
62 android.Module
63
64 OutputFiles(tag string) (android.Paths, error)
Ken Chenfad7f9d2021-11-10 22:02:57 +080065
66 // Returns the sub install directory if the bpf module is included by apex.
67 SubDir() string
markchien2f59ec92020-09-02 16:23:38 +080068}
69
Colin Cross38406592018-05-17 11:17:01 -070070type BpfProperties struct {
Colin Cross27b922f2019-03-04 22:35:41 -080071 Srcs []string `android:"path"`
Colin Cross38406592018-05-17 11:17:01 -070072 Cflags []string
73 Include_dirs []string
Ken Chenfad7f9d2021-11-10 22:02:57 +080074 Sub_dir string
Connor O'Brien25739652021-12-02 20:09:45 -080075 // If set to true, generate BTF debug info for maps & programs
Steven Moreland606c5e92019-12-12 14:23:42 -080076 Btf *bool
77 Vendor *bool
78
79 VendorInternal bool `blueprint:"mutated"`
Colin Cross38406592018-05-17 11:17:01 -070080}
81
82type bpf struct {
83 android.ModuleBase
84
85 properties BpfProperties
86
87 objs android.Paths
88}
89
Steven Moreland606c5e92019-12-12 14:23:42 -080090var _ android.ImageInterface = (*bpf)(nil)
91
92func (bpf *bpf) ImageMutatorBegin(ctx android.BaseModuleContext) {}
93
94func (bpf *bpf) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
95 return !proptools.Bool(bpf.properties.Vendor)
96}
97
98func (bpf *bpf) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
99 return false
100}
101
102func (bpf *bpf) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
103 return false
104}
105
106func (bpf *bpf) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
107 return false
108}
109
110func (bpf *bpf) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
111 return false
112}
113
114func (bpf *bpf) ExtraImageVariations(ctx android.BaseModuleContext) []string {
115 if proptools.Bool(bpf.properties.Vendor) {
116 return []string{"vendor"}
117 }
118 return nil
119}
120
121func (bpf *bpf) SetImageVariation(ctx android.BaseModuleContext, variation string, module android.Module) {
122 bpf.properties.VendorInternal = variation == "vendor"
123}
124
Colin Cross38406592018-05-17 11:17:01 -0700125func (bpf *bpf) GenerateAndroidBuildActions(ctx android.ModuleContext) {
126 cflags := []string{
127 "-nostdlibinc",
Kousik Kumarfb0e2512020-03-25 15:01:27 -0700128
129 // Make paths in deps files relative
130 "-no-canonical-prefixes",
131
Colin Cross38406592018-05-17 11:17:01 -0700132 "-O2",
133 "-isystem bionic/libc/include",
134 "-isystem bionic/libc/kernel/uapi",
135 // The architecture doesn't matter here, but asm/types.h is included by linux/types.h.
136 "-isystem bionic/libc/kernel/uapi/asm-arm64",
137 "-isystem bionic/libc/kernel/android/uapi",
Ken Chenfd264442021-12-20 18:22:55 +0800138 "-I frameworks/libs/net/common/native/bpf_headers/include/bpf",
Maciej Żenczykowski79f6f752020-02-18 15:38:36 -0800139 // TODO(b/149785767): only give access to specific file with AID_* constants
140 "-I system/core/libcutils/include",
Colin Cross38406592018-05-17 11:17:01 -0700141 "-I " + ctx.ModuleDir(),
142 }
143
144 for _, dir := range android.PathsForSource(ctx, bpf.properties.Include_dirs) {
145 cflags = append(cflags, "-I "+dir.String())
146 }
147
148 cflags = append(cflags, bpf.properties.Cflags...)
149
Connor O'Brien25739652021-12-02 20:09:45 -0800150 if proptools.Bool(bpf.properties.Btf) {
151 cflags = append(cflags, "-g")
152 }
153
Colin Cross8a497952019-03-05 22:25:09 -0800154 srcs := android.PathsForModuleSrc(ctx, bpf.properties.Srcs)
Colin Cross38406592018-05-17 11:17:01 -0700155
156 for _, src := range srcs {
Connor O'Brien25739652021-12-02 20:09:45 -0800157 obj := android.ObjPathWithExt(ctx, "unstripped", src, "o")
Colin Cross38406592018-05-17 11:17:01 -0700158
159 ctx.Build(pctx, android.BuildParams{
Colin Cross815daf92019-05-14 16:05:20 -0700160 Rule: ccRule,
Colin Cross38406592018-05-17 11:17:01 -0700161 Input: src,
162 Output: obj,
163 Args: map[string]string{
164 "cFlags": strings.Join(cflags, " "),
165 "ccCmd": "${config.ClangBin}/clang",
166 },
167 })
168
Connor O'Brien25739652021-12-02 20:09:45 -0800169 if proptools.Bool(bpf.properties.Btf) {
170 objStripped := android.ObjPathWithExt(ctx, "", src, "o")
171 ctx.Build(pctx, android.BuildParams{
Steven Moreland606c5e92019-12-12 14:23:42 -0800172 Rule: stripRule,
173 Input: obj,
Connor O'Brien25739652021-12-02 20:09:45 -0800174 Output: objStripped,
175 Args: map[string]string{
176 "stripCmd": "${config.ClangBin}/llvm-strip",
177 },
178 })
179 bpf.objs = append(bpf.objs, objStripped.WithoutRel())
180 } else {
181 bpf.objs = append(bpf.objs, obj.WithoutRel())
182 }
183
Colin Cross38406592018-05-17 11:17:01 -0700184 }
185}
186
Colin Cross38406592018-05-17 11:17:01 -0700187func (bpf *bpf) AndroidMk() android.AndroidMkData {
188 return android.AndroidMkData{
189 Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
190 var names []string
191 fmt.Fprintln(w)
192 fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
193 fmt.Fprintln(w)
Steven Moreland606c5e92019-12-12 14:23:42 -0800194 var localModulePath string
195 if bpf.properties.VendorInternal {
196 localModulePath = "LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_ETC)/bpf"
197 } else {
198 localModulePath = "LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/bpf"
199 }
Ken Chenfad7f9d2021-11-10 22:02:57 +0800200 if len(bpf.properties.Sub_dir) > 0 {
201 localModulePath += "/" + bpf.properties.Sub_dir
202 }
Colin Cross38406592018-05-17 11:17:01 -0700203 for _, obj := range bpf.objs {
204 objName := name + "_" + obj.Base()
205 names = append(names, objName)
206 fmt.Fprintln(w, "include $(CLEAR_VARS)")
207 fmt.Fprintln(w, "LOCAL_MODULE := ", objName)
Bob Badourb4999222021-01-07 03:34:31 +0000208 data.Entries.WriteLicenseVariables(w)
Colin Cross38406592018-05-17 11:17:01 -0700209 fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", obj.String())
210 fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", obj.Base())
211 fmt.Fprintln(w, "LOCAL_MODULE_CLASS := ETC")
Ken Chenfad7f9d2021-11-10 22:02:57 +0800212 fmt.Fprintln(w, localModulePath)
Colin Cross38406592018-05-17 11:17:01 -0700213 fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
214 fmt.Fprintln(w)
215 }
216 fmt.Fprintln(w, "include $(CLEAR_VARS)")
217 fmt.Fprintln(w, "LOCAL_MODULE := ", name)
Bob Badourb4999222021-01-07 03:34:31 +0000218 data.Entries.WriteLicenseVariables(w)
Colin Cross38406592018-05-17 11:17:01 -0700219 fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES :=", strings.Join(names, " "))
220 fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")
221 },
222 }
223}
224
Colin Cross41955e82019-05-29 14:40:35 -0700225// Implements OutputFileFileProducer interface so that the obj output can be used in the data property
Jaewoong Jung5f3fb4b2018-12-13 15:01:46 -0800226// of other modules.
Colin Cross41955e82019-05-29 14:40:35 -0700227func (bpf *bpf) OutputFiles(tag string) (android.Paths, error) {
228 switch tag {
229 case "":
230 return bpf.objs, nil
231 default:
232 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
233 }
Jaewoong Jung5f3fb4b2018-12-13 15:01:46 -0800234}
235
Ken Chenfad7f9d2021-11-10 22:02:57 +0800236func (bpf *bpf) SubDir() string {
237 return bpf.properties.Sub_dir
238}
239
Colin Cross41955e82019-05-29 14:40:35 -0700240var _ android.OutputFileProducer = (*bpf)(nil)
Jaewoong Jung5f3fb4b2018-12-13 15:01:46 -0800241
markchien2f59ec92020-09-02 16:23:38 +0800242func BpfFactory() android.Module {
Colin Cross38406592018-05-17 11:17:01 -0700243 module := &bpf{}
244
245 module.AddProperties(&module.properties)
246
247 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
248 return module
249}