Search code examples
c++mingwldmsys2lld

ld can't find symbol, but lld can, why? (MinGW64 library on MSYS2)


On the MSYS2 shell, ld fails to link a simple binary:

$ clang++ -iquote /mingw64/include -L /mingw64/lib -lLLVM-16 -x c++ - <<<$'#include "llvm/Support/raw_ostream.h"\nint main() { llvm::errs(); }'
/mingw64/bin/ld: [...] undefined reference to `llvm::errs()'

However, if I use lld, then it works:

$ clang++ -fuse-ld=lld -iquote /mingw64/include -L /mingw64/lib -lLLVM-16 -x c++ - <<<$'#include "llvm/Support/raw_ostream.h"\nint main() { llvm::errs(); }'

Why is this? (For reference, I'm using these precompiled libraries.)


Solution

  • In this case, the order of .o and .a files was the culprit.

    Reordering the files solved that issue.

    HOWEVER: There can be another culprit too.

    lld has another feature to aid DLL linking that ld has poor support for. It is supposed to support these via the following flags (which may be already enabled by default):

    -Wl,--enable-auto-import,--enable-runtime-pseudo-reloc
    

    However, they don't seem to quite work well, from what I find in practice.

    If you get an error such as the following on a platform such as MinGW64...

    ld: app.o:app.cpp:(.text+0x1000): undefined reference to `.refptr._ZN6symbol'
    

    ...then you may be running into this issue, and the only solution I see is to use lld -- nothing I did with ld managed to resolve these errors.