| // 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 cc |
| |
| import ( |
| "reflect" |
| "slices" |
| "testing" |
| |
| "android/soong/android" |
| ) |
| |
| func testGenruleContext(config android.Config) *android.TestContext { |
| ctx := android.NewTestArchContext(config) |
| ctx.RegisterModuleType("cc_genrule", GenRuleFactory) |
| ctx.Register() |
| |
| return ctx |
| } |
| |
| func TestArchGenruleCmd(t *testing.T) { |
| fs := map[string][]byte{ |
| "tool": nil, |
| "foo": nil, |
| "bar": nil, |
| } |
| bp := ` |
| cc_genrule { |
| name: "gen", |
| tool_files: ["tool"], |
| cmd: "$(location tool) $(in) $(out)", |
| out: ["out_arm"], |
| arch: { |
| arm: { |
| srcs: ["foo"], |
| }, |
| arm64: { |
| srcs: ["bar"], |
| }, |
| }, |
| } |
| ` |
| config := android.TestArchConfig(t.TempDir(), nil, bp, fs) |
| |
| ctx := testGenruleContext(config) |
| |
| _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) |
| if errs == nil { |
| _, errs = ctx.PrepareBuildActions(config) |
| } |
| if errs != nil { |
| t.Fatal(errs) |
| } |
| |
| gen := ctx.ModuleForTests("gen", "android_arm_armv7-a-neon").Output("out_arm") |
| expected := []string{"foo"} |
| if !reflect.DeepEqual(expected, gen.Implicits.Strings()[:len(expected)]) { |
| t.Errorf(`want arm inputs %v, got %v`, expected, gen.Implicits.Strings()) |
| } |
| |
| gen = ctx.ModuleForTests("gen", "android_arm64_armv8-a").Output("out_arm") |
| expected = []string{"bar"} |
| if !reflect.DeepEqual(expected, gen.Implicits.Strings()[:len(expected)]) { |
| t.Errorf(`want arm64 inputs %v, got %v`, expected, gen.Implicits.Strings()) |
| } |
| } |
| |
| func TestLibraryGenruleCmd(t *testing.T) { |
| bp := ` |
| cc_library { |
| name: "libboth", |
| } |
| |
| cc_library_shared { |
| name: "libshared", |
| } |
| |
| cc_library_static { |
| name: "libstatic", |
| } |
| |
| cc_genrule { |
| name: "gen", |
| tool_files: ["tool"], |
| srcs: [ |
| ":libboth", |
| ":libshared", |
| ":libstatic", |
| ], |
| cmd: "$(location tool) $(in) $(out)", |
| out: ["out"], |
| } |
| ` |
| ctx := testCc(t, bp) |
| |
| gen := ctx.ModuleForTests("gen", "android_arm_armv7-a-neon").Output("out") |
| expected := []string{"libboth.so", "libshared.so", "libstatic.a"} |
| var got []string |
| for _, input := range gen.Implicits { |
| got = append(got, input.Base()) |
| } |
| if !reflect.DeepEqual(expected, got[:len(expected)]) { |
| t.Errorf(`want inputs %v, got %v`, expected, got) |
| } |
| } |
| |
| func TestCmdPrefix(t *testing.T) { |
| bp := ` |
| cc_genrule { |
| name: "gen", |
| cmd: "echo foo", |
| out: ["out"], |
| native_bridge_supported: true, |
| } |
| ` |
| |
| testCases := []struct { |
| name string |
| variant string |
| preparer android.FixturePreparer |
| |
| arch string |
| nativeBridge string |
| multilib string |
| }{ |
| { |
| name: "arm", |
| variant: "android_arm_armv7-a-neon", |
| arch: "arm", |
| multilib: "lib32", |
| }, |
| { |
| name: "arm64", |
| variant: "android_arm64_armv8-a", |
| arch: "arm64", |
| multilib: "lib64", |
| }, |
| { |
| name: "nativebridge", |
| variant: "android_native_bridge_arm_armv7-a-neon", |
| preparer: android.FixtureModifyConfig(func(config android.Config) { |
| config.Targets[android.Android] = []android.Target{ |
| { |
| Os: android.Android, |
| Arch: android.Arch{ArchType: android.X86, ArchVariant: "silvermont", Abi: []string{"armeabi-v7a"}}, |
| NativeBridge: android.NativeBridgeDisabled, |
| }, |
| { |
| Os: android.Android, |
| Arch: android.Arch{ArchType: android.Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}}, |
| NativeBridge: android.NativeBridgeEnabled, |
| NativeBridgeHostArchName: "x86", |
| NativeBridgeRelativePath: "arm", |
| }, |
| } |
| }), |
| arch: "arm", |
| multilib: "lib32", |
| nativeBridge: "arm", |
| }, |
| } |
| |
| for _, tt := range testCases { |
| t.Run(tt.name, func(t *testing.T) { |
| result := android.GroupFixturePreparers( |
| PrepareForIntegrationTestWithCc, |
| android.OptionalFixturePreparer(tt.preparer), |
| ).RunTestWithBp(t, bp) |
| gen := result.ModuleForTests("gen", tt.variant) |
| sboxProto := android.RuleBuilderSboxProtoForTests(t, result.TestContext, gen.Output("genrule.sbox.textproto")) |
| cmd := *sboxProto.Commands[0].Command |
| android.AssertStringDoesContain(t, "incorrect CC_ARCH", cmd, "CC_ARCH="+tt.arch+" ") |
| android.AssertStringDoesContain(t, "incorrect CC_NATIVE_BRIDGE", cmd, "CC_NATIVE_BRIDGE="+tt.nativeBridge+" ") |
| android.AssertStringDoesContain(t, "incorrect CC_MULTILIB", cmd, "CC_MULTILIB="+tt.multilib+" ") |
| }) |
| } |
| } |
| |
| func TestVendorProductVariantGenrule(t *testing.T) { |
| bp := ` |
| cc_genrule { |
| name: "gen", |
| tool_files: ["tool"], |
| cmd: "$(location tool) $(in) $(out)", |
| out: ["out"], |
| vendor_available: true, |
| product_available: true, |
| } |
| ` |
| t.Helper() |
| ctx := PrepareForIntegrationTestWithCc.RunTestWithBp(t, bp) |
| |
| variants := ctx.ModuleVariantsForTests("gen") |
| if !slices.Contains(variants, "android_vendor_arm64_armv8-a") { |
| t.Errorf(`expected vendor variant, but does not exist in %v`, variants) |
| } |
| if !slices.Contains(variants, "android_product_arm64_armv8-a") { |
| t.Errorf(`expected product variant, but does not exist in %v`, variants) |
| } |
| } |
| |
| // cc_genrule is initialized to android.InitAndroidArchModule |
| // that is an architecture-specific Android module. |
| // So testing properties tagged with `android:"arch_variant"` |
| // for cc_genrule. |
| func TestMultilibGenruleOut(t *testing.T) { |
| bp := ` |
| cc_genrule { |
| name: "gen", |
| cmd: "cp $(in) $(out)", |
| srcs: ["foo"], |
| multilib: { |
| lib32: { |
| out: [ |
| "subdir32/external-module32", |
| ], |
| }, |
| lib64: { |
| out: [ |
| "subdir64/external-module64", |
| ], |
| }, |
| }, |
| } |
| ` |
| result := PrepareForIntegrationTestWithCc.RunTestWithBp(t, bp) |
| gen_32bit := result.ModuleForTests("gen", "android_arm_armv7-a-neon").OutputFiles(t, "") |
| android.AssertPathsEndWith(t, |
| "genrule_out", |
| []string{ |
| "subdir32/external-module32", |
| }, |
| gen_32bit, |
| ) |
| |
| gen_64bit := result.ModuleForTests("gen", "android_arm64_armv8-a").OutputFiles(t, "") |
| android.AssertPathsEndWith(t, |
| "genrule_out", |
| []string{ |
| "subdir64/external-module64", |
| }, |
| gen_64bit, |
| ) |
| } |