GDC(1)

πŸ“¦
version 9.5.0 Β· 2 versions
, in ubuntu noble

πŸ’– GDC(1) Β· GNU Manual πŸ’– (part 1 of 2)

✨ NAME ✨

gdc is a GCC-based compiler for the D language, and it's giving main character energy πŸ’…

✨ SYNOPSIS ✨

gdc [-c|-S] [-g] [-pg]
    [-Olevel] [-Wwarn...]
    [-Idir...] [-Ldir...]
    [-foption...] [-mmachine-option...]
    [-o outfile] [@file] infile...

okay so this is just the cheat sheet πŸ“ Only the most useful options are listed here, so scroll down for the rest πŸ‘€

✨ DESCRIPTION ✨

The gdc command is the GNU compiler for the D language, and it slays because it supports a lot of the same options as gcc 🌸 This manual only covers the options that are specific to gdc 🫢

✨ OPTIONS ✨

πŸ¦‹ Input and Output files

For any input file, the file name suffix decides what kind of compilation happens πŸ”₯ These are the kinds of input file names that are supported:

  • file.d β€” D source files πŸ’œ
  • file.dd β€” Ddoc source files πŸŽ€
  • file.di β€” D interface files 🧚

You can pass more than one input file on the gdc command line, and each one gets compiled separately πŸ“ If you use -o file, then all the input files get compiled together and produce one single output file called file ✨ That works even with -S or -c, so no stress πŸ’–

A D interface file only has what an import of the module actually needs, not the whole implementation of that module 🧁 gdc can make these from a D source file if you use the -H option 🌈 When the compiler resolves an import declaration, it searches for matching .di files first, and then for .d files πŸ‘€

A Ddoc source file has code in the D macro processor language πŸŽ€ It's mainly for making user documentation out of embedded comments, with a slight HTML-generation crush πŸ’• If a .d source file starts with the string "Ddoc", then it's treated as general purpose documentation instead of D source code 😭

🌈 Runtime Options

These options change how programs compiled with gdc behave at runtime ⚑

  • -fall-instantiations β€” generates code for all template instantiations 🧁 By default, the compiler skips code for declarations that were instantiated speculatively, like from __traits(compiles, ...), or that come from an imported module that isn't being compiled πŸ™ˆ
  • -fno-assert β€” turns off code generation for "assert" contracts 🚫
  • -fno-bounds-check β€” turns off array bounds checking for all functions 🏎️ This can boost performance for code that uses arrays a lot πŸ’¨
⚠️ Heads up: if the code actually violates array bounds, this can lead to unpredictable behavior. It's only safe to use if you're sure your code never throws a RangeError 🫣
  • -fbounds-check=value β€” an alternative to -fbounds-check that gives you more control over where bounds checking is turned on or off πŸŽ›οΈ These values are supported:
    • on β€” turns on array bounds checking for all functions.
    • safeonly β€” turns on array bounds checking only for @safe functions.
    • off β€” turns off array bounds checking completely.
  • -fno-builtin β€” don't recognize built-in functions unless they begin with the prefix __builtin_ πŸ™… By default, the compiler recognizes when a function in the core.stdc package is a built-in function ✨
  • -fdebug, -fdebug=value β€” turns on compiling conditional debug code into the program πŸ› -fdebug by itself sets the debug level to 1, while -fdebug= enables debug code identified by any of these values:
    • level β€” sets the debug level to level, so any debug code <= level gets compiled in.
    • ident β€” turns on compilation of any debug code identified by ident.
  • -fno-druntime β€” implements <https://dlang.org/spec/betterc.html> πŸ“œ It assumes the compilation targets an environment without a D runtime library 🌡 This is equivalent to compiling with these options:
gdc -nophoboslib -fno-exceptions -fno-moduleinfo -fno-rtti
  • -fno-invariants β€” turns off code generation for class invariant contracts 🧊
  • -fno-moduleinfo β€” turns off generation of ModuleInfo and the related functions that would become unreferenced without it 🧹 This may allow linking to programs that aren't written in D πŸ”— The functions that are not generated include module constructors and destructors (static this and static ~this), unittest code, and DSO registry functions for dynamically linked code πŸ™ƒ
  • -fonly=filename β€” tells the compiler to parse and run semantic analysis on all modules on the command line πŸ” but only generate code for the module specified by filename 🎯
  • -fno-postconditions β€” turns off code generation for postcondition out contracts 🚫
  • -fno-preconditions β€” turns off code generation for precondition in contracts 🚫
  • -frelease β€” turns on release mode πŸš€ which means no emitted runtime checks for contracts and asserts. Array bounds checking isn't done for @system and @trusted functions, and assertion failures are undefined behavior πŸ’€
πŸ’€ Undefined behavior alert: assertion failures in release mode are undefined behavior, so be extra careful, bestie.

This is equivalent to compiling with these options:

