• Getting Started with the D Programming Language

General and Gameplay Programming

Installing DMD

At the time of writing, there are three D compilers available. GDC is built on top of the GNU Compiler Collection. LDC is based on LLVM. DMD is the reference compiler maintained by Walter Bright, the creator of the D Programming Language. GDC and LDC are great compilers. In fact, they often produce more performant executables than DMD. But they do require a bit more effort to setup on Windows than DMD does. So for this article, I'm going to focus on DMD. On the DMD download page you will find a Windows installer, a dmg file for Mac users, several deb packages and RPMs for a few different Linux distros and an all-inclusive zip file which contains binaries for all supported platforms. Personally, I prefer the zip file, even for the rare occasions I have to drop into Linux. I really believe that the Windows installer is superfluous. There's nothing to configure besides the path and nothing needs to be copied into any system directories. Unzip, set the path, done. With the zipped DMD package, the path for the Windows binaries is "dmd2\windows\bin", but there are also binaries for FreeBSD, Linux, and OSX (32- and 64-bit where supported). A decision must be made on whether or not to add the appropriate path to the globabl environment. Setting the global path is certainly the simplest thing to do (a quick trip to Google should help in figuring out how to do this for a particular version of Windows). Be careful, though, as one of the Windows binaries is the Digital Mars version of 'make'. If another version of make is on the global path, that can cause some headaches. Setting the global path also makes it difficult to support multiple versions of DMD. There are easy ways around that (I use batch files and cmd.exe shortcuts, and there's also Jacob Carlborg's D Version Manager), but for someone just starting out it's not a big deal. Linux users using the zip file can either copy some stuff around to make everything globally visible, or edit the appropriate shell config file to set things up for a specific user. More details can be found at dlang. Once the path is configured properly, whether manually or via installer or deb package/RPM, get to a command prompt and type the following:  dmd  Invoking dmd with no args will cause it to display the version number along with all the valid command line options, the same as typing dmd --help. This will confirm that the path is properly configured. Next, open up a text editor (I used Crimson Editor, a.k.a. Emerald Editor, for years, but switched to Sublime Text 2 a few months back -- well-worth the price of the license). Enter the following into a text file and save it somewhere as "hello.d".  import std.stdio; void main() { writeln( "Hello D!" ); }  Now navigate on the command line to the directory in which hello.d was saved and enter dmd hello.d. If it compiles without error, then the compiler was able to find the standard library and all is well. If there were errors, be sure to read them carefully. Most DMD errors are fairly clear, but for someone without experience with compilers on the command line this might not be the case. At any rate, if it is not clear that the error was caused by the code or the configuration, the digitalmars.D.learn newsgroup is the place to go for answers. For those who left their newsreaders in the 90s or have no idea what a newsreader is, there is both a forum interface and a mailing list interface for all of the D newsgroups to make them more palatable. One final note on the installation. The vanilla DMD package on Windows only fully provides what is needed to compile 32-bit programs. For 64-bit, it's only half the story. 32-bit makes use of the Digital Mars C++ compiler backend toolchain (including the annoyingly ancient OPTLINK linker and some equally ancient Win32 libraries). 64-bit compilation actually relies on the Microsoft C++ compiler tools, meaning a version of the Windows SDK which includes the compiler tools must be installed. Right now, that means version 7.1 of the Windows SDK.

Derelict 3

