blob: 01b89dbe20fe295aec7e8ea18911b1b02278028d [file] [log] [blame]
Ivan Lozanoffee3342019-08-27 12:03:00 -07001// Copyright 2019 The Android Open Source Project
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 rust
16
17import (
18 "io/ioutil"
19 "os"
Ivan Lozanoc0083612019-09-03 13:49:39 -070020 "runtime"
Ivan Lozanob9040d62019-09-24 13:23:50 -070021 "strings"
Ivan Lozanoffee3342019-08-27 12:03:00 -070022 "testing"
23
24 "android/soong/android"
25)
26
27var (
28 buildDir string
29)
30
31func setUp() {
32 var err error
33 buildDir, err = ioutil.TempDir("", "soong_rust_test")
34 if err != nil {
35 panic(err)
36 }
37}
38
39func tearDown() {
40 os.RemoveAll(buildDir)
41}
42
43func TestMain(m *testing.M) {
44 run := func() int {
45 setUp()
46 defer tearDown()
47
48 return m.Run()
49 }
50
51 os.Exit(run())
52}
53
54func testRust(t *testing.T, bp string) *android.TestContext {
Ivan Lozanoc0083612019-09-03 13:49:39 -070055 // TODO (b/140435149)
56 if runtime.GOOS != "linux" {
57 t.Skip("Only the Linux toolchain is supported for Rust")
58 }
59
Ivan Lozanoffee3342019-08-27 12:03:00 -070060 t.Helper()
61 config := android.TestArchConfig(buildDir, nil)
62
63 t.Helper()
64 ctx := CreateTestContext(bp)
65 ctx.Register()
66
67 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
68 android.FailIfErrored(t, errs)
69 _, errs = ctx.PrepareBuildActions(config)
70 android.FailIfErrored(t, errs)
71
72 return ctx
73}
74
75func testRustError(t *testing.T, pattern string, bp string) {
Ivan Lozanoc0083612019-09-03 13:49:39 -070076 // TODO (b/140435149)
77 if runtime.GOOS != "linux" {
78 t.Skip("Only the Linux toolchain is supported for Rust")
79 }
80
Ivan Lozanoffee3342019-08-27 12:03:00 -070081 t.Helper()
82 config := android.TestArchConfig(buildDir, nil)
83
84 ctx := CreateTestContext(bp)
85 ctx.Register()
86
87 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
88 if len(errs) > 0 {
89 android.FailIfNoMatchingErrors(t, pattern, errs)
90 return
91 }
92
93 _, errs = ctx.PrepareBuildActions(config)
94 if len(errs) > 0 {
95 android.FailIfNoMatchingErrors(t, pattern, errs)
96 return
97 }
98
99 t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
100}
101
102// Test that we can extract the lib name from a lib path.
103func TestLibNameFromFilePath(t *testing.T) {
Ivan Lozano52767be2019-10-18 14:49:46 -0700104 libBarPath := android.PathForTesting("out/soong/.intermediates/external/libbar/libbar/linux_glibc_x86_64_shared/libbar.so")
105 libLibPath := android.PathForTesting("out/soong/.intermediates/external/libbar/libbar/linux_glibc_x86_64_shared/liblib.dylib.so")
Ivan Lozanoffee3342019-08-27 12:03:00 -0700106
Ivan Lozano52767be2019-10-18 14:49:46 -0700107 libBarName := libNameFromFilePath(libBarPath)
108 libLibName := libNameFromFilePath(libLibPath)
109
110 expectedResult := "bar"
111 if libBarName != expectedResult {
112 t.Errorf("libNameFromFilePath returned the wrong name; expected '%#v', got '%#v'", expectedResult, libBarName)
113 }
114
115 expectedResult = "lib.dylib"
116 if libLibName != expectedResult {
117 t.Errorf("libNameFromFilePath returned the wrong name; expected '%#v', got '%#v'", expectedResult, libLibPath)
Ivan Lozanoffee3342019-08-27 12:03:00 -0700118 }
119}
120
121// Test that we can extract the link path from a lib path.
122func TestLinkPathFromFilePath(t *testing.T) {
123 barPath := android.PathForTesting("out/soong/.intermediates/external/libbar/libbar/linux_glibc_x86_64_shared/libbar.so")
124 libName := linkPathFromFilePath(barPath)
125 expectedResult := "out/soong/.intermediates/external/libbar/libbar/linux_glibc_x86_64_shared/"
126
127 if libName != expectedResult {
128 t.Errorf("libNameFromFilePath returned the wrong name; expected '%#v', got '%#v'", expectedResult, libName)
129 }
130}
131
Ivan Lozanoffee3342019-08-27 12:03:00 -0700132// Test to make sure dependencies are being picked up correctly.
133func TestDepsTracking(t *testing.T) {
134 ctx := testRust(t, `
Ivan Lozano52767be2019-10-18 14:49:46 -0700135 rust_library_host_static {
136 name: "libstatic",
137 srcs: ["foo.rs"],
Ivan Lozanoad8b18b2019-10-31 19:38:29 -0700138 crate_name: "static",
Ivan Lozano52767be2019-10-18 14:49:46 -0700139 }
140 rust_library_host_shared {
141 name: "libshared",
142 srcs: ["foo.rs"],
Ivan Lozanoad8b18b2019-10-31 19:38:29 -0700143 crate_name: "shared",
Ivan Lozano52767be2019-10-18 14:49:46 -0700144 }
Ivan Lozanoffee3342019-08-27 12:03:00 -0700145 rust_library_host_dylib {
Ivan Lozano52767be2019-10-18 14:49:46 -0700146 name: "libdylib",
Ivan Lozanoffee3342019-08-27 12:03:00 -0700147 srcs: ["foo.rs"],
Ivan Lozanoad8b18b2019-10-31 19:38:29 -0700148 crate_name: "dylib",
Ivan Lozanoffee3342019-08-27 12:03:00 -0700149 }
150 rust_library_host_rlib {
Ivan Lozano52767be2019-10-18 14:49:46 -0700151 name: "librlib",
Ivan Lozanoffee3342019-08-27 12:03:00 -0700152 srcs: ["foo.rs"],
Ivan Lozanoad8b18b2019-10-31 19:38:29 -0700153 crate_name: "rlib",
Ivan Lozanoffee3342019-08-27 12:03:00 -0700154 }
155 rust_proc_macro {
156 name: "libpm",
157 srcs: ["foo.rs"],
Ivan Lozanoad8b18b2019-10-31 19:38:29 -0700158 crate_name: "pm",
Ivan Lozanoffee3342019-08-27 12:03:00 -0700159 }
160 rust_binary_host {
161 name: "fizz-buzz",
Ivan Lozano52767be2019-10-18 14:49:46 -0700162 dylibs: ["libdylib"],
163 rlibs: ["librlib"],
Ivan Lozanoffee3342019-08-27 12:03:00 -0700164 proc_macros: ["libpm"],
Ivan Lozano52767be2019-10-18 14:49:46 -0700165 static_libs: ["libstatic"],
166 shared_libs: ["libshared"],
Ivan Lozanoffee3342019-08-27 12:03:00 -0700167 srcs: ["foo.rs"],
168 }
169 `)
170 module := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Module().(*Module)
171
172 // Since dependencies are added to AndroidMk* properties, we can check these to see if they've been picked up.
Ivan Lozano52767be2019-10-18 14:49:46 -0700173 if !android.InList("libdylib", module.Properties.AndroidMkDylibs) {
Ivan Lozanoffee3342019-08-27 12:03:00 -0700174 t.Errorf("Dylib dependency not detected (dependency missing from AndroidMkDylibs)")
175 }
176
Ivan Lozano52767be2019-10-18 14:49:46 -0700177 if !android.InList("librlib", module.Properties.AndroidMkRlibs) {
Ivan Lozanoffee3342019-08-27 12:03:00 -0700178 t.Errorf("Rlib dependency not detected (dependency missing from AndroidMkRlibs)")
179 }
180
181 if !android.InList("libpm", module.Properties.AndroidMkProcMacroLibs) {
182 t.Errorf("Proc_macro dependency not detected (dependency missing from AndroidMkProcMacroLibs)")
183 }
184
Ivan Lozano52767be2019-10-18 14:49:46 -0700185 if !android.InList("libshared", module.Properties.AndroidMkSharedLibs) {
186 t.Errorf("Shared library dependency not detected (dependency missing from AndroidMkSharedLibs)")
187 }
188
189 if !android.InList("libstatic", module.Properties.AndroidMkStaticLibs) {
190 t.Errorf("Static library dependency not detected (dependency missing from AndroidMkStaticLibs)")
191 }
Ivan Lozanoffee3342019-08-27 12:03:00 -0700192}
Ivan Lozanob9040d62019-09-24 13:23:50 -0700193
194// Test to make sure proc_macros use host variants when building device modules.
195func TestProcMacroDeviceDeps(t *testing.T) {
196 ctx := testRust(t, `
197 rust_library_host_rlib {
198 name: "libbar",
199 srcs: ["foo.rs"],
Ivan Lozanoad8b18b2019-10-31 19:38:29 -0700200 crate_name: "bar",
Ivan Lozanob9040d62019-09-24 13:23:50 -0700201 }
Matthew Maurer99020b02019-10-31 10:44:40 -0700202 // Make a dummy libstd to let resolution go through
203 rust_library_dylib {
204 name: "libstd",
205 crate_name: "std",
206 srcs: ["foo.rs"],
207 no_stdlibs: true,
208 }
209 rust_library_dylib {
210 name: "libterm",
211 crate_name: "term",
212 srcs: ["foo.rs"],
213 no_stdlibs: true,
214 }
215 rust_library_dylib {
216 name: "libtest",
217 crate_name: "test",
218 srcs: ["foo.rs"],
219 no_stdlibs: true,
220 }
Ivan Lozanob9040d62019-09-24 13:23:50 -0700221 rust_proc_macro {
222 name: "libpm",
223 rlibs: ["libbar"],
224 srcs: ["foo.rs"],
Ivan Lozanoad8b18b2019-10-31 19:38:29 -0700225 crate_name: "pm",
Ivan Lozanob9040d62019-09-24 13:23:50 -0700226 }
227 rust_binary {
228 name: "fizz-buzz",
229 proc_macros: ["libpm"],
230 srcs: ["foo.rs"],
231 }
232 `)
233 rustc := ctx.ModuleForTests("libpm", "linux_glibc_x86_64").Rule("rustc")
234
235 if !strings.Contains(rustc.Args["libFlags"], "libbar/linux_glibc_x86_64") {
236 t.Errorf("Proc_macro is not using host variant of dependent modules.")
237 }
238}
Matthew Maurer99020b02019-10-31 10:44:40 -0700239
240// Test that no_stdlibs suppresses dependencies on rust standard libraries
241func TestNoStdlibs(t *testing.T) {
242 ctx := testRust(t, `
243 rust_binary {
244 name: "fizz-buzz",
245 srcs: ["foo.rs"],
246 no_stdlibs: true,
247 }`)
Colin Cross7113d202019-11-20 16:39:12 -0800248 module := ctx.ModuleForTests("fizz-buzz", "android_arm64_armv8-a").Module().(*Module)
Matthew Maurer99020b02019-10-31 10:44:40 -0700249
250 if android.InList("libstd", module.Properties.AndroidMkDylibs) {
251 t.Errorf("no_stdlibs did not suppress dependency on libstd")
252 }
253}