Skip to content

Commit d991452

Browse files
authored
Merge pull request #14746 from benlangmuir/working-directory
[driver] Add -working-directory option
2 parents 677491f + 20cb3e3 commit d991452

File tree

9 files changed

+388
-117
lines changed

9 files changed

+388
-117
lines changed

include/swift/Driver/Driver.h

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -208,9 +208,11 @@ class Driver {
208208
std::unique_ptr<llvm::opt::InputArgList>
209209
parseArgStrings(ArrayRef<const char *> Args);
210210

211-
/// Translate the input arguments into a DerivedArgList.
212-
llvm::opt::DerivedArgList *translateInputArgs(
213-
const llvm::opt::InputArgList &ArgList) const;
211+
/// Resolve path arguments if \p workingDirectory is non-empty, and translate
212+
/// inputs from -- arguments into a DerivedArgList.
213+
llvm::opt::DerivedArgList *
214+
translateInputAndPathArgs(const llvm::opt::InputArgList &ArgList,
215+
StringRef workingDirectory) const;
214216

215217
/// Construct the list of inputs and their types from the given arguments.
216218
///
@@ -250,20 +252,22 @@ class Driver {
250252

251253
/// Construct the OutputFileMap for the driver from the given arguments.
252254
std::unique_ptr<OutputFileMap>
253-
buildOutputFileMap(const llvm::opt::DerivedArgList &Args) const;
255+
buildOutputFileMap(const llvm::opt::DerivedArgList &Args,
256+
StringRef workingDirectory) const;
254257

255258
/// Add top-level Jobs to Compilation \p C for the given \p Actions and
256259
/// OutputInfo.
257260
///
258261
/// \param TopLevelActions The main Actions to build Jobs for.
259262
/// \param OI The OutputInfo for which Jobs should be generated.
260263
/// \param OFM The OutputFileMap for which Jobs should be generated.
264+
/// \param workingDirectory If non-empty, used to resolve any generated paths.
261265
/// \param TC The ToolChain to build Jobs with.
262266
/// \param C The Compilation containing the Actions for which Jobs should be
263267
/// created.
264268
void buildJobs(ArrayRef<const Action *> TopLevelActions, const OutputInfo &OI,
265-
const OutputFileMap *OFM, const ToolChain &TC,
266-
Compilation &C) const;
269+
const OutputFileMap *OFM, StringRef workingDirectory,
270+
const ToolChain &TC, Compilation &C) const;
267271

268272
/// A map for caching Jobs for a given Action/ToolChain pair
269273
using JobCacheMap =
@@ -283,8 +287,8 @@ class Driver {
283287
/// \returns a Job for the given Action/ToolChain pair
284288
Job *buildJobsForAction(Compilation &C, const JobAction *JA,
285289
const OutputInfo &OI, const OutputFileMap *OFM,
286-
const ToolChain &TC, bool AtTopLevel,
287-
JobCacheMap &JobCache) const;
290+
StringRef workingDirectory, const ToolChain &TC,
291+
bool AtTopLevel, JobCacheMap &JobCache) const;
288292

289293
private:
290294
void computeMainOutput(Compilation &C, const JobAction *JA,
@@ -293,6 +297,7 @@ class Driver {
293297
SmallVectorImpl<const Action *> &InputActions,
294298
SmallVectorImpl<const Job *> &InputJobs,
295299
const TypeToPathMap *OutputMap,
300+
StringRef workingDirectory,
296301
StringRef BaseInput,
297302
StringRef PrimaryInput,
298303
llvm::SmallString<128> &Buf,
@@ -301,38 +306,46 @@ class Driver {
301306
void chooseSwiftModuleOutputPath(Compilation &C, const OutputInfo &OI,
302307
const OutputFileMap *OFM,
303308
const TypeToPathMap *OutputMap,
309+
StringRef workingDirectory,
304310
CommandOutput *Output) const;
305311

306312
void chooseSwiftModuleDocOutputPath(Compilation &C,
307313
const TypeToPathMap *OutputMap,
314+
StringRef workingDirectory,
308315
CommandOutput *Output) const;
309316
void chooseRemappingOutputPath(Compilation &C, const TypeToPathMap *OutputMap,
310317
CommandOutput *Output) const;
311318

312319
void chooseSerializedDiagnosticsPath(Compilation &C, const JobAction *JA,
313320
const OutputInfo &OI,
314321
const TypeToPathMap *OutputMap,
322+
StringRef workingDirectory,
315323
CommandOutput *Output) const;
316324

317325
void chooseDependenciesOutputPaths(Compilation &C, const OutputInfo &OI,
318326
const TypeToPathMap *OutputMap,
327+
StringRef workingDirectory,
319328
llvm::SmallString<128> &Buf,
320329
CommandOutput *Output) const;
321330

322331
void chooseOptimizationRecordPath(Compilation &C, const OutputInfo &OI,
332+
StringRef workingDirectory,
323333
llvm::SmallString<128> &Buf,
324334
CommandOutput *Output) const;
325335

326336
void chooseObjectiveCHeaderOutputPath(Compilation &C, const OutputInfo &OI,
327337
const TypeToPathMap *OutputMap,
338+
StringRef workingDirectory,
328339
CommandOutput *Output) const;
329340

330341
void chooseLoadedModuleTracePath(Compilation &C, const OutputInfo &OI,
342+
StringRef workingDirectory,
331343
llvm::SmallString<128> &Buf,
332344
CommandOutput *Output) const;
333345

334346
void chooseTBDPath(Compilation &C, const OutputInfo &OI,
335-
llvm::SmallString<128> &Buf, CommandOutput *Output) const;
347+
StringRef workingDirectory, llvm::SmallString<128> &Buf,
348+
CommandOutput *Output) const;
336349

337350
public:
338351
/// Handle any arguments which should be treated before building actions or

include/swift/Driver/OutputFileMap.h

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,23 @@ class OutputFileMap {
3939
~OutputFileMap() = default;
4040

4141
/// Loads an OutputFileMap from the given \p Path, if possible.
42-
static std::unique_ptr<OutputFileMap> loadFromPath(StringRef Path);
42+
///
43+
/// When non-empty, \p workingDirectory is used to resolve relative paths in
44+
/// the output file map.
45+
static std::unique_ptr<OutputFileMap>
46+
loadFromPath(StringRef Path, StringRef workingDirectory);
4347

44-
static std::unique_ptr<OutputFileMap> loadFromBuffer(StringRef Data);
48+
static std::unique_ptr<OutputFileMap>
49+
loadFromBuffer(StringRef Data, StringRef workingDirectory);
4550

4651
/// Loads an OutputFileMap from the given \p Buffer, taking ownership
4752
/// of the buffer in the process.
53+
///
54+
/// When non-empty, \p workingDirectory is used to resolve relative paths in
55+
/// the output file map.
4856
static std::unique_ptr<OutputFileMap>
49-
loadFromBuffer(std::unique_ptr<llvm::MemoryBuffer> Buffer);
57+
loadFromBuffer(std::unique_ptr<llvm::MemoryBuffer> Buffer,
58+
StringRef workingDirectory);
5059

5160
/// Get the map of outputs for the given \p Input, if present in the
5261
/// OutputFileMap. (If not present, returns nullptr.)
@@ -69,8 +78,12 @@ class OutputFileMap {
6978
/// \brief Parses the given \p Buffer into the OutputFileMap, taking ownership
7079
/// of \p Buffer in the process.
7180
///
81+
/// When non-empty, \p workingDirectory is used to resolve relative paths in
82+
/// the output file map.
83+
///
7284
/// \returns true on error, false on success
73-
bool parse(std::unique_ptr<llvm::MemoryBuffer> Buffer);
85+
bool parse(std::unique_ptr<llvm::MemoryBuffer> Buffer,
86+
StringRef workingDirectory);
7487
};
7588

7689
} // end namespace driver

include/swift/Option/Options.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ namespace options {
3434
AutolinkExtractOption = (1 << 9),
3535
ModuleWrapOption = (1 << 10),
3636
SwiftFormatOption = (1 << 11),
37+
ArgumentIsPath = (1 << 12),
3738
};
3839

3940
enum ID {

include/swift/Option/Options.td

Lines changed: 55 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ def NoBatchOption : OptionFlag;
4343
// The option should not force a full rebuild if added, changed, or removed.
4444
def DoesNotAffectIncrementalBuild : OptionFlag;
4545

46+
// The option's argument is a file-system path that may be affected by the
47+
// current working directory.
48+
def ArgumentIsPath : OptionFlag;
49+
4650
/////////
4751
// Options
4852

@@ -132,47 +136,51 @@ def _DASH_DASH : Option<["--"], "", KIND_REMAINING_ARGS>,
132136

133137
def o : JoinedOrSeparate<["-"], "o">,
134138
Flags<[FrontendOption, AutolinkExtractOption, ModuleWrapOption,
135-
NoInteractiveOption, SwiftFormatOption]>,
139+
NoInteractiveOption, SwiftFormatOption, ArgumentIsPath]>,
136140
HelpText<"Write output to <file>">, MetaVarName<"<file>">;
137141

138142
def j : JoinedOrSeparate<["-"], "j">, Flags<[DoesNotAffectIncrementalBuild]>,
139143
HelpText<"Number of commands to execute in parallel">, MetaVarName<"<n>">;
140144

141-
def sdk : Separate<["-"], "sdk">, Flags<[FrontendOption]>,
145+
def sdk : Separate<["-"], "sdk">, Flags<[FrontendOption, ArgumentIsPath]>,
142146
HelpText<"Compile against <sdk>">, MetaVarName<"<sdk>">;
143147

144148
def swift_version : Separate<["-"], "swift-version">, Flags<[FrontendOption]>,
145149
HelpText<"Interpret input according to a specific Swift language version number">,
146150
MetaVarName<"<vers>">;
147151

148152
def tools_directory : Separate<["-"], "tools-directory">,
149-
Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild]>,
153+
Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild,
154+
ArgumentIsPath]>,
150155
HelpText<"Look for external executables (ld, clang, binutils) in <directory>">, MetaVarName<"<directory>">;
151156

152157
def D : JoinedOrSeparate<["-"], "D">, Flags<[FrontendOption]>,
153158
HelpText<"Marks a conditional compilation flag as true">;
154159

155-
def F : JoinedOrSeparate<["-"], "F">, Flags<[FrontendOption]>,
160+
def F : JoinedOrSeparate<["-"], "F">, Flags<[FrontendOption, ArgumentIsPath]>,
156161
HelpText<"Add directory to framework search path">;
157-
def F_EQ : Joined<["-"], "F=">, Flags<[FrontendOption]>, Alias<F>;
162+
def F_EQ : Joined<["-"], "F=">, Flags<[FrontendOption, ArgumentIsPath]>,
163+
Alias<F>;
158164

159-
def Fsystem : Separate<["-"], "Fsystem">, Flags<[FrontendOption]>,
165+
def Fsystem : Separate<["-"], "Fsystem">,
166+
Flags<[FrontendOption, ArgumentIsPath]>,
160167
HelpText<"Add directory to system framework search path">;
161168

162-
def I : JoinedOrSeparate<["-"], "I">, Flags<[FrontendOption]>,
169+
def I : JoinedOrSeparate<["-"], "I">, Flags<[FrontendOption, ArgumentIsPath]>,
163170
HelpText<"Add directory to the import search path">;
164-
def I_EQ : Joined<["-"], "I=">, Flags<[FrontendOption]>, Alias<I>;
171+
def I_EQ : Joined<["-"], "I=">, Flags<[FrontendOption, ArgumentIsPath]>,
172+
Alias<I>;
165173

166174
def import_underlying_module : Flag<["-"], "import-underlying-module">,
167175
Flags<[FrontendOption, NoInteractiveOption]>,
168176
HelpText<"Implicitly imports the Objective-C half of a module">;
169177

170178
def import_objc_header : Separate<["-"], "import-objc-header">,
171-
Flags<[FrontendOption, HelpHidden]>,
179+
Flags<[FrontendOption, HelpHidden, ArgumentIsPath]>,
172180
HelpText<"Implicitly imports an Objective-C header file">;
173181

174182
def pch_output_dir: Separate<["-"], "pch-output-dir">,
175-
Flags<[FrontendOption, HelpHidden]>,
183+
Flags<[FrontendOption, HelpHidden, ArgumentIsPath]>,
176184
HelpText<"Directory to persist automatically created precompiled bridging headers">;
177185

178186
// FIXME: Unhide this once it doesn't depend on an output file map.
@@ -184,10 +192,11 @@ def nostdimport : Flag<["-"], "nostdimport">, Flags<[FrontendOption]>,
184192
HelpText<"Don't search the standard library import path for modules">;
185193

186194
def output_file_map : Separate<["-"], "output-file-map">,
187-
Flags<[NoInteractiveOption]>,
195+
Flags<[NoInteractiveOption, ArgumentIsPath]>,
188196
HelpText<"A file which specifies the location of outputs">,
189197
MetaVarName<"<path>">;
190198
def output_file_map_EQ : Joined<["-"], "output-file-map=">,
199+
Flags<[NoInteractiveOption, ArgumentIsPath]>,
191200
Alias<output_file_map>;
192201

193202
def save_temps : Flag<["-"], "save-temps">,
@@ -197,7 +206,7 @@ def driver_time_compilation : Flag<["-"], "driver-time-compilation">,
197206
Flags<[NoInteractiveOption,DoesNotAffectIncrementalBuild]>,
198207
HelpText<"Prints the total time it took to execute all compilation tasks">;
199208
def stats_output_dir: Separate<["-"], "stats-output-dir">,
200-
Flags<[FrontendOption, HelpHidden]>,
209+
Flags<[FrontendOption, HelpHidden, ArgumentIsPath]>,
201210
HelpText<"Directory to write unified compilation-statistics files to">;
202211
def trace_stats_events: Flag<["-"], "trace-stats-events">,
203212
Flags<[FrontendOption, HelpHidden]>,
@@ -211,28 +220,30 @@ def emit_loaded_module_trace : Flag<["-"], "emit-loaded-module-trace">,
211220
Flags<[FrontendOption, NoInteractiveOption]>,
212221
HelpText<"Emit a JSON file containing information about what modules were loaded">;
213222
def emit_loaded_module_trace_path : Separate<["-"], "emit-loaded-module-trace-path">,
214-
Flags<[FrontendOption, NoInteractiveOption]>,
223+
Flags<[FrontendOption, NoInteractiveOption, ArgumentIsPath]>,
215224
HelpText<"Emit the loaded module trace JSON to <path>">,
216225
MetaVarName<"<path>">;
217226
def emit_loaded_module_trace_path_EQ : Joined<["-"], "emit-loaded-module-trace-path=">,
218-
Flags<[FrontendOption, NoInteractiveOption]>, Alias<emit_loaded_module_trace_path>;
227+
Flags<[FrontendOption, NoInteractiveOption, ArgumentIsPath]>,
228+
Alias<emit_loaded_module_trace_path>;
219229

220230
def emit_tbd : Flag<["-"], "emit-tbd">,
221231
HelpText<"Emit a TBD file">,
222232
Flags<[FrontendOption, NoInteractiveOption]>;
223233
def emit_tbd_path : Separate<["-"], "emit-tbd-path">,
224-
Flags<[FrontendOption, NoInteractiveOption]>,
234+
Flags<[FrontendOption, NoInteractiveOption, ArgumentIsPath]>,
225235
HelpText<"Emit the TBD file to <path>">,
226236
MetaVarName<"<path>">;
227237
def emit_tbd_path_EQ : Joined<["-"], "emit-tbd-path=">,
228-
Flags<[FrontendOption, NoInteractiveOption]>, Alias<emit_tbd_path>;
238+
Flags<[FrontendOption, NoInteractiveOption, ArgumentIsPath]>,
239+
Alias<emit_tbd_path>;
229240

230241
def serialize_diagnostics : Flag<["-"], "serialize-diagnostics">,
231242
Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild]>,
232243
HelpText<"Serialize diagnostics in a binary format">;
233244

