1 // 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 15 package bpf 16 17 import ( 18 "fmt" 19 "io" 20 "strings" 21 22 "android/soong/android" 23 _ "android/soong/cc/config" 24 25 "github.com/google/blueprint" 26 ) 27 28 func init() { 29 android.RegisterModuleType("bpf", bpfFactory) 30 pctx.Import("android/soong/cc/config") 31 } 32 33 var ( 34 pctx = android.NewPackageContext("android/soong/bpf") 35 36 cc = pctx.AndroidGomaStaticRule("cc", 37 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") 44 ) 45 46 type BpfProperties struct { 47 Srcs []string `android:"path"` 48 Cflags []string 49 Include_dirs []string 50 } 51 52 type bpf struct { 53 android.ModuleBase 54 55 properties BpfProperties 56 57 objs android.Paths 58 } 59 60 func (bpf *bpf) GenerateAndroidBuildActions(ctx android.ModuleContext) { 61 cflags := []string{ 62 "-nostdlibinc", 63 "-O2", 64 "-isystem bionic/libc/include", 65 "-isystem bionic/libc/kernel/uapi", 66 // The architecture doesn't matter here, but asm/types.h is included by linux/types.h. 67 "-isystem bionic/libc/kernel/uapi/asm-arm64", 68 "-isystem bionic/libc/kernel/android/uapi", 69 "-I system/bpf/progs/include", 70 "-I " + ctx.ModuleDir(), 71 } 72 73 for _, dir := range android.PathsForSource(ctx, bpf.properties.Include_dirs) { 74 cflags = append(cflags, "-I "+dir.String()) 75 } 76 77 cflags = append(cflags, bpf.properties.Cflags...) 78 79 srcs := android.PathsForModuleSrc(ctx, bpf.properties.Srcs) 80 81 for _, src := range srcs { 82 obj := android.ObjPathWithExt(ctx, "", src, "o") 83 84 ctx.Build(pctx, android.BuildParams{ 85 Rule: cc, 86 Input: src, 87 Output: obj, 88 Args: map[string]string{ 89 "cFlags": strings.Join(cflags, " "), 90 "ccCmd": "${config.ClangBin}/clang", 91 }, 92 }) 93 94 bpf.objs = append(bpf.objs, obj.WithoutRel()) 95 } 96 } 97 98 func (bpf *bpf) AndroidMk() android.AndroidMkData { 99 return android.AndroidMkData{ 100 Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) { 101 var names []string 102 fmt.Fprintln(w) 103 fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir) 104 fmt.Fprintln(w) 105 for _, obj := range bpf.objs { 106 objName := name + "_" + obj.Base() 107 names = append(names, objName) 108 fmt.Fprintln(w, "include $(CLEAR_VARS)") 109 fmt.Fprintln(w, "LOCAL_MODULE := ", objName) 110 fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", obj.String()) 111 fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", obj.Base()) 112 fmt.Fprintln(w, "LOCAL_MODULE_CLASS := ETC") 113 fmt.Fprintln(w, "LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/bpf") 114 fmt.Fprintln(w, "include $(BUILD_PREBUILT)") 115 fmt.Fprintln(w) 116 } 117 fmt.Fprintln(w, "include $(CLEAR_VARS)") 118 fmt.Fprintln(w, "LOCAL_MODULE := ", name) 119 fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES :=", strings.Join(names, " ")) 120 fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)") 121 }, 122 } 123 } 124 125 // Implements SourceFileProducer interface so that the obj output can be used in the data property 126 // of other modules. 127 func (bpf *bpf) Srcs() android.Paths { 128 return bpf.objs 129 } 130 131 var _ android.SourceFileProducer = (*bpf)(nil) 132 133 func bpfFactory() android.Module { 134 module := &bpf{} 135 136 module.AddProperties(&module.properties) 137 138 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon) 139 return module 140 } 141