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 7da8e1cf2..8488f6f14 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -28,6 +28,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 ( certificateTag = dependencyTag{name: "certificate"} usesTag = dependencyTag{name: "uses"} androidAppTag = dependencyTag{name: "androidApp", payload: true} + bpfTag = dependencyTag{name: "bpf", payload: true} apexAvailBaseline = makeApexAvailableBaseline() @@ -1062,6 +1064,9 @@ type apexBundleProperties struct { // List of tests that are embedded inside this APEX bundle Tests []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 @@ -1552,6 +1557,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(), @@ -1813,6 +1821,11 @@ func apexFileForAndroidApp(ctx android.BaseModuleContext, aapp interface { 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 @@ -2079,6 +2092,15 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { } else { ctx.PropertyErrorf("apps", "%q is not an android_app 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 e5ae304a4..ecdb88e08 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" @@ -232,6 +233,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) @@ -556,6 +558,7 @@ func TestDefaults(t *testing.T) { native_shared_libs: ["mylib"], java_libs: ["myjar"], apps: ["AppFoo"], + bpfs: ["bpf"], } prebuilt_etc { @@ -596,12 +599,20 @@ func TestDefaults(t *testing.T) { system_modules: "none", apex_available: [ "myapex" ], } + + bpf { + name: "bpf", + srcs: ["bpf.c", "bpf2.c"], + } + `) ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{ "etc/myetc", "javalib/myjar.jar", "lib64/mylib.so", "app/AppFoo/AppFoo.apk", + "etc/bpf/bpf.o", + "etc/bpf/bpf2.o", }) } diff --git a/bpf/bpf.go b/bpf/bpf.go index 59d1502ff..4b5237576 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 @@ -137,7 +144,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