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	"testing"
19
20	"android/soong/android"
21
22	"github.com/google/blueprint"
23)
24
25func testPrebuilt(t *testing.T, bp string, fs map[string][]byte) *android.TestContext {
26	config := TestConfig(buildDir, android.Android, nil, bp, fs)
27	ctx := CreateTestContext()
28
29	// Enable androidmk support.
30	// * Register the singleton
31	// * Configure that we are inside make
32	// * Add CommonOS to ensure that androidmk processing works.
33	android.RegisterAndroidMkBuildComponents(ctx)
34	android.SetInMakeForTests(config)
35
36	ctx.Register(config)
37	_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
38	android.FailIfErrored(t, errs)
39	_, errs = ctx.PrepareBuildActions(config)
40	android.FailIfErrored(t, errs)
41	return ctx
42}
43
44func TestPrebuilt(t *testing.T) {
45	bp := `
46		cc_library {
47			name: "liba",
48		}
49
50		cc_prebuilt_library_shared {
51			name: "liba",
52			srcs: ["liba.so"],
53		}
54
55		cc_library {
56			name: "libb",
57		}
58
59		cc_prebuilt_library_static {
60			name: "libb",
61			srcs: ["libb.a"],
62		}
63
64		cc_library_shared {
65			name: "libd",
66		}
67
68		cc_prebuilt_library_shared {
69			name: "libd",
70			srcs: ["libd.so"],
71		}
72
73		cc_library_static {
74			name: "libe",
75		}
76
77		cc_prebuilt_library_static {
78			name: "libe",
79			srcs: ["libe.a"],
80		}
81
82		cc_library {
83			name: "libf",
84		}
85
86		cc_prebuilt_library {
87			name: "libf",
88			static: {
89				srcs: ["libf.a"],
90			},
91			shared: {
92				srcs: ["libf.so"],
93			},
94		}
95
96		cc_object {
97			name: "crtx",
98		}
99
100		cc_prebuilt_object {
101			name: "crtx",
102			srcs: ["crtx.o"],
103		}
104	`
105
106	ctx := testPrebuilt(t, bp, map[string][]byte{
107		"liba.so": nil,
108		"libb.a":  nil,
109		"libd.so": nil,
110		"libe.a":  nil,
111		"libf.a":  nil,
112		"libf.so": nil,
113		"crtx.o":  nil,
114	})
115
116	// Verify that all the modules exist and that their dependencies were connected correctly
117	liba := ctx.ModuleForTests("liba", "android_arm64_armv8-a_shared").Module()
118	libb := ctx.ModuleForTests("libb", "android_arm64_armv8-a_static").Module()
119	libd := ctx.ModuleForTests("libd", "android_arm64_armv8-a_shared").Module()
120	libe := ctx.ModuleForTests("libe", "android_arm64_armv8-a_static").Module()
121	libfStatic := ctx.ModuleForTests("libf", "android_arm64_armv8-a_static").Module()
122	libfShared := ctx.ModuleForTests("libf", "android_arm64_armv8-a_shared").Module()
123	crtx := ctx.ModuleForTests("crtx", "android_arm64_armv8-a").Module()
124
125	prebuiltLiba := ctx.ModuleForTests("prebuilt_liba", "android_arm64_armv8-a_shared").Module()
126	prebuiltLibb := ctx.ModuleForTests("prebuilt_libb", "android_arm64_armv8-a_static").Module()
127	prebuiltLibd := ctx.ModuleForTests("prebuilt_libd", "android_arm64_armv8-a_shared").Module()
128	prebuiltLibe := ctx.ModuleForTests("prebuilt_libe", "android_arm64_armv8-a_static").Module()
129	prebuiltLibfStatic := ctx.ModuleForTests("prebuilt_libf", "android_arm64_armv8-a_static").Module()
130	prebuiltLibfShared := ctx.ModuleForTests("prebuilt_libf", "android_arm64_armv8-a_shared").Module()
131	prebuiltCrtx := ctx.ModuleForTests("prebuilt_crtx", "android_arm64_armv8-a").Module()
132
133	hasDep := func(m android.Module, wantDep android.Module) bool {
134		t.Helper()
135		var found bool
136		ctx.VisitDirectDeps(m, func(dep blueprint.Module) {
137			if dep == wantDep {
138				found = true
139			}
140		})
141		return found
142	}
143
144	if !hasDep(liba, prebuiltLiba) {
145		t.Errorf("liba missing dependency on prebuilt_liba")
146	}
147
148	if !hasDep(libb, prebuiltLibb) {
149		t.Errorf("libb missing dependency on prebuilt_libb")
150	}
151
152	if !hasDep(libd, prebuiltLibd) {
153		t.Errorf("libd missing dependency on prebuilt_libd")
154	}
155
156	if !hasDep(libe, prebuiltLibe) {
157		t.Errorf("libe missing dependency on prebuilt_libe")
158	}
159
160	if !hasDep(libfStatic, prebuiltLibfStatic) {
161		t.Errorf("libf static missing dependency on prebuilt_libf")
162	}
163
164	if !hasDep(libfShared, prebuiltLibfShared) {
165		t.Errorf("libf shared missing dependency on prebuilt_libf")
166	}
167
168	if !hasDep(crtx, prebuiltCrtx) {
169		t.Errorf("crtx missing dependency on prebuilt_crtx")
170	}
171}
172
173func TestPrebuiltLibraryShared(t *testing.T) {
174	ctx := testPrebuilt(t, `
175	cc_prebuilt_library_shared {
176		name: "libtest",
177		srcs: ["libf.so"],
178    strip: {
179        none: true,
180    },
181	}
182	`, map[string][]byte{
183		"libf.so": nil,
184	})
185
186	shared := ctx.ModuleForTests("libtest", "android_arm64_armv8-a_shared").Module().(*Module)
187	assertString(t, shared.OutputFile().Path().Base(), "libtest.so")
188}
189
190func TestPrebuiltLibraryStatic(t *testing.T) {
191	ctx := testPrebuilt(t, `
192	cc_prebuilt_library_static {
193		name: "libtest",
194		srcs: ["libf.a"],
195	}
196	`, map[string][]byte{
197		"libf.a": nil,
198	})
199
200	static := ctx.ModuleForTests("libtest", "android_arm64_armv8-a_static").Module().(*Module)
201	assertString(t, static.OutputFile().Path().Base(), "libf.a")
202}
203
204func TestPrebuiltLibrary(t *testing.T) {
205	ctx := testPrebuilt(t, `
206	cc_prebuilt_library {
207		name: "libtest",
208		static: {
209			srcs: ["libf.a"],
210		},
211		shared: {
212			srcs: ["libf.so"],
213		},
214    strip: {
215        none: true,
216    },
217	}
218	`, map[string][]byte{
219		"libf.a":  nil,
220		"libf.so": nil,
221	})
222
223	shared := ctx.ModuleForTests("libtest", "android_arm64_armv8-a_shared").Module().(*Module)
224	assertString(t, shared.OutputFile().Path().Base(), "libtest.so")
225
226	static := ctx.ModuleForTests("libtest", "android_arm64_armv8-a_static").Module().(*Module)
227	assertString(t, static.OutputFile().Path().Base(), "libf.a")
228}
229
230func TestPrebuiltLibraryStem(t *testing.T) {
231	ctx := testPrebuilt(t, `
232	cc_prebuilt_library {
233		name: "libfoo",
234		stem: "libbar",
235		static: {
236			srcs: ["libfoo.a"],
237		},
238		shared: {
239			srcs: ["libfoo.so"],
240		},
241		strip: {
242			none: true,
243		},
244	}
245	`, map[string][]byte{
246		"libfoo.a":  nil,
247		"libfoo.so": nil,
248	})
249
250	static := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static").Module().(*Module)
251	assertString(t, static.OutputFile().Path().Base(), "libfoo.a")
252
253	shared := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module().(*Module)
254	assertString(t, shared.OutputFile().Path().Base(), "libbar.so")
255}
256
257func TestPrebuiltLibrarySharedStem(t *testing.T) {
258	ctx := testPrebuilt(t, `
259	cc_prebuilt_library_shared {
260		name: "libfoo",
261		stem: "libbar",
262		srcs: ["libfoo.so"],
263		strip: {
264			none: true,
265		},
266	}
267	`, map[string][]byte{
268		"libfoo.so": nil,
269	})
270
271	shared := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module().(*Module)
272	assertString(t, shared.OutputFile().Path().Base(), "libbar.so")
273}
274