Derek Parnell’s Build Utility

January 17th, 2006 | by Aldacron |

Compiling and linking a D project is no different than compiling a C or C++ project. Fitting since the D front end relies on C back ends (DMC on Windows, GCC on Linux). Digital Mars provides a version of make with the DMC++ compiler tools, which is required when one installs the DMD compiler. For those (like me) who don’t have the patience to learn the innards of yet another version of make, Derek Parnell has come to the rescue with Build.

Build is a wonderful tool. Feed it one D source module and it will follow all imports and compile everything your project uses (much like javac does for Java). Build goes farther. One thing it does is define a special version. D does away with the C preprocessor and in its place allows for a ‘version’ statement. Anything wrapped in a version statement will not be compiled if the version is not active. Some built-in versions are: Windows, linux, BigEndian, LittleEndian, X86. There are compiler-specific versions, such as DigitalMars. You can define your own versions on the command line, or via assignments in the source file (version = someversion, which is only good at module scope in the module in which it appears). Build allows you to special case code when it is used. Wrap up your special Build-only code with a version(Build){ } block and you’re good to go. When compiling via another means, such as make or the command line, that block of code will be ignored (unless you explicitly define the ‘Build’ version yourself on the commandline). When using Build, that bit of code will be compiled in for you.

Build also does more parsing of your source modules than just looking for imports. One thing it looks for is a special pragma. D, like C and C++, allows for vendor-specific pragma statements. Compilers should ignore unrecognized pragmas. The Digital Mars implementation defines a ‘lib’ pragma which allows you to specifiy link libraries in source rather than on the command line (as with VC++ - this was one of the features requested by the D community that Walter added). Initially, the lib pragma was only implemented on Windows (DMD now handles it on Linux as well). Build searches for its own special pragma, called ‘link’, which serves the same purpose as the ‘lib’ pragma. There’s a difference between the two.With the link pragma, you don’t need to specify a file extension. As long as the library names are the same on both Windows and Linux, build will link them in with the one statement (so you don’t need to version them).

On Windows, Build will recognize if you have a WinMain or main function. If WinMain is present, it passes the appropriate arguments to DMD to compile a Windows GUI (no console) app. If both main and WinMain are missing, it will create a library for you instead. Additionally, any command line parameters accepted by either Build or DMD can be stored in a special Build Response File. I typically make two brfs for my D projects - projectName_debug.brf and projectName_release.brf. I create them both at the start of the project (usually by copying from another project and editing some paths) and never touch them again. Building projects then becomes a one-liner: “build @projectName_debug”.

The DMD compiler is blazingly fast. I doubt you’ve ever seen anything that compiles as quickly (though DMC comes close). One of the reasons for this is that D is designed to be easily parsed - compiler writers need help as much as the programmers who use their products. Build adds so little overhead that it is not even noticeable. I maintain a project at DSource.org called Derelict (a collection of bindings to C libraries that can be dynamically loaded, such as OpenGL and SDL). Initially, I relied on make files to build the Derelict libraries. Those days are gone, and now I use Build exclusively. I use it for all of my D projects as well. Build is also showing up in community-created IDEs.

Derek Parnell has created a real gem. The only downside to Build is that it currently doesn’t work with GDC (to my knowledge). If you are using DMD and not Build, then something is sorely amiss!

Post a Comment