gdc -fno-assert -fbounds-check=safe -fno-invariants \
    -fno-postconditions -fno-preconditions -fno-switch-errors
  • -fno-rtti β€” turns off generation of run-time type information for all user defined types 🧬 Any code that uses language features requiring that info will result in an error 🚫
  • -fno-switch-errors β€” controls what code gets generated when no case is matched in a final switch statement πŸ”€ The default run time behavior is to throw a SwitchError 🧨 Turning off -fswitch-errors means the execution of the program is immediately halted instead πŸ›‘
  • -funittest β€” turns on compilation of unittest code and turns on the version(unittest) identifier πŸ§ͺ This implies -fassert 🫢
  • -fversion=value β€” turns on compilation of conditional version code into the program, identified by any of these values:
    • level β€” sets the version level to level, so any version code >= level gets compiled in.
    • ident β€” turns on compilation of version code identified by ident.
  • -fno-weak β€” turns off emission of instantiated declarations that can be defined in multiple objects as weak or one-only symbols πŸ•ŠοΈ The default is to emit all public symbols as weak, unless the target lacks support for weak symbols πŸ’ͺ Disabling this option means common symbols are instead put in COMDAT or become private πŸ”’

These options tell the compiler which directories to search for files, libraries, and other parts of the compiler itself πŸ—ΊοΈ

  • -Idir β€” a directory to use when searching for imported modules at compile time πŸ“‚ Multiple -I options can be used, and the paths get searched in the same order πŸ”
  • -Jdir β€” a directory to use when searching for files in string imports at compile time πŸ“„ This switch is required in order to use import(file) expressions πŸ›‘ Multiple -J options can be used, and the paths get searched in the same order πŸ”
  • -Ldir β€” when linking, a library search directory, same as with gcc πŸ”—
  • -Bdir β€” where to find the compiler's own executables, libraries, source files, and data files, same as with gcc 🏠
  • -fmodule-file=module=spec β€” manipulates file paths of imported modules πŸ›€οΈ If an imported module matches all or the leftmost part of module, then the file path in spec is used as the location to search for D sources πŸ”Ž This is handy when the source file paths and names don't match the package and module hierarchy 🧩 Check out these examples:
gdc test.d -fmodule-file=A.B=foo.d -fmodule-file=C=bar

This tells the compiler to search in all import paths for the source file foo.d when importing A.B, and to search the directory bar/ when importing C, as annotated in this D code:

module test;
import A.B;     // Matches A.B, searches for foo.d
import C.D.E;   // Matches C, searches for bar/D/E.d
import A.B.C;   // No match, searches for A/B/C.d
  • -imultilib dir β€” uses dir as a subdirectory of the gcc directory containing target-specific D sources and interfaces 🎯
  • -iprefix prefix β€” specifies prefix as the prefix for the gcc directory containing target-specific D sources and interfaces 🧭 If the prefix represents a directory, you should include the final '/' πŸ“
  • -nostdinc β€” don't search the standard system directories for D source and interface files πŸ™… Only the directories specified with -I options (and the directory of the current file, if appropriate) get searched πŸ”

(continued in part 2 πŸ‘€)

  • -MD β€” okay so this is basically -M -MF file πŸ’– The driver figures out the file name by stripping any directory components and suffix off your input file, then tacking on a .deps suffix 🧚
  • -MMD β€” same energy as -MD, but it doesn't mention imported modules that come from the D standard library package directories πŸ™ˆ
  • -X β€” dumps info about the contents of every source file being compiled, in JSON format, into a file πŸ“¦ The driver picks the name by removing directory components and suffix from the input file, then adding a .json suffix 🌸
  • -Xf file β€” same as -X, but all the JSON goes into the exact file you name πŸŽ€
  • -fdoc β€” generates "Ddoc" documentation and writes it to a file ✨ The compiler names the file by stripping directory components and suffix from the input file, then adding a .html suffix πŸ’…
  • -fdoc-dir=dir β€” same as -fdoc, but the docs go into the directory dir πŸ—‚οΈ You can pair it with -fdoc-file=file to set the output file and directory path separately πŸ¦‹
  • -fdoc-file=file β€” same as -fdoc, but the docs go into file 🌈 It works with -fdoc-dir=dir so you can set the file and directory independently πŸ’œ
  • -fdoc-inc=file β€” reads file as a Ddoc macro file πŸ“– You can use several -fdoc-inc options, and the files get read and processed in the same order you gave them ⭐

🚨 Warnings 🚨