234245
def module_cache_path : Separate<["-"], "module-cache-path">,
235-
Flags<[FrontendOption, DoesNotAffectIncrementalBuild]>,
246+
Flags<[FrontendOption, DoesNotAffectIncrementalBuild, ArgumentIsPath]>,
236247
HelpText<"Specifies the Clang module cache path">;
237248

238249
def module_name : Separate<["-"], "module-name">, Flags<[FrontendOption]>,
@@ -253,17 +264,21 @@ def emit_module : Flag<["-"], "emit-module">,
253264
Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild]>,
254265
HelpText<"Emit an importable module">;
255266
def emit_module_path : Separate<["-"], "emit-module-path">,
256-
Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild]>,
267+
Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild,
268+
ArgumentIsPath]>,
257269
HelpText<"Emit an importable module to <path>">,
258270
MetaVarName<"<path>">;
259271
def emit_module_path_EQ : Joined<["-"], "emit-module-path=">,
260-
Flags<[FrontendOption, NoInteractiveOption]>, Alias<emit_module_path>;
272+
Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild,
273+
ArgumentIsPath]>,
274+
Alias<emit_module_path>;
261275

262276
def emit_objc_header : Flag<["-"], "emit-objc-header">,
263277
Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild]>,
264278
HelpText<"Emit an Objective-C header file">;
265279
def emit_objc_header_path : Separate<["-"], "emit-objc-header-path">,
266-
Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild]>,
280+
Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild,
281+
ArgumentIsPath]>,
267282
MetaVarName<"<path>">, HelpText<"Emit an Objective-C header file to <path>">;
268283

