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 15package bpf 16 17import ( 18 "fmt" 19 "io" 20 "strings" 21 22 "android/soong/android" 23 _ "android/soong/cc/config" 24 25 "github.com/google/blueprint" 26) 27 28func init() { 29 android.RegisterModuleType("bpf", bpfFactory) 30 pctx.Import("android/soong/cc/config") 31} 32 33var ( 34 pctx = android.NewPackageContext("android/soong/bpf") 35 36 ccRule = pctx.AndroidRemoteStaticRule("ccRule", android.RemoteRuleSupports{Goma: true}, 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 46type BpfProperties struct { 47 Srcs []string `android:"path"` 48 Cflags []string 49 Include_dirs []string 50} 51 52type bpf struct { 53 android.ModuleBase 54 55 properties BpfProperties 56 57 objs android.Paths 58} 59 60func (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 // TODO(b/149785767): only give access to specific file with AID_* constants 70 "-I system/core/libcutils/include", 71 "-I system/bpf/progs/include", 72 "-I " + ctx.ModuleDir(), 73 } 74 75 for _, dir := range android.PathsForSource(ctx, bpf.properties.Include_dirs) { 76 cflags = append(cflags, "-I "+dir.String()) 77 } 78 79 cflags = append(cflags, bpf.properties.Cflags...) 80 81 srcs := android.PathsForModuleSrc(ctx, bpf.properties.Srcs) 82 83 for _, src := range srcs { 84 obj := android.ObjPathWithExt(ctx, "", src, "o") 85 86 ctx.Build(pctx, android.BuildParams{ 87 Rule: ccRule, 88 Input: src, 89 Output: obj, 90 Args: map[string]string{ 91 "cFlags": strings.Join(cflags, " "), 92 "ccCmd": "${config.ClangBin}/clang", 93 }, 94 }) 95 96 bpf.objs = append(bpf.objs, obj.WithoutRel()) 97 } 98} 99 100func (bpf *bpf) AndroidMk() android.AndroidMkData { 101 return android.AndroidMkData{ 102 Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) { 103 var names []string 104 fmt.Fprintln(w) 105 fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir) 106 fmt.Fprintln(w) 107 for _, obj := range bpf.objs { 108 objName := name + "_" + obj.Base() 109 names = append(names, objName) 110 fmt.Fprintln(w, "include $(CLEAR_VARS)") 111 fmt.Fprintln(w, "LOCAL_MODULE := ", objName) 112 fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", obj.String()) 113 fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", obj.Base()) 114 fmt.Fprintln(w, "LOCAL_MODULE_CLASS := ETC") 115 fmt.Fprintln(w, "LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/bpf") 116 fmt.Fprintln(w, "include $(BUILD_PREBUILT)") 117 fmt.Fprintln(w) 118 } 119 fmt.Fprintln(w, "include $(CLEAR_VARS)") 120 fmt.Fprintln(w, "LOCAL_MODULE := ", name) 121 fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES :=", strings.Join(names, " ")) 122 fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)") 123 }, 124 } 125} 126 127// Implements OutputFileFileProducer interface so that the obj output can be used in the data property 128// of other modules. 129func (bpf *bpf) OutputFiles(tag string) (android.Paths, error) { 130 switch tag { 131 case "": 132 return bpf.objs, nil 133 default: 134 return nil, fmt.Errorf("unsupported module reference tag %q", tag) 135 } 136} 137 138var _ android.OutputFileProducer = (*bpf)(nil) 139 140func bpfFactory() android.Module { 141 module := &bpf{} 142 143 module.AddProperties(&module.properties) 144 145 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon) 146 return module 147} 148