@@ -38,8 +38,6 @@ int PW_MAIN(int argc, const CharType* argv[], const CharType* envp[]) {
38
38
39
39
System::EnvironmentBlock environment_file_block;
40
40
41
- using Subst = std::pair<System::StrType, System::StrType>;
42
-
43
41
System::StrType exec_path;
44
42
std::vector<Subst> subst_mappings;
45
43
std::vector<Subst> stamp_mappings;
@@ -79,7 +77,8 @@ int PW_MAIN(int argc, const CharType* argv[], const CharType* envp[]) {
79
77
if (value == PW_SYS_STR (" ${pwd}" )) {
80
78
value = System::GetWorkingDirectory ();
81
79
}
82
- subst_mappings.push_back ({std::move (key), std::move (value)});
80
+ subst_mappings.push_back ({PW_SYS_STR (" ${" ) + key + PW_SYS_STR (" }" ),
81
+ std::move (value)});
83
82
} else if (arg == PW_SYS_STR (" --volatile-status-file" )) {
84
83
if (!volatile_status_file.empty ()) {
85
84
std::cerr << " process wrapper error: \" --volatile-status-file\" can "
@@ -143,24 +142,74 @@ int PW_MAIN(int argc, const CharType* argv[], const CharType* envp[]) {
143
142
for (++i; i < argc; ++i) {
144
143
arguments.push_back (argv[i]);
145
144
}
146
- // after we consume all arguments we append the files arguments
147
- for (const System::StrType& file_arg : file_arguments) {
148
- arguments.push_back (file_arg);
149
- }
150
145
} else {
151
146
std::cerr << " process wrapper error: unknow argument \" " << ToUtf8 (arg)
152
147
<< " \" ." << ' \n ' ;
153
148
return -1 ;
154
149
}
155
150
}
156
151
152
+ // Expand tokens into the file arguments (since some paths might embed
153
+ // `${pwd}` that we need to resolve it from the subsitution mappings).
154
+ for (System::StrType& file_arg : file_arguments) {
155
+ ReplaceTokens (file_arg, subst_mappings);
156
+ }
157
+
158
+ // Process the arguments, making sure that we don't have paths to param files
159
+ // within another param file (that is an arg composed of `@` + a path), which
160
+ // rustc doesn't support.
161
+ // (We process them in reverse so that we can append the param files to the
162
+ // front of `file_arguments` in the right order).
163
+ for (auto arg_it = arguments.rbegin (); arg_it != arguments.rend (); arg_it++) {
164
+ System::StrType& arg = *arg_it;
165
+ ReplaceTokens (arg, subst_mappings);
166
+
167
+ // Check whether this is a regular argument or a path to a param file.
168
+ if (arg.size () > 0 && arg.substr (0 , 1 ) == PW_SYS_STR (" @" )) {
169
+ System::StrType path = arg.substr (1 );
170
+
171
+ // Read the actual params off the param file so that we can 1) extract
172
+ // potential other param files inside and 2) substitute mappings.
173
+ System::StrVecType params;
174
+ if (!ReadFileToArray (path, params)) {
175
+ std::cerr << " Cannot read param file " << ToUtf8 (path) << " \n " ;
176
+ return -1 ;
177
+ }
178
+
179
+ for (auto par_it = params.rbegin (); par_it != params.rend (); par_it++) {
180
+ System::StrType& param = *par_it;
181
+ ReplaceTokens (param, subst_mappings);
182
+
183
+ // If we find a path to a param file, move it to the top-level file
184
+ // arguments instead (we cannot have nested param files).
185
+ if (param.size () > 0 && param.substr (0 , 1 ) == PW_SYS_STR (" @" )) {
186
+ file_arguments.insert (file_arguments.begin (), param);
187
+ params.erase (std::next (par_it).base ());
188
+ }
189
+ }
190
+
191
+ // Create a new param file so that we don't need to edit the original one
192
+ // that Bazel created.
193
+ System::StrType new_path = path + PW_SYS_STR (" .expanded" );
194
+ if (!WriteArrayToFile (new_path, params)) {
195
+ std::cerr << " Cannot write params to file " << ToUtf8 (new_path) << " \n " ;
196
+ return -1 ;
197
+ }
198
+
199
+ arguments.erase (std::next (arg_it).base ());
200
+ file_arguments.insert (file_arguments.begin (), PW_SYS_STR (" @" ) + new_path);
201
+ }
202
+ }
203
+
204
+ // after we consume all arguments we append the files arguments
205
+ for (const System::StrType& file_arg : file_arguments) {
206
+ arguments.push_back (file_arg);
207
+ }
208
+
157
209
// Stamp any format string in an environment variable block
158
- for (const Subst& stamp : stamp_mappings) {
159
- System::StrType token = PW_SYS_STR (" {" );
160
- token += stamp.first ;
161
- token.push_back (' }' );
210
+ if (stamp_mappings.size ()) {
162
211
for (System::StrType& env : environment_file_block) {
163
- ReplaceToken (env, token, stamp. second );
212
+ ReplaceTokens (env, stamp_mappings );
164
213
}
165
214
}
166
215
@@ -171,19 +220,9 @@ int PW_MAIN(int argc, const CharType* argv[], const CharType* envp[]) {
171
220
environment_file_block.begin (),
172
221
environment_file_block.end ());
173
222
174
- if (subst_mappings.size ()) {
175
- for (const Subst& subst : subst_mappings) {
176
- System::StrType token = PW_SYS_STR (" ${" );
177
- token += subst.first ;
178
- token.push_back (' }' );
179
- for (System::StrType& arg : arguments) {
180
- ReplaceToken (arg, token, subst.second );
181
- }
182
-
183
- for (System::StrType& env : environment_block) {
184
- ReplaceToken (env, token, subst.second );
185
- }
186
- }
223
+ // Expand tokens in environment
224
+ for (System::StrType& env : environment_block) {
225
+ ReplaceTokens (env, subst_mappings);
187
226
}
188
227
189
228
// Have the last values added take precedence over the first.
0 commit comments