• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "gn/rust_project_writer_helpers.h"
6 
7 #include "base/strings/string_util.h"
8 #include "gn/filesystem_utils.h"
9 #include "gn/string_output_buffer.h"
10 #include "gn/test_with_scheduler.h"
11 #include "gn/test_with_scope.h"
12 #include "util/build_config.h"
13 #include "util/test/test.h"
14 
ExpectEqOrShowDiff(const char * expected,const std::string & actual)15 static void ExpectEqOrShowDiff(const char* expected,
16                                const std::string& actual) {
17   if (expected != actual) {
18     printf("\nExpected: >>>\n%s<<<\n", expected);
19     printf("  Actual: >>>\n%s<<<\n", actual.c_str());
20   }
21   EXPECT_EQ(expected, actual);
22 }
23 
24 using RustProjectWriterHelper = TestWithScheduler;
25 
TEST_F(RustProjectWriterHelper,WriteCrates)26 TEST_F(RustProjectWriterHelper, WriteCrates) {
27   TestWithScope setup;
28 
29   CrateList crates;
30   Crate dep = Crate(SourceFile("/root/tortoise/lib.rs"), std::nullopt, 0,
31                     "//tortoise:bar", "2015");
32   Crate target = Crate(SourceFile("/root/hare/lib.rs"),
33                        OutputFile("gendir/hare/"), 1, "//hare:bar", "2015");
34   target.AddDependency(0, "tortoise");
35   target.AddConfigItem("unix");
36   target.AddConfigItem("feature=\"test\"");
37 
38   crates.push_back(dep);
39   crates.push_back(target);
40 
41   std::ostringstream stream;
42   WriteCrates(setup.build_settings(), crates, stream);
43   std::string out = stream.str();
44 #if defined(OS_WIN)
45   base::ReplaceSubstringsAfterOffset(&out, 0, "\r\n", "\n");
46 #endif
47   const char expected_json[] =
48       "{\n"
49       "  \"crates\": [\n"
50       "    {\n"
51       "      \"crate_id\": 0,\n"
52       "      \"root_module\": \"/root/tortoise/lib.rs\",\n"
53       "      \"label\": \"//tortoise:bar\",\n"
54       "      \"source\": {\n"
55       "          \"include_dirs\": [\n"
56       "               \"/root/tortoise/\"\n"
57       "          ],\n"
58       "          \"exclude_dirs\": []\n"
59       "      },\n"
60       "      \"deps\": [\n"
61       "      ],\n"
62       "      \"edition\": \"2015\",\n"
63       "      \"cfg\": [\n"
64       "      ]\n"
65       "    },\n"
66       "    {\n"
67       "      \"crate_id\": 1,\n"
68       "      \"root_module\": \"/root/hare/lib.rs\",\n"
69       "      \"label\": \"//hare:bar\",\n"
70       "      \"source\": {\n"
71       "          \"include_dirs\": [\n"
72       "               \"/root/hare/\",\n"
73       "               \"out/Debug/gendir/hare/\"\n"
74       "          ],\n"
75       "          \"exclude_dirs\": []\n"
76       "      },\n"
77       "      \"deps\": [\n"
78       "        {\n"
79       "          \"crate\": 0,\n"
80       "          \"name\": \"tortoise\"\n"
81       "        }\n"
82       "      ],\n"
83       "      \"edition\": \"2015\",\n"
84       "      \"cfg\": [\n"
85       "        \"unix\",\n"
86       "        \"feature=\\\"test\\\"\"\n"
87       "      ]\n"
88       "    }\n"
89       "  ]\n"
90       "}\n";
91 
92   ExpectEqOrShowDiff(expected_json, out);
93 }
94 
TEST_F(RustProjectWriterHelper,SysrootDepsAreCorrect)95 TEST_F(RustProjectWriterHelper, SysrootDepsAreCorrect) {
96   TestWithScope setup;
97   setup.build_settings()->SetRootPath(UTF8ToFilePath("/root"));
98 
99   SysrootIndexMap sysroot_lookup;
100   CrateList crates;
101 
102   AddSysroot(setup.build_settings(), "sysroot", sysroot_lookup, crates);
103 
104   std::ostringstream stream;
105   WriteCrates(setup.build_settings(), crates, stream);
106   std::string out = stream.str();
107 #if defined(OS_WIN)
108   base::ReplaceSubstringsAfterOffset(&out, 0, "\r\n", "\n");
109 #endif
110 
111   const char expected_json[] =
112       "{\n"
113       "  \"crates\": [\n"
114       "    {\n"
115       "      \"crate_id\": 0,\n"
116       "      \"root_module\": "
117       "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/core/src/"
118       "lib.rs\",\n"
119       "      \"label\": \"core\",\n"
120       "      \"source\": {\n"
121       "          \"include_dirs\": [\n"
122       "               "
123       "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/core/src/\"\n"
124       "          ],\n"
125       "          \"exclude_dirs\": []\n"
126       "      },\n"
127       "      \"deps\": [\n"
128       "      ],\n"
129       "      \"edition\": \"2018\",\n"
130       "      \"cfg\": [\n"
131       "        \"debug_assertions\"\n"
132       "      ]\n"
133       "    },\n"
134       "    {\n"
135       "      \"crate_id\": 1,\n"
136       "      \"root_module\": "
137       "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/alloc/src/"
138       "lib.rs\",\n"
139       "      \"label\": \"alloc\",\n"
140       "      \"source\": {\n"
141       "          \"include_dirs\": [\n"
142       "               "
143       "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/alloc/src/\"\n"
144       "          ],\n"
145       "          \"exclude_dirs\": []\n"
146       "      },\n"
147       "      \"deps\": [\n"
148       "        {\n"
149       "          \"crate\": 0,\n"
150       "          \"name\": \"core\"\n"
151       "        }\n"
152       "      ],\n"
153       "      \"edition\": \"2018\",\n"
154       "      \"cfg\": [\n"
155       "        \"debug_assertions\"\n"
156       "      ]\n"
157       "    },\n"
158       "    {\n"
159       "      \"crate_id\": 2,\n"
160       "      \"root_module\": "
161       "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/panic_abort/src/"
162       "lib.rs\",\n"
163       "      \"label\": \"panic_abort\",\n"
164       "      \"source\": {\n"
165       "          \"include_dirs\": [\n"
166       "               "
167       "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/panic_abort/src/"
168       "\"\n"
169       "          ],\n"
170       "          \"exclude_dirs\": []\n"
171       "      },\n"
172       "      \"deps\": [\n"
173       "      ],\n"
174       "      \"edition\": \"2018\",\n"
175       "      \"cfg\": [\n"
176       "        \"debug_assertions\"\n"
177       "      ]\n"
178       "    },\n"
179       "    {\n"
180       "      \"crate_id\": 3,\n"
181       "      \"root_module\": "
182       "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/unwind/src/"
183       "lib.rs\",\n"
184       "      \"label\": \"unwind\",\n"
185       "      \"source\": {\n"
186       "          \"include_dirs\": [\n"
187       "               "
188       "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/unwind/src/\"\n"
189       "          ],\n"
190       "          \"exclude_dirs\": []\n"
191       "      },\n"
192       "      \"deps\": [\n"
193       "      ],\n"
194       "      \"edition\": \"2018\",\n"
195       "      \"cfg\": [\n"
196       "        \"debug_assertions\"\n"
197       "      ]\n"
198       "    },\n"
199       "    {\n"
200       "      \"crate_id\": 4,\n"
201       "      \"root_module\": "
202       "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/std/src/"
203       "lib.rs\",\n"
204       "      \"label\": \"std\",\n"
205       "      \"source\": {\n"
206       "          \"include_dirs\": [\n"
207       "               "
208       "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/std/src/\"\n"
209       "          ],\n"
210       "          \"exclude_dirs\": []\n"
211       "      },\n"
212       "      \"deps\": [\n"
213       "        {\n"
214       "          \"crate\": 1,\n"
215       "          \"name\": \"alloc\"\n"
216       "        },\n"
217       "        {\n"
218       "          \"crate\": 0,\n"
219       "          \"name\": \"core\"\n"
220       "        },\n"
221       "        {\n"
222       "          \"crate\": 2,\n"
223       "          \"name\": \"panic_abort\"\n"
224       "        },\n"
225       "        {\n"
226       "          \"crate\": 3,\n"
227       "          \"name\": \"unwind\"\n"
228       "        }\n"
229       "      ],\n"
230       "      \"edition\": \"2018\",\n"
231       "      \"cfg\": [\n"
232       "        \"debug_assertions\"\n"
233       "      ]\n"
234       "    },\n"
235       "    {\n"
236       "      \"crate_id\": 5,\n"
237       "      \"root_module\": "
238       "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/panic_unwind/src/"
239       "lib.rs\",\n"
240       "      \"label\": \"panic_unwind\",\n"
241       "      \"source\": {\n"
242       "          \"include_dirs\": [\n"
243       "               "
244       "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/panic_unwind/src/"
245       "\"\n"
246       "          ],\n"
247       "          \"exclude_dirs\": []\n"
248       "      },\n"
249       "      \"deps\": [\n"
250       "      ],\n"
251       "      \"edition\": \"2018\",\n"
252       "      \"cfg\": [\n"
253       "        \"debug_assertions\"\n"
254       "      ]\n"
255       "    },\n"
256       "    {\n"
257       "      \"crate_id\": 6,\n"
258       "      \"root_module\": "
259       "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/proc_macro/src/"
260       "lib.rs\",\n"
261       "      \"label\": \"proc_macro\",\n"
262       "      \"source\": {\n"
263       "          \"include_dirs\": [\n"
264       "               "
265       "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/proc_macro/src/"
266       "\"\n"
267       "          ],\n"
268       "          \"exclude_dirs\": []\n"
269       "      },\n"
270       "      \"deps\": [\n"
271       "      ],\n"
272       "      \"edition\": \"2018\",\n"
273       "      \"cfg\": [\n"
274       "        \"debug_assertions\"\n"
275       "      ]\n"
276       "    },\n"
277       "    {\n"
278       "      \"crate_id\": 7,\n"
279       "      \"root_module\": "
280       "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/test/src/"
281       "lib.rs\",\n"
282       "      \"label\": \"test\",\n"
283       "      \"source\": {\n"
284       "          \"include_dirs\": [\n"
285       "               "
286       "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library/test/src/\"\n"
287       "          ],\n"
288       "          \"exclude_dirs\": []\n"
289       "      },\n"
290       "      \"deps\": [\n"
291       "      ],\n"
292       "      \"edition\": \"2018\",\n"
293       "      \"cfg\": [\n"
294       "        \"debug_assertions\"\n"
295       "      ]\n"
296       "    }\n"
297       "  ]\n"
298       "}\n";
299 
300   ExpectEqOrShowDiff(expected_json, out);
301 }
302 
TEST_F(RustProjectWriterHelper,ExtractCompilerTargetTupleSimple)303 TEST_F(RustProjectWriterHelper, ExtractCompilerTargetTupleSimple) {
304   TestWithScope setup;
305 
306   Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
307   target.set_output_type(Target::RUST_LIBRARY);
308   target.visibility().SetPublic();
309   SourceFile lib("//foo/lib.rs");
310   target.sources().push_back(lib);
311   target.source_types_used().Set(SourceFile::SOURCE_RS);
312   target.rust_values().set_crate_root(lib);
313   target.rust_values().crate_name() = "foo";
314   target.config_values().rustflags().push_back("--cfg=feature=\"foo_enabled\"");
315   target.config_values().rustflags().push_back("--target");
316   target.config_values().rustflags().push_back("x86-someos");
317   target.config_values().rustflags().push_back("--edition=2018");
318 
319   auto args = ExtractCompilerArgs(&target);
320   std::optional<std::string> result = FindArgValue("--target", args);
321   auto expected = std::optional<std::string>{"x86-someos"};
322   EXPECT_EQ(expected, result);
323 }
324 
TEST_F(RustProjectWriterHelper,ExtractCompilerTargetTupleMissing)325 TEST_F(RustProjectWriterHelper, ExtractCompilerTargetTupleMissing) {
326   TestWithScope setup;
327 
328   Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
329   target.set_output_type(Target::RUST_LIBRARY);
330   target.visibility().SetPublic();
331   SourceFile lib("//foo/lib.rs");
332   target.sources().push_back(lib);
333   target.source_types_used().Set(SourceFile::SOURCE_RS);
334   target.rust_values().set_crate_root(lib);
335   target.rust_values().crate_name() = "foo";
336   target.config_values().rustflags().push_back(
337       "--cfg=featur4e=\"foo_enabled\"");
338   target.config_values().rustflags().push_back("x86-someos");
339   target.config_values().rustflags().push_back("--edition=2018");
340 
341   auto args = ExtractCompilerArgs(&target);
342   std::optional<std::string> result = FindArgValue("--target", args);
343   auto expected = std::nullopt;
344   EXPECT_EQ(expected, result);
345 }
346 
TEST_F(RustProjectWriterHelper,ExtractCompilerTargetTupleDontFallOffEnd)347 TEST_F(RustProjectWriterHelper, ExtractCompilerTargetTupleDontFallOffEnd) {
348   TestWithScope setup;
349 
350   Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
351   target.set_output_type(Target::RUST_LIBRARY);
352   target.visibility().SetPublic();
353   SourceFile lib("//foo/lib.rs");
354   target.sources().push_back(lib);
355   target.source_types_used().Set(SourceFile::SOURCE_RS);
356   target.rust_values().set_crate_root(lib);
357   target.rust_values().crate_name() = "foo";
358   target.config_values().rustflags().push_back("--cfg=feature=\"foo_enabled\"");
359   target.config_values().rustflags().push_back("--edition=2018");
360   target.config_values().rustflags().push_back("--target");
361 
362   auto args = ExtractCompilerArgs(&target);
363   std::optional<std::string> result = FindArgValue("--target", args);
364   auto expected = std::nullopt;
365   EXPECT_EQ(expected, result);
366 }
367 
TEST_F(RustProjectWriterHelper,ExtractFirstArgValueWithPrefixMissing)368 TEST_F(RustProjectWriterHelper, ExtractFirstArgValueWithPrefixMissing) {
369   TestWithScope setup;
370 
371   Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
372   target.set_output_type(Target::RUST_LIBRARY);
373   target.visibility().SetPublic();
374   SourceFile lib("//foo/lib.rs");
375   target.sources().push_back(lib);
376   target.source_types_used().Set(SourceFile::SOURCE_RS);
377   target.rust_values().set_crate_root(lib);
378   target.rust_values().crate_name() = "foo";
379   target.config_values().rustflags().push_back("--cfg=feature=\"foo_enabled\"");
380   target.config_values().rustflags().push_back("--edition=2018");
381   target.config_values().rustflags().push_back("--target");
382 
383   auto args = ExtractCompilerArgs(&target);
384   std::optional<std::string> result =
385       FindArgValueAfterPrefix("--missing", args);
386   auto expected = std::nullopt;
387   EXPECT_EQ(expected, result);
388 }
389 
TEST_F(RustProjectWriterHelper,ExtractFirstArgValueWithPrefix)390 TEST_F(RustProjectWriterHelper, ExtractFirstArgValueWithPrefix) {
391   TestWithScope setup;
392 
393   Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
394   target.set_output_type(Target::RUST_LIBRARY);
395   target.visibility().SetPublic();
396   SourceFile lib("//foo/lib.rs");
397   target.sources().push_back(lib);
398   target.source_types_used().Set(SourceFile::SOURCE_RS);
399   target.rust_values().set_crate_root(lib);
400   target.rust_values().crate_name() = "foo";
401   target.config_values().rustflags().push_back("--cfg=feature=\"foo_enabled\"");
402   target.config_values().rustflags().push_back("--edition=2018");
403   target.config_values().rustflags().push_back("--target");
404 
405   auto args = ExtractCompilerArgs(&target);
406   std::optional<std::string> result =
407       FindArgValueAfterPrefix("--edition=", args);
408   auto expected = std::optional<std::string>{"2018"};
409   EXPECT_EQ(expected, result);
410 }
411 
TEST_F(RustProjectWriterHelper,ExtractAllArgValueWithPrefix)412 TEST_F(RustProjectWriterHelper, ExtractAllArgValueWithPrefix) {
413   TestWithScope setup;
414 
415   Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
416   target.set_output_type(Target::RUST_LIBRARY);
417   target.visibility().SetPublic();
418   SourceFile lib("//foo/lib.rs");
419   target.sources().push_back(lib);
420   target.source_types_used().Set(SourceFile::SOURCE_RS);
421   target.rust_values().set_crate_root(lib);
422   target.rust_values().crate_name() = "foo";
423   target.config_values().rustflags().push_back("--cfg=feature=\"foo_enabled\"");
424   target.config_values().rustflags().push_back("--edition=2018");
425   target.config_values().rustflags().push_back("--cfg=feature=\"bar_enabled\"");
426   target.config_values().rustflags().push_back("--target");
427 
428   auto args = ExtractCompilerArgs(&target);
429   std::vector<std::string> result = FindAllArgValuesAfterPrefix("--cfg=", args);
430   std::vector<std::string> expected = {"feature=\"foo_enabled\"",
431                                        "feature=\"bar_enabled\""};
432   EXPECT_EQ(expected, result);
433 }