Thread overview
linking obj files compiled with LDC2 1.20.0 on Win64
Mar 22, 2020
realhet
Mar 23, 2020
realhet
Mar 24, 2020
realhet
Mar 24, 2020
realhet
Mar 25, 2020
realhet
Mar 31, 2020
realhet
Mar 26, 2020
Ferhat Kurtulmuş
Mar 31, 2020
realhet
March 22, 2020
Hello,

I'm try to use the latest LDC2 version: 1.20.0
Previously I used 1.6.0

After fixing all the compiler errors and warnings, I managed to compile all the d source files to obj files, and I got 4 linking errors. I think all of them caused by the first 2:

1:
msvcrt.lib(initializers.obj) : warning LNK4098: defaultlib 'libcmt.lib' conflicts with use of other libs; use /NODEFAULTLIB:library

2:
exceptions.obj : error LNK2019: unresolved external symbol _D3std6format__T11hasToStringTSQBd4json9JSONValueTaZ9__lambda2MFZ1S3putMFNaNbNiNfaZv referenced in function _D3std5range10primitives__T5doPutTSQBh6format__T11hasToStringTSQCj4json9JSONValueTaZ9__lambda2MFZ1STaZQCxFNaNbNiNfKQDdKaZv

Anyone knows how to solve these? Please help me!

I uploaded all the details to here: https://github.com/realhet/hetlib/blob/master/het/test/linkingerror.txt

Or if there is info about how to use the Microsoft 64bit linker with the newest version of LDC2 please let me no.
Or maybe an open source build tool that is up to date and I can extract the most recent linker parameters?
Is there a new VS Community version requirement?

I remember it was also tricky 2.5 years ago, since then it worked perfectly fine for me, but I just decided to use the latest LDC2 and bumped to this.

Thank you for the assistance in advance!

March 22, 2020
On 3/22/20 2:43 PM, realhet wrote:
> Hello,
> 
> I'm try to use the latest LDC2 version: 1.20.0
> Previously I used 1.6.0
> 
> After fixing all the compiler errors and warnings, I managed to compile all the d source files to obj files, and I got 4 linking errors. I think all of them caused by the first 2:
> 
> 1:
> msvcrt.lib(initializers.obj) : warning LNK4098: defaultlib 'libcmt.lib' conflicts with use of other libs; use /NODEFAULTLIB:library
> 
> 2:
> exceptions.obj : error LNK2019: unresolved external symbol _D3std6format__T11hasToStringTSQBd4json9JSONValueTaZ9__lambda2MFZ1S3putMFNaNbNiNfaZv referenced in function _D3std5range10primitives__T5doPutTSQBh6format__T11hasToStringTSQCj4json9JSONValueTaZ9__lambda2MFZ1STaZQCxFNaNbNiNfKQDdKaZv 
> 

Make sure you don't have any stale objects left over in your project from the older build. Build everything clean from scratch.

-Steve
March 23, 2020
On Sunday, 22 March 2020 at 20:20:17 UTC, Steven Schveighoffer wrote:
>
> Make sure you don't have any stale objects left over in your project from the older build. Build everything clean from scratch.
>
> -Steve

Thx, I double checked this. Then I attempted to link from the commandline and it worked. o.O So there must be some weirdness in my build tool which is fine with LDC2 1.6.0 but fails with 1.20.0 :S
March 24, 2020
On Sunday, 22 March 2020 at 20:20:17 UTC, Steven Schveighoffer wrote:
> Make sure you don't have any stale objects left over in your project from the older build. Build everything clean from scratch.
>
> -Steve

After narrowing the problem, I fixed all warnings, and deprecations, and I have only one linker error now:

Compiler command line (LDC 1.20.0 Win64):
ldmd2 -vcolumns -c -op -allinst -Ic:\D\libs\ -m64 -mcpu=athlon64-sse3 -mattr=+ssse3 -release -O -inline -boundscheck=off c:\D\libs\jsonizer\exceptions.d

Linker command line:
link /LIBPATH:c:\D\ldc2\lib64 /OUT:c:\D\libs\het\hdmd\hdmd.exe /MACHINE:X64 kernel32.lib user32.lib legacy_stdio_definitions.lib ***All the required obj files*** druntime-ldc.lib phobos2-ldc.lib msvcrt.lib

Linker response (after demangling):
Microsoft (R) Incremental Linker Version 14.23.28105.4
Copyright (C) Microsoft Corporation.  All rights reserved.

---------------------------------------------

exceptions.obj : error LNK2019: unresolved external symbol

