Skip to content

Commit 96c0083

Browse files
[Driver] Provide executed command as an actual array (swiftlang#15012)
This patch adds additional entries to the JSON command messages output by the Swift compiler. It's now possible to get the command executable ("command_executable") and arguments ("command_arguments") as a single string and array, respectively, rather than having to parse the shell-escaped command line provided in the "command" key. <rdar://problem/35701809>
1 parent f3f54ec commit 96c0083

File tree

5 files changed

+129
-4
lines changed

5 files changed

+129
-4
lines changed

docs/DriverParseableOutput.rst

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ task's inputs as an array of paths under the "inputs" key. It may specify the
5151
task's outputs as an array of objects under the "outputs" key. An "outputs"
5252
object will have two fields, a "kind" describing the type of the output, and a
5353
"path" containing the path to the output. A "began" message will specify the
54-
command which was executed under the "command" key.
54+
command which was executed under the "command_executable" and "command_arguments"
55+
keys.
5556

5657
Example::
5758

@@ -74,7 +75,8 @@ Example::
7475
"path": "/build/foo.dia"
7576
},
7677
],
77-
"command": "swift -frontend -c -primary-file /src/foo.swift /src/bar.swift -emit-module-path /build/foo.swiftmodule -emit-diagnostics-path /build/foo.dia"
78+
"command_executable": "swift",
79+
"command_arguments" : ["-frontend", "-c", "-primary-file", "/src/foo.swift", "/src/bar.swift", "-emit-module-path", "/build/foo.swiftmodule", "-emit-diagnostics-path", "/build/foo.dia"]
7880
}
7981

8082
Finished Message
@@ -145,7 +147,8 @@ Example::
145147
"path": "/build/foo.dia"
146148
},
147149
],
148-
"command": "swift -frontend -c -primary-file /src/foo.swift /src/bar.swift -emit-module-path /build/foo.swiftmodule -emit-diagnostics-path /build/foo.dia"
150+
"command_executable": "swift",
151+
"command_arguments": ["-frontend", "-c", "-primary-file", "/src/foo.swift", "/src/bar.swift", "-emit-module-path", "/build/foo.swiftmodule", "-emit-diagnostics-path", "/build/foo.dia"]
149152
}
150153

151154
Message Names

lib/Driver/ParseableOutput.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,18 @@ class CommandBasedMessage : public Message {
9898
};
9999

