1// Copyright 2019 Google Inc. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package cc 16 17import ( 18 "fmt" 19 "testing" 20 21 "android/soong/android" 22) 23 24func TestMinSdkVersionsOfCrtObjects(t *testing.T) { 25 ctx := testCc(t, ` 26 cc_object { 27 name: "crt_foo", 28 srcs: ["foo.c"], 29 crt: true, 30 stl: "none", 31 min_sdk_version: "28", 32 vendor_available: true, 33 }`) 34 35 variants := []struct { 36 variant string 37 num string 38 }{ 39 {"android_arm64_armv8-a", "10000"}, 40 {"android_arm64_armv8-a_sdk_28", "28"}, 41 {"android_arm64_armv8-a_sdk_29", "29"}, 42 {"android_arm64_armv8-a_sdk_30", "30"}, 43 {"android_arm64_armv8-a_sdk_current", "10000"}, 44 {"android_vendor.29_arm64_armv8-a", "29"}, 45 } 46 for _, v := range variants { 47 cflags := ctx.ModuleForTests("crt_foo", v.variant).Rule("cc").Args["cFlags"] 48 expected := "-target aarch64-linux-android" + v.num + " " 49 android.AssertStringDoesContain(t, "cflag", cflags, expected) 50 } 51} 52 53func TestUseCrtObjectOfCorrectVersion(t *testing.T) { 54 ctx := testCc(t, ` 55 cc_binary { 56 name: "bin", 57 srcs: ["foo.c"], 58 stl: "none", 59 min_sdk_version: "29", 60 sdk_version: "current", 61 } 62 `) 63 64 // Sdk variant uses the crt object of the matching min_sdk_version 65 variant := "android_arm64_armv8-a_sdk" 66 crt := ctx.ModuleForTests("bin", variant).Rule("ld").Args["crtBegin"] 67 android.AssertStringDoesContain(t, "crt dep of sdk variant", crt, 68 "29/crtbegin_dynamic.o") 69 70 // platform variant uses the crt object built for platform 71 variant = "android_arm64_armv8-a" 72 crt = ctx.ModuleForTests("bin", variant).Rule("ld").Args["crtBegin"] 73 android.AssertStringDoesContain(t, "crt dep of platform variant", crt, 74 variant+"/crtbegin_dynamic.o") 75} 76 77func TestLinkerScript(t *testing.T) { 78 t.Run("script", func(t *testing.T) { 79 testCc(t, ` 80 cc_object { 81 name: "foo", 82 srcs: ["baz.o"], 83 linker_script: "foo.lds", 84 }`) 85 }) 86} 87 88func TestCcObjectWithBazel(t *testing.T) { 89 bp := ` 90cc_object { 91 name: "foo", 92 srcs: ["baz.o"], 93 bazel_module: { label: "//foo/bar:bar" }, 94}` 95 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil) 96 config.BazelContext = android.MockBazelContext{ 97 OutputBaseDir: "outputbase", 98 LabelToOutputFiles: map[string][]string{ 99 "//foo/bar:bar": []string{"bazel_out.o"}}} 100 ctx := testCcWithConfig(t, config) 101 102 module := ctx.ModuleForTests("foo", "android_arm_armv7-a-neon").Module() 103 outputFiles, err := module.(android.OutputFileProducer).OutputFiles("") 104 if err != nil { 105 t.Errorf("Unexpected error getting cc_object outputfiles %s", err) 106 } 107 108 expectedOutputFiles := []string{"outputbase/execroot/__main__/bazel_out.o"} 109 android.AssertDeepEquals(t, "output files", expectedOutputFiles, outputFiles.Strings()) 110} 111 112func TestCcObjectOutputFile(t *testing.T) { 113 testcases := []struct { 114 name string 115 moduleName string 116 bp string 117 }{ 118 { 119 name: "normal", 120 moduleName: "foo", 121 bp: ` 122 srcs: ["bar.c"], 123 `, 124 }, 125 { 126 name: "suffix", 127 moduleName: "foo.o", 128 bp: ` 129 srcs: ["bar.c"], 130 `, 131 }, 132 { 133 name: "keep symbols", 134 moduleName: "foo", 135 bp: ` 136 srcs: ["bar.c"], 137 prefix_symbols: "foo_", 138 `, 139 }, 140 { 141 name: "partial linking", 142 moduleName: "foo", 143 bp: ` 144 srcs: ["bar.c", "baz.c"], 145 `, 146 }, 147 { 148 name: "partial linking and prefix symbols", 149 moduleName: "foo", 150 bp: ` 151 srcs: ["bar.c", "baz.c"], 152 prefix_symbols: "foo_", 153 `, 154 }, 155 } 156 157 for _, testcase := range testcases { 158 bp := fmt.Sprintf(` 159 cc_object { 160 name: "%s", 161 %s 162 } 163 `, testcase.moduleName, testcase.bp) 164 t.Run(testcase.name, func(t *testing.T) { 165 ctx := PrepareForIntegrationTestWithCc.RunTestWithBp(t, bp) 166 android.AssertPathRelativeToTopEquals(t, "expected output file foo.o", 167 fmt.Sprintf("out/soong/.intermediates/%s/android_arm64_armv8-a/foo.o", testcase.moduleName), 168 ctx.ModuleForTests(testcase.moduleName, "android_arm64_armv8-a").Output("foo.o").Output) 169 }) 170 } 171 172} 173