Home | History | Annotate | Download | only in bpf
      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
     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 " + ctx.ModuleDir(),
     70 	}
     71 
     72 	for _, dir := range android.PathsForSource(ctx, bpf.properties.Include_dirs) {
     73 		cflags = append(cflags, "-I "+dir.String())
     74 	}
     75 
     76 	cflags = append(cflags, bpf.properties.Cflags...)
     77 
     78 	srcs := ctx.ExpandSources(bpf.properties.Srcs, nil)
     79 
     80 	for _, src := range srcs {
     81 		obj := android.ObjPathWithExt(ctx, "", src, "o")
     82 
     83 		ctx.Build(pctx, android.BuildParams{
     84 			Rule:   cc,
     85 			Input:  src,
     86 			Output: obj,
     87 			Args: map[string]string{
     88 				"cFlags": strings.Join(cflags, " "),
     89 				"ccCmd":  "${config.ClangBin}/clang",
     90 			},
     91 		})
     92 
     93 		bpf.objs = append(bpf.objs, obj)
     94 	}
     95 }
     96 
     97 func (bpf *bpf) DepsMutator(ctx android.BottomUpMutatorContext) {
     98 	android.ExtractSourcesDeps(ctx, bpf.properties.Srcs)
     99 }
    100 
    101 func (bpf *bpf) AndroidMk() android.AndroidMkData {
    102 	return android.AndroidMkData{
    103 		Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
    104 			var names []string
    105 			fmt.Fprintln(w)
    106 			fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
    107 			fmt.Fprintln(w)
    108 			for _, obj := range bpf.objs {
    109 				objName := name + "_" + obj.Base()
    110 				names = append(names, objName)
    111 				fmt.Fprintln(w, "include $(CLEAR_VARS)")
    112 				fmt.Fprintln(w, "LOCAL_MODULE := ", objName)
    113 				fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", obj.String())
    114 				fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", obj.Base())
    115 				fmt.Fprintln(w, "LOCAL_MODULE_CLASS := ETC")
    116 				fmt.Fprintln(w, "LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/bpf")
    117 				fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
    118 				fmt.Fprintln(w)
    119 			}
    120 			fmt.Fprintln(w, "include $(CLEAR_VARS)")
    121 			fmt.Fprintln(w, "LOCAL_MODULE := ", name)
    122 			fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES :=", strings.Join(names, " "))
    123 			fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")
    124 		},
    125 	}
    126 }
    127 
    128 func bpfFactory() android.Module {
    129 	module := &bpf{}
    130 
    131 	module.AddProperties(&module.properties)
    132 
    133 	android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
    134 	return module
    135 }
    136