100100
class DetailedCommandBasedMessage : public CommandBasedMessage {
101+
std::string Executable;
102+
SmallVector<std::string, 16> Arguments;
101103
std::string CommandLine;
102104
SmallVector<CommandInput, 4> Inputs;
103105
SmallVector<OutputPair, 8> Outputs;
104106
public:
105107
DetailedCommandBasedMessage(StringRef Kind, const Job &Cmd) :
106108
CommandBasedMessage(Kind, Cmd) {
109+
Executable = Cmd.getExecutable();
110+
for (const auto &A : Cmd.getArguments()) {
111+
Arguments.push_back(A);
112+
}
107113
llvm::raw_string_ostream wrapper(CommandLine);
108114
Cmd.printCommandLine(wrapper, "");
109115
wrapper.flush();
@@ -141,7 +147,9 @@ class DetailedCommandBasedMessage : public CommandBasedMessage {
141147

142148
void provideMapping(swift::json::Output &out) override {
143149
Message::provideMapping(out);
144-
out.mapRequired("command", CommandLine);
150+
out.mapRequired("command", CommandLine); // Deprecated, do not document
151+
out.mapRequired("command_executable", Executable);
152+
out.mapRequired("command_arguments", Arguments);
145153
out.mapOptional("inputs", Inputs);
146154
out.mapOptional("outputs", Outputs);
147155
}

test/Driver/batch_mode_parseable_output.swift

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,31 @@
1010
// CHECK-NEXT: "kind": "began",
1111
// CHECK-NEXT: "name": "compile",
1212
// CHECK-NEXT: "command": "{{.*}}/swift{{c?}} -frontend -c -primary-file {{.*}}/file-01.swift -primary-file {{.*}}/file-02.swift {{.*}}/file-03.swift {{.*}}/main.swift {{.*}} -emit-module-doc-path {{.*}}/file-01-[[SWIFTDOC01:[a-z0-9]+]].swiftdoc -emit-module-doc-path {{.*}}/file-02-[[SWIFTDOC02:[a-z0-9]+]].swiftdoc -module-name main -emit-module-path {{.*}}/file-01-[[MODULE01:[a-z0-9]+]].swiftmodule -emit-module-path {{.*}}/file-02-[[MODULE02:[a-z0-9]+]].swiftmodule -o {{.*}}/file-01-[[OBJ01:[a-z0-9]+]].o -o {{.*}}/file-02-[[OBJ02:[a-z0-9]+]].o",
13+
// CHECK-NEXT: "command_executable": "{{.*}}/swift{{c?}}",
14+
// CHECK-NEXT: "command_arguments": [
15+
// CHECK-NEXT: "-frontend",
16+
// CHECK-NEXT: "-c",
17+
// CHECK-NEXT: "-primary-file",
18+
// CHECK-NEXT: "{{.*}}/file-01.swift",
19+
// CHECK-NEXT: "-primary-file",
20+
// CHECK-NEXT: "{{.*}}/file-02.swift",
21+
// CHECK-NEXT: "{{.*}}/file-03.swift",
22+
// CHECK-NEXT: "{{.*}}/main.swift",
23+
// CHECK: "-emit-module-doc-path",
24+
// CHECK-NEXT: "{{.*}}/file-01-[[SWIFTDOC01:[a-z0-9]+]].swiftdoc",
25+
// CHECK-NEXT: "-emit-module-doc-path",
26+
// CHECK-NEXT: "{{.*}}/file-02-[[SWIFTDOC02:[a-z0-9]+]].swiftdoc",
27+
// CHECK-NEXT: "-module-name",
28+
// CHECK-NEXT: "main",
29+
// CHECK-NEXT: "-emit-module-path",
30+
// CHECK-NEXT: "{{.*}}/file-01-[[MODULE01:[a-z0-9]+]].swiftmodule",
31+
// CHECK-NEXT: "-emit-module-path",
32+
// CHECK-NEXT: "{{.*}}/file-02-[[MODULE02:[a-z0-9]+]].swiftmodule",
33+
// CHECK-NEXT: "-o",
34+
// CHECK-NEXT: "{{.*}}/file-01-[[OBJ01:[a-z0-9]+]].o",
35+
// CHECK-NEXT: "-o",
36+
// CHECK-NEXT: "{{.*}}/file-02-[[OBJ02:[a-z0-9]+]].o"
37+
// CHECK-NEXT: ],
1338
// CHECK-NEXT: "inputs": [
1439
// CHECK-NEXT: "{{.*}}/file-01.swift",
1540
// CHECK-NEXT: "{{.*}}/file-02.swift"
@@ -47,6 +72,31 @@
4772
// CHECK-NEXT: "kind": "began",
4873
// CHECK-NEXT: "name": "compile",
4974
// CHECK-NEXT: "command": "{{.*}}/swift{{c?}} -frontend -c {{.*}}/file-01.swift {{.*}}/file-02.swift -primary-file {{.*}}/file-03.swift -primary-file {{.*}}/main.swift {{.*}} -emit-module-doc-path {{.*}}/file-03-[[SWIFTDOC03:[a-z0-9]+]].swiftdoc -emit-module-doc-path {{.*}}/main-[[SWIFTDOCMAIN:[a-z0-9]+]].swiftdoc -module-name main -emit-module-path {{.*}}/file-03-[[MODULE03:[a-z0-9]+]].swiftmodule -emit-module-path {{.*}}/main-[[MODULEMAIN:[a-z0-9]+]].swiftmodule -o {{.*}}/file-03-[[OBJ03:[a-z0-9]+]].o -o {{.*}}/main-[[OBJMAIN:[a-z0-9]+]].o",
75+
// CHECK-NEXT: "command_executable": "{{.*}}/swift{{c?}}",
76+
// CHECK-NEXT: "command_arguments": [
77+
// CHECK-NEXT: "-frontend",
78+
// CHECK-NEXT: "-c",
79+
// CHECK-NEXT: "{{.*}}/file-01.swift",
80+
// CHECK-NEXT: "{{.*}}/file-02.swift",
81+
// CHECK-NEXT: "-primary-file",
82+
// CHECK-NEXT: "{{.*}}/file-03.swift",
83+
// CHECK-NEXT: "-primary-file",
84+
// CHECK-NEXT: "{{.*}}/main.swift",
85+
// CHECK: "-emit-module-doc-path",
86+
// CHECK-NEXT: "{{.*}}/file-03-[[SWIFTDOC03:[a-z0-9]+]].swiftdoc",
87+
// CHECK-NEXT: "-emit-module-doc-path",
88+
// CHECK-NEXT: "{{.*}}/main-[[SWIFTDOCMAIN:[a-z0-9]+]].swiftdoc",
89+
// CHECK-NEXT: "-module-name",
90+
// CHECK-NEXT: "main",
91+
// CHECK-NEXT: "-emit-module-path",
92+
// CHECK-NEXT: "{{.*}}/file-03-[[MODULE03:[a-z0-9]+]].swiftmodule",
93+
// CHECK-NEXT: "-emit-module-path",
94+
// CHECK-NEXT: "{{.*}}/main-[[MODULEMAIN:[a-z0-9]+]].swiftmodule",
95+
// CHECK-NEXT: "-o",
96+
// CHECK-NEXT: "{{.*}}/file-03-[[OBJ03:[a-z0-9]+]].o",
97+
// CHECK-NEXT: "-o",
98+
// CHECK-NEXT: "{{.*}}/main-[[OBJMAIN:[a-z0-9]+]].o"
99+
// CHECK-NEXT: ],
50100
// CHECK-NEXT: "inputs": [
51101
// CHECK-NEXT: "{{.*}}/file-03.swift",
52102
// CHECK-NEXT: "{{.*}}/main.swift"
@@ -98,6 +148,22 @@
98148
// CHECK-NEXT: "kind": "began",
99149
// CHECK-NEXT: "name": "merge-module",
100150
// CHECK-NEXT: "command": "{{.*}}/swift{{c?}} -frontend -merge-modules -emit-module {{.*}}/file-01-[[MODULE01]].swiftmodule {{.*}}/file-02-[[MODULE02]].swiftmodule {{.*}}/file-03-[[MODULE03]].swiftmodule {{.*}}/main-[[MODULEMAIN]].swiftmodule {{.*}} -emit-module-doc-path main.swiftdoc -module-name main -o main.swiftmodule",
151+
// CHECK-NEXT: "command_executable": "{{.*}}/swift{{c?}}",
152+
// CHECK-NEXT: "command_arguments": [
153+
// CHECK-NEXT: "-frontend",
154+
// CHECK-NEXT: "-merge-modules",
155+
// CHECK-NEXT: "-emit-module",
156+
// CHECK-NEXT: "{{.*}}/file-01-[[MODULE01]].swiftmodule",
157+
// CHECK-NEXT: "{{.*}}/file-02-[[MODULE02]].swiftmodule",
158+
// CHECK-NEXT: "{{.*}}/file-03-[[MODULE03]].swiftmodule",
159+
// CHECK-NEXT: "{{.*}}/main-[[MODULEMAIN]].swiftmodule",
160+
// CHECK: "-emit-module-doc-path",
161+
// CHECK-NEXT: "main.swiftdoc",
162+
// CHECK-NEXT: "-module-name",
163+
// CHECK-NEXT: "main",
164+
// CHECK-NEXT: "-o",
165+
// CHECK-NEXT: "main.swiftmodule"
166+
// CHECK-NEXT: ],
101167
// CHECK-NEXT: "inputs": [
102168
// CHECK-NEXT: "{{.*}}/file-01-[[OBJ01]].o",
103169
// CHECK-NEXT: "{{.*}}/file-02-[[OBJ02]].o",

test/Driver/parseable_output.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@
77
// CHECK-NEXT: "kind": "began",
88
// CHECK-NEXT: "name": "compile",
99
// CHECK-NEXT: "command": "{{.*}}/swift{{c?}} -frontend -c -primary-file {{.*}}/parseable_output.swift {{.*}} -o {{.*}}/parseable_output-[[OUTPUT:.*]].o",
10+
// CHECK-NEXT: "command_executable": "{{.*}}/swift{{c?}}",
11+
// CHECK-NEXT: "command_arguments": [
12+
// CHECK-NEXT: "-frontend",
13+
// CHECK-NEXT: "-c",
14+
// CHECK-NEXT: "-primary-file",
15+
// CHECK-NEXT: "{{.*}}/parseable_output.swift",
16+
// CHECK: "-o",
17+
// CHECK-NEXT: "{{.*}}/parseable_output-[[OUTPUT:.*]].o"
18+
// CHECK-NEXT: ],
1019
// CHECK-NEXT: "inputs": [
1120
// CHECK-NEXT: "{{.*}}/parseable_output.swift"
1221
// CHECK-NEXT: ],
@@ -49,6 +58,15 @@
4958
// CHECK-NEXT: "kind": "began",
5059
// CHECK-NEXT: "name": "merge-module",
5160
// CHECK-NEXT: "command": "{{.*}}/swift{{c?}} -frontend -merge-modules -emit-module {{.*}}/parseable_output-[[OUTPUT]].swiftmodule {{.*}} -o {{.*}}/parseable_output.swift.tmp.swiftmodule",
61+
// CHECK-NEXT: "command_executable": "{{.*}}/swift{{c?}}",
62+
// CHECK-NEXT: "command_arguments": [
63+
// CHECK-NEXT: "-frontend",
64+
// CHECK-NEXT: "-merge-modules",
65+
// CHECK-NEXT: "-emit-module",
66+
// CHECK-NEXT: "{{.*}}/parseable_output-[[OUTPUT]].swiftmodule",
67+
// CHECK: "-o",
68+
// CHECK-NEXT: "{{.*}}/parseable_output.swift.tmp.swiftmodule"
69+
// CHECK-NEXT: ],
5270
// CHECK-NEXT: "inputs": [
5371
// CHECK-NEXT: "{{.*}}/parseable_output-[[OUTPUT]].o"
5472
// CHECK-NEXT: ],
@@ -83,6 +101,12 @@
83101
// CHECK-NEXT: "kind": "began",
84102
// CHECK-NEXT: "name": "link",
85103
// CHECK-NEXT: "command": "{{.*}}/ld{{(\\")?}} {{.*}}/parseable_output-[[OUTPUT]].o {{.*}} -o {{.*}}/parseable_output.swift.tmp.out",
104+
// CHECK-NEXT: "command_executable": "{{.*}}/ld{{(\\")?}}",
105+
// CHECK-NEXT: "command_arguments": [
106+
// CHECK-NEXT: "{{.*}}/parseable_output-[[OUTPUT]].o",
107+
// CHECK: "-o",
108+
// CHECK-NEXT: "{{.*}}/parseable_output.swift.tmp.out"
109+
// CHECK-NEXT: ],
86110
// CHECK-NEXT: "inputs": [
87111
// CHECK-NEXT: "{{.*}}/parseable_output-[[OUTPUT]].o"
88112
// CHECK-NEXT: ],

test/Driver/parseable_output_unicode.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@
77
// CHECK-NEXT: "kind": "began",
88
// CHECK-NEXT: "name": "compile",
99
// CHECK-NEXT: "command": "{{.*}}/swift{{c?}} -frontend -c -primary-file {{.*}}/你好.swift {{.*}} -o {{.*}}/你好-[[OUTPUT:.*]].o",
10+
// CHECK-NEXT: "command_executable": "{{.*}}/swift{{c?}}",
11+
// CHECK-NEXT: "command_arguments": [
12+
// CHECK-NEXT: "-frontend",
13+
// CHECK-NEXT: "-c",
14+
// CHECK-NEXT: "-primary-file",
15+
// CHECK-NEXT: "{{.*}}/你好.swift",
16+
// CHECK: "-o",
17+
// CHECK-NEXT: "{{.*}}/你好-[[OUTPUT:.*]].o"
18+
// CHECK-NEXT: ],
1019
// CHECK-NEXT: "inputs": [
1120
// CHECK-NEXT: "{{.*}}/你好.swift"
1221
// CHECK-NEXT: ],
@@ -49,6 +58,15 @@
4958
// CHECK-NEXT: "kind": "began",
5059
// CHECK-NEXT: "name": "merge-module",
5160
// CHECK-NEXT: "command": "{{.*}}/swift{{c?}} -frontend -merge-modules -emit-module {{.*}}/你好-[[OUTPUT]].swiftmodule {{.*}} -o {{.*}}/parseable_output_unicode.swift.tmp.swiftmodule",
61+
// CHECK-NEXT: "command_executable": "{{.*}}/swift{{c?}}",
62+
// CHECK-NEXT: "command_arguments": [
63+
// CHECK-NEXT: "-frontend",
64+
// CHECK-NEXT: "-merge-modules",
65+
// CHECK-NEXT: "-emit-module",
66+
// CHECK-NEXT: "{{.*}}/你好-[[OUTPUT]].swiftmodule",
67+
// CHECK: "-o",
68+
// CHECK-NEXT: "{{.*}}/parseable_output_unicode.swift.tmp.swiftmodule"
69+
// CHECK-NEXT: ],
5270
// CHECK-NEXT: "inputs": [
5371
// CHECK-NEXT: "{{.*}}/你好-[[OUTPUT]].o"
5472
// CHECK-NEXT: ],
@@ -83,6 +101,12 @@
83101
// CHECK-NEXT: "kind": "began",
84102
// CHECK-NEXT: "name": "link",
85103
// CHECK-NEXT: "command": "{{.*}}/ld{{(\\")?}} {{.*}}/你好-[[OUTPUT]].o {{.*}} -o {{.*}}/parseable_output_unicode.swift.tmp.out",
104+
// CHECK-NEXT: "command_executable": "{{.*}}/ld{{(\\")?}}",
105+
// CHECK-NEXT: "command_arguments": [
106+
// CHECK-NEXT: "{{.*}}/你好-[[OUTPUT]].o",
107+
// CHECK: "-o",
108+
// CHECK-NEXT: "{{.*}}/parseable_output_unicode.swift.tmp.out"
109+
// CHECK-NEXT: ],
86110
// CHECK-NEXT: "inputs": [
87111
// CHECK-NEXT: "{{.*}}/你好-[[OUTPUT]].o"
88112
// CHECK-NEXT: ],

0 commit comments

Comments
 (0)