October 16, 2017
https://issues.dlang.org/show_bug.cgi?id=17903

          Issue ID: 17903
           Summary: dmd leaves behind bad executable when linker fails
           Product: D
           Version: D2
          Hardware: x86
                OS: Windows
            Status: NEW
          Severity: normal
          Priority: P1
         Component: dmd
          Assignee: nobody@puremagic.com
          Reporter: johnnymarler@gmail.com

When compiling an executable with DMD, if the linker fails then DMD will still create the target executable even though it is invalid and cannot run.

This breaks build tools that check the existence of the executable to know if the executable needs to be rebuilt (virtually all build tools do this).  If you have a linker error, the first time you run your build dmd will leave behind an invalid executable.  If you run the build again it will think that the executable has already been built and move on to the next part of the build.

One way to fix this would be to modify dmd to remove the executable if the linker fails.  Another way would be to write the executable to a temporary file, and then rename it to the target executable or delete it depending on if the linker succeeded or failed.  This way, if the compiler gets interrupted, or you lose power, or something happens that prevents dmd from cleaning up the binary, you still won't have a target executable.

The following can be used to reproduce the issue:

forcelinkerror.d
-------------
import std.stdio, foo;
void main()
{
    writeln("This exe can run (foofunc() = %s)", foofunc());
}
-------------


foo.d
-------------
module foo;
int foofunc() { return 42; }
-------------

Run the following to force a linker error
> dmd forcelinkerror.d

This will leave behind an invalid executable forcelinkerror.exe

--