Incremental compilation with DMD

Tom S h3r3tic at remove.mat.uni.torun.pl
Sat Sep 12 04:52:39 PDT 2009


Walter Bright wrote:
> Tom S wrote:
>> Thus my suggestion of adding an option to DMD so it may emit template 
>> instances to all object files that use them. If anyone has alternative 
>> ideas, I'd be glad to hear them, because I'm running out of options.
> 
> Try compiling with -lib, which will put each template instance into its 
> own obj file.

Thanks for the suggestion. Unfortunately it's a no-go since -lib seems 
to have the same issue that compiling without -op does - if you have 
multiple modules with the same name (but different packages), one will 
overwrite the other in the lib. On the other hand, I was able to hack 
DMD a bit and use -multiobj since your suggestion gave me an idea :)

Basically, the approach would be to compile the project with -multiobj 
and move the generated objects to a local (per project) directory, 
renaming them so no conflicts arise.

The next step is to determine all public and comdat symbols in all of 
these object files - this might be done via a specialized program, 
however I've used Burton Radons' exelib to optimally run libunres.exe 
from DMC. The exports are saved to some sort of a database (a dumb 
structured file is ok).

The following is done on the initial build - so the next time we have 
some object files in a directory and a map of all their exported 
symbols. In an incremental step, we'll compile the modified modules, but 
don't move their object files immediately over to the special directory. 
We'll instead scan their public and comdat symbols and figure out which 
object files they replace from our already compiled set. For each symbol 
in the newly compiled objects, find which object in the original set 
defined it, then mark it. For all marked files, add them to a library ( 
I call it junk.lib ), then remove the source object. Finally, move the 
newly compiled objects to the special object directory.

The junk.lib will be used if the newly compiled object files missed any 
shared symbols that were in the old objects and that would be generated, 
had more modules be passed to the compiler. In other words, it contains 
symbols that the naive incremental compilation will lose.

When linking, all object files from the directory are passed explicitly 
to the compiler and symbols are pulled eagerly from them, however 
junk.lib will be queried only if a symbol cannot be found in the set of 
objects in the special directory.

I've put up a proof-of-concept implementation at 
http://h3.team0xf.com/increBuild.7z . It requires a slightly patched DMD 
(well, hacked actually), so it prints out the names of all objects it 
generates. Basically, uncomment the `printf("writing '%s'\n", fname);` 
in glue.c at line 133 and add `printf("writing '%s'\n", 
m->objfile->name->str);` after `m->genobjfile(global.params.multiobj);` 
in mars.c. I'm compiling the build tool with a recent (SVN-ish) version 
of Tango and DMD 1.047.

As for my own impressions of this idea, its biggest drawback probably is 
that the multitude of object files created via -multiobj strains the 
filesystem. Even when running on a ramdrive, my WinXP-based system took 
a good fraction of a second to move a few hundred object files to their 
destination directory. This can probably be improved on, as -multiobj 
seems to produce some empty object files (at least according to libunres 
and ddlinfo). It might also be possible to use specialized storage for 
object files by patching up dmd and hooking OPTLINK's calls to 
CreateFile. I'm not sure about Linux, but perhaps something based on 
FUSE might work. These last options are probably long shots, so I'm 
still quite curious how DMD might perform with outputting template 
instantiations into each object file that uses them.


-- 
Tomasz Stachowiak
http://h3.team0xf.com/
h3/h3r3tic on #D freenode



More information about the Digitalmars-d mailing list