269284
def import_cf_types : Flag<["-"], "import-cf-types">,
@@ -340,7 +355,7 @@ def save_optimization_record : Flag<["-"], "save-optimization-record">,
340355
Flags<[FrontendOption]>, HelpText<"Generate a YAML optimization record file">;
341356
def save_optimization_record_path :
342357
Separate<["-"], "save-optimization-record-path">,
343-
Flags<[FrontendOption]>,
358+
Flags<[FrontendOption, ArgumentIsPath]>,
344359
HelpText<"Specify the file name of any generated YAML optimization record">;
345360

346361
// Platform options.
@@ -360,9 +375,11 @@ def framework : Separate<["-"], "framework">, Group<linker_option_Group>,
360375
HelpText<"Specifies a framework which should be linked against">;
361376

362377
def L : JoinedOrSeparate<["-"], "L">, Group<linker_option_Group>,
363-
Flags<[FrontendOption, DoesNotAffectIncrementalBuild]>,
378+
Flags<[FrontendOption, DoesNotAffectIncrementalBuild, ArgumentIsPath]>,
364379
HelpText<"Add directory to library link search path">;
365-
def L_EQ : Joined<["-"], "L=">, Alias<L>;
380+
def L_EQ : Joined<["-"], "L=">,
381+
Flags<[FrontendOption, DoesNotAffectIncrementalBuild, ArgumentIsPath]>,
382+
Alias<L>;
366383

