| // Copyright 2021 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 bp2build |
| |
| import ( |
| "testing" |
| |
| "android/soong/android" |
| "android/soong/cc" |
| ) |
| |
| func registerCcObjectModuleTypes(ctx android.RegistrationContext) { |
| // Always register cc_defaults module factory |
| ctx.RegisterModuleType("cc_defaults", func() android.Module { return cc.DefaultsFactory() }) |
| } |
| |
| func runCcObjectTestCase(t *testing.T, tc bp2buildTestCase) { |
| t.Helper() |
| runBp2BuildTestCase(t, registerCcObjectModuleTypes, tc) |
| } |
| |
| func TestCcObjectSimple(t *testing.T) { |
| runCcObjectTestCase(t, bp2buildTestCase{ |
| description: "simple cc_object generates cc_object with include header dep", |
| moduleTypeUnderTest: "cc_object", |
| moduleTypeUnderTestFactory: cc.ObjectFactory, |
| moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build, |
| filesystem: map[string]string{ |
| "a/b/foo.h": "", |
| "a/b/bar.h": "", |
| "a/b/exclude.c": "", |
| "a/b/c.c": "", |
| }, |
| blueprint: `cc_object { |
| name: "foo", |
| local_include_dirs: ["include"], |
| system_shared_libs: [], |
| cflags: [ |
| "-Wno-gcc-compat", |
| "-Wall", |
| "-Werror", |
| ], |
| srcs: [ |
| "a/b/*.c" |
| ], |
| exclude_srcs: ["a/b/exclude.c"], |
| } |
| `, |
| expectedBazelTargets: []string{`cc_object( |
| name = "foo", |
| copts = [ |
| "-fno-addrsig", |
| "-Wno-gcc-compat", |
| "-Wall", |
| "-Werror", |
| ], |
| local_includes = [ |
| "include", |
| ".", |
| ], |
| srcs = ["a/b/c.c"], |
| system_dynamic_deps = [], |
| )`, |
| }, |
| }) |
| } |
| |
| func TestCcObjectDefaults(t *testing.T) { |
| runCcObjectTestCase(t, bp2buildTestCase{ |
| moduleTypeUnderTest: "cc_object", |
| moduleTypeUnderTestFactory: cc.ObjectFactory, |
| moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build, |
| blueprint: `cc_object { |
| name: "foo", |
| system_shared_libs: [], |
| srcs: [ |
| "a/b/*.h", |
| "a/b/c.c" |
| ], |
| |
| defaults: ["foo_defaults"], |
| } |
| |
| cc_defaults { |
| name: "foo_defaults", |
| defaults: ["foo_bar_defaults"], |
| } |
| |
| cc_defaults { |
| name: "foo_bar_defaults", |
| cflags: [ |
| "-Wno-gcc-compat", |
| "-Wall", |
| "-Werror", |
| ], |
| } |
| `, |
| expectedBazelTargets: []string{`cc_object( |
| name = "foo", |
| copts = [ |
| "-Wno-gcc-compat", |
| "-Wall", |
| "-Werror", |
| "-fno-addrsig", |
| ], |
| local_includes = ["."], |
| srcs = ["a/b/c.c"], |
| system_dynamic_deps = [], |
| )`, |
| }}) |
| } |
| |
| func TestCcObjectCcObjetDepsInObjs(t *testing.T) { |
| runCcObjectTestCase(t, bp2buildTestCase{ |
| description: "cc_object with cc_object deps in objs props", |
| moduleTypeUnderTest: "cc_object", |
| moduleTypeUnderTestFactory: cc.ObjectFactory, |
| moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build, |
| filesystem: map[string]string{ |
| "a/b/c.c": "", |
| "x/y/z.c": "", |
| }, |
| blueprint: `cc_object { |
| name: "foo", |
| system_shared_libs: [], |
| srcs: ["a/b/c.c"], |
| objs: ["bar"], |
| include_build_directory: false, |
| } |
| |
| cc_object { |
| name: "bar", |
| system_shared_libs: [], |
| srcs: ["x/y/z.c"], |
| include_build_directory: false, |
| } |
| `, |
| expectedBazelTargets: []string{`cc_object( |
| name = "bar", |
| copts = ["-fno-addrsig"], |
| srcs = ["x/y/z.c"], |
| system_dynamic_deps = [], |
| )`, `cc_object( |
| name = "foo", |
| copts = ["-fno-addrsig"], |
| deps = [":bar"], |
| srcs = ["a/b/c.c"], |
| system_dynamic_deps = [], |
| )`, |
| }, |
| }) |
| } |
| |
| func TestCcObjectIncludeBuildDirFalse(t *testing.T) { |
| runCcObjectTestCase(t, bp2buildTestCase{ |
| description: "cc_object with include_build_dir: false", |
| moduleTypeUnderTest: "cc_object", |
| moduleTypeUnderTestFactory: cc.ObjectFactory, |
| moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build, |
| filesystem: map[string]string{ |
| "a/b/c.c": "", |
| "x/y/z.c": "", |
| }, |
| blueprint: `cc_object { |
| name: "foo", |
| system_shared_libs: [], |
| srcs: ["a/b/c.c"], |
| include_build_directory: false, |
| } |
| `, |
| expectedBazelTargets: []string{`cc_object( |
| name = "foo", |
| copts = ["-fno-addrsig"], |
| srcs = ["a/b/c.c"], |
| system_dynamic_deps = [], |
| )`, |
| }, |
| }) |
| } |
| |
| func TestCcObjectProductVariable(t *testing.T) { |
| runCcObjectTestCase(t, bp2buildTestCase{ |
| description: "cc_object with product variable", |
| moduleTypeUnderTest: "cc_object", |
| moduleTypeUnderTestFactory: cc.ObjectFactory, |
| moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build, |
| blueprint: `cc_object { |
| name: "foo", |
| system_shared_libs: [], |
| include_build_directory: false, |
| product_variables: { |
| platform_sdk_version: { |
| asflags: ["-DPLATFORM_SDK_VERSION=%d"], |
| }, |
| }, |
| srcs: ["src.S"], |
| } |
| `, |
| expectedBazelTargets: []string{`cc_object( |
| name = "foo", |
| asflags = select({ |
| "//build/bazel/product_variables:platform_sdk_version": ["-DPLATFORM_SDK_VERSION=$(Platform_sdk_version)"], |
| "//conditions:default": [], |
| }), |
| copts = ["-fno-addrsig"], |
| srcs_as = ["src.S"], |
| system_dynamic_deps = [], |
| )`, |
| }, |
| }) |
| } |
| |
| func TestCcObjectCflagsOneArch(t *testing.T) { |
| runCcObjectTestCase(t, bp2buildTestCase{ |
| description: "cc_object setting cflags for one arch", |
| moduleTypeUnderTest: "cc_object", |
| moduleTypeUnderTestFactory: cc.ObjectFactory, |
| moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build, |
| blueprint: `cc_object { |
| name: "foo", |
| system_shared_libs: [], |
| srcs: ["a.cpp"], |
| arch: { |
| x86: { |
| cflags: ["-fPIC"], // string list |
| }, |
| arm: { |
| srcs: ["arch/arm/file.cpp"], // label list |
| }, |
| }, |
| include_build_directory: false, |
| } |
| `, |
| expectedBazelTargets: []string{ |
| `cc_object( |
| name = "foo", |
| copts = ["-fno-addrsig"] + select({ |
| "//build/bazel/platforms/arch:x86": ["-fPIC"], |
| "//conditions:default": [], |
| }), |
| srcs = ["a.cpp"] + select({ |
| "//build/bazel/platforms/arch:arm": ["arch/arm/file.cpp"], |
| "//conditions:default": [], |
| }), |
| system_dynamic_deps = [], |
| )`, |
| }, |
| }) |
| } |
| |
| func TestCcObjectCflagsFourArch(t *testing.T) { |
| runCcObjectTestCase(t, bp2buildTestCase{ |
| description: "cc_object setting cflags for 4 architectures", |
| moduleTypeUnderTest: "cc_object", |
| moduleTypeUnderTestFactory: cc.ObjectFactory, |
| moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build, |
| blueprint: `cc_object { |
| name: "foo", |
| system_shared_libs: [], |
| srcs: ["base.cpp"], |
| arch: { |
| x86: { |
| srcs: ["x86.cpp"], |
| cflags: ["-fPIC"], |
| }, |
| x86_64: { |
| srcs: ["x86_64.cpp"], |
| cflags: ["-fPIC"], |
| }, |
| arm: { |
| srcs: ["arm.cpp"], |
| cflags: ["-Wall"], |
| }, |
| arm64: { |
| srcs: ["arm64.cpp"], |
| cflags: ["-Wall"], |
| }, |
| }, |
| include_build_directory: false, |
| } |
| `, |
| expectedBazelTargets: []string{ |
| `cc_object( |
| name = "foo", |
| copts = ["-fno-addrsig"] + select({ |
| "//build/bazel/platforms/arch:arm": ["-Wall"], |
| "//build/bazel/platforms/arch:arm64": ["-Wall"], |
| "//build/bazel/platforms/arch:x86": ["-fPIC"], |
| "//build/bazel/platforms/arch:x86_64": ["-fPIC"], |
| "//conditions:default": [], |
| }), |
| srcs = ["base.cpp"] + select({ |
| "//build/bazel/platforms/arch:arm": ["arm.cpp"], |
| "//build/bazel/platforms/arch:arm64": ["arm64.cpp"], |
| "//build/bazel/platforms/arch:x86": ["x86.cpp"], |
| "//build/bazel/platforms/arch:x86_64": ["x86_64.cpp"], |
| "//conditions:default": [], |
| }), |
| system_dynamic_deps = [], |
| )`, |
| }, |
| }) |
| } |
| |
| func TestCcObjectLinkerScript(t *testing.T) { |
| runCcObjectTestCase(t, bp2buildTestCase{ |
| description: "cc_object setting linker_script", |
| moduleTypeUnderTest: "cc_object", |
| moduleTypeUnderTestFactory: cc.ObjectFactory, |
| moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build, |
| blueprint: `cc_object { |
| name: "foo", |
| srcs: ["base.cpp"], |
| linker_script: "bunny.lds", |
| include_build_directory: false, |
| } |
| `, |
| expectedBazelTargets: []string{ |
| `cc_object( |
| name = "foo", |
| copts = ["-fno-addrsig"], |
| linker_script = "bunny.lds", |
| srcs = ["base.cpp"], |
| )`, |
| }, |
| }) |
| } |
| |
| func TestCcObjectDepsAndLinkerScriptSelects(t *testing.T) { |
| runCcObjectTestCase(t, bp2buildTestCase{ |
| description: "cc_object setting deps and linker_script across archs", |
| moduleTypeUnderTest: "cc_object", |
| moduleTypeUnderTestFactory: cc.ObjectFactory, |
| moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build, |
| blueprint: `cc_object { |
| name: "foo", |
| srcs: ["base.cpp"], |
| arch: { |
| x86: { |
| objs: ["x86_obj"], |
| linker_script: "x86.lds", |
| }, |
| x86_64: { |
| objs: ["x86_64_obj"], |
| linker_script: "x86_64.lds", |
| }, |
| arm: { |
| objs: ["arm_obj"], |
| linker_script: "arm.lds", |
| }, |
| }, |
| include_build_directory: false, |
| } |
| |
| cc_object { |
| name: "x86_obj", |
| system_shared_libs: [], |
| srcs: ["x86.cpp"], |
| include_build_directory: false, |
| bazel_module: { bp2build_available: false }, |
| } |
| |
| cc_object { |
| name: "x86_64_obj", |
| system_shared_libs: [], |
| srcs: ["x86_64.cpp"], |
| include_build_directory: false, |
| bazel_module: { bp2build_available: false }, |
| } |
| |
| cc_object { |
| name: "arm_obj", |
| system_shared_libs: [], |
| srcs: ["arm.cpp"], |
| include_build_directory: false, |
| bazel_module: { bp2build_available: false }, |
| } |
| `, |
| expectedBazelTargets: []string{ |
| `cc_object( |
| name = "foo", |
| copts = ["-fno-addrsig"], |
| deps = select({ |
| "//build/bazel/platforms/arch:arm": [":arm_obj"], |
| "//build/bazel/platforms/arch:x86": [":x86_obj"], |
| "//build/bazel/platforms/arch:x86_64": [":x86_64_obj"], |
| "//conditions:default": [], |
| }), |
| linker_script = select({ |
| "//build/bazel/platforms/arch:arm": "arm.lds", |
| "//build/bazel/platforms/arch:x86": "x86.lds", |
| "//build/bazel/platforms/arch:x86_64": "x86_64.lds", |
| "//conditions:default": None, |
| }), |
| srcs = ["base.cpp"], |
| )`, |
| }, |
| }) |
| } |
| |
| func TestCcObjectSelectOnLinuxAndBionicArchs(t *testing.T) { |
| runCcObjectTestCase(t, bp2buildTestCase{ |
| description: "cc_object setting srcs based on linux and bionic archs", |
| moduleTypeUnderTest: "cc_object", |
| moduleTypeUnderTestFactory: cc.ObjectFactory, |
| moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build, |
| blueprint: `cc_object { |
| name: "foo", |
| srcs: ["base.cpp"], |
| target: { |
| linux_arm64: { |
| srcs: ["linux_arm64.cpp",] |
| }, |
| linux_x86: { |
| srcs: ["linux_x86.cpp",] |
| }, |
| bionic_arm64: { |
| srcs: ["bionic_arm64.cpp",] |
| }, |
| }, |
| include_build_directory: false, |
| } |
| `, |
| expectedBazelTargets: []string{ |
| `cc_object( |
| name = "foo", |
| copts = ["-fno-addrsig"], |
| srcs = ["base.cpp"] + select({ |
| "//build/bazel/platforms/os_arch:android_arm64": [ |
| "bionic_arm64.cpp", |
| "linux_arm64.cpp", |
| ], |
| "//build/bazel/platforms/os_arch:android_x86": ["linux_x86.cpp"], |
| "//build/bazel/platforms/os_arch:linux_bionic_arm64": [ |
| "bionic_arm64.cpp", |
| "linux_arm64.cpp", |
| ], |
| "//build/bazel/platforms/os_arch:linux_glibc_x86": ["linux_x86.cpp"], |
| "//build/bazel/platforms/os_arch:linux_musl_x86": ["linux_x86.cpp"], |
| "//conditions:default": [], |
| }), |
| )`, |
| }, |
| }) |
| } |