• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2019 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/json_project_writer.h"
6 #include "base/strings/string_util.h"
7 #include "gn/substitution_list.h"
8 #include "gn/target.h"
9 #include "gn/test_with_scheduler.h"
10 #include "gn/test_with_scope.h"
11 #include "util/build_config.h"
12 #include "util/test/test.h"
13 
14 using JSONWriter = TestWithScheduler;
15 
TEST_F(JSONWriter,ActionWithResponseFile)16 TEST_F(JSONWriter, ActionWithResponseFile) {
17   Err err;
18   TestWithScope setup;
19 
20   Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
21   target.set_output_type(Target::ACTION);
22 
23   target.sources().push_back(SourceFile("//foo/source1.txt"));
24   target.config_values().inputs().push_back(SourceFile("//foo/input1.txt"));
25   target.action_values().set_script(SourceFile("//foo/script.py"));
26 
27   target.SetToolchain(setup.toolchain());
28   ASSERT_TRUE(target.OnResolved(&err));
29 
30   // Make sure we get interesting substitutions for both the args and the
31   // response file contents.
32   target.action_values().args() =
33       SubstitutionList::MakeForTest("{{response_file_name}}");
34   target.action_values().rsp_file_contents() =
35       SubstitutionList::MakeForTest("-j", "3");
36   target.action_values().outputs() =
37       SubstitutionList::MakeForTest("//out/Debug/output1.out");
38 
39   setup.build_settings()->set_python_path(
40       base::FilePath(FILE_PATH_LITERAL("/usr/bin/python")));
41   std::vector<const Target*> targets;
42   targets.push_back(&target);
43 #if defined(OS_WIN)
44   base::FilePath root_path =
45       base::FilePath(FILE_PATH_LITERAL("c:/path/to/src"));
46 #else
47   base::FilePath root_path = base::FilePath(FILE_PATH_LITERAL("/path/to/src"));
48 #endif
49   setup.build_settings()->SetRootPath(root_path);
50   g_scheduler->AddGenDependency(root_path.Append(FILE_PATH_LITERAL(".gn")));
51   g_scheduler->AddGenDependency(
52       root_path.Append(FILE_PATH_LITERAL("BUILD.gn")));
53   g_scheduler->AddGenDependency(
54       root_path.Append(FILE_PATH_LITERAL("build/BUILD.gn")));
55   std::string out =
56       JSONProjectWriter::RenderJSON(setup.build_settings(), targets);
57 #if defined(OS_WIN)
58   base::ReplaceSubstringsAfterOffset(&out, 0, "\r\n", "\n");
59 #endif
60   const char expected_json[] =
61       R"_({
62    "build_settings": {
63       "build_dir": "//out/Debug/",
64       "default_toolchain": "//toolchain:default",
65       "gen_input_files": [ "//.gn", "//BUILD.gn", "//build/BUILD.gn" ],
66 )_"
67 #if defined(OS_WIN)
68       "      \"root_path\": \"c:/path/to/src\"\n"
69 #else
70       "      \"root_path\": \"/path/to/src\"\n"
71 #endif
72       R"_(   },
73    "targets": {
74       "//foo:bar()": {
75          "args": [ "{{response_file_name}}" ],
76          "deps": [  ],
77          "inputs": [ "//foo/input1.txt" ],
78          "metadata": {
79 
80          },
81          "outputs": [ "//out/Debug/output1.out" ],
82          "public": "*",
83          "response_file_contents": [ "-j", "3" ],
84          "script": "//foo/script.py",
85          "sources": [ "//foo/source1.txt" ],
86          "testonly": false,
87          "toolchain": "",
88          "type": "action",
89          "visibility": [  ]
90       }
91    },
92    "toolchains": {
93       "//toolchain:default": {
94          "alink": {
95             "command": "ar {{output}} {{source}}",
96             "framework_dir_switch": "-F",
97             "framework_switch": "-framework ",
98             "lib_dir_switch": "-L",
99             "lib_switch": "-l",
100             "output_prefix": "lib",
101             "outputs": [ "{{target_out_dir}}/{{target_output_name}}.a" ],
102             "weak_framework_switch": "-weak_framework "
103          },
104          "cc": {
105             "command": "cc {{source}} {{cflags}} {{cflags_c}} {{defines}} {{include_dirs}} -o {{output}}",
106             "framework_dir_switch": "-F",
107             "framework_switch": "-framework ",
108             "lib_dir_switch": "-L",
109             "lib_switch": "-l",
110             "outputs": [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ],
111             "weak_framework_switch": "-weak_framework "
112          },
113          "compile_xcassets": {
114             "command": "touch {{output}}"
115          },
116          "copy": {
117             "command": "cp {{source}} {{output}}"
118          },
119          "copy_bundle_data": {
120             "command": "cp {{source}} {{output}}"
121          },
122          "cxx": {
123             "command": "c++ {{source}} {{cflags}} {{cflags_cc}} {{defines}} {{include_dirs}} -o {{output}}",
124             "command_launcher": "launcher",
125             "framework_dir_switch": "-F",
126             "framework_switch": "-framework ",
127             "lib_dir_switch": "-L",
128             "lib_switch": "-l",
129             "outputs": [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ],
130             "weak_framework_switch": "-weak_framework "
131          },
132          "link": {
133             "command": "ld -o {{target_output_name}} {{source}} {{ldflags}} {{libs}}",
134             "framework_dir_switch": "-F",
135             "framework_switch": "-framework ",
136             "lib_dir_switch": "-L",
137             "lib_switch": "-l",
138             "outputs": [ "{{root_out_dir}}/{{target_output_name}}" ],
139             "weak_framework_switch": "-weak_framework "
140          },
141          "objc": {
142             "command": "objcc {{source}} {{cflags}} {{cflags_objc}} {{defines}} {{include_dirs}} -o {{output}}",
143             "framework_dir_switch": "-F",
144             "framework_switch": "-framework ",
145             "lib_dir_switch": "-L",
146             "lib_switch": "-l",
147             "outputs": [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ],
148             "weak_framework_switch": "-weak_framework "
149          },
150          "objcxx": {
151             "command": "objcxx {{source}} {{cflags}} {{cflags_objcc}} {{defines}} {{include_dirs}} -o {{output}}",
152             "framework_dir_switch": "-F",
153             "framework_switch": "-framework ",
154             "lib_dir_switch": "-L",
155             "lib_switch": "-l",
156             "outputs": [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ],
157             "weak_framework_switch": "-weak_framework "
158          },
159          "rust_bin": {
160             "command": "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}} -o {{output}} {{rustdeps}} {{externs}}",
161             "framework_dir_switch": "-Lframework=",
162             "framework_switch": "-lframework=",
163             "lib_dir_switch": "-Lnative=",
164             "lib_switch": "-l",
165             "linker_arg": "-Clink-arg=",
166             "outputs": [ "{{root_out_dir}}/{{crate_name}}{{output_extension}}" ]
167          },
168          "rust_cdylib": {
169             "command": "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}} -o {{output}} {{rustdeps}} {{externs}}",
170             "default_output_extension": ".so",
171             "framework_dir_switch": "-Lframework=",
172             "framework_switch": "-lframework=",
173             "lib_dir_switch": "-Lnative=",
174             "lib_switch": "-l",
175             "linker_arg": "-Clink-arg=",
176             "output_prefix": "lib",
177             "outputs": [ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
178          },
179          "rust_dylib": {
180             "command": "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}} -o {{output}} {{rustdeps}} {{externs}}",
181             "default_output_extension": ".so",
182             "framework_dir_switch": "-Lframework=",
183             "framework_switch": "-lframework=",
184             "lib_dir_switch": "-Lnative=",
185             "lib_switch": "-l",
186             "linker_arg": "-Clink-arg=",
187             "output_prefix": "lib",
188             "outputs": [ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
189          },
190          "rust_macro": {
191             "command": "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}} -o {{output}} {{rustdeps}} {{externs}}",
192             "default_output_extension": ".so",
193             "framework_dir_switch": "-Lframework=",
194             "framework_switch": "-lframework=",
195             "lib_dir_switch": "-Lnative=",
196             "lib_switch": "-l",
197             "linker_arg": "-Clink-arg=",
198             "output_prefix": "lib",
199             "outputs": [ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
200          },
201          "rust_rlib": {
202             "command": "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}} -o {{output}} {{rustdeps}} {{externs}}",
203             "default_output_extension": ".rlib",
204             "framework_dir_switch": "-Lframework=",
205             "framework_switch": "-lframework=",
206             "lib_dir_switch": "-Lnative=",
207             "lib_switch": "-l",
208             "linker_arg": "-Clink-arg=",
209             "output_prefix": "lib",
210             "outputs": [ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
211          },
212          "rust_staticlib": {
213             "command": "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}} -o {{output}} {{rustdeps}} {{externs}}",
214             "default_output_extension": ".a",
215             "framework_dir_switch": "-Lframework=",
216             "framework_switch": "-lframework=",
217             "lib_dir_switch": "-Lnative=",
218             "lib_switch": "-l",
219             "linker_arg": "-Clink-arg=",
220             "output_prefix": "lib",
221             "outputs": [ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
222          },
223          "solink": {
224             "command": "ld -shared -o {{target_output_name}}.so {{inputs}} {{ldflags}} {{libs}}",
225             "default_output_extension": ".so",
226             "framework_dir_switch": "-F",
227             "framework_switch": "-framework ",
228             "lib_dir_switch": "-L",
229             "lib_switch": "-l",
230             "output_prefix": "lib",
231             "outputs": [ "{{root_out_dir}}/{{target_output_name}}{{output_extension}}" ],
232             "weak_framework_switch": "-weak_framework "
233          },
234          "solink_module": {
235             "command": "ld -bundle -o {{target_output_name}}.so {{inputs}} {{ldflags}} {{libs}}",
236             "default_output_extension": ".so",
237             "framework_dir_switch": "-F",
238             "framework_switch": "-framework ",
239             "lib_dir_switch": "-L",
240             "lib_switch": "-l",
241             "output_prefix": "lib",
242             "outputs": [ "{{root_out_dir}}/{{target_output_name}}{{output_extension}}" ],
243             "weak_framework_switch": "-weak_framework "
244          },
245          "stamp": {
246             "command": "touch {{output}}"
247          },
248          "swift": {
249             "command": "swiftc --module-name {{module_name}} {{module_dirs}} {{inputs}}",
250             "framework_dir_switch": "-F",
251             "framework_switch": "-framework ",
252             "lib_dir_switch": "-L",
253             "lib_switch": "-l",
254             "outputs": [ "{{target_gen_dir}}/{{target_output_name}}.h", "{{target_out_dir}}/{{module_name}}.swiftmodule" ],
255             "partial_outputs": [ "{{target_out_dir}}/{{source_name_part}}.o" ],
256             "weak_framework_switch": "-weak_framework "
257          }
258       }
259    }
260 }
261 )_";
262   EXPECT_EQ(expected_json, out) << out;
263 }
264 
TEST_F(JSONWriter,RustTarget)265 TEST_F(JSONWriter, RustTarget) {
266   Err err;
267   TestWithScope setup;
268 
269   Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
270   target.set_output_type(Target::RUST_LIBRARY);
271   target.visibility().SetPublic();
272   SourceFile lib("//foo/lib.rs");
273   target.sources().push_back(lib);
274   target.source_types_used().Set(SourceFile::SOURCE_RS);
275   target.rust_values().set_crate_root(lib);
276   target.rust_values().crate_name() = "foo";
277   target.SetToolchain(setup.toolchain());
278   ASSERT_TRUE(target.OnResolved(&err));
279 
280   std::vector<const Target*> targets;
281   targets.push_back(&target);
282   std::string out =
283       JSONProjectWriter::RenderJSON(setup.build_settings(), targets);
284 #if defined(OS_WIN)
285   base::ReplaceSubstringsAfterOffset(&out, 0, "\r\n", "\n");
286 #endif
287   const char expected_json[] =
288       R"_({
289    "build_settings": {
290       "build_dir": "//out/Debug/",
291       "default_toolchain": "//toolchain:default",
292       "gen_input_files": [  ],
293       "root_path": ""
294    },
295    "targets": {
296       "//foo:bar()": {
297          "allow_circular_includes_from": [  ],
298          "check_includes": true,
299          "crate_name": "foo",
300          "crate_root": "//foo/lib.rs",
301          "deps": [  ],
302          "externs": {
303 
304          },
305          "metadata": {
306 
307          },
308          "outputs": [ "//out/Debug/obj/foo/libbar.rlib" ],
309          "public": "*",
310          "sources": [ "//foo/lib.rs" ],
311          "testonly": false,
312          "toolchain": "",
313          "type": "rust_library",
314          "visibility": [ "*" ]
315       }
316    },
317    "toolchains": {
318       "//toolchain:default": {
319          "alink": {
320             "command": "ar {{output}} {{source}}",
321             "framework_dir_switch": "-F",
322             "framework_switch": "-framework ",
323             "lib_dir_switch": "-L",
324             "lib_switch": "-l",
325             "output_prefix": "lib",
326             "outputs": [ "{{target_out_dir}}/{{target_output_name}}.a" ],
327             "weak_framework_switch": "-weak_framework "
328          },
329          "cc": {
330             "command": "cc {{source}} {{cflags}} {{cflags_c}} {{defines}} {{include_dirs}} -o {{output}}",
331             "framework_dir_switch": "-F",
332             "framework_switch": "-framework ",
333             "lib_dir_switch": "-L",
334             "lib_switch": "-l",
335             "outputs": [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ],
336             "weak_framework_switch": "-weak_framework "
337          },
338          "compile_xcassets": {
339             "command": "touch {{output}}"
340          },
341          "copy": {
342             "command": "cp {{source}} {{output}}"
343          },
344          "copy_bundle_data": {
345             "command": "cp {{source}} {{output}}"
346          },
347          "cxx": {
348             "command": "c++ {{source}} {{cflags}} {{cflags_cc}} {{defines}} {{include_dirs}} -o {{output}}",
349             "command_launcher": "launcher",
350             "framework_dir_switch": "-F",
351             "framework_switch": "-framework ",
352             "lib_dir_switch": "-L",
353             "lib_switch": "-l",
354             "outputs": [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ],
355             "weak_framework_switch": "-weak_framework "
356          },
357          "link": {
358             "command": "ld -o {{target_output_name}} {{source}} {{ldflags}} {{libs}}",
359             "framework_dir_switch": "-F",
360             "framework_switch": "-framework ",
361             "lib_dir_switch": "-L",
362             "lib_switch": "-l",
363             "outputs": [ "{{root_out_dir}}/{{target_output_name}}" ],
364             "weak_framework_switch": "-weak_framework "
365          },
366          "objc": {
367             "command": "objcc {{source}} {{cflags}} {{cflags_objc}} {{defines}} {{include_dirs}} -o {{output}}",
368             "framework_dir_switch": "-F",
369             "framework_switch": "-framework ",
370             "lib_dir_switch": "-L",
371             "lib_switch": "-l",
372             "outputs": [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ],
373             "weak_framework_switch": "-weak_framework "
374          },
375          "objcxx": {
376             "command": "objcxx {{source}} {{cflags}} {{cflags_objcc}} {{defines}} {{include_dirs}} -o {{output}}",
377             "framework_dir_switch": "-F",
378             "framework_switch": "-framework ",
379             "lib_dir_switch": "-L",
380             "lib_switch": "-l",
381             "outputs": [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ],
382             "weak_framework_switch": "-weak_framework "
383          },
384          "rust_bin": {
385             "command": "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}} -o {{output}} {{rustdeps}} {{externs}}",
386             "framework_dir_switch": "-Lframework=",
387             "framework_switch": "-lframework=",
388             "lib_dir_switch": "-Lnative=",
389             "lib_switch": "-l",
390             "linker_arg": "-Clink-arg=",
391             "outputs": [ "{{root_out_dir}}/{{crate_name}}{{output_extension}}" ]
392          },
393          "rust_cdylib": {
394             "command": "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}} -o {{output}} {{rustdeps}} {{externs}}",
395             "default_output_extension": ".so",
396             "framework_dir_switch": "-Lframework=",
397             "framework_switch": "-lframework=",
398             "lib_dir_switch": "-Lnative=",
399             "lib_switch": "-l",
400             "linker_arg": "-Clink-arg=",
401             "output_prefix": "lib",
402             "outputs": [ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
403          },
404          "rust_dylib": {
405             "command": "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}} -o {{output}} {{rustdeps}} {{externs}}",
406             "default_output_extension": ".so",
407             "framework_dir_switch": "-Lframework=",
408             "framework_switch": "-lframework=",
409             "lib_dir_switch": "-Lnative=",
410             "lib_switch": "-l",
411             "linker_arg": "-Clink-arg=",
412             "output_prefix": "lib",
413             "outputs": [ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
414          },
415          "rust_macro": {
416             "command": "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}} -o {{output}} {{rustdeps}} {{externs}}",
417             "default_output_extension": ".so",
418             "framework_dir_switch": "-Lframework=",
419             "framework_switch": "-lframework=",
420             "lib_dir_switch": "-Lnative=",
421             "lib_switch": "-l",
422             "linker_arg": "-Clink-arg=",
423             "output_prefix": "lib",
424             "outputs": [ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
425          },
426          "rust_rlib": {
427             "command": "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}} -o {{output}} {{rustdeps}} {{externs}}",
428             "default_output_extension": ".rlib",
429             "framework_dir_switch": "-Lframework=",
430             "framework_switch": "-lframework=",
431             "lib_dir_switch": "-Lnative=",
432             "lib_switch": "-l",
433             "linker_arg": "-Clink-arg=",
434             "output_prefix": "lib",
435             "outputs": [ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
436          },
437          "rust_staticlib": {
438             "command": "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}} -o {{output}} {{rustdeps}} {{externs}}",
439             "default_output_extension": ".a",
440             "framework_dir_switch": "-Lframework=",
441             "framework_switch": "-lframework=",
442             "lib_dir_switch": "-Lnative=",
443             "lib_switch": "-l",
444             "linker_arg": "-Clink-arg=",
445             "output_prefix": "lib",
446             "outputs": [ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
447          },
448          "solink": {
449             "command": "ld -shared -o {{target_output_name}}.so {{inputs}} {{ldflags}} {{libs}}",
450             "default_output_extension": ".so",
451             "framework_dir_switch": "-F",
452             "framework_switch": "-framework ",
453             "lib_dir_switch": "-L",
454             "lib_switch": "-l",
455             "output_prefix": "lib",
456             "outputs": [ "{{root_out_dir}}/{{target_output_name}}{{output_extension}}" ],
457             "weak_framework_switch": "-weak_framework "
458          },
459          "solink_module": {
460             "command": "ld -bundle -o {{target_output_name}}.so {{inputs}} {{ldflags}} {{libs}}",
461             "default_output_extension": ".so",
462             "framework_dir_switch": "-F",
463             "framework_switch": "-framework ",
464             "lib_dir_switch": "-L",
465             "lib_switch": "-l",
466             "output_prefix": "lib",
467             "outputs": [ "{{root_out_dir}}/{{target_output_name}}{{output_extension}}" ],
468             "weak_framework_switch": "-weak_framework "
469          },
470          "stamp": {
471             "command": "touch {{output}}"
472          },
473          "swift": {
474             "command": "swiftc --module-name {{module_name}} {{module_dirs}} {{inputs}}",
475             "framework_dir_switch": "-F",
476             "framework_switch": "-framework ",
477             "lib_dir_switch": "-L",
478             "lib_switch": "-l",
479             "outputs": [ "{{target_gen_dir}}/{{target_output_name}}.h", "{{target_out_dir}}/{{module_name}}.swiftmodule" ],
480             "partial_outputs": [ "{{target_out_dir}}/{{source_name_part}}.o" ],
481             "weak_framework_switch": "-weak_framework "
482          }
483       }
484    }
485 }
486 )_";
487   EXPECT_EQ(expected_json, out) << out;
488 }
489 
TEST_F(JSONWriter,ForEachWithResponseFile)490 TEST_F(JSONWriter, ForEachWithResponseFile) {
491   Err err;
492   TestWithScope setup;
493 
494   Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
495   target.set_output_type(Target::ACTION_FOREACH);
496 
497   target.sources().push_back(SourceFile("//foo/input1.txt"));
498   target.action_values().set_script(SourceFile("//foo/script.py"));
499 
500   target.SetToolchain(setup.toolchain());
501   ASSERT_TRUE(target.OnResolved(&err));
502 
503   // Make sure we get interesting substitutions for both the args and the
504   // response file contents.
505   target.action_values().args() = SubstitutionList::MakeForTest(
506       "{{source}}", "{{source_file_part}}", "{{response_file_name}}");
507   target.action_values().rsp_file_contents() =
508       SubstitutionList::MakeForTest("-j", "{{source_name_part}}");
509   target.action_values().outputs() =
510       SubstitutionList::MakeForTest("//out/Debug/{{source_name_part}}.out");
511 
512   setup.build_settings()->set_python_path(
513       base::FilePath(FILE_PATH_LITERAL("/usr/bin/python")));
514   std::vector<const Target*> targets;
515   targets.push_back(&target);
516 #if defined(OS_WIN)
517   base::FilePath root_path =
518       base::FilePath(FILE_PATH_LITERAL("c:/path/to/src"));
519 #else
520   base::FilePath root_path = base::FilePath(FILE_PATH_LITERAL("/path/to/src"));
521 #endif
522   setup.build_settings()->SetRootPath(root_path);
523   g_scheduler->AddGenDependency(root_path.Append(FILE_PATH_LITERAL(".gn")));
524   g_scheduler->AddGenDependency(
525       root_path.Append(FILE_PATH_LITERAL("BUILD.gn")));
526   std::string out =
527       JSONProjectWriter::RenderJSON(setup.build_settings(), targets);
528 #if defined(OS_WIN)
529   base::ReplaceSubstringsAfterOffset(&out, 0, "\r\n", "\n");
530 #endif
531   const char expected_json[] =
532       R"_({
533    "build_settings": {
534       "build_dir": "//out/Debug/",
535       "default_toolchain": "//toolchain:default",
536       "gen_input_files": [ "//.gn", "//BUILD.gn" ],
537 )_"
538 #if defined(OS_WIN)
539       "      \"root_path\": \"c:/path/to/src\"\n"
540 #else
541       "      \"root_path\": \"/path/to/src\"\n"
542 #endif
543       R"_(   },
544    "targets": {
545       "//foo:bar()": {
546          "args": [ "{{source}}", "{{source_file_part}}", "{{response_file_name}}" ],
547          "deps": [  ],
548          "metadata": {
549 
550          },
551          "output_patterns": [ "//out/Debug/{{source_name_part}}.out" ],
552          "outputs": [ "//out/Debug/input1.out" ],
553          "public": "*",
554          "response_file_contents": [ "-j", "{{source_name_part}}" ],
555          "script": "//foo/script.py",
556          "source_outputs": {
557             "//foo/input1.txt": [ "input1.out" ]
558          },
559          "sources": [ "//foo/input1.txt" ],
560          "testonly": false,
561          "toolchain": "",
562          "type": "action_foreach",
563          "visibility": [  ]
564       }
565    },
566    "toolchains": {
567       "//toolchain:default": {
568          "alink": {
569             "command": "ar {{output}} {{source}}",
570             "framework_dir_switch": "-F",
571             "framework_switch": "-framework ",
572             "lib_dir_switch": "-L",
573             "lib_switch": "-l",
574             "output_prefix": "lib",
575             "outputs": [ "{{target_out_dir}}/{{target_output_name}}.a" ],
576             "weak_framework_switch": "-weak_framework "
577          },
578          "cc": {
579             "command": "cc {{source}} {{cflags}} {{cflags_c}} {{defines}} {{include_dirs}} -o {{output}}",
580             "framework_dir_switch": "-F",
581             "framework_switch": "-framework ",
582             "lib_dir_switch": "-L",
583             "lib_switch": "-l",
584             "outputs": [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ],
585             "weak_framework_switch": "-weak_framework "
586          },
587          "compile_xcassets": {
588             "command": "touch {{output}}"
589          },
590          "copy": {
591             "command": "cp {{source}} {{output}}"
592          },
593          "copy_bundle_data": {
594             "command": "cp {{source}} {{output}}"
595          },
596          "cxx": {
597             "command": "c++ {{source}} {{cflags}} {{cflags_cc}} {{defines}} {{include_dirs}} -o {{output}}",
598             "command_launcher": "launcher",
599             "framework_dir_switch": "-F",
600             "framework_switch": "-framework ",
601             "lib_dir_switch": "-L",
602             "lib_switch": "-l",
603             "outputs": [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ],
604             "weak_framework_switch": "-weak_framework "
605          },
606          "link": {
607             "command": "ld -o {{target_output_name}} {{source}} {{ldflags}} {{libs}}",
608             "framework_dir_switch": "-F",
609             "framework_switch": "-framework ",
610             "lib_dir_switch": "-L",
611             "lib_switch": "-l",
612             "outputs": [ "{{root_out_dir}}/{{target_output_name}}" ],
613             "weak_framework_switch": "-weak_framework "
614          },
615          "objc": {
616             "command": "objcc {{source}} {{cflags}} {{cflags_objc}} {{defines}} {{include_dirs}} -o {{output}}",
617             "framework_dir_switch": "-F",
618             "framework_switch": "-framework ",
619             "lib_dir_switch": "-L",
620             "lib_switch": "-l",
621             "outputs": [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ],
622             "weak_framework_switch": "-weak_framework "
623          },
624          "objcxx": {
625             "command": "objcxx {{source}} {{cflags}} {{cflags_objcc}} {{defines}} {{include_dirs}} -o {{output}}",
626             "framework_dir_switch": "-F",
627             "framework_switch": "-framework ",
628             "lib_dir_switch": "-L",
629             "lib_switch": "-l",
630             "outputs": [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ],
631             "weak_framework_switch": "-weak_framework "
632          },
633          "rust_bin": {
634             "command": "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}} -o {{output}} {{rustdeps}} {{externs}}",
635             "framework_dir_switch": "-Lframework=",
636             "framework_switch": "-lframework=",
637             "lib_dir_switch": "-Lnative=",
638             "lib_switch": "-l",
639             "linker_arg": "-Clink-arg=",
640             "outputs": [ "{{root_out_dir}}/{{crate_name}}{{output_extension}}" ]
641          },
642          "rust_cdylib": {
643             "command": "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}} -o {{output}} {{rustdeps}} {{externs}}",
644             "default_output_extension": ".so",
645             "framework_dir_switch": "-Lframework=",
646             "framework_switch": "-lframework=",
647             "lib_dir_switch": "-Lnative=",
648             "lib_switch": "-l",
649             "linker_arg": "-Clink-arg=",
650             "output_prefix": "lib",
651             "outputs": [ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
652          },
653          "rust_dylib": {
654             "command": "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}} -o {{output}} {{rustdeps}} {{externs}}",
655             "default_output_extension": ".so",
656             "framework_dir_switch": "-Lframework=",
657             "framework_switch": "-lframework=",
658             "lib_dir_switch": "-Lnative=",
659             "lib_switch": "-l",
660             "linker_arg": "-Clink-arg=",
661             "output_prefix": "lib",
662             "outputs": [ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
663          },
664          "rust_macro": {
665             "command": "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}} -o {{output}} {{rustdeps}} {{externs}}",
666             "default_output_extension": ".so",
667             "framework_dir_switch": "-Lframework=",
668             "framework_switch": "-lframework=",
669             "lib_dir_switch": "-Lnative=",
670             "lib_switch": "-l",
671             "linker_arg": "-Clink-arg=",
672             "output_prefix": "lib",
673             "outputs": [ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
674          },
675          "rust_rlib": {
676             "command": "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}} -o {{output}} {{rustdeps}} {{externs}}",
677             "default_output_extension": ".rlib",
678             "framework_dir_switch": "-Lframework=",
679             "framework_switch": "-lframework=",
680             "lib_dir_switch": "-Lnative=",
681             "lib_switch": "-l",
682             "linker_arg": "-Clink-arg=",
683             "output_prefix": "lib",
684             "outputs": [ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
685          },
686          "rust_staticlib": {
687             "command": "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}} -o {{output}} {{rustdeps}} {{externs}}",
688             "default_output_extension": ".a",
689             "framework_dir_switch": "-Lframework=",
690             "framework_switch": "-lframework=",
691             "lib_dir_switch": "-Lnative=",
692             "lib_switch": "-l",
693             "linker_arg": "-Clink-arg=",
694             "output_prefix": "lib",
695             "outputs": [ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
696          },
697          "solink": {
698             "command": "ld -shared -o {{target_output_name}}.so {{inputs}} {{ldflags}} {{libs}}",
699             "default_output_extension": ".so",
700             "framework_dir_switch": "-F",
701             "framework_switch": "-framework ",
702             "lib_dir_switch": "-L",
703             "lib_switch": "-l",
704             "output_prefix": "lib",
705             "outputs": [ "{{root_out_dir}}/{{target_output_name}}{{output_extension}}" ],
706             "weak_framework_switch": "-weak_framework "
707          },
708          "solink_module": {
709             "command": "ld -bundle -o {{target_output_name}}.so {{inputs}} {{ldflags}} {{libs}}",
710             "default_output_extension": ".so",
711             "framework_dir_switch": "-F",
712             "framework_switch": "-framework ",
713             "lib_dir_switch": "-L",
714             "lib_switch": "-l",
715             "output_prefix": "lib",
716             "outputs": [ "{{root_out_dir}}/{{target_output_name}}{{output_extension}}" ],
717             "weak_framework_switch": "-weak_framework "
718          },
719          "stamp": {
720             "command": "touch {{output}}"
721          },
722          "swift": {
723             "command": "swiftc --module-name {{module_name}} {{module_dirs}} {{inputs}}",
724             "framework_dir_switch": "-F",
725             "framework_switch": "-framework ",
726             "lib_dir_switch": "-L",
727             "lib_switch": "-l",
728             "outputs": [ "{{target_gen_dir}}/{{target_output_name}}.h", "{{target_out_dir}}/{{module_name}}.swiftmodule" ],
729             "partial_outputs": [ "{{target_out_dir}}/{{source_name_part}}.o" ],
730             "weak_framework_switch": "-weak_framework "
731          }
732       }
733    }
734 }
735 )_";
736   EXPECT_EQ(expected_json, out) << out;
737 }
738