blob: fbd91be4625f8a93d9414e689ceccfb75b90de7d [file] [log] [blame]
Liz Kammer3b0f36c2022-09-16 12:39:27 -04001// Copyright 2021 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 "android/soong/android"
19 "strings"
20 "testing"
21
22 "github.com/google/blueprint"
23)
24
25func TestThinLtoDeps(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -040026 t.Parallel()
Liz Kammer3b0f36c2022-09-16 12:39:27 -040027 bp := `
Liz Kammer81d09502022-10-31 14:44:46 -040028 cc_library_shared {
Liz Kammer3b0f36c2022-09-16 12:39:27 -040029 name: "lto_enabled",
30 srcs: ["src.c"],
Liz Kammer81d09502022-10-31 14:44:46 -040031 static_libs: ["foo", "lib_never_lto"],
Liz Kammer3b0f36c2022-09-16 12:39:27 -040032 shared_libs: ["bar"],
33 lto: {
34 thin: true,
35 }
36 }
Liz Kammer81d09502022-10-31 14:44:46 -040037 cc_library_static {
Liz Kammer3b0f36c2022-09-16 12:39:27 -040038 name: "foo",
39 static_libs: ["baz"],
40 }
Liz Kammer81d09502022-10-31 14:44:46 -040041 cc_library_shared {
Liz Kammer3b0f36c2022-09-16 12:39:27 -040042 name: "bar",
43 static_libs: ["qux"],
44 }
Liz Kammer81d09502022-10-31 14:44:46 -040045 cc_library_static {
Liz Kammer3b0f36c2022-09-16 12:39:27 -040046 name: "baz",
47 }
Liz Kammer81d09502022-10-31 14:44:46 -040048 cc_library_static {
Liz Kammer3b0f36c2022-09-16 12:39:27 -040049 name: "qux",
50 }
Liz Kammer81d09502022-10-31 14:44:46 -040051 cc_library_static {
52 name: "lib_never_lto",
53 lto: {
54 never: true,
55 },
56 }
Liz Kammer3b0f36c2022-09-16 12:39:27 -040057`
58
59 result := android.GroupFixturePreparers(
60 prepareForCcTest,
61 ).RunTestWithBp(t, bp)
62
63 libLto := result.ModuleForTests("lto_enabled", "android_arm64_armv8-a_shared").Module()
Liz Kammer3b0f36c2022-09-16 12:39:27 -040064
65 hasDep := func(m android.Module, wantDep android.Module) bool {
66 var found bool
67 result.VisitDirectDeps(m, func(dep blueprint.Module) {
68 if dep == wantDep {
69 found = true
70 }
71 })
72 return found
73 }
74
Liz Kammer81d09502022-10-31 14:44:46 -040075 libFoo := result.ModuleForTests("foo", "android_arm64_armv8-a_static_lto-thin").Module()
Liz Kammer3b0f36c2022-09-16 12:39:27 -040076 if !hasDep(libLto, libFoo) {
77 t.Errorf("'lto_enabled' missing dependency on thin lto variant of 'foo'")
78 }
79
Liz Kammer81d09502022-10-31 14:44:46 -040080 libBaz := result.ModuleForTests("baz", "android_arm64_armv8-a_static_lto-thin").Module()
Liz Kammer3b0f36c2022-09-16 12:39:27 -040081 if !hasDep(libFoo, libBaz) {
Liz Kammer81d09502022-10-31 14:44:46 -040082 t.Errorf("'foo' missing dependency on thin lto variant of transitive dep 'baz'")
83 }
84
85 libNeverLto := result.ModuleForTests("lib_never_lto", "android_arm64_armv8-a_static_lto-thin").Module()
86 if !hasDep(libLto, libNeverLto) {
87 t.Errorf("'lto_enabled' missing dependency on NO-thin lto variant of 'lib_never_lto'")
88 }
89
90 libBar := result.ModuleForTests("bar", "android_arm64_armv8-a_shared").Module()
91 if !hasDep(libLto, libBar) {
92 t.Errorf("'lto_enabled' missing dependency on non-thin lto variant of 'bar'")
Liz Kammer3b0f36c2022-09-16 12:39:27 -040093 }
94
95 barVariants := result.ModuleVariantsForTests("bar")
96 for _, v := range barVariants {
97 if strings.Contains(v, "lto-thin") {
98 t.Errorf("Expected variants for 'bar' to not contain 'lto-thin', but found %q", v)
99 }
100 }
101 quxVariants := result.ModuleVariantsForTests("qux")
102 for _, v := range quxVariants {
103 if strings.Contains(v, "lto-thin") {
104 t.Errorf("Expected variants for 'qux' to not contain 'lto-thin', but found %q", v)
105 }
106 }
107}
Liz Kammer81d09502022-10-31 14:44:46 -0400108
109func TestThinLtoOnlyOnStaticDep(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400110 t.Parallel()
Liz Kammer81d09502022-10-31 14:44:46 -0400111 bp := `
112 cc_library_shared {
113 name: "root",
114 srcs: ["src.c"],
115 static_libs: ["foo"],
116 }
117 cc_library_shared {
118 name: "root_no_lto",
119 srcs: ["src.c"],
120 static_libs: ["foo"],
121 lto: {
122 never: true,
123 }
124 }
125 cc_library_static {
126 name: "foo",
127 srcs: ["foo.c"],
128 static_libs: ["baz"],
129 lto: {
130 thin: true,
131 }
132 }
133 cc_library_static {
134 name: "baz",
135 srcs: ["baz.c"],
136 }
137`
138
139 result := android.GroupFixturePreparers(
140 prepareForCcTest,
141 ).RunTestWithBp(t, bp)
142
143 libRoot := result.ModuleForTests("root", "android_arm64_armv8-a_shared").Module()
144 libRootLtoNever := result.ModuleForTests("root_no_lto", "android_arm64_armv8-a_shared").Module()
145
146 hasDep := func(m android.Module, wantDep android.Module) bool {
147 var found bool
148 result.VisitDirectDeps(m, func(dep blueprint.Module) {
149 if dep == wantDep {
150 found = true
151 }
152 })
153 return found
154 }
155
156 libFoo := result.ModuleForTests("foo", "android_arm64_armv8-a_static")
157 if !hasDep(libRoot, libFoo.Module()) {
158 t.Errorf("'root' missing dependency on thin lto variant of 'foo'")
159 }
160
161 if !hasDep(libRootLtoNever, libFoo.Module()) {
162 t.Errorf("'root_no_lto' missing dependency on thin lto variant of 'foo'")
163 }
164
165 libFooCFlags := libFoo.Rule("cc").Args["cFlags"]
166 if w := "-flto=thin -fsplit-lto-unit"; !strings.Contains(libFooCFlags, w) {
167 t.Errorf("'foo' expected to have flags %q, but got %q", w, libFooCFlags)
168 }
169
170 libBaz := result.ModuleForTests("baz", "android_arm64_armv8-a_static_lto-thin")
171 if !hasDep(libFoo.Module(), libBaz.Module()) {
172 t.Errorf("'foo' missing dependency on thin lto variant of transitive dep 'baz'")
173 }
174
175 libBazCFlags := libFoo.Rule("cc").Args["cFlags"]
176 if w := "-flto=thin -fsplit-lto-unit"; !strings.Contains(libBazCFlags, w) {
177 t.Errorf("'baz' expected to have flags %q, but got %q", w, libFooCFlags)
178 }
179}