Now I'm going to toot my own horn a little. Given that this is a game development site, I would imagine that people experimenting with D for the first time will quickly move beyond "Hello world" style programs and want to get to something more visual. That's where Derelict 3 comes in. Derelict is a collection of D bindings to a number of popular C and C++ libraries that are useful for game development. I first started working on it in early 2004, providing dynamic bindings for OpenGL, SDL, and OpenAL. Over the years, it has evolved through three major versions, packages have been added and removed, build systems have come and gone, and I've pulled out more hair than I care to think about. I try to spend as little time on it as I can possibly get away with without feeling guilty. So far, that has served me well. Getting started with Derelict isn't too terribly difficult. The easiest way is to use dub. I'll describe the harder way first. Anyone who has been doing any sort of C or C++ development long enough must be familiar with git by now. If not, don't look to me for help. Just move on to the next paragraph. Otherwise, Derelict 3 can be cloned from https://github.com/aldacron/Derelict3.git. Once that's done, open up a command prompt with DMD on the path, cd to the "build" subdirectory in the "Derelict3" folder, and execute dmd build (or substitute gdc or ldc2). That compiles the build script. Now execute build (or ./build for the penguins). This will compile libraries for each Derelict package and each library will be output to "Derelict3/lib". To use Derelict, make sure "Derelict3/import" is on the import path (the import path can be set on the command line with the -I switch) and that the libraries are linked (via pragma(lib, "path/to/lib") in source or specified on the command line). Yeah, this is the more complicated way, particularly since each compiler has a different way of specifying the library path on the command line, and with DMD it depends on which backend is being used (I can never remember what it is for 32-bit DMD on Windows). So I recommend using dub anyway. Using Derelict with dub is very easy. All that need be done is to add Derelict, or any combination of Derelict packages, as dependencies to a project in the configuration file. When executing dub build for that project, dub will first verify that all of the dependencies are installed and, if not, will download and compile them automatically. As an example, here's the package.json for another library I'm working on. It uses Derelict to bind with SDL2 and PhysFS. The relevant bit for Derelict is in the "dependencies" section, where it lists Derelict's sdl2 and physfs packages as dependencies.  { "name": "derringdo", "description": "A framework for 2D games with SDL2.", "homepage": "", "copyright": "Copyright (c) 2013, Michael D. Parker", "authors": [ "Mike Parker" ], "dependencies": { "derelict:sdl2": "~master", "derelict:physfs": "~master" }, "configurations": [ { "name": "lib", "targetType": "library", "targetPath": "lib" }, { "name": "dev", "targetType": "executable", "targetPath": "bin" } ] }  Nothing to it. Edit this to fit your project, save it in the parent directory of the project source tree, execute dub build or dub build --config=dev (as described above) and D Programming with Derelict 3 happiness is sure to follow. Derelict can also be installed manually by executing dub install derelict. This is true for any project in the dub registry. See the dub package documentation for more details on how to set up a config file. Using Derelict in code is quite simple as well. Let's assume a project using SDL2 and SDL2_image, two commonly used game development libraries. This snippet of code shows how to import the relevant Derelict modules and load the libraries (remember, Derelict is a set of dynamic bindings, meaning it is designed to load shared libraries (.dll, .so and .dylib) at runtime).  import derelict.sdl2.sdl; import derelict.sdl2.image; void main() { DerelictSDL2.load(); DerelictSDL2Image.load(); }  That's it. If the libraries fail to load, a DerelictException will be thrown, specifically one of the subclasses SharedLibLoadException or SymbolLoadException. The former is thrown when the library fails to load, the latter when a symbol from the library fails to load. Derelict also allows the throwing of SymbolLoadExceptions to be skipped so that if specific symbols are missing, loading can continue. This is useful for loading older versions of a library. Importing derelict.util.exception will pull all DerelictExceptions into the namespace so that they can be handled appropriately. Also, each loader has a version of the load method that allows shared library names to be specified explicitly. By default, the loaders use the common library names as output by each distribution's build system (such as SDL2.dll on Windows) and uses the default system search path to find them. Sometimes it may be desirable to override this behavior, such as when shipping all shared library dependencies in a subdirectory (DerelictSDL2.load("libs/SDL2.dll")). Notice that there are no corresponding calls to any "unload" methods. This is because Derelict makes use of D's static module destructor feature to automatically unload libraries when the app exits. Static module constructors could have been used to load them as well, but that would take away the opportunity to handle exceptions, or to specify alternate library names. The unload methods do exist and are publicly accessible in case a library needs to be explicitly unloaded at a particular time, but they are not required to be called otherwise. When compiling the above manually, the libraries DerelictSDL2.lib and DerelictUtil.lib need to be linked. There is no DerelictSDL2Image.lib. The loaders for SDL2_image, SDL2_ttf, SDL2_mixer, and SDL2_net are all part of DerelictSDL2.lib. The format of the library file names and extensions depend on the platform and compiler.(e.g. DerelictSDL2.lib with DMD on Windows, libDerelictSDL2.a with DMD elsewhere). On Posix systems, it is also necessary to link with libdl, since Derelict uses dlopen and friends to handle the shared libraries. When compiling with dub, libdl will still need to be linked on Posix systems. This can be done with a "libs-posix" entry in the package config file (see the dub package documentation for details). All Derelict packages adhere to this basic format, with the one exception being DerelictGL3. There are two OpenGL loaders in Derelict, one that does not include deprecated functions and one that does. For the former, import derelict.opengl3.gl3 and call DerelictGL3.load. For the latter, import derelict.opengl3.gl and call DerelictGL.load. In both cases, after an appropriate OpenGL context has been created, a reload method must be called (DerelictGL3.reload and DerelictGL.reload respectively). The load methods load the OpenGL 1.0 and 1.1 functions. The reload methods load the functions for versions 1.2+, as well as all supported ARB extensions (support for all ARB extensions may not yet be implemented). It is also recommended to call the reload method each time the context is switched. Both loaders also provide a means of determining the version of OpenGL that actually loaded. Derelict 3 provides bindings for OpenGL, OpenAL, SDL2, SFML2, GLFW3, AssImp3, Lua 5.2, FreeType 2.4 and more. At the time of writing, the project README claims it's all in an alpha state, but it's 100% usable. The only thing missing is the documentation and a couple of more packages I want to add. Of course, one thing I haven't mentioned here is that, when using Derelict, it's necessary for the user to get possession of the appropriate shared libraries, otherwise there's nothing to load. Most projects provide binary distributions, some do not. In the latter case, it is necessary to have a build environment set up to compile C binaries. I try to keep the bindings up to date for each project, but sometimes I fall behind. I'm always happy to accept pull requests to correct that.

