blob: 9e30bd2d5914a97f7315f24e31ae8e12b1924ea8 [file] [log] [blame]
Sharjeel Khanc6a93d82023-07-18 21:01:11 +00001// Copyright 2023 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 "testing"
19 "strings"
20
21 "android/soong/android"
22)
23
24func TestOrderfileProfileSharedLibrary(t *testing.T) {
25 t.Parallel()
26 bp := `
27 cc_library_shared {
28 name: "libTest",
29 srcs: ["test.c"],
30 orderfile : {
31 instrumentation: true,
32 load_order_file: false,
33 order_file_path: "",
34 },
35 }
36 `
37
38 result := android.GroupFixturePreparers(
39 prepareForCcTest,
40 ).RunTestWithBp(t, bp)
41
42 expectedCFlag := "-forder-file-instrumentation"
43
44 libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared")
45
46 // Check cFlags of orderfile-enabled module
47 cFlags := libTest.Rule("cc").Args["cFlags"]
48 if !strings.Contains(cFlags, expectedCFlag) {
49 t.Errorf("Expected 'libTest' to enable orderfile, but did not find %q in cflags %q", expectedCFlag, cFlags)
50 }
51
52 // Check ldFlags of orderfile-enabled module
53 ldFlags := libTest.Rule("ld").Args["ldFlags"]
54 if !strings.Contains(ldFlags, expectedCFlag) {
55 t.Errorf("Expected 'libTest' to enable orderfile, but did not find %q in ldflags %q", expectedCFlag, ldFlags)
56 }
57}
58
59func TestOrderfileLoadSharedLibrary(t *testing.T) {
60 t.Parallel()
61 bp := `
62 cc_library_shared {
63 name: "libTest",
64 srcs: ["test.c"],
65 orderfile : {
66 instrumentation: true,
67 load_order_file: true,
68 order_file_path: "libTest.orderfile",
69 },
70 }
71 `
72
73 result := android.GroupFixturePreparers(
74 prepareForCcTest,
75 android.FixtureAddTextFile("toolchain/pgo-profiles/orderfiles/libTest.orderfile", "TEST"),
76 ).RunTestWithBp(t, bp)
77
78 expectedCFlag := "-Wl,--symbol-ordering-file=toolchain/pgo-profiles/orderfiles/libTest.orderfile"
79
80 libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared")
81
82 // Check cFlags of orderfile-enabled module
83 cFlags := libTest.Rule("cc").Args["cFlags"]
84 if !strings.Contains(cFlags, expectedCFlag) {
85 t.Errorf("Expected 'libTest' to load orderfile, but did not find %q in cflags %q", expectedCFlag, cFlags)
86 }
87
88 // Check ldFlags of orderfile-enabled module
89 ldFlags := libTest.Rule("ld").Args["ldFlags"]
90 if !strings.Contains(ldFlags, expectedCFlag) {
91 t.Errorf("Expected 'libTest' to load orderfile, but did not find %q in ldflags %q", expectedCFlag, ldFlags)
92 }
93}
94
95func TestOrderfileProfileBinary(t *testing.T) {
96 t.Parallel()
97 bp := `
98 cc_binary {
99 name: "test",
100 srcs: ["test.c"],
101 orderfile : {
102 instrumentation: true,
103 load_order_file: false,
104 order_file_path: "",
105 },
106 }
107 `
108
109 result := android.GroupFixturePreparers(
110 prepareForCcTest,
111 ).RunTestWithBp(t, bp)
112
113 expectedCFlag := "-forder-file-instrumentation"
114
115 test := result.ModuleForTests("test", "android_arm64_armv8-a")
116
117 // Check cFlags of orderfile-enabled module
118 cFlags := test.Rule("cc").Args["cFlags"]
119 if !strings.Contains(cFlags, expectedCFlag) {
120 t.Errorf("Expected 'test' to enable orderfile, but did not find %q in cflags %q", expectedCFlag, cFlags)
121 }
122
123 // Check ldFlags of orderfile-enabled module
124 ldFlags := test.Rule("ld").Args["ldFlags"]
125 if !strings.Contains(ldFlags, expectedCFlag) {
126 t.Errorf("Expected 'test' to enable orderfile, but did not find %q in ldflags %q", expectedCFlag, ldFlags)
127 }
128}
129
130func TestOrderfileLoadBinary(t *testing.T) {
131 t.Parallel()
132 bp := `
133 cc_binary {
134 name: "test",
135 srcs: ["test.c"],
136 orderfile : {
137 instrumentation: true,
138 load_order_file: true,
139 order_file_path: "test.orderfile",
140 },
141 }
142 `
143
144 result := android.GroupFixturePreparers(
145 prepareForCcTest,
146 android.FixtureAddTextFile("toolchain/pgo-profiles/orderfiles/test.orderfile", "TEST"),
147 ).RunTestWithBp(t, bp)
148
149 expectedCFlag := "-Wl,--symbol-ordering-file=toolchain/pgo-profiles/orderfiles/test.orderfile"
150
151 test := result.ModuleForTests("test", "android_arm64_armv8-a")
152
153 // Check cFlags of orderfile-enabled module
154 cFlags := test.Rule("cc").Args["cFlags"]
155 if !strings.Contains(cFlags, expectedCFlag) {
156 t.Errorf("Expected 'test' to load orderfile, but did not find %q in cflags %q", expectedCFlag, cFlags)
157 }
158
159 // Check ldFlags of orderfile-enabled module
160 ldFlags := test.Rule("ld").Args["ldFlags"]
161 if !strings.Contains(ldFlags, expectedCFlag) {
162 t.Errorf("Expected 'test' to load orderfile, but did not find %q in ldflags %q", expectedCFlag, ldFlags)
163 }
164}
165
166// Profile flags should propagate through static libraries
167func TestOrderfileProfilePropagateStaticDeps(t *testing.T) {
168 t.Parallel()
169 bp := `
170 cc_library_shared {
171 name: "libTest",
172 srcs: ["test.c"],
173 static_libs: ["libFoo"],
174 orderfile : {
175 instrumentation: true,
176 load_order_file: false,
177 order_file_path: "",
178 },
179 }
180
181 cc_library_static {
182 name: "libFoo",
183 srcs: ["foo.c"],
184 static_libs: ["libBar"],
185 }
186
187 cc_library_static {
188 name: "libBar",
189 srcs: ["bar.c"],
190 }
191 `
192
193 result := android.GroupFixturePreparers(
194 prepareForCcTest,
195 ).RunTestWithBp(t, bp)
196
197 expectedCFlag := "-forder-file-instrumentation"
198
199 // Check cFlags of orderfile-enabled module
200 libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared")
201
202 cFlags := libTest.Rule("cc").Args["cFlags"]
203 if !strings.Contains(cFlags, expectedCFlag) {
204 t.Errorf("Expected 'libTest' to enable orderfile, but did not find %q in cflags %q", expectedCFlag, cFlags)
205 }
206
207 // Check cFlags of orderfile variant static libraries
208 libFooOfVariant := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static_orderfile")
209 libBarOfVariant := result.ModuleForTests("libBar", "android_arm64_armv8-a_static_orderfile")
210
211 cFlags = libFooOfVariant.Rule("cc").Args["cFlags"]
212 if !strings.Contains(cFlags, expectedCFlag) {
213 t.Errorf("Expected 'libFooOfVariant' to enable orderfile, but did not find %q in cflags %q", expectedCFlag, cFlags)
214 }
215
216 cFlags = libBarOfVariant.Rule("cc").Args["cFlags"]
217 if !strings.Contains(cFlags, expectedCFlag) {
218 t.Errorf("Expected 'libBarOfVariant' to enable orderfile, but did not find %q in cflags %q", expectedCFlag, cFlags)
219 }
220
221 // Check dependency edge from orderfile-enabled module to orderfile variant static libraries
222 if !hasDirectDep(result, libTest.Module(), libFooOfVariant.Module()) {
223 t.Errorf("libTest missing dependency on orderfile variant of libFoo")
224 }
225
226 if !hasDirectDep(result, libFooOfVariant.Module(), libBarOfVariant.Module()) {
227 t.Errorf("libTest missing dependency on orderfile variant of libBar")
228 }
229
230 // Check cFlags of the non-orderfile variant static libraries
231 libFoo := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static")
232 libBar := result.ModuleForTests("libBar", "android_arm64_armv8-a_static")
233
234 cFlags = libFoo.Rule("cc").Args["cFlags"]
235 if strings.Contains(cFlags, expectedCFlag) {
236 t.Errorf("Expected 'libFoo' to not enable orderfile, but did find %q in cflags %q", expectedCFlag, cFlags)
237 }
238
239 cFlags = libBar.Rule("cc").Args["cFlags"]
240 if strings.Contains(cFlags, expectedCFlag) {
241 t.Errorf("Expected 'libBar' to not enable orderfile, but did find %q in cflags %q", expectedCFlag, cFlags)
242 }
243
244 // Check no dependency edge from orderfile-enabled module to non-orderfile variant static libraries
245 if hasDirectDep(result, libTest.Module(), libFoo.Module()) {
246 t.Errorf("libTest has dependency on non-orderfile variant of libFoo")
247 }
248
249 if !hasDirectDep(result, libFoo.Module(), libBar.Module()) {
250 t.Errorf("libTest has dependency on non-orderfile variant of libBar")
251 }
252}
253
254// Load flags should never propagate
255func TestOrderfileLoadPropagateStaticDeps(t *testing.T) {
256 t.Parallel()
257 bp := `
258 cc_library_shared {
259 name: "libTest",
260 srcs: ["test.c"],
261 static_libs: ["libFoo"],
262 orderfile : {
263 instrumentation: true,
264 load_order_file: true,
265 order_file_path: "test.orderfile",
266 },
267 }
268
269 cc_library_static {
270 name: "libFoo",
271 srcs: ["foo.c"],
272 static_libs: ["libBar"],
273 }
274
275 cc_library_static {
276 name: "libBar",
277 srcs: ["bar.c"],
278 }
279 `
280
281 result := android.GroupFixturePreparers(
282 prepareForCcTest,
283 android.FixtureAddTextFile("toolchain/pgo-profiles/orderfiles/test.orderfile", "TEST"),
284 ).RunTestWithBp(t, bp)
285
286 expectedCFlag := "-Wl,--symbol-ordering-file=toolchain/pgo-profiles/orderfiles/test.orderfile"
287
288 // Check cFlags of orderfile-enabled module
289 libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared")
290
291 cFlags := libTest.Rule("cc").Args["cFlags"]
292 if !strings.Contains(cFlags, expectedCFlag) {
293 t.Errorf("Expected 'libTest' to load orderfile, but did not find %q in cflags %q", expectedCFlag, cFlags)
294 }
295
296 // Check cFlags of the non-orderfile variant static libraries
297 libFoo := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static")
298 libBar := result.ModuleForTests("libBar", "android_arm64_armv8-a_static")
299
300 cFlags = libFoo.Rule("cc").Args["cFlags"]
301 if strings.Contains(cFlags, expectedCFlag) {
302 t.Errorf("Expected 'libFoo' not load orderfile, but did find %q in cflags %q", expectedCFlag, cFlags)
303 }
304
305 cFlags = libBar.Rule("cc").Args["cFlags"]
306 if strings.Contains(cFlags, expectedCFlag) {
307 t.Errorf("Expected 'libBar' not load orderfile, but did find %q in cflags %q", expectedCFlag, cFlags)
308 }
309
310 // Check dependency edge from orderfile-enabled module to non-orderfile variant static libraries
311 if !hasDirectDep(result, libTest.Module(), libFoo.Module()) {
312 t.Errorf("libTest missing dependency on non-orderfile variant of libFoo")
313 }
314
315 if !hasDirectDep(result, libFoo.Module(), libBar.Module()) {
316 t.Errorf("libTest missing dependency on non-orderfile variant of libBar")
317 }
318
319 // Make sure no orderfile variants are created for static libraries because the flags were not propagated
320 libFooVariants := result.ModuleVariantsForTests("libFoo")
321 for _, v := range libFooVariants {
322 if strings.Contains(v, "orderfile") {
323 t.Errorf("Expected variants for 'libFoo' to not contain 'orderfile', but found %q", v)
324 }
325 }
326
327 libBarVariants := result.ModuleVariantsForTests("libBar")
328 for _, v := range libBarVariants {
329 if strings.Contains(v, "orderfile") {
330 t.Errorf("Expected variants for 'libBar' to not contain 'orderfile', but found %q", v)
331 }
332 }
333}
334
335// Profile flags should not propagate through shared libraries
336func TestOrderfileProfilePropagateSharedDeps(t *testing.T) {
337 t.Parallel()
338 bp := `
339 cc_library_shared {
340 name: "libTest",
341 srcs: ["test.c"],
342 shared_libs: ["libFoo"],
343 orderfile : {
344 instrumentation: true,
345 load_order_file: false,
346 order_file_path: "",
347 },
348 }
349
350 cc_library_shared {
351 name: "libFoo",
352 srcs: ["foo.c"],
353 static_libs: ["libBar"],
354 }
355
356 cc_library_static {
357 name: "libBar",
358 srcs: ["bar.c"],
359 }
360 `
361
362 result := android.GroupFixturePreparers(
363 prepareForCcTest,
364 ).RunTestWithBp(t, bp)
365
366 expectedCFlag := "-forder-file-instrumentation"
367
368 // Check cFlags of orderfile-enabled module
369 libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared")
370
371 cFlags := libTest.Rule("cc").Args["cFlags"]
372 if !strings.Contains(cFlags, expectedCFlag) {
373 t.Errorf("Expected 'libTest' to enable orderfile, but did not find %q in cflags %q", expectedCFlag, cFlags)
374 }
375
376 // Check cFlags of the static and shared libraries
377 libFoo := result.ModuleForTests("libFoo", "android_arm64_armv8-a_shared")
378 libBar := result.ModuleForTests("libBar", "android_arm64_armv8-a_static")
379
380 cFlags = libFoo.Rule("cc").Args["cFlags"]
381 if strings.Contains(cFlags, expectedCFlag) {
382 t.Errorf("Expected 'libFoo' to not enable orderfile, but did find %q in cflags %q", expectedCFlag, cFlags)
383 }
384
385 cFlags = libBar.Rule("cc").Args["cFlags"]
386 if strings.Contains(cFlags, expectedCFlag) {
387 t.Errorf("Expected 'libBar' to not enable orderfile, but did find %q in cflags %q", expectedCFlag, cFlags)
388 }
389
390 // Check dependency edge from orderfile-enabled module to non-orderfile variant static libraries
391 if !hasDirectDep(result, libTest.Module(), libFoo.Module()) {
392 t.Errorf("libTest missing dependency on non-orderfile variant of libFoo")
393 }
394
395 if !hasDirectDep(result, libFoo.Module(), libBar.Module()) {
396 t.Errorf("libTest missing dependency on non-orderfile variant of libBar")
397 }
398
399 // Make sure no orderfile variants are created for libraries because the flags were not propagated
400 libFooVariants := result.ModuleVariantsForTests("libFoo")
401 for _, v := range libFooVariants {
402 if strings.Contains(v, "orderfile") {
403 t.Errorf("Expected variants for 'libFoo' to not contain 'orderfile', but found %q", v)
404 }
405 }
406
407 libBarVariants := result.ModuleVariantsForTests("libBar")
408 for _, v := range libBarVariants {
409 if strings.Contains(v, "orderfile") {
410 t.Errorf("Expected variants for 'libBar' to not contain 'orderfile', but found %q", v)
411 }
412 }
413}
414
415// Profile flags should not work or be propagated if orderfile flags start at a static library
416func TestOrderfileProfileStaticLibrary(t *testing.T) {
417 t.Parallel()
418 bp := `
419 cc_library_static {
420 name: "libTest",
421 srcs: ["test.c"],
422 static_libs: ["libFoo"],
423 orderfile : {
424 instrumentation: true,
425 load_order_file: false,
426 order_file_path: "",
427 },
428 }
429
430 cc_library_static {
431 name: "libFoo",
432 srcs: ["foo.c"],
433 static_libs: ["libBar"],
434 }
435
436 cc_library_static {
437 name: "libBar",
438 srcs: ["bar.c"],
439 }
440 `
441
442 result := android.GroupFixturePreparers(
443 prepareForCcTest,
444 ).RunTestWithBp(t, bp)
445
446 expectedCFlag := "-forder-file-instrumentation"
447
448 // Check cFlags of module
449 libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_static")
450
451 cFlags := libTest.Rule("cc").Args["cFlags"]
452 if strings.Contains(cFlags, expectedCFlag) {
453 t.Errorf("Expected 'libTest' to not enable orderfile, but did find %q in cflags %q", expectedCFlag, cFlags)
454 }
455
456 // Check cFlags of the static libraries
457 libFoo := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static")
458 libBar := result.ModuleForTests("libBar", "android_arm64_armv8-a_static")
459
460 cFlags = libFoo.Rule("cc").Args["cFlags"]
461 if strings.Contains(cFlags, expectedCFlag) {
462 t.Errorf("Expected 'libFoo' to not enable orderfile, but did find %q in cflags %q", expectedCFlag, cFlags)
463 }
464
465 cFlags = libBar.Rule("cc").Args["cFlags"]
466 if strings.Contains(cFlags, expectedCFlag) {
467 t.Errorf("Expected 'libBar' to not enable orderfile, but did find %q in cflags %q", expectedCFlag, cFlags)
468 }
469
470 // Check dependency edge from orderfile-enabled module to non-orderfile variant libraries
471 if !hasDirectDep(result, libTest.Module(), libFoo.Module()) {
472 t.Errorf("libTest missing dependency on non-orderfile variant of libFoo")
473 }
474
475 if !hasDirectDep(result, libFoo.Module(), libBar.Module()) {
476 t.Errorf("libTest missing dependency on non-orderfile variant of libBar")
477 }
478
479 // Make sure no orderfile variants are created for static libraries because the flags were not propagated
480 libFooVariants := result.ModuleVariantsForTests("libFoo")
481 for _, v := range libFooVariants {
482 if strings.Contains(v, "orderfile") {
483 t.Errorf("Expected variants for 'libFoo' to not contain 'orderfile', but found %q", v)
484 }
485 }
486
487 libBarVariants := result.ModuleVariantsForTests("libBar")
488 for _, v := range libBarVariants {
489 if strings.Contains(v, "orderfile") {
490 t.Errorf("Expected variants for 'libBar' to not contain 'orderfile', but found %q", v)
491 }
492 }
493}