• 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_switch": "-lframework=",
162             "lib_dir_switch": "-Lnative=",
163             "lib_switch": "-l",
164             "linker_arg": "-Clink-arg=",
165             "outputs": [ "{{root_out_dir}}/{{crate_name}}{{output_extension}}" ]
166          },
167          "rust_cdylib": {
168             "command": "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}} -o {{output}} {{rustdeps}} {{externs}}",
169             "default_output_extension": ".so",
170             "framework_switch": "-lframework=",
171             "lib_dir_switch": "-Lnative=",
172             "lib_switch": "-l",
173             "linker_arg": "-Clink-arg=",
174             "output_prefix": "lib",
175             "outputs": [ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
176          },
177          "rust_dylib": {
178             "command": "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}} -o {{output}} {{rustdeps}} {{externs}}",
179             "default_output_extension": ".so",
180             "framework_switch": "-lframework=",
181             "lib_dir_switch": "-Lnative=",
182             "lib_switch": "-l",
183             "linker_arg": "-Clink-arg=",
184             "output_prefix": "lib",
185             "outputs": [ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
186          },
187          "rust_macro": {
188             "command": "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}} -o {{output}} {{rustdeps}} {{externs}}",
189             "default_output_extension": ".so",
190             "framework_switch": "-lframework=",
191             "lib_dir_switch": "-Lnative=",
192             "lib_switch": "-l",
193             "linker_arg": "-Clink-arg=",
194             "output_prefix": "lib",
195             "outputs": [ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
196          },
197          "rust_rlib": {
198             "command": "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}} -o {{output}} {{rustdeps}} {{externs}}",
199             "default_output_extension": ".rlib",
200             "framework_switch": "-lframework=",
201             "lib_dir_switch": "-Lnative=",
202             "lib_switch": "-l",
203             "linker_arg": "-Clink-arg=",
204             "output_prefix": "lib",
205             "outputs": [ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
206          },
207          "rust_staticlib": {
208             "command": "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}} -o {{output}} {{rustdeps}} {{externs}}",
209             "default_output_extension": ".a",
210             "framework_switch": "-lframework=",
211             "lib_dir_switch": "-Lnative=",
212             "lib_switch": "-l",
213             "linker_arg": "-Clink-arg=",
214             "output_prefix": "lib",
215             "outputs": [ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
216          },
217          "solink": {
218             "command": "ld -shared -o {{target_output_name}}.so {{inputs}} {{ldflags}} {{libs}}",
219             "default_output_extension": ".so",
220             "framework_dir_switch": "-F",
221             "framework_switch": "-framework ",
222             "lib_dir_switch": "-L",
223             "lib_switch": "-l",
224             "output_prefix": "lib",
225             "outputs": [ "{{root_out_dir}}/{{target_output_name}}{{output_extension}}" ],
226             "weak_framework_switch": "-weak_framework "
227          },
228          "solink_module": {
229             "command": "ld -bundle -o {{target_output_name}}.so {{inputs}} {{ldflags}} {{libs}}",
230             "default_output_extension": ".so",
231             "framework_dir_switch": "-F",
232             "framework_switch": "-framework ",
233             "lib_dir_switch": "-L",
234             "lib_switch": "-l",
235             "output_prefix": "lib",
236             "outputs": [ "{{root_out_dir}}/{{target_output_name}}{{output_extension}}" ],
237             "weak_framework_switch": "-weak_framework "
238          },
239          "stamp": {
240             "command": "touch {{output}}"
241          },
242          "swift": {
243             "command": "swiftc --module-name {{module_name}} {{module_dirs}} {{inputs}}",
244             "framework_dir_switch": "-F",
245             "framework_switch": "-framework ",
246             "lib_dir_switch": "-L",
247             "lib_switch": "-l",
248             "outputs": [ "{{target_out_dir}}/{{module_name}}.swiftmodule" ],
249             "partial_outputs": [ "{{target_out_dir}}/{{source_name_part}}.o" ],
250             "weak_framework_switch": "-weak_framework "
251          }
252       }
253    }
254 }
255 )_";
256   EXPECT_EQ(expected_json, out) << out;
257 }
258 
TEST_F(JSONWriter,RustTarget)259 TEST_F(JSONWriter, RustTarget) {
260   Err err;
261   TestWithScope setup;
262 
263   Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
264   target.set_output_type(Target::RUST_LIBRARY);
265   target.visibility().SetPublic();
266   SourceFile lib("//foo/lib.rs");
267   target.sources().push_back(lib);
268   target.source_types_used().Set(SourceFile::SOURCE_RS);
269   target.rust_values().set_crate_root(lib);
270   target.rust_values().crate_name() = "foo";
271   target.SetToolchain(setup.toolchain());
272   ASSERT_TRUE(target.OnResolved(&err));
273 
274   std::vector<const Target*> targets;
275   targets.push_back(&target);
276   std::string out =
277       JSONProjectWriter::RenderJSON(setup.build_settings(), targets);
278 #if defined(OS_WIN)
279   base::ReplaceSubstringsAfterOffset(&out, 0, "\r\n", "\n");
280 #endif
281   const char expected_json[] =
282       R"_({
283    "build_settings": {
284       "build_dir": "//out/Debug/",
285       "default_toolchain": "//toolchain:default",
286       "gen_input_files": [  ],
287       "root_path": ""
288    },
289    "targets": {
290       "//foo:bar()": {
291          "allow_circular_includes_from": [  ],
292          "check_includes": true,
293          "crate_name": "foo",
294          "crate_root": "//foo/lib.rs",
295          "deps": [  ],
296          "externs": {
297 
298          },
299          "metadata": {
300 
301          },
302          "outputs": [ "//out/Debug/obj/foo/libbar.rlib" ],
303          "public": "*",
304          "sources": [ "//foo/lib.rs" ],
305          "testonly": false,
306          "toolchain": "",
307          "type": "rust_library",
308          "visibility": [ "*" ]
309       }
310    },
311    "toolchains": {
312       "//toolchain:default": {
313          "alink": {
314             "command": "ar {{output}} {{source}}",
315             "framework_dir_switch": "-F",
316             "framework_switch": "-framework ",
317             "lib_dir_switch": "-L",
318             "lib_switch": "-l",
319             "output_prefix": "lib",
320             "outputs": [ "{{target_out_dir}}/{{target_output_name}}.a" ],
321             "weak_framework_switch": "-weak_framework "
322          },
323          "cc": {
324             "command": "cc {{source}} {{cflags}} {{cflags_c}} {{defines}} {{include_dirs}} -o {{output}}",
325             "framework_dir_switch": "-F",
326             "framework_switch": "-framework ",
327             "lib_dir_switch": "-L",
328             "lib_switch": "-l",
329             "outputs": [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ],
330             "weak_framework_switch": "-weak_framework "
331          },
332          "compile_xcassets": {
333             "command": "touch {{output}}"
334          },
335          "copy": {
336             "command": "cp {{source}} {{output}}"
337          },
338          "copy_bundle_data": {
339             "command": "cp {{source}} {{output}}"
340          },
341          "cxx": {
342             "command": "c++ {{source}} {{cflags}} {{cflags_cc}} {{defines}} {{include_dirs}} -o {{output}}",
343             "command_launcher": "launcher",
344             "framework_dir_switch": "-F",
345             "framework_switch": "-framework ",
346             "lib_dir_switch": "-L",
347             "lib_switch": "-l",
348             "outputs": [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ],
349             "weak_framework_switch": "-weak_framework "
350          },
351          "link": {
352             "command": "ld -o {{target_output_name}} {{source}} {{ldflags}} {{libs}}",
353             "framework_dir_switch": "-F",
354             "framework_switch": "-framework ",
355             "lib_dir_switch": "-L",
356             "lib_switch": "-l",
357             "outputs": [ "{{root_out_dir}}/{{target_output_name}}" ],
358             "weak_framework_switch": "-weak_framework "
359          },
360          "objc": {
361             "command": "objcc {{source}} {{cflags}} {{cflags_objc}} {{defines}} {{include_dirs}} -o {{output}}",
362             "framework_dir_switch": "-F",
363             "framework_switch": "-framework ",
364             "lib_dir_switch": "-L",
365             "lib_switch": "-l",
366             "outputs": [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ],
367             "weak_framework_switch": "-weak_framework "
368          },
369          "objcxx": {
370             "command": "objcxx {{source}} {{cflags}} {{cflags_objcc}} {{defines}} {{include_dirs}} -o {{output}}",
371             "framework_dir_switch": "-F",
372             "framework_switch": "-framework ",
373             "lib_dir_switch": "-L",
374             "lib_switch": "-l",
375             "outputs": [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ],
376             "weak_framework_switch": "-weak_framework "
377          },
378          "rust_bin": {
379             "command": "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}} -o {{output}} {{rustdeps}} {{externs}}",
380             "framework_switch": "-lframework=",
381             "lib_dir_switch": "-Lnative=",
382             "lib_switch": "-l",
383             "linker_arg": "-Clink-arg=",
384             "outputs": [ "{{root_out_dir}}/{{crate_name}}{{output_extension}}" ]
385          },
386          "rust_cdylib": {
387             "command": "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}} -o {{output}} {{rustdeps}} {{externs}}",
388             "default_output_extension": ".so",
389             "framework_switch": "-lframework=",
390             "lib_dir_switch": "-Lnative=",
391             "lib_switch": "-l",
392             "linker_arg": "-Clink-arg=",
393             "output_prefix": "lib",
394             "outputs": [ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
395          },
396          "rust_dylib": {
397             "command": "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}} -o {{output}} {{rustdeps}} {{externs}}",
398             "default_output_extension": ".so",
399             "framework_switch": "-lframework=",
400             "lib_dir_switch": "-Lnative=",
401             "lib_switch": "-l",
402             "linker_arg": "-Clink-arg=",
403             "output_prefix": "lib",
404             "outputs": [ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
405          },
406          "rust_macro": {
407             "command": "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}} -o {{output}} {{rustdeps}} {{externs}}",
408             "default_output_extension": ".so",
409             "framework_switch": "-lframework=",
410             "lib_dir_switch": "-Lnative=",
411             "lib_switch": "-l",
412             "linker_arg": "-Clink-arg=",
413             "output_prefix": "lib",
414             "outputs": [ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
415          },
416          "rust_rlib": {
417             "command": "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}} -o {{output}} {{rustdeps}} {{externs}}",
418             "default_output_extension": ".rlib",
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_staticlib": {
427             "command": "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}} -o {{output}} {{rustdeps}} {{externs}}",
428             "default_output_extension": ".a",
429             "framework_switch": "-lframework=",
430             "lib_dir_switch": "-Lnative=",
431             "lib_switch": "-l",
432             "linker_arg": "-Clink-arg=",
433             "output_prefix": "lib",
434             "outputs": [ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
435          },
436          "solink": {
437             "command": "ld -shared -o {{target_output_name}}.so {{inputs}} {{ldflags}} {{libs}}",
438             "default_output_extension": ".so",
439             "framework_dir_switch": "-F",
440             "framework_switch": "-framework ",
441             "lib_dir_switch": "-L",
442             "lib_switch": "-l",
443             "output_prefix": "lib",
444             "outputs": [ "{{root_out_dir}}/{{target_output_name}}{{output_extension}}" ],
445             "weak_framework_switch": "-weak_framework "
446          },
447          "solink_module": {
448             "command": "ld -bundle -o {{target_output_name}}.so {{inputs}} {{ldflags}} {{libs}}",
449             "default_output_extension": ".so",
450             "framework_dir_switch": "-F",
451             "framework_switch": "-framework ",
452             "lib_dir_switch": "-L",
453             "lib_switch": "-l",
454             "output_prefix": "lib",
455             "outputs": [ "{{root_out_dir}}/{{target_output_name}}{{output_extension}}" ],
456             "weak_framework_switch": "-weak_framework "
457          },
458          "stamp": {
459             "command": "touch {{output}}"
460          },
461          "swift": {
462             "command": "swiftc --module-name {{module_name}} {{module_dirs}} {{inputs}}",
463             "framework_dir_switch": "-F",
464             "framework_switch": "-framework ",
465             "lib_dir_switch": "-L",
466             "lib_switch": "-l",
467             "outputs": [ "{{target_out_dir}}/{{module_name}}.swiftmodule" ],
468             "partial_outputs": [ "{{target_out_dir}}/{{source_name_part}}.o" ],
469             "weak_framework_switch": "-weak_framework "
470          }
471       }
472    }
473 }
474 )_";
475   EXPECT_EQ(expected_json, out) << out;
476 }
477 
TEST_F(JSONWriter,ForEachWithResponseFile)478 TEST_F(JSONWriter, ForEachWithResponseFile) {
479   Err err;
480   TestWithScope setup;
481 
482   Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
483   target.set_output_type(Target::ACTION_FOREACH);
484 
485   target.sources().push_back(SourceFile("//foo/input1.txt"));
486   target.action_values().set_script(SourceFile("//foo/script.py"));
487 
488   target.SetToolchain(setup.toolchain());
489   ASSERT_TRUE(target.OnResolved(&err));
490 
491   // Make sure we get interesting substitutions for both the args and the
492   // response file contents.
493   target.action_values().args() = SubstitutionList::MakeForTest(
494       "{{source}}", "{{source_file_part}}", "{{response_file_name}}");
495   target.action_values().rsp_file_contents() =
496       SubstitutionList::MakeForTest("-j", "{{source_name_part}}");
497   target.action_values().outputs() =
498       SubstitutionList::MakeForTest("//out/Debug/{{source_name_part}}.out");
499 
500   setup.build_settings()->set_python_path(
501       base::FilePath(FILE_PATH_LITERAL("/usr/bin/python")));
502   std::vector<const Target*> targets;
503   targets.push_back(&target);
504 #if defined(OS_WIN)
505   base::FilePath root_path =
506       base::FilePath(FILE_PATH_LITERAL("c:/path/to/src"));
507 #else
508   base::FilePath root_path = base::FilePath(FILE_PATH_LITERAL("/path/to/src"));
509 #endif
510   setup.build_settings()->SetRootPath(root_path);
511   g_scheduler->AddGenDependency(root_path.Append(FILE_PATH_LITERAL(".gn")));
512   g_scheduler->AddGenDependency(
513       root_path.Append(FILE_PATH_LITERAL("BUILD.gn")));
514   std::string out =
515       JSONProjectWriter::RenderJSON(setup.build_settings(), targets);
516 #if defined(OS_WIN)
517   base::ReplaceSubstringsAfterOffset(&out, 0, "\r\n", "\n");
518 #endif
519   const char expected_json[] =
520       R"_({
521    "build_settings": {
522       "build_dir": "//out/Debug/",
523       "default_toolchain": "//toolchain:default",
524       "gen_input_files": [ "//.gn", "//BUILD.gn" ],
525 )_"
526 #if defined(OS_WIN)
527       "      \"root_path\": \"c:/path/to/src\"\n"
528 #else
529       "      \"root_path\": \"/path/to/src\"\n"
530 #endif
531       R"_(   },
532    "targets": {
533       "//foo:bar()": {
534          "args": [ "{{source}}", "{{source_file_part}}", "{{response_file_name}}" ],
535          "deps": [  ],
536          "metadata": {
537 
538          },
539          "output_patterns": [ "//out/Debug/{{source_name_part}}.out" ],
540          "outputs": [ "//out/Debug/input1.out" ],
541          "public": "*",
542          "response_file_contents": [ "-j", "{{source_name_part}}" ],
543          "script": "//foo/script.py",
544          "source_outputs": {
545             "//foo/input1.txt": [ "input1.out" ]
546          },
547          "sources": [ "//foo/input1.txt" ],
548          "testonly": false,
549          "toolchain": "",
550          "type": "action_foreach",
551          "visibility": [  ]
552       }
553    },
554    "toolchains": {
555       "//toolchain:default": {
556          "alink": {
557             "command": "ar {{output}} {{source}}",
558             "framework_dir_switch": "-F",
559             "framework_switch": "-framework ",
560             "lib_dir_switch": "-L",
561             "lib_switch": "-l",
562             "output_prefix": "lib",
563             "outputs": [ "{{target_out_dir}}/{{target_output_name}}.a" ],
564             "weak_framework_switch": "-weak_framework "
565          },
566          "cc": {
567             "command": "cc {{source}} {{cflags}} {{cflags_c}} {{defines}} {{include_dirs}} -o {{output}}",
568             "framework_dir_switch": "-F",
569             "framework_switch": "-framework ",
570             "lib_dir_switch": "-L",
571             "lib_switch": "-l",
572             "outputs": [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ],
573             "weak_framework_switch": "-weak_framework "
574          },
575          "compile_xcassets": {
576             "command": "touch {{output}}"
577          },
578          "copy": {
579             "command": "cp {{source}} {{output}}"
580          },
581          "copy_bundle_data": {
582             "command": "cp {{source}} {{output}}"
583          },
584          "cxx": {
585             "command": "c++ {{source}} {{cflags}} {{cflags_cc}} {{defines}} {{include_dirs}} -o {{output}}",
586             "command_launcher": "launcher",
587             "framework_dir_switch": "-F",
588             "framework_switch": "-framework ",
589             "lib_dir_switch": "-L",
590             "lib_switch": "-l",
591             "outputs": [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ],
592             "weak_framework_switch": "-weak_framework "
593          },
594          "link": {
595             "command": "ld -o {{target_output_name}} {{source}} {{ldflags}} {{libs}}",
596             "framework_dir_switch": "-F",
597             "framework_switch": "-framework ",
598             "lib_dir_switch": "-L",
599             "lib_switch": "-l",
600             "outputs": [ "{{root_out_dir}}/{{target_output_name}}" ],
601             "weak_framework_switch": "-weak_framework "
602          },
603          "objc": {
604             "command": "objcc {{source}} {{cflags}} {{cflags_objc}} {{defines}} {{include_dirs}} -o {{output}}",
605             "framework_dir_switch": "-F",
606             "framework_switch": "-framework ",
607             "lib_dir_switch": "-L",
608             "lib_switch": "-l",
609             "outputs": [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ],
610             "weak_framework_switch": "-weak_framework "
611          },
612          "objcxx": {
613             "command": "objcxx {{source}} {{cflags}} {{cflags_objcc}} {{defines}} {{include_dirs}} -o {{output}}",
614             "framework_dir_switch": "-F",
615             "framework_switch": "-framework ",
616             "lib_dir_switch": "-L",
617             "lib_switch": "-l",
618             "outputs": [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ],
619             "weak_framework_switch": "-weak_framework "
620          },
621          "rust_bin": {
622             "command": "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}} -o {{output}} {{rustdeps}} {{externs}}",
623             "framework_switch": "-lframework=",
624             "lib_dir_switch": "-Lnative=",
625             "lib_switch": "-l",
626             "linker_arg": "-Clink-arg=",
627             "outputs": [ "{{root_out_dir}}/{{crate_name}}{{output_extension}}" ]
628          },
629          "rust_cdylib": {
630             "command": "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}} -o {{output}} {{rustdeps}} {{externs}}",
631             "default_output_extension": ".so",
632             "framework_switch": "-lframework=",
633             "lib_dir_switch": "-Lnative=",
634             "lib_switch": "-l",
635             "linker_arg": "-Clink-arg=",
636             "output_prefix": "lib",
637             "outputs": [ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
638          },
639          "rust_dylib": {
640             "command": "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}} -o {{output}} {{rustdeps}} {{externs}}",
641             "default_output_extension": ".so",
642             "framework_switch": "-lframework=",
643             "lib_dir_switch": "-Lnative=",
644             "lib_switch": "-l",
645             "linker_arg": "-Clink-arg=",
646             "output_prefix": "lib",
647             "outputs": [ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
648          },
649          "rust_macro": {
650             "command": "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}} -o {{output}} {{rustdeps}} {{externs}}",
651             "default_output_extension": ".so",
652             "framework_switch": "-lframework=",
653             "lib_dir_switch": "-Lnative=",
654             "lib_switch": "-l",
655             "linker_arg": "-Clink-arg=",
656             "output_prefix": "lib",
657             "outputs": [ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
658          },
659          "rust_rlib": {
660             "command": "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}} -o {{output}} {{rustdeps}} {{externs}}",
661             "default_output_extension": ".rlib",
662             "framework_switch": "-lframework=",
663             "lib_dir_switch": "-Lnative=",
664             "lib_switch": "-l",
665             "linker_arg": "-Clink-arg=",
666             "output_prefix": "lib",
667             "outputs": [ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
668          },
669          "rust_staticlib": {
670             "command": "{{rustenv}} rustc --crate-name {{crate_name}} {{source}} --crate-type {{crate_type}} {{rustflags}} -o {{output}} {{rustdeps}} {{externs}}",
671             "default_output_extension": ".a",
672             "framework_switch": "-lframework=",
673             "lib_dir_switch": "-Lnative=",
674             "lib_switch": "-l",
675             "linker_arg": "-Clink-arg=",
676             "output_prefix": "lib",
677             "outputs": [ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
678          },
679          "solink": {
680             "command": "ld -shared -o {{target_output_name}}.so {{inputs}} {{ldflags}} {{libs}}",
681             "default_output_extension": ".so",
682             "framework_dir_switch": "-F",
683             "framework_switch": "-framework ",
684             "lib_dir_switch": "-L",
685             "lib_switch": "-l",
686             "output_prefix": "lib",
687             "outputs": [ "{{root_out_dir}}/{{target_output_name}}{{output_extension}}" ],
688             "weak_framework_switch": "-weak_framework "
689          },
690          "solink_module": {
691             "command": "ld -bundle -o {{target_output_name}}.so {{inputs}} {{ldflags}} {{libs}}",
692             "default_output_extension": ".so",
693             "framework_dir_switch": "-F",
694             "framework_switch": "-framework ",
695             "lib_dir_switch": "-L",
696             "lib_switch": "-l",
697             "output_prefix": "lib",
698             "outputs": [ "{{root_out_dir}}/{{target_output_name}}{{output_extension}}" ],
699             "weak_framework_switch": "-weak_framework "
700          },
701          "stamp": {
702             "command": "touch {{output}}"
703          },
704          "swift": {
705             "command": "swiftc --module-name {{module_name}} {{module_dirs}} {{inputs}}",
706             "framework_dir_switch": "-F",
707             "framework_switch": "-framework ",
708             "lib_dir_switch": "-L",
709             "lib_switch": "-l",
710             "outputs": [ "{{target_out_dir}}/{{module_name}}.swiftmodule" ],
711             "partial_outputs": [ "{{target_out_dir}}/{{source_name_part}}.o" ],
712             "weak_framework_switch": "-weak_framework "
713          }
714       }
715    }
716 }
717 )_";
718   EXPECT_EQ(expected_json, out) << out;
719 }
720