pure nothrow @nogc @safe void std.format.hasToString!(std.json.JSONValue, char).__lambda2().S.put(char)

referenced in function

pure nothrow @nogc @safe void std.range.primitives.put!(std.format.hasToString!(std.json.JSONValue, char).__lambda2().S, char).put(ref std.format.hasToString!(std.json.JSONValue, char).__lambda2().S, char)

---------------------------------------------

I've searched for the hasToString template, but this seems way too complicated for me.
This nested lambda template thing o.O

Here is the source code for the exceptions.obj file: https://github.com/rcorre/jsonizer/blob/master/src/jsonizer/exceptions.d

These are caused by some format() calls, I don't know why it is a problem now and it's totally OK with a 2017 version.

This nested std.range.primitives.put is weird for me. Maybe it's a bug because by the -CompileAllTemplateInstances flag? (That's not the normal use, I know: I comile all the objs, and while I work, I only compile the ones that changed (recursively ofc), and finally link. It's much faster this way on a 8 core machine.).



March 24, 2020
On 3/24/20 10:28 AM, realhet wrote:
> On Sunday, 22 March 2020 at 20:20:17 UTC, Steven Schveighoffer wrote:
>> Make sure you don't have any stale objects left over in your project from the older build. Build everything clean from scratch.
>>
> 
> After narrowing the problem, I fixed all warnings, and deprecations, and I have only one linker error now:
> 
> Compiler command line (LDC 1.20.0 Win64):
> ldmd2 -vcolumns -c -op -allinst -Ic:\D\libs\ -m64 -mcpu=athlon64-sse3 -mattr=+ssse3 -release -O -inline -boundscheck=off c:\D\libs\jsonizer\exceptions.d
> 
> Linker command line:
> link /LIBPATH:c:\D\ldc2\lib64 /OUT:c:\D\libs\het\hdmd\hdmd.exe /MACHINE:X64 kernel32.lib user32.lib legacy_stdio_definitions.lib ***All the required obj files*** druntime-ldc.lib phobos2-ldc.lib msvcrt.lib
> 
> Linker response (after demangling):
> Microsoft (R) Incremental Linker Version 14.23.28105.4
> Copyright (C) Microsoft Corporation.  All rights reserved.
> 
> ---------------------------------------------
> 
> exceptions.obj : error LNK2019: unresolved external symbol
> 
> pure nothrow @nogc @safe void std.format.hasToString!(std.json.JSONValue, char).__lambda2().S.put(char)
> 
> referenced in function
> 
> pure nothrow @nogc @safe void std.range.primitives.put!(std.format.hasToString!(std.json.JSONValue, char).__lambda2().S, char).put(ref std.format.hasToString!(std.json.JSONValue, char).__lambda2().S, char)
> 
> ---------------------------------------------
> 
> I've searched for the hasToString template, but this seems way too complicated for me.
> This nested lambda template thing o.O

Ugh, this is a template constraint. There's no reason to see it in compiled code.

> 
> Here is the source code for the exceptions.obj file: https://github.com/rcorre/jsonizer/blob/master/src/jsonizer/exceptions.d
> 
> These are caused by some format() calls, I don't know why it is a problem now and it's totally OK with a 2017 version.
> 
> This nested std.range.primitives.put is weird for me. Maybe it's a bug because by the -CompileAllTemplateInstances flag? (That's not the normal use, I know: I comile all the objs, and while I work, I only compile the ones that changed (recursively ofc), and finally link. It's much faster this way on a 8 core machine.).

I think this might be part of the problem. It's still a bug in the compiler, but this unusual way of compiling might be bringing it out. Most likely either the mangling is changed when compiling the dependency, or the symbol is being incorrectly referenced or incorrectly excluded.

If this were Linux, I'd start using nm to search the object files for the symbol that is missing (like search for symbols defining hasToString), and see if it possibly might be mangled in a different way. I'm not sure what tools there are on Windows to do this.

-Steve
March 24, 2020
On Tuesday, 24 March 2020 at 15:22:19 UTC, Steven Schveighoffer wrote:
> On 3/24/20 10:28 AM, realhet wrote:
>> On Sunday, 22 March 2020 at 20:20:17 UTC, Steven Schveighoffer

I managed to compile it with normal compilation.
The -allInst flag may be the problem.

I also had success by manual linking:

ldmd2 -vcolumns -Ic:\D\libs\ -m64 -mcpu=athlon64-sse3 -mattr=+ssse3 -release -O -inline -boundscheck=off -of=c:\D\libs\het\hdmd\hdmd.obj c:\D\libs\het\hdmd\hdmd.d ... -c