Conclusion

This has been a brief introduction on one way to get ready to compile programs with the D Programming Language, with an eye toward would-be D game developers. I hope the information here is useful enough to help those new to the language in getting started. As for how to actually program in D, I'll leave that to Andrei Alexandrescu to explain in his excellent book, The D Programming Language, and to the helpful souls in the D Community, which includes the D Newsgroups and #D on freenode.net. For those who want to go beyond the bounds of what I've described here, I encourage a look at VisualD, MonoD, and DDT for Eclipse to experiment with D IDEs, and of course GDC and LDC to get a feel for alternative compilers. Anyone using Derelict is encouraged to join the Derelict forums to ask for help and to report bugs and other issues on the project page at github. I find D an enjoyable programming language to use and I look forward to seeing more new faces join the ranks of our ever-growing community.

Report Article

User Feedback

Article is a little heavy on anecdotes, and a little light on justification. Why use D? Why use Derelict?

Also a little short of examples. Be great to see some code snippets that aren't just 'Hello, World!'.

Share on other sites

I'm not trying to justify D. The intent here is just to help someone get a D environment set up quickly and easily once they've decided to give it a try.

Share on other sites

You could boil that part of the article down to:

- set PATH variable

- install derelict via dub

What value do the lengthy anecdotes and marketing pitch for derelict add for the reader? Why outline the whole history of D build tools?

You mention using dub to install derelict several times, but then you never actually show how. Also, why describe the whole manual installation of derelict, if right after you say "use dub anyway"?

Share on other sites

Regarding your points, here's what was in my mind as I wrote this.

1) A step-by-step list of do this, do that, is not an article. It's a blog post. An article should be more than a dry list. I'm not sure which anecdotes you are referring to, but if there's anything specific you can point out as problematic, I'll happily consider rewriting or removing it.

2) There are still some old tutorials and blog posts out there about bud and dsss, plus the project pages are still online even though the projects are dead. Now and again, I've seen newcomers head down the wrong trail because of this. By talking about these tools here, I'm making it clear that they are dead. Plus, I thought a brief description of how they worked might be interesting to some people given that rdmd and dsss expand on what they did.

3)  The example package.json shows how to use Derelict as a dependency in any project. I had assumed that it was clear that this is all that is needed, but I see now that is not the case. I'll add a bit to clarify that.

4) I describe the manual installation of Derelict because that is the primary way it has been used for years and not everyone is going to want to use dub. My adding support for dub is a recent thing.

5) Finally, this isn't a marketing pitch for Derelict. There aren't a lot of options for bindings to game development-related libraries in D and, to the best of my knowledge, Derelict is the only collection of dynamic bindings that has been made publicly available. Plus, the static bindings that exist out there for the libraries that Derelict covers are spread out all over the place, many of them outdated. Given that this is a game development site, I made the assumption that my audience would consist of people who might be interested in using D for game development. Derelict is the easiest way I know to get started with that.

I'm describing how to get started using D the way I use it. These days, I use DMD, dub, and Derelict. And I'm trying to do it in a way that adds some value to just a simple step-by-step list.

Share on other sites

I've edited the Derelict section to be more clear on how to use dub to install.

Share on other sites

Seeing you are targeting this article to Windows developers why does derelict not support D3D? Or DirectX for that matter?

Share on other sites

This article is targeting Windows users because, in my experience, they tend to have the hardest time working from the command line. I have had a pretty strict rule over the years that Derelict only binds to cross-platform libraries. The more packages I allow in, the more maintenance I have to do, so the fewer the better.

Besides, D has native support for COM via a special interface. As such, the only functions that really need to be bound from the DX DLLs are the *Create functions. Given that there is already a DX binding out there as part of the WindowsAPI project (as well as others) and given that a Derelict binding would only differ in that the *Create functions would be loaded dynamically, I don't think a Derelict binding would add much value. If dynamic loading is really needed, it's a 5-minute job to prototype the *Create functions and implement a loader using DerelictUtil, then use one of the existing bindings for the type declarations.

Create an account

Register a new account

• Game Developer Survey

We are looking for qualified game developers to participate in a 10-minute online survey. Qualified participants will be offered a \$15 incentive for your time and insights. Click here to start!

• 0
• 0
• 4
• 3

• 15
• 21
• 21
• 11
• 9
×