D needs to publicize its speed of compilation
Atila Neves
atila.neves at gmail.com
Fri Dec 29 23:05:47 UTC 2017
On Thursday, 28 December 2017 at 21:58:07 UTC, Walter Bright
wrote:
> On 12/28/2017 5:22 AM, Atila Neves wrote:
>> On Thursday, 28 December 2017 at 07:21:28 UTC, Walter Bright
>> wrote:
>>> On 12/27/2017 1:23 PM, Atila Neves wrote:
>>>> However, my experience has been that D has fast builds from
>>>> scratch, but is really really slow for incremental builds.
>>> You can do fast incremental builds with D by not putting all
>>> the files on the command line. Just put one.
>>
>> I don't build the compiler command-line myself, nor do I want
>> to. Even then, recompiling one file isn't useful to me, what
>> is is to recompile what's needed and run the tests.
>> Emacs/flycheck already highlights compilation errors in just
>> one file.
>
> I don't understand. C++ compiles files one at a time. You can
> do the same in D. How can this model be useful in C++ but not
> with D?
Because:
. As Iain pointed out independently, D modules are like C/C++
headers. All dependencies must also be recompiled. If I edit a
C++ source file, only that source file has to be recompiled. I
can use .di files, and they can even be generated for me (nice!)
but there's no build system to do this properly. This is one of
the ideas I alluded to earlier - I want to put this sort of thing
in reggae. And now that dmd is a dub package I can even just use
the actual compiler code. i.e. Generate the .di, if it's the same
as before don't overwrite the old one to not mess with the
timestamp.
. C++ doesn't have built-in unit tests. Which means a framework
has to be used and since nobody wants to put their tests in
#ifdef "blocks" they live in separate files. Changing the
implementation doesn't require the tests to be rebuilt. Yes, I
can separate them in D too, but then I lose DDoc benefits and
it's actually nicer to see tests next to the code. The fact that
all D files are effectively headers means editing a unittest
means recompiling all modules that depend on the current one.
. Related to the previous point: compiling separately in D is
actually slower overall than by package, because of all of the
dependencies (I measured). Yes, I can compile by package, but I
don't want to do this by hand. To the extent of my knowledge the
only way to get per-package compilation by default or otherwise
in the D ecosystem is reggae. But:
. Until recently, it wasn't possible to use
__traits(getUnitTests) with separate compilation. I've run into
other issues with when doing so (I can't remember what they
were). Even with the bug fix editing a test entails compiling
several modules and it's slower than just one C++ file. In C++
editing a test source file always means recompiling exactly one
file.
. Speaking of dependencies, there's no easy way currently to know
what they are. _If_ I want to build per package/module and only
build what's needed, then I need to either hand-roll a Makefile
(points gun to head) or use reggae. If there's any other
alternative, I don't know about it. Even Phobos recompiles the
world. That's not a good example to set.
. C++ test framework's hacky usage of global variable assignment
to register tests seems to be faster to compile than D's
compile-time reflection to achieve the same result. I'd have to
benchmark to be sure though.
. If one has dub dependencies (and in all likelihood one has),
then either one is a reggae early adopter (I keep mentioning it
to highlight why I wrote it in the first place), or in the 99.9%
of other users typing either `dub build` or `dub test`. There is
no per-package build option. There's a per-module option, but
it's single-threaded, therefore slow. Also, no dependency
tracking, so let's recompile the whole dub package! In one
thread. Zzzzzzzzz.
What I really want is to hit F5 in emacs, rebuild the current
file _and_ all of its dependencies, cache the dependency build
per file so that if they haven't change don't rebuild, link and
run the unit tests. But build _only_ what's needed to avoid
linker errors in order to be able to run the unit tests for _one_
file.
I spent an afternoon writing the necessary elisp to get this done
and it worked! Then I tried a different project and it failed
miserably. So did the 3rd one. I think I just remembered one of
the separate compilation bugs I mentioned above. I know, I know,
if I don't file it it won't get fixed (even if I file it I have a
sneaky suspicion it'll be me fixing it anyway), but figuring out
what went wrong takes time and energy and I haven't had enough of
either to take this off my TODO list.
To summarise:
. Dependencies.
. There's no standard build system that isn't called dub.
. There's only one alternative build system that can do any of
what's needed.
. That alternative build system hasn't implemented my .di idea
yet.
. Separate compilation bugs. That nobody ever hits because dub
builds everything at once.
Atila
More information about the Digitalmars-d
mailing list