link /LIBPATH:c:\D\ldc2\lib64 /OUT:c:\D\libs\het\hdmd\hdmd.exe /MACHINE:X64 kernel32.lib user32.lib legacy_stdio_definitions.lib c:\D\libs\het\hdmd\hdmd.obj druntime-ldc.lib phobos2-ldc.lib msvcrt.lib

So I will try to narrow the problem in Jsonizer.exceptions.d

For a 11k LOC project with 10 .d files when I only modify a few top level d files, and I already have the .obj files for the rest, the compilation time is only 5-10 seconds instead of the 40 with the all in one compilation. I got used to this, so I will try anything to fix it :D
March 25, 2020
On Tuesday, 24 March 2020 at 16:35:56 UTC, realhet wrote:
> On Tuesday, 24 March 2020 at 15:22:19 UTC, Steven Schveighoffer wrote:
>> On 3/24/20 10:28 AM, realhet wrote:
>>> On Sunday, 22 March 2020 at 20:20:17 UTC, Steven Schveighoffer

Now I have 2 of this:

megatexturing.obj : error LNK2019: unresolved external symbol

pure nothrow @nogc @safe void std.format.hasToString!(
  std.typecons.Tuple!(
    ulong, "index", const(het.megatexturing.SubTexInfo), "value"
  ).Tuple, char
).__lambda1().S.put(char)

referenced in function

pure scope @safe bool std.format.FormatSpec!(char).FormatSpec.writeUpToNextSpec!(
  std.format.hasToString!(
    std.typecons.Tuple!(
      ulong,
      "index",
      const(het.megatexturing.SubTexInfo),
      "value"
    ).Tuple,
    char
  ).__lambda1().S
).writeUpToNextSpec(
  ref std.format.hasToString!(std.typecons.Tuple!(ulong, "index", const(het.megatexturing.SubTexInfo), "value").Tuple, char).__lambda1().S
)

And only with that format hasToString! template.
I hope I can locate something along this:
std.typecons.Tuple!(
  ulong, "index", const(het.megatexturing.SubTexInfo), "value"
)
Maybe it refers to a function parameter list in my program.

Something tells me that this should not be look like something recursive o.o

I'll search for that Linux tool on windows that you mentioned...
March 26, 2020
On Sunday, 22 March 2020 at 18:43:50 UTC, realhet wrote:
> Hello,
>
> I'm try to use the latest LDC2 version: 1.20.0
> Previously I used 1.6.0
>
> [...]

Try to run the compiler in visual studio command line terminal.
March 31, 2020
On Thursday, 26 March 2020 at 14:52:36 UTC, Ferhat Kurtulmuş wrote:
> On Sunday, 22 March 2020 at 18:43:50 UTC, realhet wrote:
>> Hello,
>>
>> I'm try to use the latest LDC2 version: 1.20.0
>> Previously I used 1.6.0
>>
>> [...]
>
> Try to run the compiler in visual studio command line terminal.

I set up the environment variables with "....ldc2\bin\msvcenv amd64", it calls that command prompt implicitly. That couldn't be a problem.
March 31, 2020
On Tuesday, 24 March 2020 at 15:22:19 UTC, Steven Schveighoffer wrote:
> On 3/24/20 10:28 AM, realhet wrote:
>> On Sunday, 22 March 2020 at 20:20:17 UTC, Steven Schveighoffer
> If this were Linux, I'd start using nm to search the object files for the symbol that is missing (like search for symbols defining hasToString), and see if it possibly might be mangled in a different way. I'm not sure what tools there are on Windows to do this.
>
> -Steve

I've found a similar tool in MSVC, it's called DUMPBIN.
I was able to find that the linker errors were correct: I wasn't able to find even smaller substrings of that std.format.hasToString symbol, it was called like 4 times.

But I had a clue: A problem when trying to call hasToString on my struct, so I located all the references for that and I've found this thing:

    //infoArray.enumerate.each!writeln;
    //!!! LDC 1.20.0 win64 linker bug when using enumerate here!!!!!

    //foreach(i, a; infoArray) writeln(tuple(i, a));
    //!!! linker error as well

    //foreach(i, a; infoArray) writeln(tuple(i, i+1));
    //!!! this is bad as well, the problem is not related to own structs, just to tuples

    foreach(i, a; infoArray) writefln("(%s, %s)", i, a);  //this works


Now I know that [LDC 1.20.0 win64 -allinst] has a problem generating the code for tuple parameters in std.format calls.
This was not a problem in 1.6.0

Now I go on and try my bigger projects.