367384
def link_objc_runtime : Flag<["-"], "link-objc-runtime">,
368385
Flags<[DoesNotAffectIncrementalBuild]>;
@@ -498,12 +515,14 @@ def emit_migrated_file_path: Separate<["-"], "emit-migrated-file-path">,
498515
MetaVarName<"<path>">;
499516

500517
def dump_migration_states_dir: Separate<["-"], "dump-migration-states-dir">,
501-
Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild]>,
518+
Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild,
519+
ArgumentIsPath]>,
502520
HelpText<"Dump the input text, output text, and states for migration to <path>">,
503521
MetaVarName<"<path>">;
504522

505523
def api_diff_data_file: Separate<["-"], "api-diff-data-file">,
506-
Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild]>,
524+
Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild,
525+
ArgumentIsPath]>,
507526
HelpText<"API migration data is from <path>">,
508527
MetaVarName<"<path>">;
509528

@@ -657,7 +676,7 @@ def Xllvm : Separate<["-"], "Xllvm">,
657676
MetaVarName<"<arg>">, HelpText<"Pass <arg> to LLVM.">;
658677

659678
def resource_dir : Separate<["-"], "resource-dir">,
660-
Flags<[FrontendOption, HelpHidden]>,
679+
Flags<[FrontendOption, HelpHidden, ArgumentIsPath]>,
661680
MetaVarName<"</usr/lib/swift>">,
662681
HelpText<"The directory that holds the compiler resource files">;
663682

