diff options
67 files changed, 1671 insertions, 1257 deletions
diff --git a/android/arch.go b/android/arch.go index cc70eee9c..583793efe 100644 --- a/android/arch.go +++ b/android/arch.go @@ -15,13 +15,14 @@ package android import ( - "android/soong/bazel" "encoding" "fmt" "reflect" "runtime" "strings" + "android/soong/bazel" + "github.com/google/blueprint" "github.com/google/blueprint/bootstrap" "github.com/google/blueprint/proptools" @@ -290,28 +291,6 @@ func osByName(name string) OsType { return NoOsType } -// BuildOs returns the OsType for the OS that the build is running on. -var BuildOs = func() OsType { - switch runtime.GOOS { - case "linux": - return Linux - case "darwin": - return Darwin - default: - panic(fmt.Sprintf("unsupported OS: %s", runtime.GOOS)) - } -}() - -// BuildArch returns the ArchType for the CPU that the build is running on. -var BuildArch = func() ArchType { - switch runtime.GOARCH { - case "amd64": - return X86_64 - default: - panic(fmt.Sprintf("unsupported Arch: %s", runtime.GOARCH)) - } -}() - var ( // osTypeList contains a list of all the supported OsTypes, including ones not supported // by the current build host or the target device. @@ -336,8 +315,6 @@ var ( // Android is the OS for target devices that run all of Android, including the Linux kernel // and the Bionic libc runtime. Android = newOsType("android", Device, false, Arm, Arm64, X86, X86_64) - // Fuchsia is the OS for target devices that run Fuchsia. - Fuchsia = newOsType("fuchsia", Device, false, Arm64, X86_64) // CommonOS is a pseudo OSType for a common OS variant, which is OsType agnostic and which // has dependencies on all the OS variants. @@ -1397,6 +1374,31 @@ func (m *ModuleBase) setArchProperties(ctx BottomUpMutatorContext) { } } +// determineBuildOS stores the OS and architecture used for host targets used during the build into +// config based on the runtime OS and architecture determined by Go. +func determineBuildOS(config *config) { + config.BuildOS = func() OsType { + switch runtime.GOOS { + case "linux": + return Linux + case "darwin": + return Darwin + default: + panic(fmt.Sprintf("unsupported OS: %s", runtime.GOOS)) + } + }() + + config.BuildArch = func() ArchType { + switch runtime.GOARCH { + case "amd64": + return X86_64 + default: + panic(fmt.Sprintf("unsupported Arch: %s", runtime.GOARCH)) + } + }() + +} + // Convert the arch product variables into a list of targets for each OsType. func decodeTargetProductVariables(config *config) (map[OsType][]Target, error) { variables := config.productVariables @@ -1430,9 +1432,9 @@ func decodeTargetProductVariables(config *config) (map[OsType][]Target, error) { hostCross := false if os.Class == Host { var osSupported bool - if os == BuildOs { + if os == config.BuildOS { osSupported = true - } else if BuildOs.Linux() && os.Linux() { + } else if config.BuildOS.Linux() && os.Linux() { // LinuxBionic and Linux are compatible osSupported = true } else { @@ -1470,11 +1472,11 @@ func decodeTargetProductVariables(config *config) (map[OsType][]Target, error) { } // The primary host target, which must always exist. - addTarget(BuildOs, *variables.HostArch, nil, nil, nil, NativeBridgeDisabled, nil, nil) + addTarget(config.BuildOS, *variables.HostArch, nil, nil, nil, NativeBridgeDisabled, nil, nil) // An optional secondary host target. if variables.HostSecondaryArch != nil && *variables.HostSecondaryArch != "" { - addTarget(BuildOs, *variables.HostSecondaryArch, nil, nil, nil, NativeBridgeDisabled, nil, nil) + addTarget(config.BuildOS, *variables.HostSecondaryArch, nil, nil, nil, NativeBridgeDisabled, nil, nil) } // Optional cross-compiled host targets, generally Windows. @@ -1499,13 +1501,8 @@ func decodeTargetProductVariables(config *config) (map[OsType][]Target, error) { // Optional device targets if variables.DeviceArch != nil && *variables.DeviceArch != "" { - var target = Android - if Bool(variables.Fuchsia) { - target = Fuchsia - } - // The primary device target. - addTarget(target, *variables.DeviceArch, variables.DeviceArchVariant, + addTarget(Android, *variables.DeviceArch, variables.DeviceArchVariant, variables.DeviceCpuVariant, variables.DeviceAbi, NativeBridgeDisabled, nil, nil) // An optional secondary device target. diff --git a/android/arch_test.go b/android/arch_test.go index 3aa4779fe..2a2fd454e 100644 --- a/android/arch_test.go +++ b/android/arch_test.go @@ -473,3 +473,164 @@ func TestArchMutatorNativeBridge(t *testing.T) { }) } } + +type testArchPropertiesModule struct { + ModuleBase + properties struct { + A []string `android:"arch_variant"` + } +} + +func (testArchPropertiesModule) GenerateAndroidBuildActions(ctx ModuleContext) {} + +func TestArchProperties(t *testing.T) { + bp := ` + module { + name: "foo", + a: ["root"], + arch: { + arm: { + a: ["arm"], + armv7_a_neon: { a: ["armv7_a_neon"] }, + }, + arm64: { + a: ["arm64"], + armv8_a: { a: ["armv8_a"] }, + }, + x86: { a: ["x86"] }, + x86_64: { a: ["x86_64"] }, + }, + multilib: { + lib32: { a: ["lib32"] }, + lib64: { a: ["lib64"] }, + }, + target: { + bionic: { a: ["bionic"] }, + host: { a: ["host"] }, + android: { a: ["android"] }, + linux_bionic: { a: ["linux_bionic"] }, + linux: { a: ["linux"] }, + linux_glibc: { a: ["linux_glibc"] }, + windows: { a: ["windows"], enabled: true }, + darwin: { a: ["darwin"] }, + not_windows: { a: ["not_windows"] }, + android32: { a: ["android32"] }, + android64: { a: ["android64"] }, + android_arm: { a: ["android_arm"] }, + android_arm64: { a: ["android_arm64"] }, + linux_x86: { a: ["linux_x86"] }, + linux_x86_64: { a: ["linux_x86_64"] }, + linux_glibc_x86: { a: ["linux_glibc_x86"] }, + linux_glibc_x86_64: { a: ["linux_glibc_x86_64"] }, + darwin_x86_64: { a: ["darwin_x86_64"] }, + windows_x86: { a: ["windows_x86"] }, + windows_x86_64: { a: ["windows_x86_64"] }, + }, + } + ` + + type result struct { + module string + variant string + property []string + } + + testCases := []struct { + name string + goOS string + preparer FixturePreparer + results []result + }{ + { + name: "default", + results: []result{ + { + module: "foo", + variant: "android_arm64_armv8-a", + property: []string{"root", "linux", "bionic", "android", "android64", "arm64", "armv8_a", "lib64", "android_arm64"}, + }, + { + module: "foo", + variant: "android_arm_armv7-a-neon", + property: []string{"root", "linux", "bionic", "android", "android64", "arm", "armv7_a_neon", "lib32", "android_arm"}, + }, + }, + }, + { + name: "linux", + goOS: "linux", + results: []result{ + { + module: "foo", + variant: "linux_glibc_x86_64", + property: []string{"root", "host", "linux", "linux_glibc", "not_windows", "x86_64", "lib64", "linux_x86_64", "linux_glibc_x86_64"}, + }, + { + module: "foo", + variant: "linux_glibc_x86", + property: []string{"root", "host", "linux", "linux_glibc", "not_windows", "x86", "lib32", "linux_x86", "linux_glibc_x86"}, + }, + }, + }, + { + name: "windows", + goOS: "linux", + preparer: FixtureModifyConfig(func(config Config) { + config.Targets[Windows] = []Target{ + {Windows, Arch{ArchType: X86_64}, NativeBridgeDisabled, "", "", true}, + {Windows, Arch{ArchType: X86}, NativeBridgeDisabled, "", "", true}, + } + }), + results: []result{ + { + module: "foo", + variant: "windows_x86_64", + property: []string{"root", "host", "windows", "x86_64", "lib64", "windows_x86_64"}, + }, + { + module: "foo", + variant: "windows_x86", + property: []string{"root", "host", "windows", "x86", "lib32", "windows_x86"}, + }, + }, + }, + { + name: "darwin", + goOS: "darwin", + results: []result{ + { + module: "foo", + variant: "darwin_x86_64", + property: []string{"root", "host", "darwin", "not_windows", "x86_64", "lib64", "darwin_x86_64"}, + }, + }, + }, + } + + for _, tt := range testCases { + t.Run(tt.name, func(t *testing.T) { + if tt.goOS != "" && tt.goOS != runtime.GOOS { + t.Skipf("test requires runtime.GOOS==%s, got %s", tt.goOS, runtime.GOOS) + } + result := GroupFixturePreparers( + PrepareForTestWithArchMutator, + OptionalFixturePreparer(tt.preparer), + FixtureRegisterWithContext(func(ctx RegistrationContext) { + ctx.RegisterModuleType("module", func() Module { + module := &testArchPropertiesModule{} + module.AddProperties(&module.properties) + InitAndroidArchModule(module, HostAndDeviceDefault, MultilibBoth) + return module + }) + }), + ).RunTestWithBp(t, bp) + + for _, want := range tt.results { + t.Run(want.module+"_"+want.variant, func(t *testing.T) { + got := result.ModuleForTests(want.module, want.variant).Module().(*testArchPropertiesModule).properties.A + AssertArrayString(t, "arch mutator property", want.property, got) + }) + } + }) + } +} diff --git a/android/bazel.go b/android/bazel.go index 46212dc33..d40e6508e 100644 --- a/android/bazel.go +++ b/android/bazel.go @@ -140,6 +140,7 @@ var ( "prebuilts/sdk":/* recursive = */ false, "prebuilts/sdk/tools":/* recursive = */ false, + "packages/apps/Music":/* recursive = */ false, } // Configure modules in these directories to enable bp2build_available: true or false by default. diff --git a/android/config.go b/android/config.go index 396b1a66b..871986c7c 100644 --- a/android/config.go +++ b/android/config.go @@ -108,6 +108,12 @@ type config struct { ProductVariablesFileName string + // BuildOS stores the OsType for the OS that the build is running on. + BuildOS OsType + + // BuildArch stores the ArchType for the CPU that the build is running on. + BuildArch ArchType + Targets map[OsType][]Target BuildOSTarget Target // the Target for tools run on the build machine BuildOSCommonTarget Target // the Target for common (java) tools run on the build machine @@ -326,41 +332,28 @@ func TestConfig(buildDir string, env map[string]string, bp string, fs map[string return Config{config} } -func fuchsiaTargets() map[OsType][]Target { - return map[OsType][]Target{ - Fuchsia: { - {Fuchsia, Arch{ArchType: Arm64, ArchVariant: "", Abi: []string{"arm64-v8a"}}, NativeBridgeDisabled, "", "", false}, - }, - BuildOs: { - {BuildOs, Arch{ArchType: X86_64}, NativeBridgeDisabled, "", "", false}, - }, - } -} - -var PrepareForTestSetDeviceToFuchsia = FixtureModifyConfig(func(config Config) { - config.Targets = fuchsiaTargets() -}) - func modifyTestConfigToSupportArchMutator(testConfig Config) { config := testConfig.config + determineBuildOS(config) + config.Targets = map[OsType][]Target{ Android: []Target{ {Android, Arch{ArchType: Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}}, NativeBridgeDisabled, "", "", false}, {Android, Arch{ArchType: Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}}, NativeBridgeDisabled, "", "", false}, }, - BuildOs: []Target{ - {BuildOs, Arch{ArchType: X86_64}, NativeBridgeDisabled, "", "", false}, - {BuildOs, Arch{ArchType: X86}, NativeBridgeDisabled, "", "", false}, + config.BuildOS: []Target{ + {config.BuildOS, Arch{ArchType: X86_64}, NativeBridgeDisabled, "", "", false}, + {config.BuildOS, Arch{ArchType: X86}, NativeBridgeDisabled, "", "", false}, }, } if runtime.GOOS == "darwin" { - config.Targets[BuildOs] = config.Targets[BuildOs][:1] + config.Targets[config.BuildOS] = config.Targets[config.BuildOS][:1] } - config.BuildOSTarget = config.Targets[BuildOs][0] - config.BuildOSCommonTarget = getCommonTargets(config.Targets[BuildOs])[0] + config.BuildOSTarget = config.Targets[config.BuildOS][0] + config.BuildOSCommonTarget = getCommonTargets(config.Targets[config.BuildOS])[0] config.AndroidCommonTarget = getCommonTargets(config.Targets[Android])[0] config.AndroidFirstDeviceTarget = firstTarget(config.Targets[Android], "lib64", "lib32")[0] config.TestProductVariables.DeviceArch = proptools.StringPtr("arm64") @@ -439,6 +432,8 @@ func NewConfig(srcDir, buildDir string, moduleListFile string, availableEnv map[ config.katiEnabled = true } + determineBuildOS(config) + // Sets up the map of target OSes to the finer grained compilation targets // that are configured from the product variables. targets, err := decodeTargetProductVariables(config) @@ -476,8 +471,8 @@ func NewConfig(srcDir, buildDir string, moduleListFile string, availableEnv map[ config.Targets = targets // Compilation targets for host tools. - config.BuildOSTarget = config.Targets[BuildOs][0] - config.BuildOSCommonTarget = getCommonTargets(config.Targets[BuildOs])[0] + config.BuildOSTarget = config.Targets[config.BuildOS][0] + config.BuildOSCommonTarget = getCommonTargets(config.Targets[config.BuildOS])[0] // Compilation targets for Android. if len(config.Targets[Android]) > 0 { @@ -837,10 +832,6 @@ func (c *config) SkipBootJarsCheck() bool { return Bool(c.productVariables.Skip_boot_jars_check) } -func (c *config) Fuchsia() bool { - return Bool(c.productVariables.Fuchsia) -} - func (c *config) MinimizeJavaDebugInfo() bool { return Bool(c.productVariables.MinimizeJavaDebugInfo) && !Bool(c.productVariables.Eng) } diff --git a/android/module.go b/android/module.go index 4dd580083..5f34e6259 100644 --- a/android/module.go +++ b/android/module.go @@ -327,7 +327,6 @@ type BaseModuleContext interface { Host() bool Device() bool Darwin() bool - Fuchsia() bool Windows() bool Debug() bool PrimaryArch() bool @@ -415,6 +414,7 @@ type ModuleContext interface { InstallInDebugRamdisk() bool InstallInRecovery() bool InstallInRoot() bool + InstallInVendor() bool InstallBypassMake() bool InstallForceOS() (*OsType, *ArchType) @@ -473,6 +473,7 @@ type Module interface { InstallInDebugRamdisk() bool InstallInRecovery() bool InstallInRoot() bool + InstallInVendor() bool InstallBypassMake() bool InstallForceOS() (*OsType, *ArchType) HideFromMake() @@ -1581,6 +1582,10 @@ func (m *ModuleBase) InstallInRecovery() bool { return Bool(m.commonProperties.Recovery) } +func (m *ModuleBase) InstallInVendor() bool { + return Bool(m.commonProperties.Vendor) +} + func (m *ModuleBase) InstallInRoot() bool { return false } @@ -2582,10 +2587,6 @@ func (b *baseModuleContext) Darwin() bool { return b.os == Darwin } -func (b *baseModuleContext) Fuchsia() bool { - return b.os == Fuchsia -} - func (b *baseModuleContext) Windows() bool { return b.os == Windows } @@ -2664,6 +2665,10 @@ func (m *moduleContext) InstallForceOS() (*OsType, *ArchType) { return m.module.InstallForceOS() } +func (m *moduleContext) InstallInVendor() bool { + return m.module.InstallInVendor() +} + func (m *moduleContext) skipInstall() bool { if m.module.base().commonProperties.SkipInstall { return true diff --git a/android/prebuilt_build_tool.go b/android/prebuilt_build_tool.go index 516d0420a..e5edf9129 100644 --- a/android/prebuilt_build_tool.go +++ b/android/prebuilt_build_tool.go @@ -86,7 +86,7 @@ func (t *prebuiltBuildTool) GenerateAndroidBuildActions(ctx ModuleContext) { func (t *prebuiltBuildTool) MakeVars(ctx MakeVarsModuleContext) { if makeVar := String(t.properties.Export_to_make_var); makeVar != "" { - if t.Target().Os != BuildOs { + if t.Target().Os != ctx.Config().BuildOS { return } ctx.StrictRaw(makeVar, t.toolPath.String()) diff --git a/android/prebuilt_test.go b/android/prebuilt_test.go index dcd77ea46..a1f8e6367 100644 --- a/android/prebuilt_test.go +++ b/android/prebuilt_test.go @@ -21,360 +21,362 @@ import ( "github.com/google/blueprint" ) -var prebuiltsTests = []struct { - name string - replaceBp bool // modules is added to default bp boilerplate if false. - modules string - prebuilt []OsType - preparer FixturePreparer -}{ - { - name: "no prebuilt", - modules: ` - source { - name: "bar", - }`, - prebuilt: nil, - }, - { - name: "no source prebuilt not preferred", - modules: ` - prebuilt { - name: "bar", - prefer: false, - srcs: ["prebuilt_file"], - }`, - prebuilt: []OsType{Android, BuildOs}, - }, - { - name: "no source prebuilt preferred", - modules: ` - prebuilt { - name: "bar", - prefer: true, - srcs: ["prebuilt_file"], - }`, - prebuilt: []OsType{Android, BuildOs}, - }, - { - name: "prebuilt not preferred", - modules: ` - source { - name: "bar", - } - - prebuilt { - name: "bar", - prefer: false, - srcs: ["prebuilt_file"], - }`, - prebuilt: nil, - }, - { - name: "prebuilt preferred", - modules: ` - source { - name: "bar", - } - - prebuilt { - name: "bar", - prefer: true, - srcs: ["prebuilt_file"], - }`, - prebuilt: []OsType{Android, BuildOs}, - }, - { - name: "prebuilt no file not preferred", - modules: ` - source { - name: "bar", - } - - prebuilt { - name: "bar", - prefer: false, - }`, - prebuilt: nil, - }, - { - name: "prebuilt no file preferred", - modules: ` - source { - name: "bar", - } - - prebuilt { - name: "bar", - prefer: true, - }`, - prebuilt: nil, - }, - { - name: "prebuilt file from filegroup preferred", - modules: ` - filegroup { - name: "fg", - srcs: ["prebuilt_file"], - } - prebuilt { - name: "bar", - prefer: true, - srcs: [":fg"], - }`, - prebuilt: []OsType{Android, BuildOs}, - }, - { - name: "prebuilt module for device only", - modules: ` - source { - name: "bar", - } - - prebuilt { - name: "bar", - host_supported: false, - prefer: true, - srcs: ["prebuilt_file"], - }`, - prebuilt: []OsType{Android}, - }, - { - name: "prebuilt file for host only", - modules: ` - source { - name: "bar", - } - - prebuilt { - name: "bar", - prefer: true, - target: { - host: { - srcs: ["prebuilt_file"], +func TestPrebuilts(t *testing.T) { + buildOS := TestArchConfig(t.TempDir(), nil, "", nil).BuildOS + + var prebuiltsTests = []struct { + name string + replaceBp bool // modules is added to default bp boilerplate if false. + modules string + prebuilt []OsType + preparer FixturePreparer + }{ + { + name: "no prebuilt", + modules: ` + source { + name: "bar", + }`, + prebuilt: nil, + }, + { + name: "no source prebuilt not preferred", + modules: ` + prebuilt { + name: "bar", + prefer: false, + srcs: ["prebuilt_file"], + }`, + prebuilt: []OsType{Android, buildOS}, + }, + { + name: "no source prebuilt preferred", + modules: ` + prebuilt { + name: "bar", + prefer: true, + srcs: ["prebuilt_file"], + }`, + prebuilt: []OsType{Android, buildOS}, + }, + { + name: "prebuilt not preferred", + modules: ` + source { + name: "bar", + } + + prebuilt { + name: "bar", + prefer: false, + srcs: ["prebuilt_file"], + }`, + prebuilt: nil, + }, + { + name: "prebuilt preferred", + modules: ` + source { + name: "bar", + } + + prebuilt { + name: "bar", + prefer: true, + srcs: ["prebuilt_file"], + }`, + prebuilt: []OsType{Android, buildOS}, + }, + { + name: "prebuilt no file not preferred", + modules: ` + source { + name: "bar", + } + + prebuilt { + name: "bar", + prefer: false, + }`, + prebuilt: nil, + }, + { + name: "prebuilt no file preferred", + modules: ` + source { + name: "bar", + } + + prebuilt { + name: "bar", + prefer: true, + }`, + prebuilt: nil, + }, + { + name: "prebuilt file from filegroup preferred", + modules: ` + filegroup { + name: "fg", + srcs: ["prebuilt_file"], + } + prebuilt { + name: "bar", + prefer: true, + srcs: [":fg"], + }`, + prebuilt: []OsType{Android, buildOS}, + }, + { + name: "prebuilt module for device only", + modules: ` + source { + name: "bar", + } + + prebuilt { + name: "bar", + host_supported: false, + prefer: true, + srcs: ["prebuilt_file"], + }`, + prebuilt: []OsType{Android}, + }, + { + name: "prebuilt file for host only", + modules: ` + source { + name: "bar", + } + + prebuilt { + name: "bar", + prefer: true, + target: { + host: { + srcs: ["prebuilt_file"], + }, }, - }, - }`, - prebuilt: []OsType{BuildOs}, - }, - { - name: "prebuilt override not preferred", - modules: ` - source { - name: "baz", - } - - override_source { - name: "bar", - base: "baz", - } - - prebuilt { - name: "bar", - prefer: false, - srcs: ["prebuilt_file"], - }`, - prebuilt: nil, - }, - { - name: "prebuilt override preferred", - modules: ` - source { - name: "baz", - } - - override_source { - name: "bar", - base: "baz", - } - - prebuilt { - name: "bar", - prefer: true, - srcs: ["prebuilt_file"], - }`, - prebuilt: []OsType{Android, BuildOs}, - }, - { - name: "prebuilt including default-disabled OS", - replaceBp: true, - modules: ` - source { - name: "foo", - deps: [":bar"], - target: { - windows: { - enabled: true, + }`, + prebuilt: []OsType{buildOS}, + }, + { + name: "prebuilt override not preferred", + modules: ` + source { + name: "baz", + } + + override_source { + name: "bar", + base: "baz", + } + + prebuilt { + name: "bar", + prefer: false, + srcs: ["prebuilt_file"], + }`, + prebuilt: nil, + }, + { + name: "prebuilt override preferred", + modules: ` + source { + name: "baz", + } + + override_source { + name: "bar", + base: "baz", + } + + prebuilt { + name: "bar", + prefer: true, + srcs: ["prebuilt_file"], + }`, + prebuilt: []OsType{Android, buildOS}, + }, + { + name: "prebuilt including default-disabled OS", + replaceBp: true, + modules: ` + source { + name: "foo", + deps: [":bar"], + target: { + windows: { + enabled: true, + }, }, - }, - } + } - source { - name: "bar", - target: { - windows: { - enabled: true, + source { + name: "bar", + target: { + windows: { + enabled: true, + }, }, - }, - } - - prebuilt { - name: "bar", - prefer: true, - srcs: ["prebuilt_file"], - target: { - windows: { - enabled: true, + } + + prebuilt { + name: "bar", + prefer: true, + srcs: ["prebuilt_file"], + target: { + windows: { + enabled: true, + }, }, - }, - }`, - prebuilt: []OsType{Android, BuildOs, Windows}, - }, - { - name: "fall back to source for default-disabled OS", - replaceBp: true, - modules: ` - source { - name: "foo", - deps: [":bar"], - target: { - windows: { - enabled: true, + }`, + prebuilt: []OsType{Android, buildOS, Windows}, + }, + { + name: "fall back to source for default-disabled OS", + replaceBp: true, + modules: ` + source { + name: "foo", + deps: [":bar"], + target: { + windows: { + enabled: true, + }, }, - }, - } + } - source { - name: "bar", - target: { - windows: { - enabled: true, + source { + name: "bar", + target: { + windows: { + enabled: true, + }, }, - }, - } - - prebuilt { - name: "bar", - prefer: true, - srcs: ["prebuilt_file"], - }`, - prebuilt: []OsType{Android, BuildOs}, - }, - { - name: "prebuilt properties customizable", - replaceBp: true, - modules: ` - source { - name: "foo", - deps: [":bar"], - } - - soong_config_module_type { - name: "prebuilt_with_config", - module_type: "prebuilt", - config_namespace: "any_namespace", - bool_variables: ["bool_var"], - properties: ["prefer"], - } - - prebuilt_with_config { - name: "bar", - prefer: true, - srcs: ["prebuilt_file"], - soong_config_variables: { - bool_var: { - prefer: false, - conditions_default: { - prefer: true, + } + + prebuilt { + name: "bar", + prefer: true, + srcs: ["prebuilt_file"], + }`, + prebuilt: []OsType{Android, buildOS}, + }, + { + name: "prebuilt properties customizable", + replaceBp: true, + modules: ` + source { + name: "foo", + deps: [":bar"], + } + + soong_config_module_type { + name: "prebuilt_with_config", + module_type: "prebuilt", + config_namespace: "any_namespace", + bool_variables: ["bool_var"], + properties: ["prefer"], + } + + prebuilt_with_config { + name: "bar", + prefer: true, + srcs: ["prebuilt_file"], + soong_config_variables: { + bool_var: { + prefer: false, + conditions_default: { + prefer: true, + }, }, }, - }, - }`, - prebuilt: []OsType{Android, BuildOs}, - }, - { - name: "prebuilt use_source_config_var={acme, use_source} - no var specified", - modules: ` - source { - name: "bar", - } - - prebuilt { - name: "bar", - use_source_config_var: {config_namespace: "acme", var_name: "use_source"}, - srcs: ["prebuilt_file"], - }`, - // When use_source_env is specified then it will use the prebuilt by default if the environment - // variable is not set. - prebuilt: []OsType{Android, BuildOs}, - }, - { - name: "prebuilt use_source_config_var={acme, use_source} - acme_use_source=false", - modules: ` - source { - name: "bar", - } - - prebuilt { - name: "bar", - use_source_config_var: {config_namespace: "acme", var_name: "use_source"}, - srcs: ["prebuilt_file"], - }`, - preparer: FixtureModifyProductVariables(func(variables FixtureProductVariables) { - variables.VendorVars = map[string]map[string]string{ - "acme": { - "use_source": "false", - }, - } - }), - // Setting the environment variable named in use_source_env to false will cause the prebuilt to - // be used. - prebuilt: []OsType{Android, BuildOs}, - }, - { - name: "prebuilt use_source_config_var={acme, use_source} - acme_use_source=true", - modules: ` - source { - name: "bar", - } - - prebuilt { - name: "bar", - use_source_config_var: {config_namespace: "acme", var_name: "use_source"}, - srcs: ["prebuilt_file"], - }`, - preparer: FixtureModifyProductVariables(func(variables FixtureProductVariables) { - variables.VendorVars = map[string]map[string]string{ - "acme": { - "use_source": "true", - }, - } - }), - // Setting the environment variable named in use_source_env to true will cause the source to be - // used. - prebuilt: nil, - }, - { - name: "prebuilt use_source_config_var={acme, use_source} - acme_use_source=true, no source", - modules: ` - prebuilt { - name: "bar", - use_source_config_var: {config_namespace: "acme", var_name: "use_source"}, - srcs: ["prebuilt_file"], - }`, - preparer: FixtureModifyProductVariables(func(variables FixtureProductVariables) { - variables.VendorVars = map[string]map[string]string{ - "acme": { - "use_source": "true", - }, - } - }), - // Although the environment variable says to use source there is no source available. - prebuilt: []OsType{Android, BuildOs}, - }, -} + }`, + prebuilt: []OsType{Android, buildOS}, + }, + { + name: "prebuilt use_source_config_var={acme, use_source} - no var specified", + modules: ` + source { + name: "bar", + } + + prebuilt { + name: "bar", + use_source_config_var: {config_namespace: "acme", var_name: "use_source"}, + srcs: ["prebuilt_file"], + }`, + // When use_source_env is specified then it will use the prebuilt by default if the environment + // variable is not set. + prebuilt: []OsType{Android, buildOS}, + }, + { + name: "prebuilt use_source_config_var={acme, use_source} - acme_use_source=false", + modules: ` + source { + name: "bar", + } + + prebuilt { + name: "bar", + use_source_config_var: {config_namespace: "acme", var_name: "use_source"}, + srcs: ["prebuilt_file"], + }`, + preparer: FixtureModifyProductVariables(func(variables FixtureProductVariables) { + variables.VendorVars = map[string]map[string]string{ + "acme": { + "use_source": "false", + }, + } + }), + // Setting the environment variable named in use_source_env to false will cause the prebuilt to + // be used. + prebuilt: []OsType{Android, buildOS}, + }, + { + name: "prebuilt use_source_config_var={acme, use_source} - acme_use_source=true", + modules: ` + source { + name: "bar", + } + + prebuilt { + name: "bar", + use_source_config_var: {config_namespace: "acme", var_name: "use_source"}, + srcs: ["prebuilt_file"], + }`, + preparer: FixtureModifyProductVariables(func(variables FixtureProductVariables) { + variables.VendorVars = map[string]map[string]string{ + "acme": { + "use_source": "true", + }, + } + }), + // Setting the environment variable named in use_source_env to true will cause the source to be + // used. + prebuilt: nil, + }, + { + name: "prebuilt use_source_config_var={acme, use_source} - acme_use_source=true, no source", + modules: ` + prebuilt { + name: "bar", + use_source_config_var: {config_namespace: "acme", var_name: "use_source"}, + srcs: ["prebuilt_file"], + }`, + preparer: FixtureModifyProductVariables(func(variables FixtureProductVariables) { + variables.VendorVars = map[string]map[string]string{ + "acme": { + "use_source": "true", + }, + } + }), + // Although the environment variable says to use source there is no source available. + prebuilt: []OsType{Android, buildOS}, + }, + } -func TestPrebuilts(t *testing.T) { fs := MockFS{ "prebuilt_file": nil, "source_file": nil, diff --git a/android/test_suites.go b/android/test_suites.go index 6b7b909fc..22f6cf229 100644 --- a/android/test_suites.go +++ b/android/test_suites.go @@ -60,7 +60,7 @@ func robolectricTestSuite(ctx SingletonContext, files map[string]InstallPaths) W for _, module := range SortedStringKeys(files) { installedPaths = append(installedPaths, files[module]...) } - testCasesDir := pathForInstall(ctx, BuildOs, X86, "testcases", false).ToMakePath() + testCasesDir := pathForInstall(ctx, ctx.Config().BuildOS, X86, "testcases", false).ToMakePath() outputFile := PathForOutput(ctx, "packaging", "robolectric-tests.zip") rule := NewRuleBuilder(pctx, ctx) diff --git a/android/variable.go b/android/variable.go index bbb98688f..d0a23aaa1 100644 --- a/android/variable.go +++ b/android/variable.go @@ -299,8 +299,6 @@ type productVariables struct { Override_rs_driver *string `json:",omitempty"` - Fuchsia *bool `json:",omitempty"` - DeviceKernelHeaders []string `json:",omitempty"` ExtraVndkVersions []string `json:",omitempty"` diff --git a/bazel/configurability.go b/bazel/configurability.go index 35f194dfe..3277bd049 100644 --- a/bazel/configurability.go +++ b/bazel/configurability.go @@ -29,7 +29,6 @@ const ( // OsType names in arch.go osAndroid = "android" osDarwin = "darwin" - osFuchsia = "fuchsia" osLinux = "linux_glibc" osLinuxBionic = "linux_bionic" osWindows = "windows" @@ -40,8 +39,6 @@ const ( osArchAndroidX86 = "android_x86" osArchAndroidX86_64 = "android_x86_64" osArchDarwinX86_64 = "darwin_x86_64" - osArchFuchsiaArm64 = "fuchsia_arm64" - osArchFuchsiaX86_64 = "fuchsia_x86_64" osArchLinuxX86 = "linux_glibc_x86" osArchLinuxX86_64 = "linux_glibc_x86_64" osArchLinuxBionicArm64 = "linux_bionic_arm64" @@ -84,7 +81,6 @@ var ( platformOsMap = map[string]string{ osAndroid: "//build/bazel/platforms/os:android", osDarwin: "//build/bazel/platforms/os:darwin", - osFuchsia: "//build/bazel/platforms/os:fuchsia", osLinux: "//build/bazel/platforms/os:linux", osLinuxBionic: "//build/bazel/platforms/os:linux_bionic", osWindows: "//build/bazel/platforms/os:windows", @@ -102,8 +98,6 @@ var ( osArchAndroidX86: "//build/bazel/platforms/os_arch:android_x86", osArchAndroidX86_64: "//build/bazel/platforms/os_arch:android_x86_64", osArchDarwinX86_64: "//build/bazel/platforms/os_arch:darwin_x86_64", - osArchFuchsiaArm64: "//build/bazel/platforms/os_arch:fuchsia_arm64", - osArchFuchsiaX86_64: "//build/bazel/platforms/os_arch:fuchsia_x86_64", osArchLinuxX86: "//build/bazel/platforms/os_arch:linux_glibc_x86", osArchLinuxX86_64: "//build/bazel/platforms/os_arch:linux_glibc_x86_64", osArchLinuxBionicArm64: "//build/bazel/platforms/os_arch:linux_bionic_arm64", diff --git a/bp2build/cc_library_headers_conversion_test.go b/bp2build/cc_library_headers_conversion_test.go index d1fd6af70..712d0bd5a 100644 --- a/bp2build/cc_library_headers_conversion_test.go +++ b/bp2build/cc_library_headers_conversion_test.go @@ -185,7 +185,6 @@ func TestCcLibraryHeadersOSSpecificHeader(t *testing.T) { cc_library_headers { name: "android-lib" } cc_library_headers { name: "base-lib" } cc_library_headers { name: "darwin-lib" } -cc_library_headers { name: "fuchsia-lib" } cc_library_headers { name: "linux-lib" } cc_library_headers { name: "linux_bionic-lib" } cc_library_headers { name: "windows-lib" } @@ -195,7 +194,6 @@ cc_library_headers { target: { android: { header_libs: ["android-lib"] }, darwin: { header_libs: ["darwin-lib"] }, - fuchsia: { header_libs: ["fuchsia-lib"] }, linux_bionic: { header_libs: ["linux_bionic-lib"] }, linux_glibc: { header_libs: ["linux-lib"] }, windows: { header_libs: ["windows-lib"] }, @@ -229,19 +227,12 @@ cc_library_headers { implementation_deps = [":base-lib"] + select({ "//build/bazel/platforms/os:android": [":android-lib"], "//build/bazel/platforms/os:darwin": [":darwin-lib"], - "//build/bazel/platforms/os:fuchsia": [":fuchsia-lib"], "//build/bazel/platforms/os:linux": [":linux-lib"], "//build/bazel/platforms/os:linux_bionic": [":linux_bionic-lib"], "//build/bazel/platforms/os:windows": [":windows-lib"], "//conditions:default": [], }), )`, `cc_library_headers( - name = "fuchsia-lib", - copts = [ - "-I.", - "-I$(BINDIR)/.", - ], -)`, `cc_library_headers( name = "linux-lib", copts = [ "-I.", diff --git a/cc/Android.bp b/cc/Android.bp index 4b750ff25..164d32b12 100644 --- a/cc/Android.bp +++ b/cc/Android.bp @@ -14,6 +14,7 @@ bootstrap_go_package { "soong-cc-config", "soong-etc", "soong-genrule", + "soong-snapshot", "soong-tradefed", ], srcs: [ diff --git a/cc/binary.go b/cc/binary.go index c177a0899..c6d61abbb 100644 --- a/cc/binary.go +++ b/cc/binary.go @@ -215,7 +215,7 @@ func (binary *binaryDecorator) linkerInit(ctx BaseModuleContext) { if binary.Properties.Static_executable == nil && ctx.Config().HostStaticBinaries() { binary.Properties.Static_executable = BoolPtr(true) } - } else if !ctx.Fuchsia() { + } else { // Static executables are not supported on Darwin or Windows binary.Properties.Static_executable = nil } diff --git a/cc/cc_test.go b/cc/cc_test.go index 0a3acb95f..dd51fe853 100644 --- a/cc/cc_test.go +++ b/cc/cc_test.go @@ -152,71 +152,6 @@ func TestPrepareForTestWithCcDefaultModules(t *testing.T) { ).RunTest(t) } -func TestFuchsiaDeps(t *testing.T) { - t.Helper() - - bp := ` - cc_library { - name: "libTest", - srcs: ["foo.c"], - target: { - fuchsia: { - srcs: ["bar.c"], - }, - }, - }` - - result := android.GroupFixturePreparers( - prepareForCcTest, - PrepareForTestOnFuchsia, - ).RunTestWithBp(t, bp) - - rt := false - fb := false - - ld := result.ModuleForTests("libTest", "fuchsia_arm64_shared").Rule("ld") - implicits := ld.Implicits - for _, lib := range implicits { - if strings.Contains(lib.Rel(), "libcompiler_rt") { - rt = true - } - - if strings.Contains(lib.Rel(), "libbioniccompat") { - fb = true - } - } - - if !rt || !fb { - t.Errorf("fuchsia libs must link libcompiler_rt and libbioniccompat") - } -} - -func TestFuchsiaTargetDecl(t *testing.T) { - t.Helper() - - bp := ` - cc_library { - name: "libTest", - srcs: ["foo.c"], - target: { - fuchsia: { - srcs: ["bar.c"], - }, - }, - }` - - result := android.GroupFixturePreparers( - prepareForCcTest, - PrepareForTestOnFuchsia, - ).RunTestWithBp(t, bp) - ld := result.ModuleForTests("libTest", "fuchsia_arm64_shared").Rule("ld") - var objs []string - for _, o := range ld.Inputs { - objs = append(objs, o.Base()) - } - android.AssertArrayString(t, "libTest inputs", []string{"foo.o", "bar.o"}, objs) -} - func TestVendorSrc(t *testing.T) { ctx := testCc(t, ` cc_library { diff --git a/cc/config/Android.bp b/cc/config/Android.bp index c1d4f1755..3e8ee48ca 100644 --- a/cc/config/Android.bp +++ b/cc/config/Android.bp @@ -21,10 +21,8 @@ bootstrap_go_package { "arm_device.go", "arm64_device.go", - "arm64_fuchsia_device.go", "x86_device.go", "x86_64_device.go", - "x86_64_fuchsia_device.go", "x86_darwin_host.go", "x86_linux_host.go", diff --git a/cc/config/arm64_fuchsia_device.go b/cc/config/arm64_fuchsia_device.go deleted file mode 100644 index 5ab27a03c..000000000 --- a/cc/config/arm64_fuchsia_device.go +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright 2018 Google Inc. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package config - -import ( - "android/soong/android" -) - -var fuchsiaArm64SysRoot string = "prebuilts/fuchsia_sdk/arch/arm64/sysroot" -var fuchsiaArm64PrebuiltLibsRoot string = "fuchsia/prebuilt_libs/" - -type toolchainFuchsiaArm64 struct { - toolchain64Bit - toolchainFuchsia -} - -func (t *toolchainFuchsiaArm64) Name() string { - return "arm64" -} - -func (t *toolchainFuchsiaArm64) GccRoot() string { - return "${config.Arm64GccRoot}" -} - -func (t *toolchainFuchsiaArm64) GccTriple() string { - return "aarch64-linux-android" -} - -func (t *toolchainFuchsiaArm64) GccVersion() string { - return arm64GccVersion -} - -func (t *toolchainFuchsiaArm64) IncludeFlags() string { - return "" -} - -func (t *toolchainFuchsiaArm64) ClangTriple() string { - return "arm64-fuchsia-android" -} - -func (t *toolchainFuchsiaArm64) Cppflags() string { - return "-Wno-error=deprecated-declarations" -} - -func (t *toolchainFuchsiaArm64) Ldflags() string { - return "--target=arm64-fuchsia --sysroot=" + fuchsiaArm64SysRoot + " -L" + fuchsiaArm64PrebuiltLibsRoot + "/aarch64-fuchsia/lib " + "-Lprebuilts/fuchsia_sdk/arch/arm64/dist/" -} - -func (t *toolchainFuchsiaArm64) Lldflags() string { - return "--target=arm64-fuchsia --sysroot=" + fuchsiaArm64SysRoot + " -L" + fuchsiaArm64PrebuiltLibsRoot + "/aarch64-fuchsia/lib " + "-Lprebuilts/fuchsia_sdk/arch/arm64/dist/" -} - -func (t *toolchainFuchsiaArm64) Cflags() string { - return "--target=arm64-fuchsia --sysroot=" + fuchsiaArm64SysRoot + " -I" + fuchsiaArm64SysRoot + "/include" -} - -func (t *toolchainFuchsiaArm64) ToolchainCflags() string { - return "-march=armv8-a" -} - -var toolchainArm64FuchsiaSingleton Toolchain = &toolchainFuchsiaArm64{} - -func arm64FuchsiaToolchainFactory(arch android.Arch) Toolchain { - return toolchainArm64FuchsiaSingleton -} - -func init() { - registerToolchainFactory(android.Fuchsia, android.Arm64, arm64FuchsiaToolchainFactory) -} diff --git a/cc/config/global.go b/cc/config/global.go index dfbe6c4f5..55e0d7967 100644 --- a/cc/config/global.go +++ b/cc/config/global.go @@ -15,6 +15,7 @@ package config import ( + "runtime" "strings" "android/soong/android" @@ -282,7 +283,7 @@ var ( var pctx = android.NewPackageContext("android/soong/cc/config") func init() { - if android.BuildOs == android.Linux { + if runtime.GOOS == "linux" { commonGlobalCflags = append(commonGlobalCflags, "-fdebug-prefix-map=/proc/self/cwd=") } diff --git a/cc/config/x86_64_fuchsia_device.go b/cc/config/x86_64_fuchsia_device.go deleted file mode 100644 index 86558a6cc..000000000 --- a/cc/config/x86_64_fuchsia_device.go +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright 2018 Google Inc. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package config - -import ( - "android/soong/android" -) - -var fuchsiaSysRoot string = "prebuilts/fuchsia_sdk/arch/x64/sysroot" -var fuchsiaPrebuiltLibsRoot string = "fuchsia/prebuilt_libs" - -type toolchainFuchsia struct { - cFlags, ldFlags string -} - -type toolchainFuchsiaX8664 struct { - toolchain64Bit - toolchainFuchsia -} - -func (t *toolchainFuchsiaX8664) Name() string { - return "x86_64" -} - -func (t *toolchainFuchsiaX8664) GccRoot() string { - return "${config.X86_64GccRoot}" -} - -func (t *toolchainFuchsiaX8664) GccTriple() string { - return "x86_64-linux-android" -} - -func (t *toolchainFuchsiaX8664) GccVersion() string { - return x86_64GccVersion -} - -func (t *toolchainFuchsiaX8664) IncludeFlags() string { - return "" -} - -func (t *toolchainFuchsiaX8664) ClangTriple() string { - return "x86_64-fuchsia-android" -} - -func (t *toolchainFuchsiaX8664) Cppflags() string { - return "-Wno-error=deprecated-declarations" -} - -func (t *toolchainFuchsiaX8664) Ldflags() string { - return "--target=x86_64-fuchsia --sysroot=" + fuchsiaSysRoot + " -L" + fuchsiaPrebuiltLibsRoot + "/x86_64-fuchsia/lib " + "-Lprebuilts/fuchsia_sdk/arch/x64/dist/" - -} - -func (t *toolchainFuchsiaX8664) Lldflags() string { - return "--target=x86_64-fuchsia --sysroot=" + fuchsiaSysRoot + " -L" + fuchsiaPrebuiltLibsRoot + "/x86_64-fuchsia/lib " + "-Lprebuilts/fuchsia_sdk/arch/x64/dist/" -} - -func (t *toolchainFuchsiaX8664) Cflags() string { - return "--target=x86_64-fuchsia --sysroot=" + fuchsiaSysRoot + " -I" + fuchsiaSysRoot + "/include" -} - -func (t *toolchainFuchsiaX8664) YasmFlags() string { - return "-f elf64 -m amd64" -} - -func (t *toolchainFuchsiaX8664) ToolchainCflags() string { - return "-mssse3" -} - -var toolchainFuchsiaSingleton Toolchain = &toolchainFuchsiaX8664{} - -func fuchsiaToolchainFactory(arch android.Arch) Toolchain { - return toolchainFuchsiaSingleton -} - -func init() { - registerToolchainFactory(android.Fuchsia, android.X86_64, fuchsiaToolchainFactory) -} diff --git a/cc/genrule.go b/cc/genrule.go index b0efc6ca4..0ca901e61 100644 --- a/cc/genrule.go +++ b/cc/genrule.go @@ -17,6 +17,7 @@ package cc import ( "android/soong/android" "android/soong/genrule" + "android/soong/snapshot" ) func init() { @@ -84,7 +85,7 @@ func (g *GenruleExtraProperties) RecoveryVariantNeeded(ctx android.BaseModuleCon // is not needed. recoverySnapshotVersion := ctx.DeviceConfig().RecoverySnapshotVersion() if recoverySnapshotVersion != "current" && recoverySnapshotVersion != "" && - !isRecoveryProprietaryModule(ctx) { + !snapshot.IsRecoveryProprietaryModule(ctx) { return false } else { return Bool(g.Recovery_available) @@ -103,7 +104,7 @@ func (g *GenruleExtraProperties) ExtraImageVariations(ctx android.BaseModuleCont // If not, we assume modules under proprietary paths are compatible for // BOARD_VNDK_VERSION. The other modules are regarded as AOSP, that is // PLATFORM_VNDK_VERSION. - if vndkVersion == "current" || !IsVendorProprietaryModule(ctx) { + if vndkVersion == "current" || !snapshot.IsVendorProprietaryModule(ctx) { variants = append(variants, VendorVariationPrefix+ctx.DeviceConfig().PlatformVndkVersion()) } else { variants = append(variants, VendorVariationPrefix+vndkVersion) diff --git a/cc/image.go b/cc/image.go index 15ec1c867..3a0857b21 100644 --- a/cc/image.go +++ b/cc/image.go @@ -22,6 +22,7 @@ import ( "strings" "android/soong/android" + "android/soong/snapshot" ) var _ android.ImageInterface = (*Module)(nil) @@ -496,7 +497,7 @@ func MutateImage(mctx android.BaseModuleContext, m ImageMutatableModule) { // BOARD_VNDK_VERSION. The other modules are regarded as AOSP, or // PLATFORM_VNDK_VERSION. if m.HasVendorVariant() { - if IsVendorProprietaryModule(mctx) { + if snapshot.IsVendorProprietaryModule(mctx) { vendorVariants = append(vendorVariants, boardVndkVersion) } else { vendorVariants = append(vendorVariants, platformVndkVersion) @@ -525,7 +526,7 @@ func MutateImage(mctx android.BaseModuleContext, m ImageMutatableModule) { platformVndkVersion, boardVndkVersion, ) - } else if IsVendorProprietaryModule(mctx) { + } else if snapshot.IsVendorProprietaryModule(mctx) { vendorVariants = append(vendorVariants, boardVndkVersion) } else { vendorVariants = append(vendorVariants, platformVndkVersion) @@ -582,7 +583,7 @@ func MutateImage(mctx android.BaseModuleContext, m ImageMutatableModule) { if !m.KernelHeadersDecorator() && !m.IsSnapshotPrebuilt() && usingRecoverySnapshot && - !isRecoveryProprietaryModule(mctx) { + !snapshot.IsRecoveryProprietaryModule(mctx) { recoveryVariantNeeded = false } diff --git a/cc/linkable.go b/cc/linkable.go index 6232efb95..b510508a7 100644 --- a/cc/linkable.go +++ b/cc/linkable.go @@ -3,6 +3,7 @@ package cc import ( "android/soong/android" "android/soong/bazel/cquery" + "android/soong/snapshot" "github.com/google/blueprint" ) @@ -71,15 +72,12 @@ type SantizableDependencyTagChecker func(tag blueprint.DependencyTag) bool // Snapshottable defines those functions necessary for handling module snapshots. type Snapshottable interface { + snapshot.VendorSnapshotModuleInterface + snapshot.RecoverySnapshotModuleInterface + // SnapshotHeaders returns a list of header paths provided by this module. SnapshotHeaders() android.Paths - // ExcludeFromVendorSnapshot returns true if this module should be otherwise excluded from the vendor snapshot. - ExcludeFromVendorSnapshot() bool - - // ExcludeFromRecoverySnapshot returns true if this module should be otherwise excluded from the recovery snapshot. - ExcludeFromRecoverySnapshot() bool - // SnapshotLibrary returns true if this module is a snapshot library. IsSnapshotLibrary() bool diff --git a/cc/linker.go b/cc/linker.go index a712391c2..82449a67c 100644 --- a/cc/linker.go +++ b/cc/linker.go @@ -15,9 +15,10 @@ package cc import ( + "fmt" + "android/soong/android" "android/soong/cc/config" - "fmt" "github.com/google/blueprint" "github.com/google/blueprint/proptools" @@ -244,8 +245,7 @@ func (linker *baseLinker) overrideDefaultSharedLibraries(ctx BaseModuleContext) if linker.Properties.System_shared_libs != nil && linker.Properties.Default_shared_libs != nil { ctx.PropertyErrorf("system_shared_libs", "cannot be specified if default_shared_libs is also specified") } - if ctx.toolchain().Bionic() && linker.Properties.System_shared_libs != nil { - // system_shared_libs is only honored when building against bionic. + if linker.Properties.System_shared_libs != nil { return linker.Properties.System_shared_libs } return linker.Properties.Default_shared_libs @@ -389,18 +389,6 @@ func (linker *baseLinker) linkerDeps(ctx DepsContext, deps Deps) Deps { deps.LateSharedLibs = append(deps.LateSharedLibs, deps.SystemSharedLibs...) - if ctx.Fuchsia() { - if ctx.ModuleName() != "libbioniccompat" && - ctx.ModuleName() != "libcompiler_rt-extras" && - ctx.ModuleName() != "libcompiler_rt" { - deps.StaticLibs = append(deps.StaticLibs, "libbioniccompat") - } - if ctx.ModuleName() != "libcompiler_rt" && ctx.ModuleName() != "libcompiler_rt-extras" { - deps.LateStaticLibs = append(deps.LateStaticLibs, "libcompiler_rt") - } - - } - if ctx.Windows() { deps.LateStaticLibs = append(deps.LateStaticLibs, "libwinpthread") } @@ -484,7 +472,7 @@ func (linker *baseLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags { flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.Ldflags()) } - if !ctx.toolchain().Bionic() && !ctx.Fuchsia() { + if !ctx.toolchain().Bionic() { CheckBadHostLdlibs(ctx, "host_ldlibs", linker.Properties.Host_ldlibs) flags.Local.LdFlags = append(flags.Local.LdFlags, linker.Properties.Host_ldlibs...) @@ -503,10 +491,6 @@ func (linker *baseLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags { } } - if ctx.Fuchsia() { - flags.Global.LdFlags = append(flags.Global.LdFlags, "-lfdio", "-lzircon") - } - if ctx.toolchain().LibclangRuntimeLibraryArch() != "" { flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--exclude-libs="+config.BuiltinsRuntimeLibrary(ctx.toolchain())+".a") } diff --git a/cc/makevars.go b/cc/makevars.go index 393170a81..8d7a163e3 100644 --- a/cc/makevars.go +++ b/cc/makevars.go @@ -165,7 +165,7 @@ func makeVarsProvider(ctx android.MakeVarsContext) { sort.Strings(ndkKnownLibs) ctx.Strict("NDK_KNOWN_LIBS", strings.Join(ndkKnownLibs, " ")) - hostTargets := ctx.Config().Targets[android.BuildOs] + hostTargets := ctx.Config().Targets[ctx.Config().BuildOS] makeVarsToolchain(ctx, "", hostTargets[0]) if len(hostTargets) > 1 { makeVarsToolchain(ctx, "2ND_", hostTargets[1]) diff --git a/cc/ndk_library.go b/cc/ndk_library.go index a45838063..63e8261e9 100644 --- a/cc/ndk_library.go +++ b/cc/ndk_library.go @@ -150,12 +150,6 @@ func (this *stubDecorator) stubsVersions(ctx android.BaseMutatorContext) []strin if !ctx.Module().Enabled() { return nil } - if ctx.Os() != android.Android { - // These modules are always android.DeviceEnabled only, but - // those include Fuchsia devices, which we don't support. - ctx.Module().Disable() - return nil - } if ctx.Target().NativeBridge == android.NativeBridgeEnabled { ctx.Module().Disable() return nil diff --git a/cc/prebuilt_test.go b/cc/prebuilt_test.go index fa6dd87eb..c8f8103b0 100644 --- a/cc/prebuilt_test.go +++ b/cc/prebuilt_test.go @@ -15,6 +15,7 @@ package cc import ( + "runtime" "testing" "android/soong/android" @@ -271,8 +272,8 @@ func TestPrebuiltLibrarySharedStem(t *testing.T) { } func TestPrebuiltSymlinkedHostBinary(t *testing.T) { - if android.BuildOs != android.Linux { - t.Skipf("Skipping host prebuilt testing that is only supported on %s not %s", android.Linux, android.BuildOs) + if runtime.GOOS != "linux" { + t.Skipf("Skipping host prebuilt testing that is only supported on linux not %s", runtime.GOOS) } ctx := testPrebuilt(t, ` diff --git a/cc/proto_test.go b/cc/proto_test.go index b9c89c744..abcb27304 100644 --- a/cc/proto_test.go +++ b/cc/proto_test.go @@ -51,7 +51,7 @@ func TestProto(t *testing.T) { }, }`) - buildOS := android.BuildOs.String() + buildOS := ctx.Config().BuildOS.String() proto := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Output("proto/a.pb.cc") foobar := ctx.ModuleForTests("protoc-gen-foobar", buildOS+"_x86_64") diff --git a/cc/sabi.go b/cc/sabi.go index 5fd6f5da3..e62ca6622 100644 --- a/cc/sabi.go +++ b/cc/sabi.go @@ -101,10 +101,6 @@ func classifySourceAbiDump(ctx android.BaseModuleContext) string { // Called from sabiDepsMutator to check whether ABI dumps should be created for this module. // ctx should be wrapping a native library type module. func shouldCreateSourceAbiDumpForLibrary(ctx android.BaseModuleContext) bool { - if ctx.Fuchsia() { - return false - } - // Only generate ABI dump for device modules. if !ctx.Device() { return false diff --git a/cc/sanitize.go b/cc/sanitize.go index defe8fde1..3911f48b3 100644 --- a/cc/sanitize.go +++ b/cc/sanitize.go @@ -25,6 +25,7 @@ import ( "android/soong/android" "android/soong/cc/config" + "android/soong/snapshot" ) var ( @@ -265,7 +266,6 @@ type SanitizeUserProps struct { } type SanitizeProperties struct { - // Sanitizers are not supported for Fuchsia. Sanitize SanitizeUserProps `android:"arch_variant"` SanitizerEnabled bool `blueprint:"mutated"` SanitizeDep bool `blueprint:"mutated"` @@ -305,11 +305,6 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) { s.Never = BoolPtr(true) } - // Sanitizers do not work on Fuchsia yet. - if ctx.Fuchsia() { - s.Never = BoolPtr(true) - } - // Never always wins. if Bool(s.Never) { return @@ -907,7 +902,7 @@ func (m *Module) SanitizableDepTagChecker() SantizableDependencyTagChecker { // as vendor snapshot. Such modules must create both cfi and non-cfi variants, // except for ones which explicitly disable cfi. func needsCfiForVendorSnapshot(mctx android.TopDownMutatorContext) bool { - if IsVendorProprietaryModule(mctx) { + if snapshot.IsVendorProprietaryModule(mctx) { return false } @@ -76,7 +76,7 @@ func sdkMutator(ctx android.BottomUpMutatorContext) { } ctx.AliasVariation("") } - case *snapshot: + case *snapshotModule: ctx.CreateVariations("") } } diff --git a/cc/snapshot_prebuilt.go b/cc/snapshot_prebuilt.go index 4f031ff96..9672c0fff 100644 --- a/cc/snapshot_prebuilt.go +++ b/cc/snapshot_prebuilt.go @@ -18,57 +18,17 @@ package cc // snapshot mutators and snapshot information maps which are also defined in this file. import ( - "path/filepath" "strings" "android/soong/android" + "android/soong/snapshot" "github.com/google/blueprint" ) -// Defines the specifics of different images to which the snapshot process is applicable, e.g., -// vendor, recovery, ramdisk. +// This interface overrides snapshot.SnapshotImage to implement cc module specific functions type SnapshotImage interface { - // Returns true if a snapshot should be generated for this image. - shouldGenerateSnapshot(ctx android.SingletonContext) bool - - // Function that returns true if the module is included in this image. - // Using a function return instead of a value to prevent early - // evalution of a function that may be not be defined. - inImage(m LinkableInterface) func() bool - - // Returns true if the module is private and must not be included in the - // snapshot. For example VNDK-private modules must return true for the - // vendor snapshots. But false for the recovery snapshots. - private(m LinkableInterface) bool - - // Returns true if a dir under source tree is an SoC-owned proprietary - // directory, such as device/, vendor/, etc. - // - // For a given snapshot (e.g., vendor, recovery, etc.) if - // isProprietaryPath(dir, deviceConfig) returns true, then the module in dir - // will be built from sources. - isProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool - - // Whether to include VNDK in the snapshot for this image. - includeVndk() bool - - // Whether a given module has been explicitly excluded from the - // snapshot, e.g., using the exclude_from_vendor_snapshot or - // exclude_from_recovery_snapshot properties. - excludeFromSnapshot(m LinkableInterface) bool - - // Returns true if the build is using a snapshot for this image. - isUsingSnapshot(cfg android.DeviceConfig) bool - - // Returns a version of which the snapshot should be used in this target. - // This will only be meaningful when isUsingSnapshot is true. - targetSnapshotVersion(cfg android.DeviceConfig) string - - // Whether to exclude a given module from the directed snapshot or not. - // If the makefile variable DIRECTED_{IMAGE}_SNAPSHOT is true, directed snapshot is turned on, - // and only modules listed in {IMAGE}_SNAPSHOT_MODULES will be captured. - excludeFromDirectedSnapshot(cfg android.DeviceConfig, name string) bool + snapshot.SnapshotImage // The image variant name for this snapshot image. // For example, recovery snapshot image will return "recovery", and vendor snapshot image will @@ -80,122 +40,44 @@ type SnapshotImage interface { moduleNameSuffix() string } -type vendorSnapshotImage struct{} -type recoverySnapshotImage struct{} - -type directoryMap map[string]bool - -var ( - // Modules under following directories are ignored. They are OEM's and vendor's - // proprietary modules(device/, kernel/, vendor/, and hardware/). - defaultDirectoryExcludedMap = directoryMap{ - "device": true, - "hardware": true, - "kernel": true, - "vendor": true, - } - - // Modules under following directories are included as they are in AOSP, - // although hardware/ and kernel/ are normally for vendor's own. - defaultDirectoryIncludedMap = directoryMap{ - "kernel/configs": true, - "kernel/prebuilts": true, - "kernel/tests": true, - "hardware/interfaces": true, - "hardware/libhardware": true, - "hardware/libhardware_legacy": true, - "hardware/ril": true, - } -) - -func (vendorSnapshotImage) Init(ctx android.RegistrationContext) { - ctx.RegisterSingletonType("vendor-snapshot", VendorSnapshotSingleton) - ctx.RegisterModuleType("vendor_snapshot", vendorSnapshotFactory) - ctx.RegisterModuleType("vendor_snapshot_shared", VendorSnapshotSharedFactory) - ctx.RegisterModuleType("vendor_snapshot_static", VendorSnapshotStaticFactory) - ctx.RegisterModuleType("vendor_snapshot_header", VendorSnapshotHeaderFactory) - ctx.RegisterModuleType("vendor_snapshot_binary", VendorSnapshotBinaryFactory) - ctx.RegisterModuleType("vendor_snapshot_object", VendorSnapshotObjectFactory) - - ctx.RegisterSingletonType("vendor-fake-snapshot", VendorFakeSnapshotSingleton) +type vendorSnapshotImage struct { + *snapshot.VendorSnapshotImage } -func (vendorSnapshotImage) RegisterAdditionalModule(ctx android.RegistrationContext, name string, factory android.ModuleFactory) { - ctx.RegisterModuleType(name, factory) +type recoverySnapshotImage struct { + *snapshot.RecoverySnapshotImage } -func (vendorSnapshotImage) shouldGenerateSnapshot(ctx android.SingletonContext) bool { - // BOARD_VNDK_VERSION must be set to 'current' in order to generate a snapshot. - return ctx.DeviceConfig().VndkVersion() == "current" -} - -func (vendorSnapshotImage) inImage(m LinkableInterface) func() bool { - return m.InVendor -} - -func (vendorSnapshotImage) private(m LinkableInterface) bool { - return m.IsVndkPrivate() -} - -func isDirectoryExcluded(dir string, excludedMap directoryMap, includedMap directoryMap) bool { - if dir == "." || dir == "/" { - return false - } - if includedMap[dir] { - return false - } else if excludedMap[dir] { - return true - } else if defaultDirectoryIncludedMap[dir] { - return false - } else if defaultDirectoryExcludedMap[dir] { - return true - } else { - return isDirectoryExcluded(filepath.Dir(dir), excludedMap, includedMap) - } -} - -func (vendorSnapshotImage) isProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool { - return isDirectoryExcluded(dir, deviceConfig.VendorSnapshotDirsExcludedMap(), deviceConfig.VendorSnapshotDirsIncludedMap()) -} - -// vendor snapshot includes static/header libraries with vndk: {enabled: true}. -func (vendorSnapshotImage) includeVndk() bool { - return true -} - -func (vendorSnapshotImage) excludeFromSnapshot(m LinkableInterface) bool { - return m.ExcludeFromVendorSnapshot() +func (vendorSnapshotImage) imageVariantName(cfg android.DeviceConfig) string { + return VendorVariationPrefix + cfg.VndkVersion() } -func (vendorSnapshotImage) isUsingSnapshot(cfg android.DeviceConfig) bool { - vndkVersion := cfg.VndkVersion() - return vndkVersion != "current" && vndkVersion != "" +func (vendorSnapshotImage) moduleNameSuffix() string { + return VendorSuffix } -func (vendorSnapshotImage) targetSnapshotVersion(cfg android.DeviceConfig) string { - return cfg.VndkVersion() +func (recoverySnapshotImage) imageVariantName(cfg android.DeviceConfig) string { + return android.RecoveryVariation } -// returns true iff a given module SHOULD BE EXCLUDED, false if included -func (vendorSnapshotImage) excludeFromDirectedSnapshot(cfg android.DeviceConfig, name string) bool { - // If we're using full snapshot, not directed snapshot, capture every module - if !cfg.DirectedVendorSnapshot() { - return false - } - // Else, checks if name is in VENDOR_SNAPSHOT_MODULES. - return !cfg.VendorSnapshotModules()[name] +func (recoverySnapshotImage) moduleNameSuffix() string { + return recoverySuffix } -func (vendorSnapshotImage) imageVariantName(cfg android.DeviceConfig) string { - return VendorVariationPrefix + cfg.VndkVersion() -} +// Override existing vendor and recovery snapshot for cc module specific extra functions +var VendorSnapshotImageSingleton vendorSnapshotImage = vendorSnapshotImage{&snapshot.VendorSnapshotImageSingleton} +var recoverySnapshotImageSingleton recoverySnapshotImage = recoverySnapshotImage{&snapshot.RecoverySnapshotImageSingleton} -func (vendorSnapshotImage) moduleNameSuffix() string { - return VendorSuffix +func RegisterVendorSnapshotModules(ctx android.RegistrationContext) { + ctx.RegisterModuleType("vendor_snapshot", vendorSnapshotFactory) + ctx.RegisterModuleType("vendor_snapshot_shared", VendorSnapshotSharedFactory) + ctx.RegisterModuleType("vendor_snapshot_static", VendorSnapshotStaticFactory) + ctx.RegisterModuleType("vendor_snapshot_header", VendorSnapshotHeaderFactory) + ctx.RegisterModuleType("vendor_snapshot_binary", VendorSnapshotBinaryFactory) + ctx.RegisterModuleType("vendor_snapshot_object", VendorSnapshotObjectFactory) } -func (recoverySnapshotImage) init(ctx android.RegistrationContext) { - ctx.RegisterSingletonType("recovery-snapshot", RecoverySnapshotSingleton) +func RegisterRecoverySnapshotModules(ctx android.RegistrationContext) { ctx.RegisterModuleType("recovery_snapshot", recoverySnapshotFactory) ctx.RegisterModuleType("recovery_snapshot_shared", RecoverySnapshotSharedFactory) ctx.RegisterModuleType("recovery_snapshot_static", RecoverySnapshotStaticFactory) @@ -204,66 +86,9 @@ func (recoverySnapshotImage) init(ctx android.RegistrationContext) { ctx.RegisterModuleType("recovery_snapshot_object", RecoverySnapshotObjectFactory) } -func (recoverySnapshotImage) shouldGenerateSnapshot(ctx android.SingletonContext) bool { - // RECOVERY_SNAPSHOT_VERSION must be set to 'current' in order to generate a - // snapshot. - return ctx.DeviceConfig().RecoverySnapshotVersion() == "current" -} - -func (recoverySnapshotImage) inImage(m LinkableInterface) func() bool { - return m.InRecovery -} - -// recovery snapshot does not have private libraries. -func (recoverySnapshotImage) private(m LinkableInterface) bool { - return false -} - -func (recoverySnapshotImage) isProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool { - return isDirectoryExcluded(dir, deviceConfig.RecoverySnapshotDirsExcludedMap(), deviceConfig.RecoverySnapshotDirsIncludedMap()) -} - -// recovery snapshot does NOT treat vndk specially. -func (recoverySnapshotImage) includeVndk() bool { - return false -} - -func (recoverySnapshotImage) excludeFromSnapshot(m LinkableInterface) bool { - return m.ExcludeFromRecoverySnapshot() -} - -func (recoverySnapshotImage) isUsingSnapshot(cfg android.DeviceConfig) bool { - recoverySnapshotVersion := cfg.RecoverySnapshotVersion() - return recoverySnapshotVersion != "current" && recoverySnapshotVersion != "" -} - -func (recoverySnapshotImage) targetSnapshotVersion(cfg android.DeviceConfig) string { - return cfg.RecoverySnapshotVersion() -} - -func (recoverySnapshotImage) excludeFromDirectedSnapshot(cfg android.DeviceConfig, name string) bool { - // If we're using full snapshot, not directed snapshot, capture every module - if !cfg.DirectedRecoverySnapshot() { - return false - } - // Else, checks if name is in RECOVERY_SNAPSHOT_MODULES. - return !cfg.RecoverySnapshotModules()[name] -} - -func (recoverySnapshotImage) imageVariantName(cfg android.DeviceConfig) string { - return android.RecoveryVariation -} - -func (recoverySnapshotImage) moduleNameSuffix() string { - return recoverySuffix -} - -var VendorSnapshotImageSingleton vendorSnapshotImage -var recoverySnapshotImageSingleton recoverySnapshotImage - func init() { - VendorSnapshotImageSingleton.Init(android.InitRegistrationContext) - recoverySnapshotImageSingleton.init(android.InitRegistrationContext) + RegisterVendorSnapshotModules(android.InitRegistrationContext) + RegisterRecoverySnapshotModules(android.InitRegistrationContext) android.RegisterMakeVarsProvider(pctx, snapshotMakeVarsProvider) } @@ -285,8 +110,7 @@ type SnapshotProperties struct { Binaries []string `android:"arch_variant"` Objects []string `android:"arch_variant"` } - -type snapshot struct { +type snapshotModule struct { android.ModuleBase properties SnapshotProperties @@ -296,41 +120,41 @@ type snapshot struct { image SnapshotImage } -func (s *snapshot) ImageMutatorBegin(ctx android.BaseModuleContext) { +func (s *snapshotModule) ImageMutatorBegin(ctx android.BaseModuleContext) { cfg := ctx.DeviceConfig() - if !s.image.isUsingSnapshot(cfg) || s.image.targetSnapshotVersion(cfg) != s.baseSnapshot.Version() { + if !s.image.IsUsingSnapshot(cfg) || s.image.TargetSnapshotVersion(cfg) != s.baseSnapshot.Version() { s.Disable() } } -func (s *snapshot) CoreVariantNeeded(ctx android.BaseModuleContext) bool { +func (s *snapshotModule) CoreVariantNeeded(ctx android.BaseModuleContext) bool { return false } -func (s *snapshot) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool { +func (s *snapshotModule) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool { return false } -func (s *snapshot) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { +func (s *snapshotModule) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { return false } -func (s *snapshot) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { +func (s *snapshotModule) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { return false } -func (s *snapshot) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool { +func (s *snapshotModule) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool { return false } -func (s *snapshot) ExtraImageVariations(ctx android.BaseModuleContext) []string { +func (s *snapshotModule) ExtraImageVariations(ctx android.BaseModuleContext) []string { return []string{s.image.imageVariantName(ctx.DeviceConfig())} } -func (s *snapshot) SetImageVariation(ctx android.BaseModuleContext, variation string, module android.Module) { +func (s *snapshotModule) SetImageVariation(ctx android.BaseModuleContext, variation string, module android.Module) { } -func (s *snapshot) GenerateAndroidBuildActions(ctx android.ModuleContext) { +func (s *snapshotModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { // Nothing, the snapshot module is only used to forward dependency information in DepsMutator. } @@ -342,7 +166,7 @@ func getSnapshotNameSuffix(moduleSuffix, version, arch string) string { return moduleSuffix + versionSuffix } -func (s *snapshot) DepsMutator(ctx android.BottomUpMutatorContext) { +func (s *snapshotModule) DepsMutator(ctx android.BottomUpMutatorContext) { collectSnapshotMap := func(names []string, snapshotSuffix, moduleSuffix string) map[string]string { snapshotMap := make(map[string]string) for _, name := range names { @@ -382,12 +206,12 @@ type SnapshotInfo struct { var SnapshotInfoProvider = blueprint.NewMutatorProvider(SnapshotInfo{}, "deps") -var _ android.ImageInterface = (*snapshot)(nil) +var _ android.ImageInterface = (*snapshotModule)(nil) func snapshotMakeVarsProvider(ctx android.MakeVarsContext) { snapshotSet := map[string]struct{}{} ctx.VisitAllModules(func(m android.Module) { - if s, ok := m.(*snapshot); ok { + if s, ok := m.(*snapshotModule); ok { if _, ok := snapshotSet[s.Name()]; ok { // arch variant generates duplicated modules // skip this as we only need to know the path of the module. @@ -411,13 +235,13 @@ func recoverySnapshotFactory() android.Module { } func snapshotFactory(image SnapshotImage) android.Module { - snapshot := &snapshot{} - snapshot.image = image - snapshot.AddProperties( - &snapshot.properties, - &snapshot.baseSnapshot.baseProperties) - android.InitAndroidArchModule(snapshot, android.DeviceSupported, android.MultilibBoth) - return snapshot + snapshotModule := &snapshotModule{} + snapshotModule.image = image + snapshotModule.AddProperties( + &snapshotModule.properties, + &snapshotModule.baseSnapshot.baseProperties) + android.InitAndroidArchModule(snapshotModule, android.DeviceSupported, android.MultilibBoth) + return snapshotModule } type BaseSnapshotDecoratorProperties struct { @@ -449,7 +273,7 @@ type BaseSnapshotDecoratorProperties struct { // will be seen as "libbase.vendor_static.30.arm64" by Soong. type BaseSnapshotDecorator struct { baseProperties BaseSnapshotDecoratorProperties - image SnapshotImage + Image SnapshotImage } func (p *BaseSnapshotDecorator) Name(name string) string { @@ -489,7 +313,7 @@ func (p *BaseSnapshotDecorator) SetSnapshotAndroidMkSuffix(ctx android.ModuleCon Variation: android.CoreVariation}) if ctx.OtherModuleFarDependencyVariantExists(variations, ctx.Module().(LinkableInterface).BaseModuleName()) { - p.baseProperties.Androidmk_suffix = p.image.moduleNameSuffix() + p.baseProperties.Androidmk_suffix = p.Image.moduleNameSuffix() return } @@ -498,14 +322,14 @@ func (p *BaseSnapshotDecorator) SetSnapshotAndroidMkSuffix(ctx android.ModuleCon Variation: ProductVariationPrefix + ctx.DeviceConfig().PlatformVndkVersion()}) if ctx.OtherModuleFarDependencyVariantExists(variations, ctx.Module().(LinkableInterface).BaseModuleName()) { - p.baseProperties.Androidmk_suffix = p.image.moduleNameSuffix() + p.baseProperties.Androidmk_suffix = p.Image.moduleNameSuffix() return } images := []SnapshotImage{VendorSnapshotImageSingleton, recoverySnapshotImageSingleton} for _, image := range images { - if p.image == image { + if p.Image == image { continue } variations = append(ctx.Target().Variations(), blueprint.Variation{ @@ -518,7 +342,7 @@ func (p *BaseSnapshotDecorator) SetSnapshotAndroidMkSuffix(ctx android.ModuleCon image.moduleNameSuffix()+variant, p.Version(), ctx.DeviceConfig().Arches()[0].ArchType.String())) { - p.baseProperties.Androidmk_suffix = p.image.moduleNameSuffix() + p.baseProperties.Androidmk_suffix = p.Image.moduleNameSuffix() return } } @@ -529,7 +353,7 @@ func (p *BaseSnapshotDecorator) SetSnapshotAndroidMkSuffix(ctx android.ModuleCon // Call this with a module suffix after creating a snapshot module, such as // vendorSnapshotSharedSuffix, recoverySnapshotBinarySuffix, etc. func (p *BaseSnapshotDecorator) Init(m LinkableInterface, image SnapshotImage, moduleSuffix string) { - p.image = image + p.Image = image p.baseProperties.ModuleSuffix = image.moduleNameSuffix() + moduleSuffix m.AddProperties(&p.baseProperties) android.AddLoadHook(m, func(ctx android.LoadHookContext) { diff --git a/cc/snapshot_utils.go b/cc/snapshot_utils.go index b0538bea0..24abcce55 100644 --- a/cc/snapshot_utils.go +++ b/cc/snapshot_utils.go @@ -114,7 +114,7 @@ func ShouldCollectHeadersForSnapshot(ctx android.ModuleContext, m LinkableInterf } for _, image := range []SnapshotImage{VendorSnapshotImageSingleton, recoverySnapshotImageSingleton} { - if isSnapshotAware(ctx.DeviceConfig(), m, image.isProprietaryPath(ctx.ModuleDir(), ctx.DeviceConfig()), apexInfo, image) { + if isSnapshotAware(ctx.DeviceConfig(), m, image.IsProprietaryPath(ctx.ModuleDir(), ctx.DeviceConfig()), apexInfo, image) { return true } } @@ -15,8 +15,9 @@ package cc import ( - "android/soong/android" "fmt" + + "android/soong/android" ) func getNdkStlFamily(m LinkableInterface) string { @@ -92,26 +93,6 @@ func (stl *stl) begin(ctx BaseModuleContext) { ctx.ModuleErrorf("stl: %q is not a supported STL for windows", s) return "" } - } else if ctx.Fuchsia() { - switch s { - case "c++_static": - return "libc++_static" - case "c++_shared": - return "libc++" - case "libc++", "libc++_static": - return s - case "none": - return "" - case "": - if ctx.static() { - return "libc++_static" - } else { - return "libc++" - } - default: - ctx.ModuleErrorf("stl: %q is not a supported STL on Fuchsia", s) - return "" - } } else { switch s { case "libc++", "libc++_static": diff --git a/cc/testing.go b/cc/testing.go index b9d84f6cb..19513e357 100644 --- a/cc/testing.go +++ b/cc/testing.go @@ -20,6 +20,7 @@ import ( "android/soong/android" "android/soong/genrule" + "android/soong/snapshot" ) func RegisterRequiredBuildComponentsForTest(ctx android.RegistrationContext) { @@ -44,9 +45,6 @@ func GatherRequiredDepsForTest(oses ...android.OsType) string { supportLinuxBionic := false for _, os := range oses { - if os == android.Fuchsia { - ret += withFuchsiaModules() - } if os == android.Windows { ret += withWindowsModules() } @@ -471,19 +469,6 @@ func withWindowsModules() string { ` } -func withFuchsiaModules() string { - return ` - cc_library { - name: "libbioniccompat", - stl: "none", - } - cc_library { - name: "libcompiler_rt", - stl: "none", - } - ` -} - func withLinuxBionic() string { return ` cc_binary { @@ -625,21 +610,15 @@ var PrepareForTestOnLinuxBionic = android.GroupFixturePreparers( android.FixtureOverrideTextFile(linuxBionicDefaultsPath, withLinuxBionic()), ) -// The preparer to include if running a cc related test for fuchsia. -var PrepareForTestOnFuchsia = android.GroupFixturePreparers( - // Place the default cc test modules for fuschia in a location that will not conflict with default - // test modules defined by other packages. - android.FixtureAddTextFile("defaults/cc/fuschia/Android.bp", withFuchsiaModules()), - android.PrepareForTestSetDeviceToFuchsia, -) - // This adds some additional modules and singletons which might negatively impact the performance // of tests so they are not included in the PrepareForIntegrationTestWithCc. var PrepareForTestWithCcIncludeVndk = android.GroupFixturePreparers( PrepareForIntegrationTestWithCc, android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) { - VendorSnapshotImageSingleton.Init(ctx) - recoverySnapshotImageSingleton.init(ctx) + snapshot.VendorSnapshotImageSingleton.Init(ctx) + snapshot.RecoverySnapshotImageSingleton.Init(ctx) + RegisterVendorSnapshotModules(ctx) + RegisterRecoverySnapshotModules(ctx) ctx.RegisterSingletonType("vndk-snapshot", VndkSnapshotSingleton) }), ) @@ -663,14 +642,7 @@ func TestConfig(buildDir string, os android.OsType, env map[string]string, mockFS[k] = v } - var config android.Config - if os == android.Fuchsia { - panic("Fuchsia not supported use test fixture instead") - } else { - config = android.TestArchConfig(buildDir, env, bp, mockFS) - } - - return config + return android.TestArchConfig(buildDir, env, bp, mockFS) } // CreateTestContext is the legacy way of creating a TestContext for testing cc modules. @@ -687,8 +659,10 @@ func CreateTestContext(config android.Config) *android.TestContext { ctx.RegisterModuleType("filegroup", android.FileGroupFactory) ctx.RegisterModuleType("vndk_prebuilt_shared", VndkPrebuiltSharedFactory) - VendorSnapshotImageSingleton.Init(ctx) - recoverySnapshotImageSingleton.init(ctx) + snapshot.VendorSnapshotImageSingleton.Init(ctx) + snapshot.RecoverySnapshotImageSingleton.Init(ctx) + RegisterVendorSnapshotModules(ctx) + RegisterRecoverySnapshotModules(ctx) ctx.RegisterSingletonType("vndk-snapshot", VndkSnapshotSingleton) RegisterVndkLibraryTxtTypes(ctx) diff --git a/cc/util.go b/cc/util.go index 1220d8432..9bba87676 100644 --- a/cc/util.go +++ b/cc/util.go @@ -21,6 +21,7 @@ import ( "strings" "android/soong/android" + "android/soong/snapshot" ) // Efficiently converts a list of include directories to a single string @@ -126,20 +127,6 @@ func makeSymlinkCmd(linkDirOnDevice string, linkName string, target string) stri "ln -sf " + target + " " + filepath.Join(dir, linkName) } -func copyFileRule(ctx android.SingletonContext, path android.Path, out string) android.OutputPath { - outPath := android.PathForOutput(ctx, out) - ctx.Build(pctx, android.BuildParams{ - Rule: android.Cp, - Input: path, - Output: outPath, - Description: "copy " + path.String() + " -> " + out, - Args: map[string]string{ - "cpFlags": "-f -L", - }, - }) - return outPath -} - func combineNoticesRule(ctx android.SingletonContext, paths android.Paths, out string) android.OutputPath { outPath := android.PathForOutput(ctx, out) ctx.Build(pctx, android.BuildParams{ @@ -151,12 +138,6 @@ func combineNoticesRule(ctx android.SingletonContext, paths android.Paths, out s return outPath } -func writeStringToFileRule(ctx android.SingletonContext, content, out string) android.OutputPath { - outPath := android.PathForOutput(ctx, out) - android.WriteFileRule(ctx, outPath, content) - return outPath -} - // Dump a map to a list file as: // // {key1} {value1} @@ -172,5 +153,5 @@ func installMapListFileRule(ctx android.SingletonContext, m map[string]string, p txtBuilder.WriteString(" ") txtBuilder.WriteString(m[k]) } - return writeStringToFileRule(ctx, txtBuilder.String(), path) + return snapshot.WriteStringToFileRule(ctx, txtBuilder.String(), path) } diff --git a/cc/vendor_snapshot.go b/cc/vendor_snapshot.go index 003b7c98b..ba4d79fcf 100644 --- a/cc/vendor_snapshot.go +++ b/cc/vendor_snapshot.go @@ -13,141 +13,46 @@ // limitations under the License. package cc -// This file contains singletons to capture vendor and recovery snapshot. They consist of prebuilt -// modules under AOSP so older vendor and recovery can be built with a newer system in a single -// source tree. - import ( "encoding/json" "path/filepath" - "sort" "strings" "android/soong/android" + "android/soong/snapshot" ) -var vendorSnapshotSingleton = snapshotSingleton{ - "vendor", - "SOONG_VENDOR_SNAPSHOT_ZIP", - android.OptionalPath{}, - true, - VendorSnapshotImageSingleton, - false, /* fake */ -} - -var vendorFakeSnapshotSingleton = snapshotSingleton{ - "vendor", - "SOONG_VENDOR_FAKE_SNAPSHOT_ZIP", - android.OptionalPath{}, - true, - VendorSnapshotImageSingleton, - true, /* fake */ -} - -var recoverySnapshotSingleton = snapshotSingleton{ - "recovery", - "SOONG_RECOVERY_SNAPSHOT_ZIP", - android.OptionalPath{}, - false, - recoverySnapshotImageSingleton, - false, /* fake */ -} - -func VendorSnapshotSingleton() android.Singleton { - return &vendorSnapshotSingleton -} - -func VendorFakeSnapshotSingleton() android.Singleton { - return &vendorFakeSnapshotSingleton -} - -func RecoverySnapshotSingleton() android.Singleton { - return &recoverySnapshotSingleton -} - -type snapshotSingleton struct { - // Name, e.g., "vendor", "recovery", "ramdisk". - name string - - // Make variable that points to the snapshot file, e.g., - // "SOONG_RECOVERY_SNAPSHOT_ZIP". - makeVar string - - // Path to the snapshot zip file. - snapshotZipFile android.OptionalPath +// This file defines how to capture cc modules into snapshot package. - // Whether the image supports VNDK extension modules. - supportsVndkExt bool - - // Implementation of the image interface specific to the image - // associated with this snapshot (e.g., specific to the vendor image, - // recovery image, etc.). - image SnapshotImage - - // Whether this singleton is for fake snapshot or not. - // Fake snapshot is a snapshot whose prebuilt binaries and headers are empty. - // It is much faster to generate, and can be used to inspect dependencies. - fake bool -} - -// Determine if a dir under source tree is an SoC-owned proprietary directory based -// on vendor snapshot configuration -// Examples: device/, vendor/ -func isVendorProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool { - return VendorSnapshotSingleton().(*snapshotSingleton).image.isProprietaryPath(dir, deviceConfig) -} - -// Determine if a dir under source tree is an SoC-owned proprietary directory based -// on recovery snapshot configuration -// Examples: device/, vendor/ -func isRecoveryProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool { - return RecoverySnapshotSingleton().(*snapshotSingleton).image.isProprietaryPath(dir, deviceConfig) -} - -func IsVendorProprietaryModule(ctx android.BaseModuleContext) bool { - // Any module in a vendor proprietary path is a vendor proprietary - // module. - if isVendorProprietaryPath(ctx.ModuleDir(), ctx.DeviceConfig()) { +// Checks if the target image would contain VNDK +func includeVndk(image snapshot.SnapshotImage) bool { + if image.ImageName() == snapshot.VendorSnapshotImageName { return true } - // However if the module is not in a vendor proprietary path, it may - // still be a vendor proprietary module. This happens for cc modules - // that are excluded from the vendor snapshot, and it means that the - // vendor has assumed control of the framework-provided module. - if c, ok := ctx.Module().(LinkableInterface); ok { - if c.ExcludeFromVendorSnapshot() { - return true - } - } - return false } -func isRecoveryProprietaryModule(ctx android.BaseModuleContext) bool { - - // Any module in a recovery proprietary path is a recovery proprietary - // module. - if isRecoveryProprietaryPath(ctx.ModuleDir(), ctx.DeviceConfig()) { +// Check if the module is VNDK private +func isPrivate(image snapshot.SnapshotImage, m LinkableInterface) bool { + if image.ImageName() == snapshot.VendorSnapshotImageName && m.IsVndkPrivate() { return true } - // However if the module is not in a recovery proprietary path, it may - // still be a recovery proprietary module. This happens for cc modules - // that are excluded from the recovery snapshot, and it means that the - // vendor has assumed control of the framework-provided module. + return false +} - if c, ok := ctx.Module().(LinkableInterface); ok { - if c.ExcludeFromRecoverySnapshot() { - return true - } +// Checks if target image supports VNDK Ext +func supportsVndkExt(image snapshot.SnapshotImage) bool { + if image.ImageName() == snapshot.VendorSnapshotImageName { + return true } return false } // Determines if the module is a candidate for snapshot. -func isSnapshotAware(cfg android.DeviceConfig, m LinkableInterface, inProprietaryPath bool, apexInfo android.ApexInfo, image SnapshotImage) bool { +func isSnapshotAware(cfg android.DeviceConfig, m LinkableInterface, inProprietaryPath bool, apexInfo android.ApexInfo, image snapshot.SnapshotImage) bool { if !m.Enabled() || m.HiddenFromMake() { return false } @@ -158,12 +63,12 @@ func isSnapshotAware(cfg android.DeviceConfig, m LinkableInterface, inProprietar } // skip proprietary modules, but (for the vendor snapshot only) // include all VNDK (static) - if inProprietaryPath && (!image.includeVndk() || !m.IsVndk()) { + if inProprietaryPath && (!includeVndk(image) || !m.IsVndk()) { return false } // If the module would be included based on its path, check to see if // the module is marked to be excluded. If so, skip it. - if image.excludeFromSnapshot(m) { + if image.ExcludeFromSnapshot(m) { return false } if m.Target().Os.Class != android.Device { @@ -173,7 +78,7 @@ func isSnapshotAware(cfg android.DeviceConfig, m LinkableInterface, inProprietar return false } // the module must be installed in target image - if !apexInfo.IsForPlatform() || m.IsSnapshotPrebuilt() || !image.inImage(m)() { + if !apexInfo.IsForPlatform() || m.IsSnapshotPrebuilt() || !image.InImage(m)() { return false } // skip kernel_headers which always depend on vendor @@ -203,13 +108,13 @@ func isSnapshotAware(cfg android.DeviceConfig, m LinkableInterface, inProprietar } } if sanitizable.Static() { - return sanitizable.OutputFile().Valid() && !image.private(m) + return sanitizable.OutputFile().Valid() && !isPrivate(image, m) } if sanitizable.Shared() || sanitizable.Rlib() { if !sanitizable.OutputFile().Valid() { return false } - if image.includeVndk() { + if includeVndk(image) { if !sanitizable.IsVndk() { return true } @@ -256,15 +161,9 @@ type snapshotJsonFlags struct { VintfFragments []string `json:",omitempty"` } -func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) { - if !c.image.shouldGenerateSnapshot(ctx) { - return - } - - var snapshotOutputs android.Paths - +var ccSnapshotAction snapshot.GenerateSnapshotAction = func(s snapshot.SnapshotSingleton, ctx android.SingletonContext, snapshotArchDir string) android.Paths { /* - Vendor snapshot zipped artifacts directory structure: + Vendor snapshot zipped artifacts directory structure for cc modules: {SNAPSHOT_ARCH}/ arch-{TARGET_ARCH}-{TARGET_ARCH_VARIANT}/ shared/ @@ -296,13 +195,7 @@ func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) { (header files of same directory structure with source tree) */ - snapshotDir := c.name + "-snapshot" - if c.fake { - // If this is a fake snapshot singleton, place all files under fake/ subdirectory to avoid - // collision with real snapshot files - snapshotDir = filepath.Join("fake", snapshotDir) - } - snapshotArchDir := filepath.Join(snapshotDir, ctx.DeviceConfig().DeviceArch()) + var snapshotOutputs android.Paths includeDir := filepath.Join(snapshotArchDir, "include") configsDir := filepath.Join(snapshotArchDir, "configs") @@ -317,9 +210,9 @@ func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) { if fake { // All prebuilt binaries and headers are installed by copyFile function. This makes a fake // snapshot just touch prebuilts and headers, rather than installing real files. - return writeStringToFileRule(ctx, "", out) + return snapshot.WriteStringToFileRule(ctx, "", out) } else { - return copyFileRule(ctx, path, out) + return snapshot.CopyFileRule(pctx, ctx, path, out) } } @@ -337,7 +230,7 @@ func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) { // Common properties among snapshots. prop.ModuleName = ctx.ModuleName(m) - if c.supportsVndkExt && m.IsVndkExt() { + if supportsVndkExt(s.Image) && m.IsVndkExt() { // vndk exts are installed to /vendor/lib(64)?/vndk(-sp)? if m.IsVndkSp() { prop.RelativeInstallPath = "vndk-sp" @@ -457,7 +350,7 @@ func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) { ctx.Errorf("json marshal to %q failed: %#v", propOut, err) return nil } - ret = append(ret, writeStringToFileRule(ctx, string(j), propOut)) + ret = append(ret, snapshot.WriteStringToFileRule(ctx, string(j), propOut)) return ret } @@ -469,10 +362,10 @@ func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) { } moduleDir := ctx.ModuleDir(module) - inProprietaryPath := c.image.isProprietaryPath(moduleDir, ctx.DeviceConfig()) + inProprietaryPath := s.Image.IsProprietaryPath(moduleDir, ctx.DeviceConfig()) apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo) - if c.image.excludeFromSnapshot(m) { + if s.Image.ExcludeFromSnapshot(m) { if inProprietaryPath { // Error: exclude_from_vendor_snapshot applies // to framework-path modules only. @@ -481,7 +374,7 @@ func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) { } } - if !isSnapshotAware(ctx.DeviceConfig(), m, inProprietaryPath, apexInfo, c.image) { + if !isSnapshotAware(ctx.DeviceConfig(), m, inProprietaryPath, apexInfo, s.Image) { return } @@ -489,8 +382,8 @@ func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) { // list, we will still include the module as if it was a fake module. // The reason is that soong needs all the dependencies to be present, even // if they are not using during the build. - installAsFake := c.fake - if c.image.excludeFromDirectedSnapshot(ctx.DeviceConfig(), m.BaseModuleName()) { + installAsFake := s.Fake + if s.Image.ExcludeFromDirectedSnapshot(ctx.DeviceConfig(), m.BaseModuleName()) { installAsFake = true } @@ -514,47 +407,12 @@ func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) { // install all headers after removing duplicates for _, header := range android.FirstUniquePaths(headers) { - snapshotOutputs = append(snapshotOutputs, copyFile(ctx, header, filepath.Join(includeDir, header.String()), c.fake)) + snapshotOutputs = append(snapshotOutputs, copyFile(ctx, header, filepath.Join(includeDir, header.String()), s.Fake)) } - // All artifacts are ready. Sort them to normalize ninja and then zip. - sort.Slice(snapshotOutputs, func(i, j int) bool { - return snapshotOutputs[i].String() < snapshotOutputs[j].String() - }) - - zipPath := android.PathForOutput( - ctx, - snapshotDir, - c.name+"-"+ctx.Config().DeviceName()+".zip") - zipRule := android.NewRuleBuilder(pctx, ctx) - - // filenames in rspfile from FlagWithRspFileInputList might be single-quoted. Remove it with tr - snapshotOutputList := android.PathForOutput( - ctx, - snapshotDir, - c.name+"-"+ctx.Config().DeviceName()+"_list") - rspFile := snapshotOutputList.ReplaceExtension(ctx, "rsp") - zipRule.Command(). - Text("tr"). - FlagWithArg("-d ", "\\'"). - FlagWithRspFileInputList("< ", rspFile, snapshotOutputs). - FlagWithOutput("> ", snapshotOutputList) - - zipRule.Temporary(snapshotOutputList) - - zipRule.Command(). - BuiltTool("soong_zip"). - FlagWithOutput("-o ", zipPath). - FlagWithArg("-C ", android.PathForOutput(ctx, snapshotDir).String()). - FlagWithInput("-l ", snapshotOutputList) - - zipRule.Build(zipPath.String(), c.name+" snapshot "+zipPath.String()) - zipRule.DeleteTemporaryFiles() - c.snapshotZipFile = android.OptionalPathForPath(zipPath) + return snapshotOutputs } -func (c *snapshotSingleton) MakeVars(ctx android.MakeVarsContext) { - ctx.Strict( - c.makeVar, - c.snapshotZipFile.String()) +func init() { + snapshot.RegisterSnapshotAction(ccSnapshotAction) } diff --git a/cc/vndk.go b/cc/vndk.go index 499d4282c..1ae79de05 100644 --- a/cc/vndk.go +++ b/cc/vndk.go @@ -25,6 +25,7 @@ import ( "android/soong/android" "android/soong/cc/config" "android/soong/etc" + "android/soong/snapshot" "github.com/google/blueprint" ) @@ -698,7 +699,7 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex libPath := m.outputFile.Path() snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, "shared", vndkType, libPath.Base()) - ret = append(ret, copyFileRule(ctx, libPath, snapshotLibOut)) + ret = append(ret, snapshot.CopyFileRule(pctx, ctx, libPath, snapshotLibOut)) if ctx.Config().VndkSnapshotBuildArtifacts() { prop := struct { @@ -720,7 +721,7 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex ctx.Errorf("json marshal to %q failed: %#v", propOut, err) return nil, false } - ret = append(ret, writeStringToFileRule(ctx, string(j), propOut)) + ret = append(ret, snapshot.WriteStringToFileRule(ctx, string(j), propOut)) } return ret, true } @@ -778,8 +779,8 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex // install all headers after removing duplicates for _, header := range android.FirstUniquePaths(headers) { - snapshotOutputs = append(snapshotOutputs, copyFileRule( - ctx, header, filepath.Join(includeDir, header.String()))) + snapshotOutputs = append(snapshotOutputs, snapshot.CopyFileRule( + pctx, ctx, header, filepath.Join(includeDir, header.String()))) } // install *.libraries.txt except vndkcorevariant.libraries.txt @@ -788,8 +789,8 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex if !ok || !m.Enabled() || m.Name() == vndkUsingCoreVariantLibrariesTxt { return } - snapshotOutputs = append(snapshotOutputs, copyFileRule( - ctx, m.OutputFile(), filepath.Join(configsDir, m.Name()))) + snapshotOutputs = append(snapshotOutputs, snapshot.CopyFileRule( + pctx, ctx, m.OutputFile(), filepath.Join(configsDir, m.Name()))) }) /* diff --git a/etc/Android.bp b/etc/Android.bp index cab7389b6..06a2fa15d 100644 --- a/etc/Android.bp +++ b/etc/Android.bp @@ -9,6 +9,7 @@ bootstrap_go_package { "blueprint", "soong", "soong-android", + "soong-snapshot", ], srcs: [ "prebuilt_etc.go", diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go index 4dd383d77..4107916a7 100644 --- a/etc/prebuilt_etc.go +++ b/etc/prebuilt_etc.go @@ -28,12 +28,15 @@ package etc // various `prebuilt_*` mutators. import ( + "encoding/json" "fmt" + "path/filepath" "strings" "github.com/google/blueprint/proptools" "android/soong/android" + "android/soong/snapshot" ) var pctx = android.NewPackageContext("android/soong/etc") @@ -43,6 +46,7 @@ var pctx = android.NewPackageContext("android/soong/etc") func init() { pctx.Import("android/soong/android") RegisterPrebuiltEtcBuildComponents(android.InitRegistrationContext) + snapshot.RegisterSnapshotAction(generatePrebuiltSnapshot) } func RegisterPrebuiltEtcBuildComponents(ctx android.RegistrationContext) { @@ -128,6 +132,9 @@ type PrebuiltEtc struct { android.ModuleBase android.DefaultableModuleBase + snapshot.VendorSnapshotModuleInterface + snapshot.RecoverySnapshotModuleInterface + properties prebuiltEtcProperties subdirProperties prebuiltSubdirProperties @@ -183,7 +190,7 @@ func (p *PrebuiltEtc) InstallInDebugRamdisk() bool { return p.inDebugRamdisk() } -func (p *PrebuiltEtc) inRecovery() bool { +func (p *PrebuiltEtc) InRecovery() bool { return p.ModuleBase.InRecovery() || p.ModuleBase.InstallInRecovery() } @@ -192,7 +199,7 @@ func (p *PrebuiltEtc) onlyInRecovery() bool { } func (p *PrebuiltEtc) InstallInRecovery() bool { - return p.inRecovery() + return p.InRecovery() } var _ android.ImageInterface = (*PrebuiltEtc)(nil) @@ -271,6 +278,18 @@ func (p *PrebuiltEtc) Installable() bool { return p.properties.Installable == nil || proptools.Bool(p.properties.Installable) } +func (p *PrebuiltEtc) InVendor() bool { + return p.ModuleBase.InstallInVendor() +} + +func (p *PrebuiltEtc) ExcludeFromVendorSnapshot() bool { + return false +} + +func (p *PrebuiltEtc) ExcludeFromRecoverySnapshot() bool { + return false +} + func (p *PrebuiltEtc) GenerateAndroidBuildActions(ctx android.ModuleContext) { if p.properties.Src == nil { ctx.PropertyErrorf("src", "missing prebuilt source file") @@ -344,7 +363,7 @@ func (p *PrebuiltEtc) AndroidMkEntries() []android.AndroidMkEntries { if p.inDebugRamdisk() && !p.onlyInDebugRamdisk() { nameSuffix = ".debug_ramdisk" } - if p.inRecovery() && !p.onlyInRecovery() { + if p.InRecovery() && !p.onlyInRecovery() { nameSuffix = ".recovery" } return []android.AndroidMkEntries{android.AndroidMkEntries{ @@ -494,3 +513,137 @@ func PrebuiltRFSAFactory() android.Module { android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst) return module } + +// Flags to be included in the snapshot +type snapshotJsonFlags struct { + ModuleName string `json:",omitempty"` + Filename string `json:",omitempty"` + RelativeInstallPath string `json:",omitempty"` +} + +// Copy file into the snapshot +func copyFile(ctx android.SingletonContext, path android.Path, out string, fake bool) android.OutputPath { + if fake { + // Create empty file instead for the fake snapshot + return snapshot.WriteStringToFileRule(ctx, "", out) + } else { + return snapshot.CopyFileRule(pctx, ctx, path, out) + } +} + +// Check if the module is target of the snapshot +func isSnapshotAware(ctx android.SingletonContext, m *PrebuiltEtc, image snapshot.SnapshotImage) bool { + if !m.Enabled() { + return false + } + + // Skip if the module is not included in the image + if !image.InImage(m)() { + return false + } + + // When android/prebuilt.go selects between source and prebuilt, it sets + // HideFromMake on the other one to avoid duplicate install rules in make. + if m.IsHideFromMake() { + return false + } + + // There are some prebuilt_etc module with multiple definition of same name. + // Check if the target would be included from the build + if !m.ExportedToMake() { + return false + } + + // Skip if the module is in the predefined path list to skip + if image.IsProprietaryPath(ctx.ModuleDir(m), ctx.DeviceConfig()) { + return false + } + + // Skip if the module should be excluded + if image.ExcludeFromSnapshot(m) || image.ExcludeFromDirectedSnapshot(ctx.DeviceConfig(), m.BaseModuleName()) { + return false + } + + // Skip from other exceptional cases + if m.Target().Os.Class != android.Device { + return false + } + if m.Target().NativeBridge == android.NativeBridgeEnabled { + return false + } + + return true +} + +func generatePrebuiltSnapshot(s snapshot.SnapshotSingleton, ctx android.SingletonContext, snapshotArchDir string) android.Paths { + /* + Snapshot zipped artifacts directory structure for etc modules: + {SNAPSHOT_ARCH}/ + arch-{TARGET_ARCH}-{TARGET_ARCH_VARIANT}/ + etc/ + (prebuilt etc files) + arch-{TARGET_2ND_ARCH}-{TARGET_2ND_ARCH_VARIANT}/ + etc/ + (prebuilt etc files) + NOTICE_FILES/ + (notice files) + */ + var snapshotOutputs android.Paths + noticeDir := filepath.Join(snapshotArchDir, "NOTICE_FILES") + installedNotices := make(map[string]bool) + + ctx.VisitAllModules(func(module android.Module) { + m, ok := module.(*PrebuiltEtc) + if !ok { + return + } + + if !isSnapshotAware(ctx, m, s.Image) { + return + } + + targetArch := "arch-" + m.Target().Arch.ArchType.String() + + snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, "etc", m.BaseModuleName()) + snapshotOutputs = append(snapshotOutputs, copyFile(ctx, m.OutputFile(), snapshotLibOut, s.Fake)) + + prop := snapshotJsonFlags{} + propOut := snapshotLibOut + ".json" + prop.ModuleName = m.BaseModuleName() + if m.subdirProperties.Relative_install_path != nil { + prop.RelativeInstallPath = *m.subdirProperties.Relative_install_path + } + + if m.properties.Filename != nil { + prop.Filename = *m.properties.Filename + } + + j, err := json.Marshal(prop) + if err != nil { + ctx.Errorf("json marshal to %q failed: %#v", propOut, err) + return + } + snapshotOutputs = append(snapshotOutputs, snapshot.WriteStringToFileRule(ctx, string(j), propOut)) + + if len(m.EffectiveLicenseFiles()) > 0 { + noticeName := ctx.ModuleName(m) + ".txt" + noticeOut := filepath.Join(noticeDir, noticeName) + // skip already copied notice file + if !installedNotices[noticeOut] { + installedNotices[noticeOut] = true + + noticeOutPath := android.PathForOutput(ctx, noticeOut) + ctx.Build(pctx, android.BuildParams{ + Rule: android.Cat, + Inputs: m.EffectiveLicenseFiles(), + Output: noticeOutPath, + Description: "combine notices for " + noticeOut, + }) + snapshotOutputs = append(snapshotOutputs, noticeOutPath) + } + } + + }) + + return snapshotOutputs +} diff --git a/etc/prebuilt_etc_test.go b/etc/prebuilt_etc_test.go index 354f6bb6e..cf1f6d717 100644 --- a/etc/prebuilt_etc_test.go +++ b/etc/prebuilt_etc_test.go @@ -15,11 +15,15 @@ package etc import ( + "fmt" "os" "path/filepath" "testing" + "github.com/google/blueprint/proptools" + "android/soong/android" + "android/soong/snapshot" ) func TestMain(m *testing.M) { @@ -36,6 +40,18 @@ var prepareForPrebuiltEtcTest = android.GroupFixturePreparers( }), ) +var prepareForPrebuiltEtcSnapshotTest = android.GroupFixturePreparers( + prepareForPrebuiltEtcTest, + android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) { + snapshot.VendorSnapshotImageSingleton.Init(ctx) + snapshot.RecoverySnapshotImageSingleton.Init(ctx) + }), + android.FixtureModifyConfig(func(config android.Config) { + config.TestProductVariables.DeviceVndkVersion = proptools.StringPtr("current") + config.TestProductVariables.RecoverySnapshotVersion = proptools.StringPtr("current") + }), +) + func TestPrebuiltEtcVariants(t *testing.T) { result := prepareForPrebuiltEtcTest.RunTestWithBp(t, ` prebuilt_etc { @@ -172,7 +188,7 @@ func TestPrebuiltEtcHost(t *testing.T) { } `) - buildOS := android.BuildOs.String() + buildOS := result.Config.BuildOS.String() p := result.Module("foo.conf", buildOS+"_common").(*PrebuiltEtc) if !p.Host() { t.Errorf("host bit is not set for a prebuilt_etc_host module.") @@ -226,7 +242,7 @@ func TestPrebuiltUserShareHostInstallDirPath(t *testing.T) { } `) - buildOS := android.BuildOs.String() + buildOS := result.Config.BuildOS.String() p := result.Module("foo.conf", buildOS+"_common").(*PrebuiltEtc) expected := filepath.Join("out/soong/host", result.Config.PrebuiltOS(), "usr", "share", "bar") android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPath) @@ -346,3 +362,110 @@ func TestPrebuiltRFSADirPath(t *testing.T) { }) } } + +func checkIfSnapshotTaken(t *testing.T, result *android.TestResult, image string, moduleName string) { + checkIfSnapshotExistAsExpected(t, result, image, moduleName, true) +} + +func checkIfSnapshotNotTaken(t *testing.T, result *android.TestResult, image string, moduleName string) { + checkIfSnapshotExistAsExpected(t, result, image, moduleName, false) +} + +func checkIfSnapshotExistAsExpected(t *testing.T, result *android.TestResult, image string, moduleName string, expectToExist bool) { + snapshotSingleton := result.SingletonForTests(image + "-snapshot") + archType := "arm64" + archVariant := "armv8-a" + archDir := fmt.Sprintf("arch-%s", archType) + + snapshotDir := fmt.Sprintf("%s-snapshot", image) + snapshotVariantPath := filepath.Join(snapshotDir, archType) + outputDir := filepath.Join(snapshotVariantPath, archDir, "etc") + imageVariant := "" + if image == "recovery" { + imageVariant = "recovery_" + } + mod := result.ModuleForTests(moduleName, fmt.Sprintf("android_%s%s_%s", imageVariant, archType, archVariant)) + outputFiles := mod.OutputFiles(t, "") + if len(outputFiles) != 1 { + t.Errorf("%q must have single output\n", moduleName) + return + } + snapshotPath := filepath.Join(outputDir, moduleName) + + if expectToExist { + out := snapshotSingleton.Output(snapshotPath) + + if out.Input.String() != outputFiles[0].String() { + t.Errorf("The input of snapshot %q must be %q, but %q", "prebuilt_vendor", out.Input.String(), outputFiles[0]) + } + + snapshotJsonPath := snapshotPath + ".json" + + if snapshotSingleton.MaybeOutput(snapshotJsonPath).Rule == nil { + t.Errorf("%q expected but not found", snapshotJsonPath) + } + } else { + out := snapshotSingleton.MaybeOutput(snapshotPath) + if out.Rule != nil { + t.Errorf("There must be no rule for module %q output file %q", moduleName, outputFiles[0]) + } + } +} + +func TestPrebuiltTakeSnapshot(t *testing.T) { + var testBp = ` + prebuilt_etc { + name: "prebuilt_vendor", + src: "foo.conf", + vendor: true, + } + + prebuilt_etc { + name: "prebuilt_vendor_indirect", + src: "foo.conf", + vendor: true, + } + + prebuilt_etc { + name: "prebuilt_recovery", + src: "bar.conf", + recovery: true, + } + + prebuilt_etc { + name: "prebuilt_recovery_indirect", + src: "bar.conf", + recovery: true, + } + ` + + t.Run("prebuilt: vendor and recovery snapshot", func(t *testing.T) { + result := prepareForPrebuiltEtcSnapshotTest.RunTestWithBp(t, testBp) + + checkIfSnapshotTaken(t, result, "vendor", "prebuilt_vendor") + checkIfSnapshotTaken(t, result, "vendor", "prebuilt_vendor_indirect") + checkIfSnapshotTaken(t, result, "recovery", "prebuilt_recovery") + checkIfSnapshotTaken(t, result, "recovery", "prebuilt_recovery_indirect") + }) + + t.Run("prebuilt: directed snapshot", func(t *testing.T) { + prepareForPrebuiltEtcDirectedSnapshotTest := android.GroupFixturePreparers( + prepareForPrebuiltEtcSnapshotTest, + android.FixtureModifyConfig(func(config android.Config) { + config.TestProductVariables.DirectedVendorSnapshot = true + config.TestProductVariables.VendorSnapshotModules = make(map[string]bool) + config.TestProductVariables.VendorSnapshotModules["prebuilt_vendor"] = true + config.TestProductVariables.DirectedRecoverySnapshot = true + config.TestProductVariables.RecoverySnapshotModules = make(map[string]bool) + config.TestProductVariables.RecoverySnapshotModules["prebuilt_recovery"] = true + }), + ) + + result := prepareForPrebuiltEtcDirectedSnapshotTest.RunTestWithBp(t, testBp) + + checkIfSnapshotTaken(t, result, "vendor", "prebuilt_vendor") + checkIfSnapshotNotTaken(t, result, "vendor", "prebuilt_vendor_indirect") + checkIfSnapshotTaken(t, result, "recovery", "prebuilt_recovery") + checkIfSnapshotNotTaken(t, result, "recovery", "prebuilt_recovery_indirect") + }) +} diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go index dff9543e4..2c78d7362 100644 --- a/java/dexpreopt_bootjars.go +++ b/java/dexpreopt_bootjars.go @@ -523,14 +523,14 @@ func buildBootImageVariantsForAndroidOs(ctx android.ModuleContext, image *bootIm } // buildBootImageVariantsForBuildOs generates rules to build the boot image variants for the -// android.BuildOs OsType, i.e. the type of OS on which the build is being running. +// config.BuildOS OsType, i.e. the type of OS on which the build is being running. // // The files need to be generated into their predefined location because they are used from there // both within Soong and outside, e.g. for ART based host side testing and also for use by some // cloud based tools. However, they are not needed by callers of this function and so the paths do // not need to be returned from this func, unlike the buildBootImageVariantsForAndroidOs func. func buildBootImageVariantsForBuildOs(ctx android.ModuleContext, image *bootImageConfig, profile android.WritablePath) { - buildBootImageForOsType(ctx, image, profile, android.BuildOs) + buildBootImageForOsType(ctx, image, profile, ctx.Config().BuildOS) } // buildBootImageForOsType takes a bootImageConfig, a profile file and an android.OsType diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go index b13955fba..1507aaf00 100644 --- a/java/dexpreopt_config.go +++ b/java/dexpreopt_config.go @@ -32,7 +32,7 @@ func dexpreoptTargets(ctx android.PathContext) []android.Target { } } // We may also need the images on host in order to run host-based tests. - for _, target := range ctx.Config().Targets[android.BuildOs] { + for _, target := range ctx.Config().Targets[ctx.Config().BuildOS] { targets = append(targets, target) } diff --git a/java/dexpreopt_test.go b/java/dexpreopt_test.go index b25deceac..8dc7b798a 100644 --- a/java/dexpreopt_test.go +++ b/java/dexpreopt_test.go @@ -16,6 +16,7 @@ package java import ( "fmt" + "runtime" "testing" "android/soong/android" @@ -173,9 +174,9 @@ func enabledString(enabled bool) string { } func TestDex2oatToolDeps(t *testing.T) { - if android.BuildOs != android.Linux { + if runtime.GOOS != "linux" { // The host binary paths checked below are build OS dependent. - t.Skipf("Unsupported build OS %s", android.BuildOs) + t.Skipf("Unsupported build OS %s", runtime.GOOS) } preparers := android.GroupFixturePreparers( diff --git a/java/java_test.go b/java/java_test.go index 0f9965d03..b6780c20c 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -441,7 +441,7 @@ func TestBinary(t *testing.T) { } `) - buildOS := android.BuildOs.String() + buildOS := ctx.Config().BuildOS.String() bar := ctx.ModuleForTests("bar", buildOS+"_common") barJar := bar.Output("bar.jar").Output.String() @@ -478,7 +478,7 @@ func TestTest(t *testing.T) { } `) - buildOS := android.BuildOs.String() + buildOS := ctx.Config().BuildOS.String() foo := ctx.ModuleForTests("foo", buildOS+"_common").Module().(*TestHost) @@ -523,7 +523,7 @@ func TestHostBinaryNoJavaDebugInfoOverride(t *testing.T) { } // check that -g is not overridden for host modules - buildOS := android.BuildOs.String() + buildOS := result.Config.BuildOS.String() hostBinary := result.ModuleForTests("host_binary", buildOS+"_common") hostJavaFlags := hostBinary.Module().VariablesForTests()["javacFlags"] if strings.Contains(hostJavaFlags, "-g:source,lines") { @@ -1371,7 +1371,7 @@ func TestDataNativeBinaries(t *testing.T) { } `) - buildOS := android.BuildOs.String() + buildOS := ctx.Config().BuildOS.String() test := ctx.ModuleForTests("foo", buildOS+"_common").Module().(*TestHost) entries := android.AndroidMkEntriesForTest(t, ctx, test)[0] @@ -1387,7 +1387,7 @@ func TestDefaultInstallable(t *testing.T) { } `) - buildOS := android.BuildOs.String() + buildOS := ctx.Config().BuildOS.String() module := ctx.ModuleForTests("foo", buildOS+"_common").Module().(*TestHost) assertDeepEquals(t, "Default installable value should be true.", proptools.BoolPtr(true), module.properties.Installable) diff --git a/java/kotlin_test.go b/java/kotlin_test.go index fd2f3ca61..db3069693 100644 --- a/java/kotlin_test.go +++ b/java/kotlin_test.go @@ -15,10 +15,11 @@ package java import ( - "android/soong/android" "strconv" "strings" "testing" + + "android/soong/android" ) func TestKotlin(t *testing.T) { @@ -114,7 +115,7 @@ func TestKapt(t *testing.T) { t.Run("", func(t *testing.T) { ctx, _ := testJava(t, bp) - buildOS := android.BuildOs.String() + buildOS := ctx.Config().BuildOS.String() kapt := ctx.ModuleForTests("foo", "android_common").Rule("kapt") kotlinc := ctx.ModuleForTests("foo", "android_common").Rule("kotlinc") @@ -182,7 +183,7 @@ func TestKapt(t *testing.T) { android.FixtureMergeEnv(env), ).RunTestWithBp(t, bp) - buildOS := android.BuildOs.String() + buildOS := result.Config.BuildOS.String() kapt := result.ModuleForTests("foo", "android_common").Rule("kapt") javac := result.ModuleForTests("foo", "android_common").Description("javac") diff --git a/java/plugin_test.go b/java/plugin_test.go index c7913d3db..dc29b1c3e 100644 --- a/java/plugin_test.go +++ b/java/plugin_test.go @@ -15,7 +15,6 @@ package java import ( - "android/soong/android" "testing" ) @@ -58,7 +57,7 @@ func TestPlugin(t *testing.T) { } `) - buildOS := android.BuildOs.String() + buildOS := ctx.Config().BuildOS.String() javac := ctx.ModuleForTests("foo", "android_common").Rule("javac") turbine := ctx.ModuleForTests("foo", "android_common").MaybeRule("turbine") @@ -98,7 +97,7 @@ func TestPluginGeneratesApi(t *testing.T) { } `) - buildOS := android.BuildOs.String() + buildOS := ctx.Config().BuildOS.String() javac := ctx.ModuleForTests("foo", "android_common").Rule("javac") turbine := ctx.ModuleForTests("foo", "android_common").MaybeRule("turbine") diff --git a/java/robolectric.go b/java/robolectric.go index a37a118f6..a0c9c7fcd 100644 --- a/java/robolectric.go +++ b/java/robolectric.go @@ -83,6 +83,9 @@ type robolectricTest struct { testConfig android.Path data android.Paths + + forceOSType android.OsType + forceArchType android.ArchType } func (r *robolectricTest) TestSuites() []string { @@ -115,6 +118,9 @@ func (r *robolectricTest) DepsMutator(ctx android.BottomUpMutatorContext) { } func (r *robolectricTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { + r.forceOSType = ctx.Config().BuildOS + r.forceArchType = ctx.Config().BuildArch + r.testConfig = tradefed.AutoGenRobolectricTestConfig(ctx, r.testProperties.Test_config, r.testProperties.Test_config_template, r.testProperties.Test_suites, r.testProperties.Auto_gen_config) @@ -345,7 +351,7 @@ func RobolectricTestFactory() android.Module { func (r *robolectricTest) InstallBypassMake() bool { return true } func (r *robolectricTest) InstallInTestcases() bool { return true } func (r *robolectricTest) InstallForceOS() (*android.OsType, *android.ArchType) { - return &android.BuildOs, &android.BuildArch + return &r.forceOSType, &r.forceArchType } func robolectricRuntimesFactory() android.Module { @@ -366,6 +372,9 @@ type robolectricRuntimes struct { props robolectricRuntimesProperties runtimes []android.InstallPath + + forceOSType android.OsType + forceArchType android.ArchType } func (r *robolectricRuntimes) TestSuites() []string { @@ -385,6 +394,9 @@ func (r *robolectricRuntimes) GenerateAndroidBuildActions(ctx android.ModuleCont return } + r.forceOSType = ctx.Config().BuildOS + r.forceArchType = ctx.Config().BuildArch + files := android.PathsForModuleSrc(ctx, r.props.Jars) androidAllDir := android.PathForModuleInstall(ctx, "android-all") @@ -417,5 +429,5 @@ func (r *robolectricRuntimes) GenerateAndroidBuildActions(ctx android.ModuleCont func (r *robolectricRuntimes) InstallBypassMake() bool { return true } func (r *robolectricRuntimes) InstallInTestcases() bool { return true } func (r *robolectricRuntimes) InstallForceOS() (*android.OsType, *android.ArchType) { - return &android.BuildOs, &android.BuildArch + return &r.forceOSType, &r.forceArchType } diff --git a/java/sdk_test.go b/java/sdk_test.go index bb595a54e..6d6213011 100644 --- a/java/sdk_test.go +++ b/java/sdk_test.go @@ -255,9 +255,11 @@ func TestClasspath(t *testing.T) { ` + testcase.properties + ` }` - variant := "android_common" - if testcase.host == android.Host { - variant = android.BuildOs.String() + "_common" + variant := func(result *android.TestResult) string { + if testcase.host == android.Host { + return result.Config.BuildOS.String() + "_common" + } + return "android_common" } convertModulesToPaths := func(cp []string) []string { @@ -312,7 +314,7 @@ func TestClasspath(t *testing.T) { } checkClasspath := func(t *testing.T, result *android.TestResult, isJava8 bool) { - foo := result.ModuleForTests("foo", variant) + foo := result.ModuleForTests("foo", variant(result)) javac := foo.Rule("javac") var deps []string @@ -376,7 +378,7 @@ func TestClasspath(t *testing.T) { checkClasspath(t, result, true /* isJava8 */) if testcase.host != android.Host { - aidl := result.ModuleForTests("foo", variant).Rule("aidl") + aidl := result.ModuleForTests("foo", variant(result)).Rule("aidl") android.AssertStringDoesContain(t, "aidl command", aidl.RuleParams.Command, testcase.aidl+" -I.") } @@ -389,7 +391,7 @@ func TestClasspath(t *testing.T) { checkClasspath(t, result, false /* isJava8 */) if testcase.host != android.Host { - aidl := result.ModuleForTests("foo", variant).Rule("aidl") + aidl := result.ModuleForTests("foo", variant(result)).Rule("aidl") android.AssertStringDoesContain(t, "aidl command", aidl.RuleParams.Command, testcase.aidl+" -I.") } diff --git a/rust/Android.bp b/rust/Android.bp index 11069d143..221014e5c 100644 --- a/rust/Android.bp +++ b/rust/Android.bp @@ -11,6 +11,7 @@ bootstrap_go_package { "soong-bloaty", "soong-cc", "soong-rust-config", + "soong-snapshot", ], srcs: [ "androidmk.go", diff --git a/rust/binary_test.go b/rust/binary_test.go index 86f50d3e4..968c0c1ff 100644 --- a/rust/binary_test.go +++ b/rust/binary_test.go @@ -114,6 +114,23 @@ func TestBinaryFlags(t *testing.T) { } } +// Test that the bootstrap property sets the appropriate linker +func TestBootstrap(t *testing.T) { + ctx := testRust(t, ` + rust_binary { + name: "foo", + srcs: ["foo.rs"], + bootstrap: true, + }`) + + foo := ctx.ModuleForTests("foo", "android_arm64_armv8-a").Rule("rustc") + + flag := "-Wl,-dynamic-linker,/system/bin/bootstrap/linker64" + if !strings.Contains(foo.Args["linkFlags"], flag) { + t.Errorf("missing link flag to use bootstrap linker, expecting %#v, linkFlags: %#v", flag, foo.Args["linkFlags"]) + } +} + func TestStaticBinaryFlags(t *testing.T) { ctx := testRust(t, ` rust_binary { diff --git a/rust/builder.go b/rust/builder.go index 6db508d64..523428db2 100644 --- a/rust/builder.go +++ b/rust/builder.go @@ -220,6 +220,15 @@ func transformSrctoCrate(ctx ModuleContext, main android.Path, deps PathDeps, fl linkFlags = append(linkFlags, flags.GlobalLinkFlags...) linkFlags = append(linkFlags, flags.LinkFlags...) + // Check if this module needs to use the bootstrap linker + if ctx.RustModule().Bootstrap() && !ctx.RustModule().InRecovery() && !ctx.RustModule().InRamdisk() && !ctx.RustModule().InVendorRamdisk() { + dynamicLinker := "-Wl,-dynamic-linker,/system/bin/bootstrap/linker" + if ctx.toolchain().Is64Bit() { + dynamicLinker += "64" + } + linkFlags = append(linkFlags, dynamicLinker) + } + libFlags := makeLibFlags(deps) // Collect dependencies diff --git a/rust/compiler.go b/rust/compiler.go index 0b28135ae..df77759d6 100644 --- a/rust/compiler.go +++ b/rust/compiler.go @@ -305,7 +305,7 @@ func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps { if !Bool(compiler.Properties.No_stdlibs) { for _, stdlib := range config.Stdlibs { // If we're building for the primary arch of the build host, use the compiler's stdlibs - if ctx.Target().Os == android.BuildOs { + if ctx.Target().Os == ctx.Config().BuildOS { stdlib = stdlib + "_" + ctx.toolchain().RustTriple() } deps.Stdlibs = append(deps.Stdlibs, stdlib) diff --git a/rust/config/allowed_list.go b/rust/config/allowed_list.go index 31ec3f12c..f568f276d 100644 --- a/rust/config/allowed_list.go +++ b/rust/config/allowed_list.go @@ -6,6 +6,7 @@ var ( // for an example. // TODO(b/160223496): enable rustfmt globally. RustAllowedPaths = []string{ + "bionic/libc", "device/google/cuttlefish", "external/adhd", "external/crosvm", diff --git a/rust/library.go b/rust/library.go index 5a36bd13f..8c10e298b 100644 --- a/rust/library.go +++ b/rust/library.go @@ -21,6 +21,7 @@ import ( "android/soong/android" "android/soong/cc" + "android/soong/snapshot" ) var ( @@ -645,7 +646,7 @@ func LibraryMutator(mctx android.BottomUpMutatorContext) { variation := v.(*Module).ModuleBase.ImageVariation().Variation if strings.HasPrefix(variation, cc.VendorVariationPrefix) && m.HasVendorVariant() && - !cc.IsVendorProprietaryModule(mctx) && + !snapshot.IsVendorProprietaryModule(mctx) && strings.TrimPrefix(variation, cc.VendorVariationPrefix) == mctx.DeviceConfig().VndkVersion() { // cc.MutateImage runs before LibraryMutator, so vendor variations which are meant for rlibs only are diff --git a/rust/project_json_test.go b/rust/project_json_test.go index 09d30dbde..bdd54c59b 100644 --- a/rust/project_json_test.go +++ b/rust/project_json_test.go @@ -176,6 +176,8 @@ func TestProjectJsonBinary(t *testing.T) { } func TestProjectJsonBindGen(t *testing.T) { + buildOS := android.TestConfig(t.TempDir(), nil, "", nil).BuildOS + bp := ` rust_library { name: "libd", @@ -214,9 +216,9 @@ func TestProjectJsonBindGen(t *testing.T) { if strings.Contains(rootModule, "libbindings1") && !strings.Contains(rootModule, "android_arm64") { t.Errorf("The source path for libbindings1 does not contain android_arm64, got %v", rootModule) } - if strings.Contains(rootModule, "libbindings2") && !strings.Contains(rootModule, android.BuildOs.String()) { + if strings.Contains(rootModule, "libbindings2") && !strings.Contains(rootModule, buildOS.String()) { t.Errorf("The source path for libbindings2 does not contain the BuildOs, got %v; want %v", - rootModule, android.BuildOs.String()) + rootModule, buildOS.String()) } // Check that libbindings1 does not depend on itself. if strings.Contains(rootModule, "libbindings1") { diff --git a/rust/rust.go b/rust/rust.go index 52b409435..931cb9dde 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -85,6 +85,10 @@ type BaseProperties struct { VendorRamdiskVariantNeeded bool `blueprint:"mutated"` ExtraVariants []string `blueprint:"mutated"` + // Allows this module to use non-APEX version of libraries. Useful + // for building binaries that are started before APEXes are activated. + Bootstrap *bool + // Used by vendor snapshot to record dependencies from snapshot modules. SnapshotSharedLibs []string `blueprint:"mutated"` SnapshotStaticLibs []string `blueprint:"mutated"` @@ -288,7 +292,7 @@ func (mod *Module) UseVndk() bool { } func (mod *Module) Bootstrap() bool { - return false + return Bool(mod.Properties.Bootstrap) } func (mod *Module) MustUseVendorVariant() bool { diff --git a/rust/snapshot_prebuilt.go b/rust/snapshot_prebuilt.go index 2f549738c..79eaab382 100644 --- a/rust/snapshot_prebuilt.go +++ b/rust/snapshot_prebuilt.go @@ -17,6 +17,7 @@ package rust import ( "android/soong/android" "android/soong/cc" + "github.com/google/blueprint/proptools" ) diff --git a/scripts/manifest_check.py b/scripts/manifest_check.py index 8168fbf6a..4ef4399ca 100755 --- a/scripts/manifest_check.py +++ b/scripts/manifest_check.py @@ -90,6 +90,15 @@ def enforce_uses_libraries(manifest, required, optional, relax, is_apk, path): else: manifest_required, manifest_optional, tags = extract_uses_libs_xml(manifest) + # Trim namespace component. Normally Soong does that automatically when it + # handles module names specified in Android.bp properties. However not all + # <uses-library> entries in the manifest correspond to real modules: some of + # the optional libraries may be missing at build time. Therefor this script + # accepts raw module names as spelled in Android.bp/Amdroid.mk and trims the + # optional namespace part manually. + required = trim_namespace_parts(required) + optional = trim_namespace_parts(optional) + if manifest_required == required and manifest_optional == optional: return None @@ -118,6 +127,17 @@ def enforce_uses_libraries(manifest, required, optional, relax, is_apk, path): return errmsg +MODULE_NAMESPACE = re.compile("^//[^:]+:") + +def trim_namespace_parts(modules): + """Trim the namespace part of each module, if present. Leave only the name.""" + + trimmed = [] + for module in modules: + trimmed.append(MODULE_NAMESPACE.sub('', module)) + return trimmed + + def extract_uses_libs_apk(badging): """Extract <uses-library> tags from the manifest of an APK.""" diff --git a/scripts/manifest_check_test.py b/scripts/manifest_check_test.py index 7159bdd74..e3e8ac468 100755 --- a/scripts/manifest_check_test.py +++ b/scripts/manifest_check_test.py @@ -183,6 +183,15 @@ class EnforceUsesLibrariesTest(unittest.TestCase): optional_uses_libraries=['bar']) self.assertTrue(matches) + def test_mixed_with_namespace(self): + xml = self.xml_tmpl % ('\n'.join([uses_library_xml('foo'), + uses_library_xml('bar', required_xml(False))])) + apk = self.apk_tmpl % ('\n'.join([uses_library_apk('foo'), + uses_library_apk('bar', required_apk(False))])) + matches = self.run_test(xml, apk, uses_libraries=['//x/y/z:foo'], + optional_uses_libraries=['//x/y/z:bar']) + self.assertTrue(matches) + class ExtractTargetSdkVersionTest(unittest.TestCase): def run_test(self, xml, apk, version): diff --git a/sdk/sdk_test.go b/sdk/sdk_test.go index 97fb2485f..85e3d875e 100644 --- a/sdk/sdk_test.go +++ b/sdk/sdk_test.go @@ -15,19 +15,21 @@ package sdk import ( - "android/soong/android" "log" "os" + "runtime" "testing" + "android/soong/android" + "github.com/google/blueprint/proptools" ) // Needed in an _test.go file in this package to ensure tests run correctly, particularly in IDE. func TestMain(m *testing.M) { - if android.BuildOs != android.Linux { + if runtime.GOOS != "linux" { // b/145598135 - Generating host snapshots for anything other than linux is not supported. - log.Printf("Skipping as sdk snapshot generation is only supported on %s not %s", android.Linux, android.BuildOs) + log.Printf("Skipping as sdk snapshot generation is only supported on linux not %s", runtime.GOOS) os.Exit(0) } diff --git a/sdk/update.go b/sdk/update.go index 3ec1bfaf4..1cd8f135a 100644 --- a/sdk/update.go +++ b/sdk/update.go @@ -22,6 +22,7 @@ import ( "android/soong/apex" "android/soong/cc" + "github.com/google/blueprint" "github.com/google/blueprint/proptools" @@ -1774,7 +1775,7 @@ func (s *sdk) getPossibleOsTypes() []android.OsType { var osTypes []android.OsType for _, osType := range android.OsTypeList() { if s.DeviceSupported() { - if osType.Class == android.Device && osType != android.Fuchsia { + if osType.Class == android.Device { osTypes = append(osTypes, osType) } } diff --git a/sh/sh_binary_test.go b/sh/sh_binary_test.go index 20317d88c..865d5f3d1 100644 --- a/sh/sh_binary_test.go +++ b/sh/sh_binary_test.go @@ -115,7 +115,7 @@ func TestShTest_dataModules(t *testing.T) { } `) - buildOS := android.BuildOs.String() + buildOS := config.BuildOS.String() arches := []string{"android_arm64_armv8-a", buildOS + "_x86_64"} for _, arch := range arches { variant := ctx.ModuleForTests("foo", arch) @@ -155,7 +155,7 @@ func TestShTestHost(t *testing.T) { } `) - buildOS := android.BuildOs.String() + buildOS := ctx.Config().BuildOS.String() mod := ctx.ModuleForTests("foo", buildOS+"_x86_64").Module().(*ShTest) if !mod.Host() { t.Errorf("host bit is not set for a sh_test_host module.") @@ -192,7 +192,7 @@ func TestShTestHost_dataDeviceModules(t *testing.T) { } `) - buildOS := android.BuildOs.String() + buildOS := config.BuildOS.String() variant := ctx.ModuleForTests("foo", buildOS+"_x86_64") relocated := variant.Output("relocated/lib64/libbar.so") diff --git a/snapshot/Android.bp b/snapshot/Android.bp new file mode 100644 index 000000000..f17ac532a --- /dev/null +++ b/snapshot/Android.bp @@ -0,0 +1,22 @@ +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +bootstrap_go_package { + name: "soong-snapshot", + pkgPath: "android/soong/snapshot", + deps: [ + "blueprint", + "blueprint-pathtools", + "soong", + "soong-android", + ], + srcs: [ + "recovery_snapshot.go", + "snapshot.go", + "snapshot_base.go", + "util.go", + "vendor_snapshot.go", + ], + pluginFor: ["soong_build"], +} diff --git a/snapshot/recovery_snapshot.go b/snapshot/recovery_snapshot.go new file mode 100644 index 000000000..9b3919c34 --- /dev/null +++ b/snapshot/recovery_snapshot.go @@ -0,0 +1,130 @@ +// Copyright 2021 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package snapshot + +import "android/soong/android" + +// Interface for modules which can be captured in the recovery snapshot. +type RecoverySnapshotModuleInterface interface { + SnapshotModuleInterfaceBase + InRecovery() bool + ExcludeFromRecoverySnapshot() bool +} + +var recoverySnapshotSingleton = SnapshotSingleton{ + "recovery", // name + "SOONG_RECOVERY_SNAPSHOT_ZIP", // makeVar + android.OptionalPath{}, // snapshotZipFile + RecoverySnapshotImageSingleton, // Image + false, // Fake +} + +func RecoverySnapshotSingleton() android.Singleton { + return &recoverySnapshotSingleton +} + +// Determine if a dir under source tree is an SoC-owned proprietary directory based +// on recovery snapshot configuration +// Examples: device/, vendor/ +func isRecoveryProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool { + return RecoverySnapshotSingleton().(*SnapshotSingleton).Image.IsProprietaryPath(dir, deviceConfig) +} + +func IsRecoveryProprietaryModule(ctx android.BaseModuleContext) bool { + + // Any module in a recovery proprietary path is a recovery proprietary + // module. + if isRecoveryProprietaryPath(ctx.ModuleDir(), ctx.DeviceConfig()) { + return true + } + + // However if the module is not in a recovery proprietary path, it may + // still be a recovery proprietary module. This happens for cc modules + // that are excluded from the recovery snapshot, and it means that the + // vendor has assumed control of the framework-provided module. + + if c, ok := ctx.Module().(RecoverySnapshotModuleInterface); ok { + if c.ExcludeFromRecoverySnapshot() { + return true + } + } + + return false +} + +var RecoverySnapshotImageName = "recovery" + +type RecoverySnapshotImage struct{} + +func (RecoverySnapshotImage) Init(ctx android.RegistrationContext) { + ctx.RegisterSingletonType("recovery-snapshot", RecoverySnapshotSingleton) +} + +func (RecoverySnapshotImage) shouldGenerateSnapshot(ctx android.SingletonContext) bool { + // RECOVERY_SNAPSHOT_VERSION must be set to 'current' in order to generate a + // snapshot. + return ctx.DeviceConfig().RecoverySnapshotVersion() == "current" +} + +func (RecoverySnapshotImage) InImage(m SnapshotModuleInterfaceBase) func() bool { + r, ok := m.(RecoverySnapshotModuleInterface) + + if !ok { + // This module does not support recovery snapshot + return func() bool { return false } + } + return r.InRecovery +} + +func (RecoverySnapshotImage) IsProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool { + return isDirectoryExcluded(dir, deviceConfig.RecoverySnapshotDirsExcludedMap(), deviceConfig.RecoverySnapshotDirsIncludedMap()) +} + +func (RecoverySnapshotImage) ExcludeFromSnapshot(m SnapshotModuleInterfaceBase) bool { + r, ok := m.(RecoverySnapshotModuleInterface) + + if !ok { + // This module does not support recovery snapshot + return true + } + return r.ExcludeFromRecoverySnapshot() +} + +func (RecoverySnapshotImage) IsUsingSnapshot(cfg android.DeviceConfig) bool { + recoverySnapshotVersion := cfg.RecoverySnapshotVersion() + return recoverySnapshotVersion != "current" && recoverySnapshotVersion != "" +} + +func (RecoverySnapshotImage) TargetSnapshotVersion(cfg android.DeviceConfig) string { + return cfg.RecoverySnapshotVersion() +} + +func (RecoverySnapshotImage) ExcludeFromDirectedSnapshot(cfg android.DeviceConfig, name string) bool { + // If we're using full snapshot, not directed snapshot, capture every module + if !cfg.DirectedRecoverySnapshot() { + return false + } + // Else, checks if name is in RECOVERY_SNAPSHOT_MODULES. + return !cfg.RecoverySnapshotModules()[name] +} + +func (RecoverySnapshotImage) ImageName() string { + return RecoverySnapshotImageName +} + +var RecoverySnapshotImageSingleton RecoverySnapshotImage + +func init() { + RecoverySnapshotImageSingleton.Init(android.InitRegistrationContext) +} diff --git a/snapshot/snapshot.go b/snapshot/snapshot.go new file mode 100644 index 000000000..294f8b611 --- /dev/null +++ b/snapshot/snapshot.go @@ -0,0 +1,122 @@ +// Copyright 2021 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package snapshot + +import ( + "path/filepath" + "sort" + + "android/soong/android" +) + +// This file contains singletons to capture snapshots. This singleton will generate snapshot of each target +// image, and capturing snapshot module will be delegated to each module which implements GenerateSnapshotAction +// function and register with RegisterSnapshotAction. + +var pctx = android.NewPackageContext("android/soong/snapshot") + +type SnapshotSingleton struct { + // Name, e.g., "vendor", "recovery", "ramdisk". + name string + + // Make variable that points to the snapshot file, e.g., + // "SOONG_RECOVERY_SNAPSHOT_ZIP". + makeVar string + + // Path to the snapshot zip file. + snapshotZipFile android.OptionalPath + + // Implementation of the image interface specific to the image + // associated with this snapshot (e.g., specific to the vendor image, + // recovery image, etc.). + Image SnapshotImage + + // Whether this singleton is for fake snapshot or not. + // Fake snapshot is a snapshot whose prebuilt binaries and headers are empty. + // It is much faster to generate, and can be used to inspect dependencies. + Fake bool +} + +// Interface of function to capture snapshot from each module +type GenerateSnapshotAction func(snapshot SnapshotSingleton, ctx android.SingletonContext, snapshotArchDir string) android.Paths + +var snapshotActionList []GenerateSnapshotAction + +// Register GenerateSnapshotAction function so it can be called while generating snapshot +func RegisterSnapshotAction(x GenerateSnapshotAction) { + snapshotActionList = append(snapshotActionList, x) +} + +func (c *SnapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) { + if !c.Image.shouldGenerateSnapshot(ctx) { + return + } + + var snapshotOutputs android.Paths + + // Snapshot zipped artifacts will be captured under {SNAPSHOT_ARCH} directory + + snapshotDir := c.name + "-snapshot" + if c.Fake { + // If this is a fake snapshot singleton, place all files under fake/ subdirectory to avoid + // collision with real snapshot files + snapshotDir = filepath.Join("fake", snapshotDir) + } + snapshotArchDir := filepath.Join(snapshotDir, ctx.DeviceConfig().DeviceArch()) + + for _, f := range snapshotActionList { + snapshotOutputs = append(snapshotOutputs, f(*c, ctx, snapshotArchDir)...) + } + + // All artifacts are ready. Sort them to normalize ninja and then zip. + sort.Slice(snapshotOutputs, func(i, j int) bool { + return snapshotOutputs[i].String() < snapshotOutputs[j].String() + }) + + zipPath := android.PathForOutput( + ctx, + snapshotDir, + c.name+"-"+ctx.Config().DeviceName()+".zip") + zipRule := android.NewRuleBuilder(pctx, ctx) + + // filenames in rspfile from FlagWithRspFileInputList might be single-quoted. Remove it with tr + snapshotOutputList := android.PathForOutput( + ctx, + snapshotDir, + c.name+"-"+ctx.Config().DeviceName()+"_list") + rspFile := snapshotOutputList.ReplaceExtension(ctx, "rsp") + zipRule.Command(). + Text("tr"). + FlagWithArg("-d ", "\\'"). + FlagWithRspFileInputList("< ", rspFile, snapshotOutputs). + FlagWithOutput("> ", snapshotOutputList) + + zipRule.Temporary(snapshotOutputList) + + zipRule.Command(). + BuiltTool("soong_zip"). + FlagWithOutput("-o ", zipPath). + FlagWithArg("-C ", android.PathForOutput(ctx, snapshotDir).String()). + FlagWithInput("-l ", snapshotOutputList) + + zipRule.Build(zipPath.String(), c.name+" snapshot "+zipPath.String()) + zipRule.DeleteTemporaryFiles() + c.snapshotZipFile = android.OptionalPathForPath(zipPath) +} + +func (c *SnapshotSingleton) MakeVars(ctx android.MakeVarsContext) { + ctx.Strict( + c.makeVar, + c.snapshotZipFile.String()) +} diff --git a/snapshot/snapshot_base.go b/snapshot/snapshot_base.go new file mode 100644 index 000000000..de93f3eb0 --- /dev/null +++ b/snapshot/snapshot_base.go @@ -0,0 +1,104 @@ +// Copyright 2021 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package snapshot + +import ( + "android/soong/android" + "path/filepath" +) + +// Interface for modules which can be captured in the snapshot. +type SnapshotModuleInterfaceBase interface{} + +// Defines the specifics of different images to which the snapshot process is applicable, e.g., +// vendor, recovery, ramdisk. +type SnapshotImage interface { + // Returns true if a snapshot should be generated for this image. + shouldGenerateSnapshot(ctx android.SingletonContext) bool + + // Function that returns true if the module is included in this image. + // Using a function return instead of a value to prevent early + // evalution of a function that may be not be defined. + InImage(m SnapshotModuleInterfaceBase) func() bool + + // Returns true if a dir under source tree is an SoC-owned proprietary + // directory, such as device/, vendor/, etc. + // + // For a given snapshot (e.g., vendor, recovery, etc.) if + // isProprietaryPath(dir, deviceConfig) returns true, then the module in dir + // will be built from sources. + IsProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool + + // Whether a given module has been explicitly excluded from the + // snapshot, e.g., using the exclude_from_vendor_snapshot or + // exclude_from_recovery_snapshot properties. + ExcludeFromSnapshot(m SnapshotModuleInterfaceBase) bool + + // Returns true if the build is using a snapshot for this image. + IsUsingSnapshot(cfg android.DeviceConfig) bool + + // Returns a version of which the snapshot should be used in this target. + // This will only be meaningful when isUsingSnapshot is true. + TargetSnapshotVersion(cfg android.DeviceConfig) string + + // Whether to exclude a given module from the directed snapshot or not. + // If the makefile variable DIRECTED_{IMAGE}_SNAPSHOT is true, directed snapshot is turned on, + // and only modules listed in {IMAGE}_SNAPSHOT_MODULES will be captured. + ExcludeFromDirectedSnapshot(cfg android.DeviceConfig, name string) bool + + // Returns target image name + ImageName() string +} + +type directoryMap map[string]bool + +var ( + // Modules under following directories are ignored. They are OEM's and vendor's + // proprietary modules(device/, kernel/, vendor/, and hardware/). + defaultDirectoryExcludedMap = directoryMap{ + "device": true, + "hardware": true, + "kernel": true, + "vendor": true, + } + + // Modules under following directories are included as they are in AOSP, + // although hardware/ and kernel/ are normally for vendor's own. + defaultDirectoryIncludedMap = directoryMap{ + "kernel/configs": true, + "kernel/prebuilts": true, + "kernel/tests": true, + "hardware/interfaces": true, + "hardware/libhardware": true, + "hardware/libhardware_legacy": true, + "hardware/ril": true, + } +) + +func isDirectoryExcluded(dir string, excludedMap directoryMap, includedMap directoryMap) bool { + if dir == "." || dir == "/" { + return false + } + if includedMap[dir] { + return false + } else if excludedMap[dir] { + return true + } else if defaultDirectoryIncludedMap[dir] { + return false + } else if defaultDirectoryExcludedMap[dir] { + return true + } else { + return isDirectoryExcluded(filepath.Dir(dir), excludedMap, includedMap) + } +} diff --git a/snapshot/util.go b/snapshot/util.go new file mode 100644 index 000000000..2297dfc2b --- /dev/null +++ b/snapshot/util.go @@ -0,0 +1,36 @@ +// Copyright 2021 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package snapshot + +import "android/soong/android" + +func WriteStringToFileRule(ctx android.SingletonContext, content, out string) android.OutputPath { + outPath := android.PathForOutput(ctx, out) + android.WriteFileRule(ctx, outPath, content) + return outPath +} + +func CopyFileRule(pctx android.PackageContext, ctx android.SingletonContext, path android.Path, out string) android.OutputPath { + outPath := android.PathForOutput(ctx, out) + ctx.Build(pctx, android.BuildParams{ + Rule: android.Cp, + Input: path, + Output: outPath, + Description: "copy " + path.String() + " -> " + out, + Args: map[string]string{ + "cpFlags": "-f -L", + }, + }) + return outPath +} diff --git a/snapshot/vendor_snapshot.go b/snapshot/vendor_snapshot.go new file mode 100644 index 000000000..9bd26c201 --- /dev/null +++ b/snapshot/vendor_snapshot.go @@ -0,0 +1,147 @@ +// Copyright 2021 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package snapshot + +import "android/soong/android" + +// Interface for modules which can be captured in the vendor snapshot. +type VendorSnapshotModuleInterface interface { + SnapshotModuleInterfaceBase + InVendor() bool + ExcludeFromVendorSnapshot() bool +} + +var vendorSnapshotSingleton = SnapshotSingleton{ + "vendor", // name + "SOONG_VENDOR_SNAPSHOT_ZIP", // makeVar + android.OptionalPath{}, // snapshotZipFile + VendorSnapshotImageSingleton, // Image + false, // Fake +} + +var vendorFakeSnapshotSingleton = SnapshotSingleton{ + "vendor", // name + "SOONG_VENDOR_FAKE_SNAPSHOT_ZIP", // makeVar + android.OptionalPath{}, // snapshotZipFile + VendorSnapshotImageSingleton, // Image + true, // Fake +} + +func VendorSnapshotSingleton() android.Singleton { + return &vendorSnapshotSingleton +} + +func VendorFakeSnapshotSingleton() android.Singleton { + return &vendorFakeSnapshotSingleton +} + +// Determine if a dir under source tree is an SoC-owned proprietary directory based +// on vendor snapshot configuration +// Examples: device/, vendor/ +func isVendorProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool { + return VendorSnapshotSingleton().(*SnapshotSingleton).Image.IsProprietaryPath(dir, deviceConfig) +} + +func IsVendorProprietaryModule(ctx android.BaseModuleContext) bool { + // Any module in a vendor proprietary path is a vendor proprietary + // module. + if isVendorProprietaryPath(ctx.ModuleDir(), ctx.DeviceConfig()) { + return true + } + + // However if the module is not in a vendor proprietary path, it may + // still be a vendor proprietary module. This happens for cc modules + // that are excluded from the vendor snapshot, and it means that the + // vendor has assumed control of the framework-provided module. + if c, ok := ctx.Module().(VendorSnapshotModuleInterface); ok { + if c.ExcludeFromVendorSnapshot() { + return true + } + } + + return false +} + +var VendorSnapshotImageName = "vendor" + +type VendorSnapshotImage struct{} + +func (VendorSnapshotImage) Init(ctx android.RegistrationContext) { + ctx.RegisterSingletonType("vendor-snapshot", VendorSnapshotSingleton) + ctx.RegisterSingletonType("vendor-fake-snapshot", VendorFakeSnapshotSingleton) +} + +func (VendorSnapshotImage) RegisterAdditionalModule(ctx android.RegistrationContext, name string, factory android.ModuleFactory) { + ctx.RegisterModuleType(name, factory) +} + +func (VendorSnapshotImage) shouldGenerateSnapshot(ctx android.SingletonContext) bool { + // BOARD_VNDK_VERSION must be set to 'current' in order to generate a snapshot. + return ctx.DeviceConfig().VndkVersion() == "current" +} + +func (VendorSnapshotImage) InImage(m SnapshotModuleInterfaceBase) func() bool { + v, ok := m.(VendorSnapshotModuleInterface) + + if !ok { + // This module does not support Vendor snapshot + return func() bool { return false } + } + + return v.InVendor +} + +func (VendorSnapshotImage) IsProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool { + return isDirectoryExcluded(dir, deviceConfig.VendorSnapshotDirsExcludedMap(), deviceConfig.VendorSnapshotDirsIncludedMap()) +} + +func (VendorSnapshotImage) ExcludeFromSnapshot(m SnapshotModuleInterfaceBase) bool { + v, ok := m.(VendorSnapshotModuleInterface) + + if !ok { + // This module does not support Vendor snapshot + return true + } + + return v.ExcludeFromVendorSnapshot() +} + +func (VendorSnapshotImage) IsUsingSnapshot(cfg android.DeviceConfig) bool { + vndkVersion := cfg.VndkVersion() + return vndkVersion != "current" && vndkVersion != "" +} + +func (VendorSnapshotImage) TargetSnapshotVersion(cfg android.DeviceConfig) string { + return cfg.VndkVersion() +} + +// returns true iff a given module SHOULD BE EXCLUDED, false if included +func (VendorSnapshotImage) ExcludeFromDirectedSnapshot(cfg android.DeviceConfig, name string) bool { + // If we're using full snapshot, not directed snapshot, capture every module + if !cfg.DirectedVendorSnapshot() { + return false + } + // Else, checks if name is in VENDOR_SNAPSHOT_MODULES. + return !cfg.VendorSnapshotModules()[name] +} + +func (VendorSnapshotImage) ImageName() string { + return VendorSnapshotImageName +} + +var VendorSnapshotImageSingleton VendorSnapshotImage + +func init() { + VendorSnapshotImageSingleton.Init(android.InitRegistrationContext) +} |