blob: afd2c774e2c85bcac358792176ccc674d7dfac8e [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) {
26 bp := `
Liz Kammer81d09502022-10-31 14:44:46 -040027 cc_library_shared {
Liz Kammer3b0f36c2022-09-16 12:39:27 -040028 name: "lto_enabled",
29 srcs: ["src.c"],
Liz Kammer81d09502022-10-31 14:44:46 -040030 static_libs: ["foo", "lib_never_lto"],
Liz Kammer3b0f36c2022-09-16 12:39:27 -040031 shared_libs: ["bar"],
32 lto: {
33 thin: true,
34 }
35 }
Liz Kammer81d09502022-10-31 14:44:46 -040036 cc_library_static {
Liz Kammer3b0f36c2022-09-16 12:39:27 -040037 name: "foo",
38 static_libs: ["baz"],
39 }
Liz Kammer81d09502022-10-31 14:44:46 -040040 cc_library_shared {
Liz Kammer3b0f36c2022-09-16 12:39:27 -040041 name: "bar",
42 static_libs: ["qux"],
43 }
Liz Kammer81d09502022-10-31 14:44:46 -040044 cc_library_static {
Liz Kammer3b0f36c2022-09-16 12:39:27 -040045 name: "baz",
46 }
Liz Kammer81d09502022-10-31 14:44:46 -040047 cc_library_static {
Liz Kammer3b0f36c2022-09-16 12:39:27 -040048 name: "qux",
49 }
Liz Kammer81d09502022-10-31 14:44:46 -040050 cc_library_static {
51 name: "lib_never_lto",
52 lto: {
53 never: true,
54 },
55 }
Liz Kammer3b0f36c2022-09-16 12:39:27 -040056`
57
58 result := android.GroupFixturePreparers(
59 prepareForCcTest,
60 ).RunTestWithBp(t, bp)
61
62 libLto := result.ModuleForTests("lto_enabled", "android_arm64_armv8-a_shared").Module()
Liz Kammer3b0f36c2022-09-16 12:39:27 -040063
64 hasDep := func(m android.Module, wantDep android.Module) bool {
65 var found bool
66 result.VisitDirectDeps(m, func(dep blueprint.Module) {
67 if dep == wantDep {
68 found = true
69 }
70 })
71 return found
72 }
73
Liz Kammer81d09502022-10-31 14:44:46 -040074 libFoo := result.ModuleForTests("foo", "android_arm64_armv8-a_static_lto-thin").Module()
Liz Kammer3b0f36c2022-09-16 12:39:27 -040075 if !hasDep(libLto, libFoo) {
76 t.Errorf("'lto_enabled' missing dependency on thin lto variant of 'foo'")
77 }
78
Liz Kammer81d09502022-10-31 14:44:46 -040079 libBaz := result.ModuleForTests("baz", "android_arm64_armv8-a_static_lto-thin").Module()
Liz Kammer3b0f36c2022-09-16 12:39:27 -040080 if !hasDep(libFoo, libBaz) {
Liz Kammer81d09502022-10-31 14:44:46 -040081 t.Errorf("'foo' missing dependency on thin lto variant of transitive dep 'baz'")
82 }
83
84 libNeverLto := result.ModuleForTests("lib_never_lto", "android_arm64_armv8-a_static_lto-thin").Module()
85 if !hasDep(libLto, libNeverLto) {
86 t.Errorf("'lto_enabled' missing dependency on NO-thin lto variant of 'lib_never_lto'")
87 }
88
89 libBar := result.ModuleForTests("bar", "android_arm64_armv8-a_shared").Module()
90 if !hasDep(libLto, libBar) {
91 t.Errorf("'lto_enabled' missing dependency on non-thin lto variant of 'bar'")
Liz Kammer3b0f36c2022-09-16 12:39:27 -040092 }
93
94 barVariants := result.ModuleVariantsForTests("bar")
95 for _, v := range barVariants {
96 if strings.Contains(v, "lto-thin") {
97 t.Errorf("Expected variants for 'bar' to not contain 'lto-thin', but found %q", v)
98 }
99 }
100 quxVariants := result.ModuleVariantsForTests("qux")
101 for _, v := range quxVariants {
102 if strings.Contains(v, "lto-thin") {
103 t.Errorf("Expected variants for 'qux' to not contain 'lto-thin', but found %q", v)
104 }
105 }
106}
Liz Kammer81d09502022-10-31 14:44:46 -0400107
108func TestThinLtoOnlyOnStaticDep(t *testing.T) {
109 bp := `
110 cc_library_shared {
111 name: "root",
112 srcs: ["src.c"],
113 static_libs: ["foo"],
114 }
115 cc_library_shared {
116 name: "root_no_lto",
117 srcs: ["src.c"],
118 static_libs: ["foo"],
119 lto: {
120 never: true,
121 }
122 }
123 cc_library_static {
124 name: "foo",
125 srcs: ["foo.c"],
126 static_libs: ["baz"],
127 lto: {
128 thin: true,
129 }
130 }
131 cc_library_static {
132 name: "baz",
133 srcs: ["baz.c"],
134 }
135`
136
137 result := android.GroupFixturePreparers(
138 prepareForCcTest,
139 ).RunTestWithBp(t, bp)
140
141 libRoot := result.ModuleForTests("root", "android_arm64_armv8-a_shared").Module()
142 libRootLtoNever := result.ModuleForTests("root_no_lto", "android_arm64_armv8-a_shared").Module()
143
144 hasDep := func(m android.Module, wantDep android.Module) bool {
145 var found bool
146 result.VisitDirectDeps(m, func(dep blueprint.Module) {
147 if dep == wantDep {
148 found = true
149 }
150 })
151 return found
152 }
153
154 libFoo := result.ModuleForTests("foo", "android_arm64_armv8-a_static")
155 if !hasDep(libRoot, libFoo.Module()) {
156 t.Errorf("'root' missing dependency on thin lto variant of 'foo'")
157 }
158
159 if !hasDep(libRootLtoNever, libFoo.Module()) {
160 t.Errorf("'root_no_lto' missing dependency on thin lto variant of 'foo'")
161 }
162
163 libFooCFlags := libFoo.Rule("cc").Args["cFlags"]
164 if w := "-flto=thin -fsplit-lto-unit"; !strings.Contains(libFooCFlags, w) {
165 t.Errorf("'foo' expected to have flags %q, but got %q", w, libFooCFlags)
166 }
167
168 libBaz := result.ModuleForTests("baz", "android_arm64_armv8-a_static_lto-thin")
169 if !hasDep(libFoo.Module(), libBaz.Module()) {
170 t.Errorf("'foo' missing dependency on thin lto variant of transitive dep 'baz'")
171 }
172
173 libBazCFlags := libFoo.Rule("cc").Args["cFlags"]
174 if w := "-flto=thin -fsplit-lto-unit"; !strings.Contains(libBazCFlags, w) {
175 t.Errorf("'baz' expected to have flags %q, but got %q", w, libFooCFlags)
176 }
177}