diff --git a/apex/Android.bp b/apex/Android.bp index 144f44197..1a5f6837e 100644 --- a/apex/Android.bp +++ b/apex/Android.bp @@ -5,6 +5,7 @@ bootstrap_go_package { "blueprint", "soong", "soong-android", + "soong-bpf", "soong-cc", "soong-java", "soong-python", diff --git a/apex/apex.go b/apex/apex.go index 84a1e7526..b70815384 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -26,6 +26,7 @@ import ( "github.com/google/blueprint/proptools" "android/soong/android" + "android/soong/bpf" "android/soong/cc" prebuilt_etc "android/soong/etc" "android/soong/java" @@ -63,6 +64,7 @@ var ( usesTag = dependencyTag{name: "uses"} androidAppTag = dependencyTag{name: "androidApp", payload: true} rroTag = dependencyTag{name: "rro", payload: true} + bpfTag = dependencyTag{name: "bpf", payload: true} apexAvailBaseline = makeApexAvailableBaseline() @@ -970,6 +972,9 @@ type apexBundleProperties struct { // List of prebuilt files that are embedded inside this APEX bundle Prebuilts []string + // List of BPF programs inside APEX + Bpfs []string + // Name of the apex_key module that provides the private key to sign APEX Key *string @@ -1458,6 +1463,9 @@ func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) { ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(), javaLibTag, a.properties.Java_libs...) + ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(), + bpfTag, a.properties.Bpfs...) + // With EMMA_INSTRUMENT_FRAMEWORK=true the ART boot image includes jacoco library. if a.artApex && ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") { ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(), @@ -1778,6 +1786,11 @@ func apexFileForRuntimeResourceOverlay(ctx android.BaseModuleContext, rro java.R return af } +func apexFileForBpfProgram(ctx android.BaseModuleContext, builtFile android.Path, bpfProgram bpf.BpfModule) apexFile { + dirInApex := filepath.Join("etc", "bpf") + return newApexFile(ctx, builtFile, builtFile.Base(), dirInApex, etc, bpfProgram) +} + // Context "decorator", overriding the InstallBypassMake method to always reply `true`. type flattenedApexContext struct { android.ModuleContext @@ -2113,6 +2126,15 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { } else { ctx.PropertyErrorf("rros", "%q is not an runtime_resource_overlay module", depName) } + case bpfTag: + if bpfProgram, ok := child.(bpf.BpfModule); ok { + filesToCopy, _ := bpfProgram.OutputFiles("") + for _, bpfFile := range filesToCopy { + filesInfo = append(filesInfo, apexFileForBpfProgram(ctx, bpfFile, bpfProgram)) + } + } else { + ctx.PropertyErrorf("bpfs", "%q is not a bpf module", depName) + } case prebuiltTag: if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok { filesInfo = append(filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName)) diff --git a/apex/apex_test.go b/apex/apex_test.go index 70464fc7a..33966cea2 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -27,6 +27,7 @@ import ( "github.com/google/blueprint/proptools" "android/soong/android" + "android/soong/bpf" "android/soong/cc" "android/soong/dexpreopt" prebuilt_etc "android/soong/etc" @@ -257,6 +258,7 @@ func testApexContext(_ *testing.T, bp string, handlers ...testCustomizer) (*andr java.RegisterAppBuildComponents(ctx) java.RegisterSdkLibraryBuildComponents(ctx) ctx.RegisterSingletonType("apex_keys_text", apexKeysTextFactory) + ctx.RegisterModuleType("bpf", bpf.BpfFactory) ctx.PreDepsMutators(RegisterPreDepsMutators) ctx.PostDepsMutators(RegisterPostDepsMutators) @@ -606,6 +608,7 @@ func TestDefaults(t *testing.T) { java_libs: ["myjar"], apps: ["AppFoo"], rros: ["rro"], + bpfs: ["bpf"], } prebuilt_etc { @@ -652,6 +655,11 @@ func TestDefaults(t *testing.T) { theme: "blue", } + bpf { + name: "bpf", + srcs: ["bpf.c", "bpf2.c"], + } + `) ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{ "etc/myetc", @@ -659,6 +667,8 @@ func TestDefaults(t *testing.T) { "lib64/mylib.so", "app/AppFoo/AppFoo.apk", "overlay/blue/rro.apk", + "etc/bpf/bpf.o", + "etc/bpf/bpf2.o", }) } diff --git a/bpf/bpf.go b/bpf/bpf.go index 4cdfb315c..297e13a4f 100644 --- a/bpf/bpf.go +++ b/bpf/bpf.go @@ -26,7 +26,7 @@ import ( ) func init() { - android.RegisterModuleType("bpf", bpfFactory) + android.RegisterModuleType("bpf", BpfFactory) pctx.Import("android/soong/cc/config") } @@ -43,6 +43,13 @@ var ( "ccCmd", "cFlags") ) +// BpfModule interface is used by the apex package to gather information from a bpf module. +type BpfModule interface { + android.Module + + OutputFiles(tag string) (android.Paths, error) +} + type BpfProperties struct { Srcs []string `android:"path"` Cflags []string @@ -141,7 +148,7 @@ func (bpf *bpf) OutputFiles(tag string) (android.Paths, error) { var _ android.OutputFileProducer = (*bpf)(nil) -func bpfFactory() android.Module { +func BpfFactory() android.Module { module := &bpf{} module.AddProperties(&module.properties) diff --git a/bpf/bpf_test.go b/bpf/bpf_test.go index eeca05771..d06d7d1a5 100644 --- a/bpf/bpf_test.go +++ b/bpf/bpf_test.go @@ -59,7 +59,7 @@ func testConfig(buildDir string, env map[string]string, bp string) android.Confi func testContext(config android.Config) *android.TestContext { ctx := cc.CreateTestContext() - ctx.RegisterModuleType("bpf", bpfFactory) + ctx.RegisterModuleType("bpf", BpfFactory) ctx.Register(config) return ctx