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 `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