DMD Compiler for Linux
- Requirements and Downloads
- Installation
- Compiler Arguments and Switches
- Files
- Linking
- Environment Variables
- dmd.conf Initialization File
- Differences between Windows and Linux versions
- D Interface Files
- Building Libraries
- Compiling dmd
- Compiling Phobos
Requirements and Downloads
- DMD Compiler
- 32 bit x86 and 64 bit x86-64 Linux operating system (LDC and GDC provide support for more architectures)
- Gnu C compiler (gcc) or LLVM C compiler (clang)
Installation
Unzip the archive into your home directory. It will create a ~/dmd directory with all the files in it. All the tools are command line tools, which means they are run from a console window. All tools can be run directly from the archive:~/dmd/linux/bin64/dmdTo install dmd globally, add the ~/dmd/linux/bin64 folder to your PATH.
export PATH="$HOME/dmd/linux/bin64:$PATH"Alternatively, you can install dmd locally yourself by:
- Create a configuration file in /etc/dmd.conf:
[Environment64] DFLAGS=-I/usr/local/include/d/dmd -L-L/usr/local/lib -L--export-dynamic -fPIC
- Copy binaries to /usr/local/bin:
sudo cp dmd2/linux/bin64/{dmd,dumpobj,obj2asm,rdmd,ddemangle,dub,dustmite} /usr/local/bin
- Copy the library to /usr/local/lib:
sudo cp dmd2/linux/lib64/libphobos2.a /usr/local/lib
- Copy the standard library and runtime sources to /usr/include/d/dmd:
sudo mkdir -p /usr/include/d/dmd sudo cp dmd2/{phobos/std,phobos/etc,druntime/import} /usr/include/d/dmd
Compiler Arguments and Switches
- dmd files... -switches...
- files...
-
File Extensions Extension File Type none D source files .c C source files .d D source files .dd Ddoc source files .di D interface files .i preprocessed C source files .o Object files to link in .a Object code libraries to search - @cmdfile
- If cmdfile is an environment variable, read the compiler arguments and switches from the value of that variable. Otherwise, read compiler arguments and switches from the text file cmdfile. The file may contain single-line comments starting with the hash symbol (#).
- -allinst
- Generate code for all template instantiations
- -betterC
-
Adjusts the compiler to implement D as a better C:
- Predefines D_BetterC version.
- Assert Expressions, when they fail, call the C runtime library assert failure function rather than a function in the D runtime.
- Array overflows call the C runtime library assert failure function rather than a function in the D runtime.
- Final switch errors call the C runtime library assert failure function rather than a function in the D runtime.
- Does not automatically link with phobos runtime library.
- Does not generate Dwarf eh_frame with full unwinding information, i.e. exception tables are not inserted into eh_frame.
- Module constructors and destructors are not generated meaning that static and shared static constructors and destructors will not get called.
- ModuleInfo is not generated.
- TypeInfo instances will not be generated for structs.
- -boundscheck=[on|safeonly|off ]
-
Controls if bounds checking is enabled.
- on: Bounds checks are enabled for all code. This is the default.
- safeonly: Bounds checks are enabled only in @safe code. This is the default for -release builds.
- off: Bounds checks are disabled completely (even in @safe code). This option should be used with caution and as a last resort to improve performance. Confirm turning off @safe bounds checks is worthwhile by benchmarking.
- -c
- Compile only, do not link
- -check=[assert|bounds|in|invariant|out|switch ][=[on|off]]
-
Overrides default, -boundscheck, -release and -unittest options to enable or disable specific checks.
- assert: assertion checking
- bounds: array bounds
- in: in contracts
- invariant: class/struct invariants
- out: out contracts
- switch: final switch failure checking
- on or not specified: specified check is enabled.
- off: specified check is disabled.
- -check=[h|help|? ]
- List information on all available checks
- -checkaction=[D|C|halt|context ]
-
Sets behavior when an assert or an array bounds check fails,
or a final switch errors.
- D: Default behavior, which throws an unrecoverable AssertError.
- C: Calls the C runtime library assert failure function.
- halt: Executes a halt instruction, terminating the program.
- context: Prints the error context as part of the unrecoverable AssertError.
- -checkaction=[h|help|? ]
- List information on all available check actions
- -color
- Turn colored console output on
- -color=[on|off|auto ]
-
Show colored console output. The default depends on terminal capabilities.
- auto: use colored output if a tty is detected (default)
- on: always use colored output.
- off: never use colored output.
- -conf=filename
- Use config file at filename
- -cov
- Do code coverage analysis
- -cov=ctfe
- Include code executed during CTFE in coverage report
- -cov=nnn
- Perform code coverage analysis and generate .lst file with report.
- -cpp=filename
- Normally the C preprocessor used by the associated C compiler is used to preprocess ImportC files, this is overridden by the -cpp switch.
- -D
-
Generate documentation from source.
Note: mind the security considerations.
- -Dddirectory
- Write documentation file to directory . -op can be used if the original package hierarchy should be retained
- -Dffilename
- Write documentation file to filename
- -d
- Silently allow deprecated features and use of symbols with deprecated attributes.
- -de
- Issue an error when deprecated features or symbols are used (halt compilation)
- -dw
- Issue a message when deprecated features or symbols are used (default)
- -debug
- Compile in debug code
- -debug=level
- Compile in debug level <= level
- -debug=ident
- Compile in debug identifier ident
- -debuglib=name
- Link in libname as the default library when compiling for symbolic debugging instead of libphobos2.a. If libname is not supplied, then no default library is linked in.
- -defaultlib=name
- Link in libname as the default library when not compiling for symbolic debugging instead of libphobos2.a. If libname is not supplied, then no default library is linked in.
- -deps
- Print module dependencies (imports/file/version/debug/lib)
- -deps=filename
- Without filename, print module dependencies (imports/file/version/debug/lib). With filename, write module dependencies as text to filename (only imports).
- -dllimport=value
-
Which global variables to dllimport implicitly if not defined in a root module
- none: None
- defaultLibsOnly: Only druntime/Phobos symbols
- all: All
- -extern-std=standard
-
Standards supported are:
- c++98: Use C++98 name mangling, Sets __traits(getTargetInfo, "cppStd") to 199711
- c++11 (default): Use C++11 name mangling, Sets __traits(getTargetInfo, "cppStd") to 201103
- c++14: Use C++14 name mangling, Sets __traits(getTargetInfo, "cppStd") to 201402
- c++17: Use C++17 name mangling, Sets __traits(getTargetInfo, "cppStd") to 201703
- c++20: Use C++20 name mangling, Sets __traits(getTargetInfo, "cppStd") to 202002
- -extern-std=[h|help|? ]
- List all supported standards
- -fIBT
- Generate Indirect Branch Tracking code
- -fPIC
- Generate position independent code
- -fPIE
- Generate position independent executables
- -ftime-trace
- Per function, the time to analyze it, call it from CTFE, generate code for it etc. will be measured, and events with a time longer than 500 microseconds (adjustable with -ftime-trace-granularity) will be recorded. The profiling result is output in the Chrome Trace Event Format, described here. This can be turned into a more readable text file with the included tool timetrace2txt, or inspected with an interactive viewer such as Perfetto.
- -ftime-trace-granularity=
- Measured events shorter than the specified time will be discarded from the output. Set it too high, and interesting events may not show up in the output. Set too low, and the profiler overhead will be larger, and the output will be cluttered with tiny events.
- -ftime-trace-file=filename
- By default, the output name is the same as the first object file name, but with the .time-trace extension appended. A different filename can be chosen with this option, including a path relative to the current directory or an absolute path.
- -g
- Add symbolic debug info in DWARF format for debuggers such as gdb
- -gdwarf=version
- The value of version may be 3, 4 or 5, defaulting to 3.
- -gf
- Symbolic debug info is emitted for all types referenced by the compiled code, even if the definition is in an imported file not currently being compiled.
- -gs
- Always emit stack frame
- -gx
- Adds stack stomp code, which overwrites the stack frame memory upon function exit.
- -H
- Generate D interface file
- -Hd=directory
- Write D interface file to directory. -op can be used if the original package hierarchy should be retained.
- -Hf=filename
- Write 'header' file to filename
- -HC[=[?|h|help|silent|verbose ]]
-
Write C++ 'header' equivalent to stdout configured with:",
- ?|h|help
- list available options for C++ 'header' file generation
- silent
- only list extern(C[++]) declarations (default)
- verbose
- also add comments for ignored declarations (e.g. extern(D))
- -HCd=directory
-
Write C++ 'header' file to directory, ignored if -HCf=
is not present - -HCf=filename
- Write C++ 'header' file to filename instead of stdout
- --help
- Print help and exit
- -I=directory
- Look for imports also in directory
- -i[=pattern ]
-
Enables "include imports" mode, where the compiler will include imported modules in the compilation, as if they were given on the command line. By default, when this option is enabled, all imported modules are included except those in druntime/phobos. This behavior can be overridden by providing patterns via -i=<pattern>. A pattern of the form -i=<package> is an "inclusive pattern", whereas a pattern of the form -i=-<package> is an "exclusive pattern". Inclusive patterns will include all module's whose names match the pattern, whereas exclusive patterns will exclude them. For example. all modules in the package foo.bar can be included using -i=foo.bar or excluded using -i=-foo.bar. Note that each component of the fully qualified name must match the pattern completely, so the pattern foo.bar would not match a module named foo.barx.
The default behavior of excluding druntime/phobos is accomplished by internally adding a set of standard exclusions, namely, -i=-std -i=-core -i=-etc -i=-object. Note that these can be overridden with -i=std -i=core -i=etc -i=object.
When a module matches multiple patterns, matches are prioritized by their component length, where a match with more components takes priority (i.e. pattern foo.bar.baz has priority over foo.bar).
By default modules that don't match any pattern will be included. However, if at least one inclusive pattern is given, then modules not matching any pattern will be excluded. This behavior can be overridden by usig -i=. to include by default or -i=-. to exclude by default.
Note that multiple -i=... options are allowed, each one adds a pattern.
- -identifiers=table
-
Set the identifier table to use for the non-ASCII values.
- UAX31: UAX31
- c99: C99
- c11: C11
- all: All, the least restrictive set, which comes with all others (default)
- -identifiers-importc=table
-
Set the identifier table to use for the non-ASCII values.
- UAX31: UAX31
- c99: C99
- c11: C11 (default)
- all: All, the least restrictive set, which comes with all others
- -ignore
- Deprecated flag, unsupported pragmas are always ignored now
- -inline
- Inline functions at the discretion of the compiler. This can improve performance, at the expense of making it more difficult to use a debugger on it.
- -J=directory
- Where to look for files for ImportExpressions. This switch is required in order to use ImportExpressions. path is a ; separated list of paths. Multiple -J's can be used, and the paths are searched in the same order.
- -L=linkerflag
- Pass linkerflag to the linker, for example, ld
- -lib
- Generate library file as output instead of object file(s). All compiled source files, as well as object files and library files specified on the command line, are inserted into the output library. Compiled source modules may be partitioned into several object modules to improve granularity. The name of the library is taken from the name of the first source module to be compiled. This name can be overridden with the -of switch.
- -lowmem
- Enable the garbage collector for the compiler, reducing the compiler memory requirements but increasing compile times.
- -m32
- Compile a 32 bit executable. This is the default for the 32 bit dmd.
- -m64
- Compile a 64 bit executable. This is the default for the 64 bit dmd.
- -main
- Add a default main() function when compiling. This is useful when unittesting a library, as it enables running the unittests in a library without having to manually define an entry-point function.
- -makedeps[=filename ]
- Print dependencies in Makefile compatible format. If filename is omitted, it prints to stdout. The emitted targets are the compiled artifacts (executable, object files, libraries). The emitted dependencies are imported modules and imported string files (via -J switch). Special characters in a dependency or target filename are escaped in the GNU Make manner.
- -man
- Open browser specified by the BROWSER environment variable on this page. If BROWSER is undefined, x-www-browser is assumed.
- -map
- Generate a .map file
- -mcpu=id
- Set the target architecture for code generation, where:
- -mcpu=[h|help|? ]
- List all architecture options
- -mixin=filename
- Expand and save mixins to file specified by filename
- -mv=package.module =
- Use path/filename as the source file for package.module. This is used when the source file path and names are not the same as the package and module hierarchy. The rightmost components of the path/filename and package.module can be omitted if they are the same.
- -noboundscheck
- Turns off all array bounds checking, even for safe functions. Deprecated (use -boundscheck=off instead).
- -nothrow
- Turns off generation of exception stack unwinding code, enables more efficient code for RAII objects.
- -O
- Optimize generated code. For fastest executables, compile with the -O -release -inline -boundscheck=off switches together.
- -o-
- Suppress generation of object file. Useful in conjuction with -D or -H flags.
- -od=directory
- Write object files relative to directory objdir instead of to the current directory. -op can be used if the original package hierarchy should be retained
- -of=filename
- Set output file name to filename in the output directory. The output file can be an object file, executable file, or library file depending on the other switches.
- -op
- Normally the path for .d source files is stripped off when generating an object, interface, or Ddoc file name. -op will leave it on.
- -oq
- When compiling pkg/app.d, the resulting object file name will be pkg_app.obj instead of app.o. This helps to prevent name conflicts when compiling multiple packages in the same directory with the -od flag.
- -os=os
-
Set the target operating system as other than the host.
- host: Target the host operating system (default).
- dragonflybsd: DragonFlyBSD
- freebsd: FreeBSD
- linux: Linux
- openbsd: OpenBSD
- osx: OSX
- solaris: Solaris
- windows: Windows
- -P=preprocessorflag
- Pass preprocessorflag to cpp
- -preview=name
- Preview an upcoming language change identified by id
- -preview=[h|help|? ]
- List all upcoming language changes
- -profile
-
Instrument the generated code so that runtime performance data is collected
when the generated program is run.
Upon completion of the generated program, the files trace.log and trace.def
are generated. trace.log has two sections,
- Fan in and fan out for each profiled function. The name of the function is left-justified, the functions immediately preceding it are the other functions that call it (fan in) and how many times it is called. The functions immediately following are the functions that are called (fan out) and how many times it calls that function. The function itself has 3 numbers appended: the aggregate of the fan in counts, the tree time used by the function which is the function time plus the tree times of all the functions it calls, and the time used excluding the time used by fan out.
- Timing data for each function, sorted from most used to least.
- -profile=gc
-
- gc: Instrument calls to GC memory allocation and
write a report to the file profilegc.log upon program
termination. Note: Only instrumented calls will be
logged. These include:
- Language constructs that allocate memory
- Phobos functions that allocate GC memory
- GC allocations via core.memory.GC
- gc: Instrument calls to GC memory allocation and
write a report to the file profilegc.log upon program
termination. Note: Only instrumented calls will be
logged. These include:
- -release
- Compile release version, which means not emitting run-time checks for contracts and asserts. Array bounds checking is not done for system and trusted functions, and assertion failures are undefined behaviour.
- -revert=name
- Revert language change identified by id
- -revert=[h|help|? ]
- List all revertable language changes
- -run srcfile
- Compile, link, and run the program srcfile with the rest of the command line, args..., as the arguments to the program. No .o or executable file is left behind.
- -shared
- Generate shared library
- -target=triple
- arch is the architecture: either x86, x64, x86_64 or x32, vendor is always ignored, but supported for easier interoperability, os is the operating system, this may have a trailing version number: freestanding for no operating system, darwin or osx for MacOS, dragonfly or dragonflybsd for DragonflyBSD, freebsd, openbsd, linux, solaris or windows for their respective operating systems. cenv is the C runtime environment and is optional: musl for musl-libc, msvc for the MSVC runtime, bionic for the Andriod libc, gnu or glibc for the GCC C runtime, newlib or uclibc for their respective C runtimes. ($ I cppenv) is the C++ runtime environment: clang for the LLVM C++ runtime, gcc for GCC's C++ runtime, msvc for microsoft's MSVC C++ runtime, sun for Sun's C++ runtime.
- -transition=name
- Show additional info about language change identified by id
- -transition=[h|help|? ]
- List all language changes
- -unittest
- Compile in unittest code, turns on asserts, and sets the unittest version identifier
- -v
- Enable verbose output for each compiler pass
- -vasm
- List generated assembler for each function
- -vcolumns
- Print character (column) numbers in diagnostics
- -verror-style=[digitalmars|gnu|sarif ]
-
Set the style for file/line number annotations on compiler messages,
where:
- digitalmars
- 'file(line[,column]): message'. This is the default.
- gnu
- 'file:line[:column]: message', conforming to the GNU standard used by gcc and clang.
- sarif
- 'Generates JSON output conforming to the SARIF (Static Analysis Results Interchange Format) standard, useful for integration with tools like GitHub and other SARIF readers.'
- -verror-supplements=num
- Limit the number of supplemental messages for each error (0 means unlimited)
- -verrors=num
- Limit the number of error/deprecation messages (0 means unlimited)
- -verrors=context
- Show error messages with the context of the erroring source line
- -verrors=spec
- Show errors from speculative compiles such as __traits(compiles,...)
- --version
- Print compiler version and exit
- -version=level
- Compile in version level >= level
- -version=ident
- Compile in version identifier ident
- -vgc
- List all gc allocations including hidden ones
- -visibility=value
-
- default: Hidden for Windows targets without -shared, otherwise public
- hidden: Only export symbols marked with 'export'
- public: Export all symbols
- -vtls
- List all variables going into thread local storage
- -vtemplates=[list-instances ]
-
An optional argument determines extra diagnostics,
where:
- list-instances
- Also shows all instantiation contexts for each template.
- -w
- Enable warnings
- -wi
- Enable informational warnings (i.e. compilation still proceeds normally)
- -wo
- Enable warnings about use of obsolete features that may be problematic (compilation still proceeds normally)
- -X
- Generate JSON file
- -Xf=filename
- Write JSON file to filename
- -Xcc=driverflag
- Pass driverflag to the linker driver ($CC or cc)
dmd -cov -unittest myprog.d
Files
- dmd2/src/phobos/
- D runtime library source
- dmd2/src/dmd/
- D compiler front end source under dual (GPL and Artistic) license
- dmd2/html/d/
- Documentation
- dmd2/samples/d/
- Sample D programs
- dmd2/linux/bin/ddemangle
- D symbol demangler
- dmd2/linux/bin/dman
- D manual lookup tool
- dmd2/linux/bin/dmd
- D compiler executable
- dmd2/linux/bin/dmd.conf
- Global compiler settings (copy to /etc/dmd.conf)
- dmd2/linux/bin/dub
- D's package manager
- dmd2/linux/bin/dumpobj
- ELF file dumper
- dmd2/linux/bin/dustmite
- D source code minimizer
- dmd2/linux/bin/obj2asm
- ELF file disassembler
- dmd2/linux/bin/rdmd
- D build tool for script-like D code execution
- dmd2/linux/lib/libphobos2.a
- D runtime library (copy to /usr/lib/libphobos2.a)
Linking
Linking is done directly by the dmd compiler after a successful compile. To prevent dmd from running the linker, use the -c switch.
The actual linking is done by running gcc. This ensures compatibility with modules compiled with gcc.
Environment Variables
The D compiler dmd uses the following environment variables:
- CC
- dmd normally runs the linker by looking for gcc along the PATH. To use a specific linker instead, set the CC environment variable to it. For example:
- BROWSER
- This sets the browser used to open the manual page with the -man switch. It defaults to x-www-browser.
- DFLAGS
- The value of DFLAGS is treated as if it were appended to the command line to dmd.
set CC=gcc
dmd.conf Initialization File
The dmd file dmd.conf is the same as sc.ini for Windows, it's just that the file has a different name, enabling a setup common to both Windows and this system to be created without having to re-edit the file.
dmd will look for the initialization file dmd.conf in the following sequence of directories:
- current working directory
- directory specified by the HOME environment variable
- as dotfile .dmd.conf in the directory specified by the HOME environment variable
- directory dmd resides in
- /etc/
If found, environment variable settings in the file will override any existing settings. This is handy to make dmd independent of programs with conflicting use of environment variables.
Environment variables follow the [Environment] section heading, in NAME=value pairs. The NAMEs are treated as upper case. Comments are lines that start with ;. For example:
; dmd.conf file for dmd ; Names enclosed by %% are searched for in the existing environment ; and inserted. The special name %@P% is replaced with the path ; to this file. [Environment] DFLAGS=-I%@P%/../src/phobos -I%@P%/../src/druntime/import
Differences between Windows and Linux versions
- String literals are read-only under Linux. Attempting to write to them will cause a segment violation.
D Interface Files
When an import declaration is processed in a D source file, the compiler searches for the D source file corresponding to the import, and processes that source file to extract the information needed from it. Alternatively, the compiler can instead look for a corresponding D interface file. A D interface file contains only what an import of the module needs, rather than the whole implementation of that module.
The advantages of using a D interface file for imports rather than a D source file are:
- D interface files are often significantly smaller and much faster to process than the corresponding D source file.
- They can be used to hide the source code, for example, one can ship an object code library along with D interface files rather than the complete source code.
D interface files can be created by the compiler from a D source file by using the -H switch to the compiler. D interface files have the .di file extension. When the compiler resolves an import declaration, it first looks for a .di D interface file, then it looks for a D source file.
D interface files bear some analogous similarities to C++ header files. But they are not required in the way that C++ header files are, and they are not part of the D language. They are a feature of the compiler, and serve only as an optimization of the build process.
Building Executables
dmd can build an executable much faster if as many of the source files as possible are put on the command line.
Another advantage to putting multiple source files on the same invocation of dmd is that dmd will be able to do some level of cross-module optimizations, such as function inlining across modules.
The -i flag can be used to automatically compile imported modules
Building Libraries
There are three ways to build a library. For example, given foo.d and bar.d which are to be compiled, and existing object file abc.o and existing library def.a which are all to be combined into a library foo.a:
- Compile modules separately and then run the librarian on them:
dmd -c foo.d dmd -c bar.d rm -f foo.a ar -r foo.a foo.o bar.o abc.o def.a rm foo.o bar.o
This option is typical when using a makefile to avoid compiling modules that have already been compiled. - Compile modules together and then run the librarian on them:
dmd -c foo.d bar.d rm -f foo.a ar -r foo.a foo.o bar.o abc.o def.a rm foo.o bar.o
- Use dmd to compile and build library in one operation:
dmd -lib foo.d bar.d abc.o def.a
No object files are written to disk, it's all done in memory. Using -lib also has the advantage that modules may be compiled into multiple object files rather than exactly one per module. This improves granularity of the library without having to break up the modules.
Compiling dmd
Complete source code is provided to build the compiler. Follow these steps:
cd ~/dmd2/src/dmd make -f posix.mak
Compiling Phobos
Complete source code is provided to build Phobos, the D runtime library. Follow these steps:
cd ../phobos make -f posix.mak