@@ -675,7 +694,8 @@ def profile_generate : Flag<["-"], "profile-generate">,
675694
HelpText<"Generate instrumented code to collect execution counts">;
676695

677696
def profile_use : CommaJoined<["-"], "profile-use=">,
678-
Flags<[FrontendOption, NoInteractiveOption]>, MetaVarName<"<profdata>">,
697+
Flags<[FrontendOption, NoInteractiveOption, ArgumentIsPath]>,
698+
MetaVarName<"<profdata>">,
679699
HelpText<"Supply a profdata file to enable profile-guided optimization">;
680700

681701
def profile_coverage_mapping : Flag<["-"], "profile-coverage-mapping">,
@@ -708,16 +728,22 @@ def index_file : Flag<["-"], "index-file">,
708728
HelpText<"Produce index data for a source file">, ModeOpt,
709729
Flags<[NoInteractiveOption, DoesNotAffectIncrementalBuild]>;
710730
def index_file_path : Separate<["-"], "index-file-path">,
711-
Flags<[NoInteractiveOption, DoesNotAffectIncrementalBuild]>,
731+
Flags<[NoInteractiveOption, DoesNotAffectIncrementalBuild, ArgumentIsPath]>,
712732
HelpText<"Produce index data for file <path>">,
713733
MetaVarName<"<path>">;
714734

715735
def index_store_path : Separate<["-"], "index-store-path">,
716-
Flags<[FrontendOption]>, MetaVarName<"<path>">,
736+
Flags<[FrontendOption, ArgumentIsPath]>, MetaVarName<"<path>">,
717737
HelpText<"Store indexing data to <path>">;
718738

719739
def enforce_exclusivity_EQ : Joined<["-"], "enforce-exclusivity=">,
720740
Flags<[FrontendOption]>, MetaVarName<"<enforcement>">,
721741
HelpText<"Enforce law of exclusivity">;
722742

743+
def working_directory : Separate<["-"], "working-directory">,
744+
HelpText<"Resolve file paths relative to the specified directory">,
745+
MetaVarName<"<path>">;
746+
def working_directory_EQ : Joined<["-"], "working-directory=">,
747+
Alias<working_directory>;
748+
723749
include "FrontendOptions.td"

0 commit comments

Comments
 (0)