1 /**
2  * Defines the help texts for the CLI options offered by DMD.
3  *
4  * This file is not shared with other compilers which use the DMD front-end.
5  * However, this file will be used to generate the
6  * $(LINK2 https://dlang.org/dmd-linux.html, online documentation) and MAN pages.
7  *
8  * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
9  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
10  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
11  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/cli.d, _cli.d)
12  * Documentation:  https://dlang.org/phobos/dmd_cli.html
13  * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/cli.d
14  */
15 module dmd.cli;
16 
17 /* The enum TargetOS is an exact copy of the one in dmd.globals.
18  * Duplicated here because this file is stand-alone.
19  */
20 
21 /// Bit decoding of the TargetOS
22 enum TargetOS : ubyte
23 {
24     /* These are mutually exclusive; one and only one is set.
25      * Match spelling and casing of corresponding version identifiers
26      */
27     linux        = 1,
28     Windows      = 2,
29     OSX          = 4,
30     OpenBSD      = 8,
31     FreeBSD      = 0x10,
32     Solaris      = 0x20,
33     DragonFlyBSD = 0x40,
34 
35     // Combination masks
36     all = linux | Windows | OSX | OpenBSD | FreeBSD | Solaris | DragonFlyBSD,
37     Posix = linux | OSX | OpenBSD | FreeBSD | Solaris | DragonFlyBSD,
38 }
39 
40 // Detect the current TargetOS
41 version (linux)
42 {
43     private enum targetOS = TargetOS.linux;
44 }
45 else version(Windows)
46 {
47     private enum targetOS = TargetOS.Windows;
48 }
49 else version(OSX)
50 {
51     private enum targetOS = TargetOS.OSX;
52 }
53 else version(OpenBSD)
54 {
55     private enum targetOS = TargetOS.OpenBSD;
56 }
57 else version(FreeBSD)
58 {
59     private enum targetOS = TargetOS.FreeBSD;
60 }
61 else version(DragonFlyBSD)
62 {
63     private enum targetOS = TargetOS.DragonFlyBSD;
64 }
65 else version(Solaris)
66 {
67     private enum targetOS = TargetOS.Solaris;
68 }
69 else
70 {
71     private enum targetOS = TargetOS.all;
72 }
73 
74 /**
75 Checks whether `os` is the current $(LREF TargetOS).
76 For `TargetOS.all` it will always return true.
77 
78 Params:
79     os = $(LREF TargetOS) to check
80 
81 Returns: true iff `os` contains the current targetOS.
82 */
83 bool isCurrentTargetOS(TargetOS os)
84 {
85     return (os & targetOS) > 0;
86 }
87 
88 /**
89 Capitalize a the first character of a ASCII string.
90 Params:
91     w = ASCII i string to capitalize
92 Returns: capitalized string
93 */
94 static string capitalize(string w)
95 {
96     char[] result = cast(char[]) w;
97     char c1 = w.length ? w[0] : '\0';
98 
99     if (c1 >= 'a' && c1 <= 'z')
100     {
101         enum adjustment = 'A' - 'a';
102 
103         result = new char[] (w.length);
104         result[0] = cast(char) (c1 + adjustment);
105         result[1 .. $] = w[1 .. $];
106     }
107 
108     return cast(string) result;
109 }
110 
111 /**
112 Contains all available CLI $(LREF Usage.Option)s.
113 
114 See_Also: $(LREF Usage.Option)
115 */
116 struct Usage
117 {
118     /**
119     * Representation of a CLI `Option`
120     *
121     * The DDoc description `ddoxText` is only available when compiled with `-version=DdocOptions`.
122     */
123     struct Option
124     {
125         string flag; /// The CLI flag without leading `-`, e.g. `color`
126         string helpText; /// A detailed description of the flag
127         TargetOS os = TargetOS.all; /// For which `TargetOS` the flags are applicable
128 
129         // Needs to be version-ed to prevent the text ending up in the binary
130         // See also: https://issues.dlang.org/show_bug.cgi?id=18238
131         version(DdocOptions) string ddocText; /// Detailed description of the flag (in Ddoc)
132 
133         /**
134         * Params:
135         *  flag = CLI flag without leading `-`, e.g. `color`
136         *  helpText = detailed description of the flag
137         *  os = for which `TargetOS` the flags are applicable
138         *  ddocText = detailed description of the flag (in Ddoc)
139         */
140         this(string flag, string helpText, TargetOS os = TargetOS.all)
141         {
142             this.flag = flag;
143             this.helpText = helpText;
144             version(DdocOptions) this.ddocText = helpText;
145             this.os = os;
146         }
147 
148         /// ditto
149         this(string flag, string helpText, string ddocText, TargetOS os = TargetOS.all)
150         {
151             this.flag = flag;
152             this.helpText = helpText;
153             version(DdocOptions) this.ddocText = ddocText;
154             this.os = os;
155         }
156     }
157 
158     /// Returns all available CLI options
159     static immutable options = [
160         Option("allinst",
161             "generate code for all template instantiations"
162         ),
163         Option("betterC",
164             "omit generating some runtime information and helper functions",
165             "Adjusts the compiler to implement D as a $(LINK2 $(ROOT_DIR)spec/betterc.html, better C):
166             $(UL
167                 $(LI Predefines `D_BetterC` $(LINK2 $(ROOT_DIR)spec/version.html#predefined-versions, version).)
168                 $(LI $(LINK2 $(ROOT_DIR)spec/expression.html#AssertExpression, Assert Expressions), when they fail,
169                 call the C runtime library assert failure function
170                 rather than a function in the D runtime.)
171                 $(LI $(LINK2 $(ROOT_DIR)spec/arrays.html#bounds, Array overflows)
172                 call the C runtime library assert failure function
173                 rather than a function in the D runtime.)
174                 $(LI $(LINK2 spec/statement.html#final-switch-statement/, Final switch errors)
175                 call the C runtime library assert failure function
176                 rather than a function in the D runtime.)
177                 $(LI Does not automatically link with phobos runtime library.)
178                 $(UNIX
179                 $(LI Does not generate Dwarf `eh_frame` with full unwinding information, i.e. exception tables
180                 are not inserted into `eh_frame`.)
181                 )
182                 $(LI Module constructors and destructors are not generated meaning that
183                 $(LINK2 $(ROOT_DIR)spec/class.html#StaticConstructor, static) and
184                 $(LINK2 $(ROOT_DIR)spec/class.html#SharedStaticConstructor, shared static constructors) and
185                 $(LINK2 $(ROOT_DIR)spec/class.html#StaticDestructor, destructors)
186                 will not get called.)
187                 $(LI `ModuleInfo` is not generated.)
188                 $(LI $(LINK2 $(ROOT_DIR)phobos/object.html#.TypeInfo, `TypeInfo`)
189                 instances will not be generated for structs.)
190             )",
191         ),
192         Option("boundscheck=[on|safeonly|off]",
193             "bounds checks on, in @safe only, or off",
194             `Controls if bounds checking is enabled.
195                 $(UL
196                     $(LI $(I on): Bounds checks are enabled for all code. This is the default.)
197                     $(LI $(I safeonly): Bounds checks are enabled only in $(D @safe) code.
198                                         This is the default for $(SWLINK -release) builds.)
199                     $(LI $(I off): Bounds checks are disabled completely (even in $(D @safe)
200                                    code). This option should be used with caution and as a
201                                    last resort to improve performance. Confirm turning off
202                                    $(D @safe) bounds checks is worthwhile by benchmarking.)
203                 )`
204         ),
205         Option("c",
206             "compile only, do not link"
207         ),
208         Option("check=[assert|bounds|in|invariant|out|switch][=[on|off]]",
209             "enable or disable specific checks",
210             `Overrides default, -boundscheck, -release and -unittest options to enable or disable specific checks.
211                 $(UL
212                     $(LI $(B assert): assertion checking)
213                     $(LI $(B bounds): array bounds)
214                     $(LI $(B in): in contracts)
215                     $(LI $(B invariant): class/struct invariants)
216                     $(LI $(B out): out contracts)
217                     $(LI $(B switch): finalswitch failure checking)
218                 )
219                 $(UL
220                     $(LI $(B on) or not specified: specified check is enabled.)
221                     $(LI $(B off): specified check is disabled.)
222                 )`
223         ),
224         Option("check=[h|help|?]",
225             "list information on all available checks"
226         ),
227         Option("checkaction=[D|C|halt|context]",
228             "behavior on assert/boundscheck/finalswitch failure",
229             `Sets behavior when an assert fails, and array boundscheck fails,
230              or a final switch errors.
231                 $(UL
232                     $(LI $(B D): Default behavior, which throws an unrecoverable $(D AssertError).)
233                     $(LI $(B C): Calls the C runtime library assert failure function.)
234                     $(LI $(B halt): Executes a halt instruction, terminating the program.)
235                     $(LI $(B context): Prints the error context as part of the unrecoverable $(D AssertError).)
236                 )`
237         ),
238         Option("checkaction=[h|help|?]",
239             "list information on all available check actions"
240         ),
241         Option("color",
242             "turn colored console output on"
243         ),
244         Option("color=[on|off|auto]",
245             "force colored console output on or off, or only when not redirected (default)",
246             `Show colored console output. The default depends on terminal capabilities.
247             $(UL
248                 $(LI $(B auto): use colored output if a tty is detected (default))
249                 $(LI $(B on): always use colored output.)
250                 $(LI $(B off): never use colored output.)
251             )`
252         ),
253         Option("conf=<filename>",
254             "use config file at filename"
255         ),
256         Option("cov",
257             "do code coverage analysis"
258         ),
259         Option("cov=ctfe", "Include code executed during CTFE in coverage report"),
260         Option("cov=<nnn>",
261             "require at least nnn% code coverage",
262             `Perform $(LINK2 $(ROOT_DIR)code_coverage.html, code coverage analysis) and generate
263             $(TT .lst) file with report.)
264 ---
265 dmd -cov -unittest myprog.d
266 ---
267             `,
268         ),
269         Option("cpp=<filename>",
270             "use filename as the name of the C preprocessor to use for ImportC files",
271             `Normally the C preprocessor used by the associated C compiler is used to
272             preprocess ImportC files,
273             this is overridden by the $(TT -cpp) switch.`
274         ),
275         Option("D",
276             "generate documentation",
277             `$(P Generate $(LINK2 $(ROOT_DIR)spec/ddoc.html, documentation) from source.)
278             $(P Note: mind the $(LINK2 $(ROOT_DIR)spec/ddoc.html#security, security considerations).)
279             `,
280         ),
281         Option("Dd<directory>",
282             "write documentation file to directory",
283             `Write documentation file to $(I directory) . $(SWLINK -op)
284             can be used if the original package hierarchy should
285             be retained`,
286         ),
287         Option("Df<filename>",
288             "write documentation file to filename"
289         ),
290         Option("d",
291             "silently allow deprecated features and symbols",
292             `Silently allow $(DDLINK deprecate,deprecate,deprecated features) and use of symbols with
293             $(DDSUBLINK $(ROOT_DIR)spec/attribute, deprecated, deprecated attributes).`,
294         ),
295         Option("de",
296             "issue an error when deprecated features or symbols are used (halt compilation)"
297         ),
298         Option("dw",
299             "issue a message when deprecated features or symbols are used (default)"
300         ),
301         Option("debug",
302             "compile in debug code",
303             `Compile in $(LINK2 spec/version.html#debug, debug) code`,
304         ),
305         Option("debug=<level>",
306             "compile in debug code <= level",
307             `Compile in $(LINK2 spec/version.html#debug, debug level) &lt;= $(I level)`,
308         ),
309         Option("debug=<ident>",
310             "compile in debug code identified by ident",
311             `Compile in $(LINK2 spec/version.html#debug, debug identifier) $(I ident)`,
312         ),
313         Option("debuglib=<name>",
314             "set symbolic debug library to name",
315             `Link in $(I libname) as the default library when
316             compiling for symbolic debugging instead of $(B $(LIB)).
317             If $(I libname) is not supplied, then no default library is linked in.`
318         ),
319         Option("defaultlib=<name>",
320             "set default library to name",
321             `Link in $(I libname) as the default library when
322             not compiling for symbolic debugging instead of $(B $(LIB)).
323             If $(I libname) is not supplied, then no default library is linked in.`,
324         ),
325         Option("deps",
326             "print module dependencies (imports/file/version/debug/lib)"
327         ),
328         Option("deps=<filename>",
329             "write module dependencies to filename (only imports)",
330             `Without $(I filename), print module dependencies
331             (imports/file/version/debug/lib).
332             With $(I filename), write module dependencies as text to $(I filename)
333             (only imports).`,
334         ),
335         Option("extern-std=<standard>",
336             "set C++ name mangling compatibility with <standard>",
337             "Standards supported are:
338             $(UL
339                 $(LI $(I c++98): Use C++98 name mangling,
340                     Sets `__traits(getTargetInfo, \"cppStd\")` to `199711`)
341                 $(LI $(I c++11) (default): Use C++11 name mangling,
342                     Sets `__traits(getTargetInfo, \"cppStd\")` to `201103`)
343                 $(LI $(I c++14): Use C++14 name mangling,
344                     Sets `__traits(getTargetInfo, \"cppStd\")` to `201402`)
345                 $(LI $(I c++17): Use C++17 name mangling,
346                     Sets `__traits(getTargetInfo, \"cppStd\")` to `201703`)
347                 $(LI $(I c++20): Use C++20 name mangling,
348                     Sets `__traits(getTargetInfo, \"cppStd\")` to `202002`)
349             )",
350         ),
351         Option("extern-std=[h|help|?]",
352             "list all supported standards"
353         ),
354         Option("fPIC",
355             "generate position independent code",
356             cast(TargetOS) (TargetOS.all & ~(TargetOS.Windows | TargetOS.OSX))
357         ),
358         Option("fPIE",
359             "generate position independent executables",
360             cast(TargetOS) (TargetOS.all & ~(TargetOS.Windows | TargetOS.OSX))
361         ),
362         Option("g",
363             "add symbolic debug info",
364             `$(WINDOWS
365                 Add CodeView symbolic debug info. See
366                 $(LINK2 https://dlang.org/windbg.html, Debugging on Windows).
367             )
368             $(UNIX
369                 Add symbolic debug info in DWARF format
370                 for debuggers such as
371                 $(D gdb)
372             )`,
373         ),
374         Option("gdwarf=<version>",
375             "add DWARF symbolic debug info",
376             "The value of version may be 3, 4 or 5, defaulting to 3.",
377             cast(TargetOS) (TargetOS.all & ~cast(uint)TargetOS.Windows)
378         ),
379         Option("gf",
380             "emit debug info for all referenced types",
381             `Symbolic debug info is emitted for all types referenced by the compiled code,
382              even if the definition is in an imported file not currently being compiled.`,
383         ),
384         Option("gs",
385             "always emit stack frame"
386         ),
387         Option("gx",
388             "add stack stomp code",
389             `Adds stack stomp code, which overwrites the stack frame memory upon function exit.`,
390         ),
391         Option("H",
392             "generate 'header' file",
393             `Generate $(RELATIVE_LINK2 $(ROOT_DIR)interface-files, D interface file)`,
394         ),
395         Option("Hd=<directory>",
396             "write 'header' file to directory",
397             `Write D interface file to $(I dir) directory. $(SWLINK -op)
398             can be used if the original package hierarchy should
399             be retained.`,
400         ),
401         Option("Hf=<filename>",
402             "write 'header' file to filename"
403         ),
404         Option("HC[=[silent|verbose]]",
405             "generate C++ 'header' file",
406             `Generate C++ 'header' files using the given configuration:",
407             $(DL
408             $(DT silent)$(DD only list extern(C[++]) declarations (default))
409             $(DT verbose)$(DD also add comments for ignored declarations (e.g. extern(D)))
410             )`,
411         ),
412         Option("HC=[?|h|help]",
413             "list available modes for C++ 'header' file generation"
414         ),
415         Option("HCd=<directory>",
416             "write C++ 'header' file to directory"
417         ),
418         Option("HCf=<filename>",
419             "write C++ 'header' file to filename"
420         ),
421         Option("-help",
422             "print help and exit"
423         ),
424         Option("I=<directory>",
425             "look for imports also in directory"
426         ),
427         Option("i[=<pattern>]",
428             "include imported modules in the compilation",
429             q"{$(P Enables "include imports" mode, where the compiler will include imported
430              modules in the compilation, as if they were given on the command line. By default, when
431              this option is enabled, all imported modules are included except those in
432              druntime/phobos. This behavior can be overriden by providing patterns via `-i=<pattern>`.
433              A pattern of the form `-i=<package>` is an "inclusive pattern", whereas a pattern
434              of the form `-i=-<package>` is an "exclusive pattern". Inclusive patterns will include
435              all module's whose names match the pattern, whereas exclusive patterns will exclude them.
436              For example. all modules in the package `foo.bar` can be included using `-i=foo.bar` or excluded
437              using `-i=-foo.bar`. Note that each component of the fully qualified name must match the
438              pattern completely, so the pattern `foo.bar` would not match a module named `foo.barx`.)
439 
440              $(P The default behavior of excluding druntime/phobos is accomplished by internally adding a
441              set of standard exclusions, namely, `-i=-std -i=-core -i=-etc -i=-object`. Note that these
442              can be overriden with `-i=std -i=core -i=etc -i=object`.)
443 
444              $(P When a module matches multiple patterns, matches are prioritized by their component length, where
445              a match with more components takes priority (i.e. pattern `foo.bar.baz` has priority over `foo.bar`).)
446 
447              $(P By default modules that don't match any pattern will be included. However, if at
448              least one inclusive pattern is given, then modules not matching any pattern will
449              be excluded. This behavior can be overriden by usig `-i=.` to include by default or `-i=-.` to
450              exclude by default.)
451 
452              $(P Note that multiple `-i=...` options are allowed, each one adds a pattern.)}"
453         ),
454         Option("ignore",
455             "ignore unsupported pragmas"
456         ),
457         Option("inline",
458             "do function inlining",
459             `Inline functions at the discretion of the compiler.
460             This can improve performance, at the expense of making
461             it more difficult to use a debugger on it.`,
462         ),
463         Option("J=<directory>",
464             "look for string imports also in directory",
465             `Where to look for files for
466             $(LINK2 $(ROOT_DIR)spec/expression.html#ImportExpression, $(I ImportExpression))s.
467             This switch is required in order to use $(I ImportExpression)s.
468             $(I path) is a ; separated
469             list of paths. Multiple $(B -J)'s can be used, and the paths
470             are searched in the same order.`,
471         ),
472         Option("L=<linkerflag>",
473             "pass linkerflag to link",
474             `Pass $(I linkerflag) to the
475             $(WINDOWS linker $(OPTLINK))
476             $(UNIX linker), for example, ld`,
477         ),
478         Option("lib",
479             "generate library rather than object files",
480             `Generate library file as output instead of object file(s).
481             All compiled source files, as well as object files and library
482             files specified on the command line, are inserted into
483             the output library.
484             Compiled source modules may be partitioned into several object
485             modules to improve granularity.
486             The name of the library is taken from the name of the first
487             source module to be compiled. This name can be overridden with
488             the $(SWLINK -of) switch.`,
489         ),
490         Option("lowmem",
491             "enable garbage collection for the compiler",
492             `Enable the garbage collector for the compiler, reducing the
493             compiler memory requirements but increasing compile times.`,
494         ),
495         Option("m32",
496             "generate 32 bit code",
497             `$(UNIX Compile a 32 bit executable. This is the default for the 32 bit dmd.)`,
498             cast(TargetOS) (TargetOS.all & ~cast(uint)TargetOS.DragonFlyBSD)  // available on all OS'es except DragonFly, which does not support 32-bit binaries
499         ),
500         Option("m32mscoff",
501             "generate 32 bit code and write MS-COFF object files (deprecated use -m32)",
502             TargetOS.Windows
503         ),
504         Option("m32omf",
505             "(deprecated) generate 32 bit code and write OMF object files",
506             `$(WINDOWS Compile a 32 bit executable. The generated object code is in OMF and is meant to be used with the
507                $(LINK2 http://www.digitalmars.com/download/freecompiler.html, Digital Mars C/C++ compiler)).`,
508             TargetOS.Windows
509         ),
510         Option("m64",
511             "generate 64 bit code",
512             `$(UNIX Compile a 64 bit executable. This is the default for the 64 bit dmd.)
513             $(WINDOWS The generated object code is in MS-COFF and is meant to be used with the
514             $(LINK2 https://msdn.microsoft.com/en-us/library/dd831853(v=vs.100).aspx, Microsoft Visual Studio 10)
515             or later compiler.`,
516         ),
517         Option("main",
518             "add default main() if not present already (e.g. for unittesting)",
519             `Add a default $(D main()) function when compiling. This is useful when
520             unittesting a library, as it enables running the unittests
521             in a library without having to manually define an entry-point function.`,
522         ),
523         Option("makedeps[=<filename>]",
524             "print dependencies in Makefile compatible format to filename or stdout.",
525             `Print dependencies in Makefile compatible format.
526             If filename is omitted, it prints to stdout.
527             The emitted targets are the compiled artifacts (executable, object files, libraries).
528             The emitted dependencies are imported modules and imported string files (via $(B -J) switch).
529             Special characters in a dependency or target filename are escaped in the GNU Make manner.
530             `,
531         ),
532         Option("man",
533             "open web browser on manual page",
534             `$(WINDOWS
535                 Open default browser on this page
536             )
537             $(LINUX
538                 Open browser specified by the $(B BROWSER)
539                 environment variable on this page. If $(B BROWSER) is
540                 undefined, $(B x-www-browser) is assumed.
541             )
542             $(FREEBSD
543                 Open browser specified by the $(B BROWSER)
544                 environment variable on this page. If $(B BROWSER) is
545                 undefined, $(B x-www-browser) is assumed.
546             )
547             $(OSX
548                 Open browser specified by the $(B BROWSER)
549                 environment variable on this page. If $(B BROWSER) is
550                 undefined, $(B Safari) is assumed.
551             )`,
552         ),
553         Option("map",
554             "generate linker .map file",
555             `Generate a $(TT .map) file`,
556         ),
557         Option("mcpu=<id>",
558             "generate instructions for architecture identified by 'id'",
559             `Set the target architecture for code generation,
560             where:
561             $(DL
562             $(DT help)$(DD list alternatives)
563             $(DT baseline)$(DD the minimum architecture for the target platform (default))
564             $(DT avx)$(DD
565             generate $(LINK2 https://en.wikipedia.org/wiki/Advanced_Vector_Extensions, AVX)
566             instructions instead of $(LINK2 https://en.wikipedia.org/wiki/Streaming_SIMD_Extensions, SSE)
567             instructions for vector and floating point operations.
568             Not available for 32 bit memory models other than OSX32.
569             )
570             $(DT native)$(DD use the architecture the compiler is running on)
571             )`,
572         ),
573         Option("mcpu=[h|help|?]",
574             "list all architecture options"
575         ),
576         Option("mixin=<filename>",
577             "expand and save mixins to file specified by <filename>"
578         ),
579         Option("mscrtlib=<libname>",
580             "MS C runtime library to reference from main/WinMain/DllMain",
581             "If building MS-COFF object files when targeting Windows, embed a reference to
582             the given C runtime library $(I libname) into the object file containing `main`,
583             `DllMain` or `WinMain` for automatic linking. The default is $(TT libcmt)
584             (release version with static linkage), the other usual alternatives are
585             $(TT libcmtd), $(TT msvcrt) and $(TT msvcrtd).
586             If no Visual C installation is detected, a wrapper for the redistributable
587             VC2010 dynamic runtime library and mingw based platform import libraries will
588             be linked instead using the LLD linker provided by the LLVM project.
589             The detection can be skipped explicitly if $(TT msvcrt120) is specified as
590             $(I libname).
591             If $(I libname) is empty, no C runtime library is automatically linked in.",
592             TargetOS.Windows,
593         ),
594         Option("mv=<package.module>=<filespec>",
595             "use <filespec> as source file for <package.module>",
596             `Use $(I path/filename) as the source file for $(I package.module).
597             This is used when the source file path and names are not the same
598             as the package and module hierarchy.
599             The rightmost components of the  $(I path/filename) and $(I package.module)
600             can be omitted if they are the same.`,
601         ),
602         Option("noboundscheck",
603             "no array bounds checking (deprecated, use -boundscheck=off)",
604             `Turns off all array bounds checking, even for safe functions. $(RED Deprecated
605             (use $(TT $(SWLINK -boundscheck)=off) instead).)`,
606         ),
607         Option("O",
608             "optimize",
609             `Optimize generated code. For fastest executables, compile
610             with the $(TT $(SWLINK -O) $(SWLINK -release) $(SWLINK -inline) $(SWLINK -boundscheck)=off)
611             switches together.`,
612         ),
613         Option("o-",
614             "do not write object file",
615             `Suppress generation of object file. Useful in
616             conjuction with $(SWLINK -D) or $(SWLINK -H) flags.`
617         ),
618         Option("od=<directory>",
619             "write object & library files to directory",
620             `Write object files relative to directory $(I objdir)
621             instead of to the current directory. $(SWLINK -op)
622             can be used if the original package hierarchy should
623             be retained`,
624         ),
625         Option("of=<filename>",
626             "name output file to filename",
627             `Set output file name to $(I filename) in the output
628             directory. The output file can be an object file,
629             executable file, or library file depending on the other
630             switches.`
631         ),
632         Option("op",
633             "preserve source path for output files",
634             `Normally the path for $(B .d) source files is stripped
635             off when generating an object, interface, or Ddoc file
636             name. $(SWLINK -op) will leave it on.`,
637         ),
638         Option("os=<os>",
639             "sets target operating system to <os>",
640             `Set the target operating system as other than the host.
641                 $(UL
642                     $(LI $(I host): Target the host operating system (default).)
643                     $(LI $(I dragonflybsd): DragonFlyBSD)
644                     $(LI $(I freebsd): FreeBSD)
645                     $(LI $(I linux): Linux)
646                     $(LI $(I openbsd): OpenBSD)
647                     $(LI $(I osx): OSX)
648                     $(LI $(I solaris): Solaris)
649                     $(LI $(I windows): Windows)
650                 )`
651         ),
652         Option("P=<preprocessorflag>",
653             "pass preprocessorflag to C preprocessor",
654             `Pass $(I preprocessorflag) to
655             $(WINDOWS sppn.exe or cl.exe)
656             $(UNIX cpp)`,
657         ),
658         Option("preview=<name>",
659             "enable an upcoming language change identified by 'name'",
660             `Preview an upcoming language change identified by $(I id)`,
661         ),
662         Option("preview=[h|help|?]",
663             "list all upcoming language changes"
664         ),
665         Option("profile",
666             "profile runtime performance of generated code",
667             `Instrument the generated code so that runtime performance data is collected
668             when the generated program is run.
669             Upon completion of the generated program, the files $(TT trace.log) and $(TT trace.def)
670             are generated. $(TT trace.log) has two sections,
671             $(OL
672             $(LI Fan in and fan out for each profiled function. The name of the function is left-justified,
673             the functions immediately preceding it are the other functions that call it (fan in) and how many times
674             it is called. The functions immediately following are the functions that are called (fan out) and how
675             many times it calls that function. The function itself has 3 numbers appended: the aggregate of the fan in counts,
676             the tree time used by the function which is the function time plus the tree times of all the functions it calls,
677             and the time used excluding
678             the time used by fan out.
679             )
680             $(LI Timing data for each function, sorted from most used to least.)
681             )
682             The $(TT trace.def) file contains linker commands to associate functions which are strongly coupled
683             so they appear adjacent in the resulting executable file.
684             For more information see $(LINK2 https://www.digitalmars.com/ctg/trace.html, profile)
685             `,
686         ),
687         Option("profile=gc",
688             "profile runtime allocations",
689             `$(UL
690                 $(LI $(B gc): Instrument calls to GC memory allocation and
691                 write a report to the file $(TT profilegc.log) upon program
692                 termination.  $(B Note:) Only instrumented calls will be
693                 logged. These include:
694                    $(UL
695                        $(LI Language constructs that allocate memory)
696                        $(LI Phobos functions that allocate GC memory)
697                        $(LI GC allocations via core.memory.GC)
698                    )
699                    Allocations made by other means will not be logged,
700                    including direct calls to the GC's C API.)
701             )`,
702         ),
703         Option("release",
704             "contracts and asserts are not emitted, and bounds checking is performed only in @safe functions",
705             `Compile release version, which means not emitting run-time
706             checks for contracts and asserts. Array bounds checking is not
707             done for system and trusted functions, and assertion failures
708             are undefined behaviour.`
709         ),
710         Option("revert=<name>",
711             "revert language change identified by 'name'",
712             `Revert language change identified by $(I id)`,
713         ),
714         Option("revert=[h|help|?]",
715             "list all revertable language changes"
716         ),
717         Option("run <srcfile>",
718             "compile, link, and run the program srcfile",
719             `Compile, link, and run the program $(I srcfile) with the
720             rest of the
721             command line, $(I args...), as the arguments to the program.
722             No .$(OBJEXT) or executable file is left behind.`
723         ),
724         Option("shared",
725             "generate shared library (DLL)",
726             `$(UNIX Generate shared library)
727              $(WINDOWS Generate DLL library)`,
728         ),
729         Option("target=<triple>",
730                "use <triple> as <arch>-[<vendor>-]<os>[-<cenv>[-<cppenv]]",
731                "$(I arch) is the architecture: either `x86`, `x64`, `x86_64` or `x32`,
732                $(I vendor) is always ignored, but supported for easier interoperability,
733                $(I os) is the operating system, this may have a trailing version number:
734                `freestanding` for no operating system,
735                `darwin` or `osx` for MacOS, `dragonfly` or `dragonflybsd` for DragonflyBSD,
736                `freebsd`, `openbsd`, `linux`, `solaris` or `windows` for their respective operating systems.
737                $(I cenv) is the C runtime environment and is optional: `musl` for musl-libc,
738                `msvc` for the MSVC runtime (the default for windows with this option),
739                `bionic` for the Andriod libc, `digital_mars` for the Digital Mars runtime for Windows
740                `gnu` or `glibc` for the GCC C runtime, `newlib` or `uclibc` for their respective C runtimes.
741                ($ I cppenv) is the C++ runtime environment: `clang` for the LLVM C++ runtime
742                `gcc` for GCC's C++ runtime, `msvc` for microsoft's MSVC C++ runtime (the default for windows with this switch),
743                `sun` for Sun's C++ runtime and `digital_mars` for the Digital Mars C++ runtime for windows.
744                "
745         ),
746         Option("transition=<name>",
747             "help with language change identified by 'name'",
748             `Show additional info about language change identified by $(I id)`,
749         ),
750         Option("transition=[h|help|?]",
751             "list all language changes"
752         ),
753         Option("unittest",
754             "compile in unit tests",
755             `Compile in $(LINK2 spec/unittest.html, unittest) code, turns on asserts, and sets the
756              $(D unittest) $(LINK2 spec/version.html#PredefinedVersions, version identifier)`,
757         ),
758         Option("v",
759             "verbose",
760             `Enable verbose output for each compiler pass`,
761         ),
762         Option("vasm",
763             "list generated assembler for each function"
764         ),
765         Option("vcolumns",
766             "print character (column) numbers in diagnostics"
767         ),
768         Option("verror-style=[digitalmars|gnu]",
769             "set the style for file/line number annotations on compiler messages",
770             `Set the style for file/line number annotations on compiler messages,
771             where:
772             $(DL
773             $(DT digitalmars)$(DD 'file(line[,column]): message'. This is the default.)
774             $(DT gnu)$(DD 'file:line[:column]: message', conforming to the GNU standard used by gcc and clang.)
775             )`,
776         ),
777         Option("verror-supplements=<num>",
778             "limit the number of supplemental messages for each error (0 means unlimited)"
779         ),
780         Option("verrors=<num>",
781             "limit the number of error messages (0 means unlimited)"
782         ),
783         Option("verrors=context",
784             "show error messages with the context of the erroring source line"
785         ),
786         Option("verrors=spec",
787             "show errors from speculative compiles such as __traits(compiles,...)"
788         ),
789         Option("-version",
790             "print compiler version and exit"
791         ),
792         Option("version=<level>",
793             "compile in version code >= level",
794             `Compile in $(LINK2 $(ROOT_DIR)spec/version.html#version, version level) >= $(I level)`,
795         ),
796         Option("version=<ident>",
797             "compile in version code identified by ident",
798             `Compile in $(LINK2 $(ROOT_DIR)spec/version.html#version, version identifier) $(I ident)`
799         ),
800         Option("vgc",
801             "list all gc allocations including hidden ones"
802         ),
803         Option("vtls",
804             "list all variables going into thread local storage"
805         ),
806         Option("vtemplates=[list-instances]",
807             "list statistics on template instantiations",
808             `An optional argument determines extra diagnostics,
809             where:
810             $(DL
811             $(DT list-instances)$(DD Also shows all instantiation contexts for each template.)
812             )`,
813         ),
814         Option("w",
815             "warnings as errors (compilation will halt)",
816             `Enable $(LINK2 $(ROOT_DIR)articles/warnings.html, warnings)`
817         ),
818         Option("wi",
819             "warnings as messages (compilation will continue)",
820             `Enable $(LINK2 $(ROOT_DIR)articles/warnings.html, informational warnings (i.e. compilation
821             still proceeds normally))`,
822         ),
823         Option("X",
824             "generate JSON file"
825         ),
826         Option("Xf=<filename>",
827             "write JSON file to filename"
828         ),
829         Option("Xcc=<driverflag>",
830             "pass driverflag to linker driver (cc)",
831             "Pass $(I driverflag) to the linker driver (`$CC` or `cc`)",
832             cast(TargetOS) (TargetOS.all & ~cast(uint)TargetOS.Windows)
833         ),
834     ];
835 
836     /// Representation of a CLI feature
837     struct Feature
838     {
839         string name; /// name of the feature
840         string paramName; // internal transition parameter name
841         string helpText; // detailed description of the feature
842         bool documented = true; // whether this option should be shown in the documentation
843         bool deprecated_; /// whether the feature is still in use
844     }
845 
846     /// Returns all available transitions
847     static immutable transitions = [
848         Feature("field", "vfield",
849             "list all non-mutable fields which occupy an object instance"),
850         Feature("complex", "vcomplex",
851             "give deprecation messages about all usages of complex or imaginary types", true, true),
852         Feature("tls", "vtls",
853             "list all variables going into thread local storage"),
854         Feature("in", "vin",
855             "list all usages of 'in' on parameter"),
856     ];
857 
858     /// Returns all available reverts
859     static immutable reverts = [
860         Feature("dip25", "useDIP25", "revert DIP25 changes https://github.com/dlang/DIPs/blob/master/DIPs/archive/DIP25.md", true, true),
861         Feature("dip1000", "useDIP1000",
862                 "revert DIP1000 changes https://github.com/dlang/DIPs/blob/master/DIPs/other/DIP1000.md (Scoped Pointers)"),
863         Feature("intpromote", "fix16997", "revert integral promotions for unary + - ~ operators"),
864         Feature("dtorfields", "dtorFields", "don't destruct fields of partially constructed objects"),
865     ];
866 
867     /// Returns all available previews
868     static immutable previews = [
869         Feature("dip25", "useDIP25",
870             "implement https://github.com/dlang/DIPs/blob/master/DIPs/archive/DIP25.md (Sealed references)", true, true),
871         Feature("dip1000", "useDIP1000",
872             "implement https://github.com/dlang/DIPs/blob/master/DIPs/other/DIP1000.md (Scoped Pointers)"),
873         Feature("dip1008", "ehnogc",
874             "implement https://github.com/dlang/DIPs/blob/master/DIPs/other/DIP1008.md (@nogc Throwable)"),
875         Feature("dip1021", "useDIP1021",
876             "implement https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1021.md (Mutable function arguments)"),
877         Feature("bitfields", "bitfields", "add bitfields https://github.com/dlang/dlang.org/pull/3190"),
878         Feature("fieldwise", "fieldwise", "use fieldwise comparisons for struct equality"),
879         Feature("fixAliasThis", "fixAliasThis",
880             "when a symbol is resolved, check alias this scope before going to upper scopes"),
881         Feature("intpromote", "fix16997",
882             "fix integral promotions for unary + - ~ operators", false, true),
883         Feature("dtorfields", "dtorFields",
884             "destruct fields of partially constructed objects", false, false),
885         Feature("rvaluerefparam", "rvalueRefParam",
886             "enable rvalue arguments to ref parameters"),
887         Feature("nosharedaccess", "noSharedAccess",
888             "disable access to shared memory objects"),
889         Feature("in", "previewIn",
890             "`in` on parameters means `scope const [ref]` and accepts rvalues"),
891         Feature("inclusiveincontracts", "inclusiveInContracts",
892             "'in' contracts of overridden methods must be a superset of parent contract"),
893         Feature("shortenedMethods", "shortenedMethods",
894             "allow use of => for methods and top-level functions in addition to lambdas", false, false),
895         Feature("fixImmutableConv", "fixImmutableConv",
896             "disallow unsound immutable conversions that were formerly incorrectly permitted"),
897         Feature("systemVariables", "systemVariables",
898             "disable access to variables marked '@system' from @safe code"),
899     ];
900 }
901 
902 /**
903 Formats the `Options` for CLI printing.
904 */
905 struct CLIUsage
906 {
907     /**
908     Returns a string of all available CLI options for the current targetOS.
909     Options are separated by newlines.
910     */
911     static string usage()
912     {
913         enum maxFlagLength = 18;
914         enum s = () {
915             char[] buf;
916             foreach (option; Usage.options)
917             {
918                 if (option.os.isCurrentTargetOS)
919                 {
920                     buf ~= "  -" ~ option.flag;
921                     // create new lines if the flag name is too long
922                     if (option.flag.length >= 17)
923                     {
924                             buf ~= "\n                    ";
925                     }
926                     else if (option.flag.length <= maxFlagLength)
927                     {
928                         const spaces = maxFlagLength - option.flag.length - 1;
929                         buf.length += spaces;
930                         buf[$ - spaces .. $] = ' ';
931                     }
932                     else
933                     {
934                             buf ~= "  ";
935                     }
936                     buf ~= option.helpText;
937                     buf ~= "\n";
938                 }
939             }
940             return cast(string) buf;
941         }();
942         return s;
943     }
944 
945     /// CPU architectures supported -mcpu=id
946     enum mcpuUsage = "CPU architectures supported by -mcpu=id:
947   =[h|help|?]    list information on all available choices
948   =baseline      use default architecture as determined by target
949   =avx           use AVX 1 instructions
950   =avx2          use AVX 2 instructions
951   =native        use CPU architecture that this compiler is running on
952 ";
953 
954     static string generateFeatureUsage(const Usage.Feature[] features, string flagName, string description)
955     {
956         enum maxFlagLength = 20;
957         auto buf = description.capitalize ~ " listed by -"~flagName~"=name:
958 ";
959         auto allTransitions = [Usage.Feature("all", null,
960             "Enables all available " ~ description)] ~ features;
961         foreach (t; allTransitions)
962         {
963             if (!t.documented)
964                 continue;
965             buf ~= "  =";
966             buf ~= t.name;
967             buf ~= " "; // at least one separating space
968             auto lineLength = "  =".length + t.name.length + " ".length;
969             foreach (i; lineLength .. maxFlagLength)
970                 buf ~= " ";
971             buf ~= t.helpText;
972             if (t.deprecated_)
973                 buf ~= " [DEPRECATED]";
974             buf ~= "\n";
975         }
976         return buf;
977     }
978 
979     /// Language changes listed by -transition=id
980     enum transitionUsage = generateFeatureUsage(Usage.transitions, "transition", "language transitions");
981 
982     /// Language changes listed by -revert
983     enum revertUsage = generateFeatureUsage(Usage.reverts, "revert", "revertable language changes");
984 
985     /// Language previews listed by -preview
986     enum previewUsage = generateFeatureUsage(Usage.previews, "preview", "upcoming language changes");
987 
988     /// Options supported by -checkaction=
989     enum checkActionUsage = "Behavior on assert/boundscheck/finalswitch failure:
990   =[h|help|?]    List information on all available choices
991   =D             Usual D behavior of throwing an AssertError
992   =C             Call the C runtime library assert failure function
993   =halt          Halt the program execution (very lightweight)
994   =context       Use D assert with context information (when available)
995 ";
996 
997     /// Options supported by -check
998     enum checkUsage = "Enable or disable specific checks:
999   =[h|help|?]           List information on all available choices
1000   =assert[=[on|off]]    Assertion checking
1001   =bounds[=[on|off]]    Array bounds checking
1002   =in[=[on|off]]        Generate In contracts
1003   =invariant[=[on|off]] Class/struct invariants
1004   =out[=[on|off]]       Out contracts
1005   =switch[=[on|off]]    Final switch failure checking
1006   =on                   Enable all assertion checking
1007                         (default for non-release builds)
1008   =off                  Disable all assertion checking
1009 ";
1010 
1011     /// Options supported by -extern-std
1012     enum externStdUsage = "Available C++ standards:
1013   =[h|help|?]           List information on all available choices
1014   =c++98                Sets `__traits(getTargetInfo, \"cppStd\")` to `199711`
1015   =c++11                Sets `__traits(getTargetInfo, \"cppStd\")` to `201103`
1016   =c++14                Sets `__traits(getTargetInfo, \"cppStd\")` to `201402`
1017   =c++17                Sets `__traits(getTargetInfo, \"cppStd\")` to `201703`
1018   =c++20                Sets `__traits(getTargetInfo, \"cppStd\")` to `202002`
1019 ";
1020 
1021     /// Options supported by -HC
1022     enum hcUsage = "Available header generation modes:
1023   =[h|help|?]           List information on all available choices
1024   =silent               Silently ignore non-exern(C[++]) declarations
1025   =verbose              Add a comment for ignored non-exern(C[++]) declarations
1026 ";
1027 
1028     /// Options supported by -gdwarf
1029     enum gdwarfUsage = "Available DWARF versions:
1030   =[h|help|?]           List information on choices
1031   =3                    Emit DWARF version 3 debug information
1032   =4                    Emit DWARF version 4 debug information
1033   =5                    Emit DWARF version 5 debug information
1034 ";
1035 
1036 }