On Saturday, 27 February 2016 at 06:34:19 UTC, Joakim wrote:
On Friday, 26 February 2016 at 12:45:35 UTC, Atila Neves wrote:
foo.d:
-----
void main() {
import bar;
foreach(ut; __traits(getUnitTests, bar)) ut();
}
-----
bar.d:
-----
unittest { assert(1 == 2); }
-----
# compile all at once
dmd -unittest foo.d bar.d # fine
# compile separately
dmd -c -unittest foo.d
dmd -c -unittest bar.d
dmd foo.o bar.o
foo.o:foo.d:function _Dmain: error: undefined reference to
'_D3bar16__unittestL2_531FZv'
collect2: error: ld returned 1 exit status
--- errorlevel 1
objdump shows me that bar.o has a '_D3bar14__unittestL2_1FZv'
symbol, which is nearly, but not quite, what foo.o is trying
to call.
Huh?
As Walter notes, it's because the mangling changes based on
whether you separately compile the unit tests. It's why you
needed to generate the main D source file for unit-threaded
too, becuase __traits(getUnitTests) gets confused by this same
issue if the modules containing tests are separately compiled:
https://github.com/atilaneves/unit-threaded/blob/master/source/unit_threaded/runtime.d#L175
Well, guess how I found out about this issue? ;) It turns out all
my unit test files were always in the same package due to
laziness, and as soon as I tried compiling separately, things
broke. Sigh.
I've had similar problems in the past with template mixins. It
seems D's compile-time features don't mix with any kind of
separate compilation, which is a shame.
Atila