Linking portably against C++ objects is very, very hard
@Bodigrim is looking to depend upon simdjson
, a C++ library, in text-utf8
. However, doing the (mostly) naive thing fails on Windows as gcc
's default is to link libstdc++.dll.6
dynamically.
Specifically on Windows:
$ git clone git@github.com:haskell/text
$ cd text
$ git checkout 8e02d95f01d6ee9a8d3dff28a4b9b2af38f91446
$ cabal new-test
Will fail due to the dynamic linker being unable to locate libstdc++.dll
I have tried several ways of working around this:
- trying to force
gcc
to link statically againstlibstdc++
by adding-optl-static-libstdc++
flag to the link. However, this fails as gcc ignores this flag when invoked as a C linker. - using
g++
for linking by adding-pgmlg++.exe -optl-static-libstdc++
to the final link. This fail with various linker errors:
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: c:\msys64/mingw64/mingw/lib/gcc/x86_64-w64-mingw32/5.2.0/libgcc_eh.a(unwind-seh.o):(.text+0x3c0): multiple definition of `_Unwind_Resume'; c:\msys64/mingw64/mingw/lib/gcc/x86_64-w64-mingw32/5.2.0/libgcc_s.a(d000015.o):(.text+0x0): first defined here
C:\msys64\home\ben\text\dist-newstyle\build\x86_64-windows\ghc-9.0.1\text-1.2.4.2\b\text-benchmarks\build\text-benchmarks\text-benchmarks-tmp\Benchmarks\Builder.o:fake:(.text+0x38): relocation truncated to fit: IMAGE_REL_AMD64_ADDR32 against symbol `stg_bh_upd_frame_info' defined in .text section in C:\msys64\home\ben\ghc\_build\stage1\lib\x86_64-windows-ghc-9.0.1\rts-1.0/libHSrts-1.0.a(Updates.o)
C:\msys64\home\ben\text\dist-newstyle\build\x86_64-windows\ghc-9.0.1\text-1.2.4.2\b\text-benchmarks\build\text-benchmarks\text-benchmarks-tmp\Benchmarks\Builder.o:fake:(.text+0x46): relocation truncated to fit: IMAGE_REL_AMD64_ADDR32 against `.rdata'
- trying to force
gcc
to link staticallylibstdc++
by adding-optl'-Wl,-Bstatic,-lstdc++,-lgcc_s,-Bdynamic'
to the link flags. This can link the executable correctly butghci
fails to locatelibstdc++
unless/mingw64/bin
is inPATH
Ultimately this is quite a poor experience for users linking against a very common language. However, it's not clear to me how to improve this situation as C++ compilers do not provide any way of querying what linkables are necessary to satisfy the dependencies of a compilation unit.
Edited by Ben Gamari