1// Copyright 2017 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 "reflect" 19 "testing" 20 21 "android/soong/android" 22) 23 24func TestLibraryReuse(t *testing.T) { 25 t.Run("simple", func(t *testing.T) { 26 ctx := testCc(t, ` 27 cc_library { 28 name: "libfoo", 29 srcs: ["foo.c", "baz.o"], 30 }`) 31 32 libfooShared := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Rule("ld") 33 libfooStatic := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_static").Output("libfoo.a") 34 35 if len(libfooShared.Inputs) != 2 { 36 t.Fatalf("unexpected inputs to libfoo shared: %#v", libfooShared.Inputs.Strings()) 37 } 38 39 if len(libfooStatic.Inputs) != 2 { 40 t.Fatalf("unexpected inputs to libfoo static: %#v", libfooStatic.Inputs.Strings()) 41 } 42 43 if libfooShared.Inputs[0] != libfooStatic.Inputs[0] { 44 t.Errorf("static object not reused for shared library") 45 } 46 if libfooShared.Inputs[1] != libfooStatic.Inputs[1] { 47 t.Errorf("static object not reused for shared library") 48 } 49 }) 50 51 t.Run("extra static source", func(t *testing.T) { 52 ctx := testCc(t, ` 53 cc_library { 54 name: "libfoo", 55 srcs: ["foo.c"], 56 static: { 57 srcs: ["bar.c"] 58 }, 59 }`) 60 61 libfooShared := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Rule("ld") 62 libfooStatic := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_static").Output("libfoo.a") 63 64 if len(libfooShared.Inputs) != 1 { 65 t.Fatalf("unexpected inputs to libfoo shared: %#v", libfooShared.Inputs.Strings()) 66 } 67 68 if len(libfooStatic.Inputs) != 2 { 69 t.Fatalf("unexpected inputs to libfoo static: %#v", libfooStatic.Inputs.Strings()) 70 } 71 72 if libfooShared.Inputs[0] != libfooStatic.Inputs[0] { 73 t.Errorf("static object not reused for shared library") 74 } 75 }) 76 77 t.Run("extra shared source", func(t *testing.T) { 78 ctx := testCc(t, ` 79 cc_library { 80 name: "libfoo", 81 srcs: ["foo.c"], 82 shared: { 83 srcs: ["bar.c"] 84 }, 85 }`) 86 87 libfooShared := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Rule("ld") 88 libfooStatic := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_static").Output("libfoo.a") 89 90 if len(libfooShared.Inputs) != 2 { 91 t.Fatalf("unexpected inputs to libfoo shared: %#v", libfooShared.Inputs.Strings()) 92 } 93 94 if len(libfooStatic.Inputs) != 1 { 95 t.Fatalf("unexpected inputs to libfoo static: %#v", libfooStatic.Inputs.Strings()) 96 } 97 98 if libfooShared.Inputs[0] != libfooStatic.Inputs[0] { 99 t.Errorf("static object not reused for shared library") 100 } 101 }) 102 103 t.Run("extra static cflags", func(t *testing.T) { 104 ctx := testCc(t, ` 105 cc_library { 106 name: "libfoo", 107 srcs: ["foo.c"], 108 static: { 109 cflags: ["-DFOO"], 110 }, 111 }`) 112 113 libfooShared := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Rule("ld") 114 libfooStatic := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_static").Output("libfoo.a") 115 116 if len(libfooShared.Inputs) != 1 { 117 t.Fatalf("unexpected inputs to libfoo shared: %#v", libfooShared.Inputs.Strings()) 118 } 119 120 if len(libfooStatic.Inputs) != 1 { 121 t.Fatalf("unexpected inputs to libfoo static: %#v", libfooStatic.Inputs.Strings()) 122 } 123 124 if libfooShared.Inputs[0] == libfooStatic.Inputs[0] { 125 t.Errorf("static object reused for shared library when it shouldn't be") 126 } 127 }) 128 129 t.Run("extra shared cflags", func(t *testing.T) { 130 ctx := testCc(t, ` 131 cc_library { 132 name: "libfoo", 133 srcs: ["foo.c"], 134 shared: { 135 cflags: ["-DFOO"], 136 }, 137 }`) 138 139 libfooShared := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Rule("ld") 140 libfooStatic := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_static").Output("libfoo.a") 141 142 if len(libfooShared.Inputs) != 1 { 143 t.Fatalf("unexpected inputs to libfoo shared: %#v", libfooShared.Inputs.Strings()) 144 } 145 146 if len(libfooStatic.Inputs) != 1 { 147 t.Fatalf("unexpected inputs to libfoo static: %#v", libfooStatic.Inputs.Strings()) 148 } 149 150 if libfooShared.Inputs[0] == libfooStatic.Inputs[0] { 151 t.Errorf("static object reused for shared library when it shouldn't be") 152 } 153 }) 154 155 t.Run("global cflags for reused generated sources", func(t *testing.T) { 156 ctx := testCc(t, ` 157 cc_library { 158 name: "libfoo", 159 srcs: [ 160 "foo.c", 161 "a.proto", 162 ], 163 shared: { 164 srcs: [ 165 "bar.c", 166 ], 167 }, 168 }`) 169 170 libfooShared := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Rule("ld") 171 libfooStatic := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_static").Output("libfoo.a") 172 173 if len(libfooShared.Inputs) != 3 { 174 t.Fatalf("unexpected inputs to libfoo shared: %#v", libfooShared.Inputs.Strings()) 175 } 176 177 if len(libfooStatic.Inputs) != 2 { 178 t.Fatalf("unexpected inputs to libfoo static: %#v", libfooStatic.Inputs.Strings()) 179 } 180 181 if !reflect.DeepEqual(libfooShared.Inputs[0:2].Strings(), libfooStatic.Inputs.Strings()) { 182 t.Errorf("static objects not reused for shared library") 183 } 184 185 libfoo := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Module().(*Module) 186 if !inList("-DGOOGLE_PROTOBUF_NO_RTTI", libfoo.flags.Local.CFlags) { 187 t.Errorf("missing protobuf cflags") 188 } 189 }) 190} 191 192func TestStubsVersions(t *testing.T) { 193 bp := ` 194 cc_library { 195 name: "libfoo", 196 srcs: ["foo.c"], 197 stubs: { 198 versions: ["29", "R", "10000"], 199 }, 200 } 201 ` 202 config := TestConfig(buildDir, android.Android, nil, bp, nil) 203 config.TestProductVariables.Platform_version_active_codenames = []string{"R"} 204 ctx := testCcWithConfig(t, config) 205 206 variants := ctx.ModuleVariantsForTests("libfoo") 207 for _, expectedVer := range []string{"29", "9000", "10000"} { 208 expectedVariant := "android_arm_armv7-a-neon_shared_" + expectedVer 209 if !inList(expectedVariant, variants) { 210 t.Errorf("missing expected variant: %q", expectedVariant) 211 } 212 } 213} 214 215func TestStubsVersions_NotSorted(t *testing.T) { 216 bp := ` 217 cc_library { 218 name: "libfoo", 219 srcs: ["foo.c"], 220 stubs: { 221 versions: ["29", "10000", "R"], 222 }, 223 } 224 ` 225 config := TestConfig(buildDir, android.Android, nil, bp, nil) 226 config.TestProductVariables.Platform_version_active_codenames = []string{"R"} 227 testCcErrorWithConfig(t, `"libfoo" .*: versions: not sorted`, config) 228} 229 230func TestStubsVersions_ParseError(t *testing.T) { 231 bp := ` 232 cc_library { 233 name: "libfoo", 234 srcs: ["foo.c"], 235 stubs: { 236 versions: ["29", "10000", "X"], 237 }, 238 } 239 ` 240 241 testCcError(t, `"libfoo" .*: versions: SDK version should be`, bp) 242} 243