• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // 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 
15 package rust
16 
17 import (
18 	"strings"
19 	"testing"
20 
21 	"android/soong/android"
22 )
23 
24 // Test that rustlibs default linkage is correct for binaries.
25 func TestBinaryLinkage(t *testing.T) {
26 	ctx := testRust(t, `
27 		rust_binary {
28 			name: "fizz-buzz",
29 			srcs: ["foo.rs"],
30 			rustlibs: ["libfoo"],
31 			host_supported: true,
32 		}
33 		rust_binary {
34 			name: "rlib_linked",
35 			srcs: ["foo.rs"],
36 			rustlibs: ["libfoo"],
37 			host_supported: true,
38 			prefer_rlib: true,
39 		}
40 		rust_library {
41 			name: "libfoo",
42 			srcs: ["foo.rs"],
43 			crate_name: "foo",
44 			host_supported: true,
45 		}`)
46 
47 	fizzBuzzHost := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Module().(*Module)
48 	fizzBuzzDevice := ctx.ModuleForTests("fizz-buzz", "android_arm64_armv8-a").Module().(*Module)
49 
50 	if !android.InList("libfoo.rlib-std", fizzBuzzHost.Properties.AndroidMkRlibs) {
51 		t.Errorf("rustlibs dependency libfoo should be an rlib dep for host modules")
52 	}
53 
54 	if !android.InList("libfoo", fizzBuzzDevice.Properties.AndroidMkDylibs) {
55 		t.Errorf("rustlibs dependency libfoo should be an dylib dep for device modules")
56 	}
57 }
58 
59 // Test that prefer_rlib links in libstd statically as well as rustlibs.
60 func TestBinaryPreferRlib(t *testing.T) {
61 	ctx := testRust(t, `
62 		rust_binary {
63 			name: "rlib_linked",
64 			srcs: ["foo.rs"],
65 			rustlibs: ["libfoo"],
66 			host_supported: true,
67 			prefer_rlib: true,
68 		}
69 		rust_library {
70 			name: "libfoo",
71 			srcs: ["foo.rs"],
72 			crate_name: "foo",
73 			host_supported: true,
74 		}`)
75 
76 	mod := ctx.ModuleForTests("rlib_linked", "android_arm64_armv8-a").Module().(*Module)
77 
78 	if !android.InList("libfoo.rlib-std", mod.Properties.AndroidMkRlibs) {
79 		t.Errorf("rustlibs dependency libfoo should be an rlib dep when prefer_rlib is defined")
80 	}
81 
82 	if !android.InList("libstd", mod.Properties.AndroidMkRlibs) {
83 		t.Errorf("libstd dependency should be an rlib dep when prefer_rlib is defined")
84 	}
85 }
86 
87 // Test that the path returned by HostToolPath is correct
88 func TestHostToolPath(t *testing.T) {
89 	ctx := testRust(t, `
90 		rust_binary_host {
91 			name: "fizz-buzz",
92 			srcs: ["foo.rs"],
93 		}`)
94 
95 	path := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Module().(*Module).HostToolPath()
96 	if g, w := path.String(), "/host/linux-x86/bin/fizz-buzz"; !strings.Contains(g, w) {
97 		t.Errorf("wrong host tool path, expected %q got %q", w, g)
98 	}
99 }
100 
101 // Test that the flags being passed to rust_binary modules are as expected
102 func TestBinaryFlags(t *testing.T) {
103 	ctx := testRust(t, `
104 		rust_binary_host {
105 			name: "fizz-buzz",
106 			srcs: ["foo.rs"],
107 		}`)
108 
109 	fizzBuzz := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Output("fizz-buzz")
110 
111 	flags := fizzBuzz.Args["rustcFlags"]
112 	if strings.Contains(flags, "--test") {
113 		t.Errorf("extra --test flag, rustcFlags: %#v", flags)
114 	}
115 }
116 
117 func TestStaticBinaryFlags(t *testing.T) {
118 	ctx := testRust(t, `
119 		rust_binary {
120 			name: "fizz",
121 			srcs: ["foo.rs"],
122 			static_executable: true,
123 		}`)
124 
125 	fizzOut := ctx.ModuleForTests("fizz", "android_arm64_armv8-a").Output("fizz")
126 	fizzMod := ctx.ModuleForTests("fizz", "android_arm64_armv8-a").Module().(*Module)
127 
128 	flags := fizzOut.Args["rustcFlags"]
129 	linkFlags := fizzOut.Args["linkFlags"]
130 	if !strings.Contains(flags, "-C relocation-model=static") {
131 		t.Errorf("static binary missing '-C relocation-model=static' in rustcFlags, found: %#v", flags)
132 	}
133 	if !strings.Contains(flags, "-C panic=abort") {
134 		t.Errorf("static binary missing '-C panic=abort' in rustcFlags, found: %#v", flags)
135 	}
136 	if !strings.Contains(linkFlags, "-static") {
137 		t.Errorf("static binary missing '-static' in linkFlags, found: %#v", flags)
138 	}
139 
140 	if !android.InList("libc", fizzMod.Properties.AndroidMkStaticLibs) {
141 		t.Errorf("static binary not linking against libc as a static library")
142 	}
143 	if len(fizzMod.Properties.AndroidMkSharedLibs) > 0 {
144 		t.Errorf("static binary incorrectly linking against shared libraries")
145 	}
146 }
147 
148 func TestLinkObjects(t *testing.T) {
149 	ctx := testRust(t, `
150 		rust_binary {
151 			name: "fizz-buzz",
152 			srcs: ["foo.rs"],
153 			shared_libs: ["libfoo"],
154 		}
155 		cc_library {
156 			name: "libfoo",
157 		}`)
158 
159 	fizzBuzz := ctx.ModuleForTests("fizz-buzz", "android_arm64_armv8-a").Output("fizz-buzz")
160 	linkFlags := fizzBuzz.Args["linkFlags"]
161 	if !strings.Contains(linkFlags, "/libfoo.so") {
162 		t.Errorf("missing shared dependency 'libfoo.so' in linkFlags: %#v", linkFlags)
163 	}
164 }
165 
166 // Test that stripped versions are correctly generated and used.
167 func TestStrippedBinary(t *testing.T) {
168 	ctx := testRust(t, `
169 		rust_binary {
170 			name: "foo",
171 			srcs: ["foo.rs"],
172 		}
173 		rust_binary {
174 			name: "bar",
175 			srcs: ["foo.rs"],
176 			strip: {
177 				none: true
178 			}
179 		}
180 	`)
181 
182 	foo := ctx.ModuleForTests("foo", "android_arm64_armv8-a")
183 	foo.Output("stripped/foo")
184 	// Check that the `cp` rules is using the stripped version as input.
185 	cp := foo.Rule("android.Cp")
186 	if !strings.HasSuffix(cp.Input.String(), "stripped/foo") {
187 		t.Errorf("installed binary not based on stripped version: %v", cp.Input)
188 	}
189 
190 	fizzBar := ctx.ModuleForTests("bar", "android_arm64_armv8-a").MaybeOutput("stripped/bar")
191 	if fizzBar.Rule != nil {
192 		t.Errorf("stripped version of bar has been generated")
193 	}
194 }
195