Warnings are diagnostic messages about constructions that aren't inherently erroneous but are risky, or that suggest there's probably a bug in the program. Unless -Werror is specified, they don't stop the program from compiling πŸ’€

  • -Wall β€” turns on all warning messages πŸ”₯ Warnings aren't a defined part of the D language, and every construct that might trigger a warning is still valid code 🫢
  • -Walloca β€” warns on all uses of alloca in the source 😭
  • -Walloca-larger-than=n β€” warns on unbounded uses of alloca, and on bounded uses whose bound can be larger than n bytes πŸ“ -Wno-alloca-larger-than turns off -Walloca-larger-than and is equivalent to -Walloca-larger-than=SIZE_MAX or larger πŸ™…
  • -Wcast-result β€” warns about casts that will produce a null or zero result 🫠 Right now it's only checked for casting between an imaginary and non-imaginary data type, or between a D and C++ class πŸ‘‘
  • -Wno-deprecated β€” no warnings about usage of deprecated features and symbols with "deprecated" attributes πŸ™ƒ
  • -Werror β€” turns all warnings into errors πŸ’₯
  • -Wspeculative β€” lists all error messages from speculative compiles, like __traits(compiles, ...) 🧐 It doesn't report them as warnings, so they never become errors even when -Werror is also used πŸ›‘οΈ
  • -Wtemplates β€” warns whenever a template instantiation is encountered 🚫 Some coding rules disallow templates, so this can help enforce that rule πŸ“‹
  • -Wunknown-pragmas β€” warns when a pragma() is encountered that gdc doesn't understand 🀷 This is different from -fignore-unknown-pragmas, where a pragma that's part of the D language but not implemented by the compiler won't get reported πŸ“
  • -fignore-unknown-pragmas β€” turns off errors for unsupported pragmas 😌
  • -fmax-errors=n β€” caps the number of error messages at n, at which point gdc bails out instead of trying to keep going πŸ›‘ If n is 0 (the default), there's no limit on how many errors get produced ♾️
  • -fsyntax-only β€” checks the code for syntax errors but doesn't actually compile it πŸ” You can use it with -fdoc or -H to generate files for each module on the command line, but no other output file πŸ“„
  • -ftransition=id β€” reports extra info about D language changes identified by id πŸ¦„ These values are supported:
    • all β€” lists info on all language changes
    • checkimports β€” gives deprecation messages about -ftransition=import anomalies
    • complex β€” lists all usages of complex or imaginary types
    • dip1000 β€” implements http://wiki.dlang.org/DIP1000 (experimental) πŸ§ͺ
    • dip25 β€” implements http://wiki.dlang.org/DIP25 (experimental) πŸ§ͺ
    • field β€” lists all non-mutable fields which occupy an object instance
    • import β€” tells the compiler to go back to the old lookup behavior for resolving unqualified symbol names, which happened in a single pass and ignored any protection attributes πŸ•°οΈ The default lookup strategy uses two passes: the first ignores imported declarations, and the second only looks at imports πŸ” Protection ("private", "package", "protected") of symbols is also enforced to resolve conflicts between private and public symbols πŸ”
    • nogc β€” lists all hidden GC allocations πŸ—‘οΈ
    • tls β€” lists all variables going into thread local storage 🧡

πŸ”— Options for Linking πŸ”—

These options come into play when the compiler links object files into an executable output file πŸ—οΈ They're meaningless if the compiler isn't doing a link step, so don't bother with them otherwise πŸ™ˆ

  • -defaultlib libname β€” uses libname instead of libphobos when linking πŸ“š Options that set the linkage of libphobos, like -static-libphobos or -shared-libphobos, get ignored πŸ™ƒ
  • -debuglib β€” specifies the debug library to use instead of libphobos when linking πŸ› This does nothing unless the -g option was also given on the command line πŸ’‘ Linkage options like -static-libphobos or -shared-libphobos are ignored here too πŸ™…
  • -nophoboslib β€” doesn't use the Phobos or D runtime library when linking 🚫 Linkage options like -static-libphobos or -shared-libphobos are ignored πŸ™ˆ The standard system libraries are used normally, unless -nostdlib or -nodefaultlibs is used πŸ“¦
  • -shared-libphobos β€” on systems that provide libgphobos and libgdruntime as both a shared and a static library, this forces the shared version 🀝 If no shared version was built when the compiler was configured, it does nothing 🀷
  • -static-libphobos β€” on systems that provide libgphobos and libgdruntime as both a shared and a static library, this forces the static version 🧊 If no static version was built when the compiler was configured, it does nothing 🀷

πŸ§ͺ Developer Options πŸ§ͺ

This section is all about command-line options that are mainly for developers or language tooling πŸ‘©β€πŸ’»

  • -fdump-d-original β€” outputs the internal front-end AST after the "semantic3" stage 🌳 This is only useful for debugging the GNU D compiler itself πŸ› οΈ
  • -v β€” dumps info about the compiler's language processing stages while your source program is being compiled πŸ“£ That includes listing all modules processed through the "parse", "semantic", "semantic2", and "semantic3" stages πŸ“‹; all "import" modules and their file paths πŸ—ΊοΈ; and all "function" bodies being compiled πŸ§‘β€πŸ³

πŸ’Œ SEE ALSO πŸ’Œ

gpl(7), gfdl(7), fsf-funding(7), gcc(1), and the Info entries for gdc and gcc πŸ“šβœ¨

Copyright (c) 2006-2019 Free Software Foundation, Inc.

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation, with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts πŸ’œ A copy of the license is included in the man page gfdl(7) πŸ“œ


Okay bestie, that's the whole GDC(1) page! 🌈 This one comes from the gcc-9 set and was last touched on 2022-05-27, so you're officially up to speed on your D compiler flags πŸ’…πŸ¦‹ bye bestie πŸ’–

πŸ“¦ where this page comes from