Creating a foreign library on Windows that links to a native library

I’m trying to build a shared library callable from non-Haskell languages (a Cabal foreign-library), that also itself links to a native library (one that I’ve written in Rust). On Linux and Mac this works; I can import the GHC-built library from Python, and it happily calls the foreign export functions in that library that under the hood end up calling into the underlying Rust library via foreign import.

On Windows, however, this fails - it seems like Cabal/GHC are not linking against the Rust DLL properly, because the GHC-built DLL fails to load from Python and if I inspect it with Dependency Walker then the GHC-built DLL doesn’t have a dependency on the Rust DLL. (So it makes sense that when the GHC-built DLL gets loaded from Python, it tries to look up symbols from the Rust DLL but those don’t exist.)

GHC-built executables on Windows that link against the Rust DLL do work - they run correctly and Dependency Walker shows that they do in fact have a dependency on the Rust DLL.

I’ve tried various combinations of adding extra-libraries and extra-libraries-static entries to the foreign-library Cabal project file, and just to be safe adding a -l option under ghc-options explicitly, but no matter what I do the resulting GHC-built DLL doesn’t have a dependency on the Rust DLL.

Any thoughts? Happy to expand with more detail…but I’m a bit worried that in general the set of people using foreign-library packages, on Windows, that also import from other native libraries, is going to be pretty small…

(Another option would be to link the Rust library in statically, but when I tried that I got a whole slew of compiler/linker errors so I figured that probably wasn’t a well supported option on Windows. Might be worth another try though!)

3 Likes

For what it’s worth if I try building the Rust library as a static library and then switch to using extra-libraries-static in my .cabal file, I get some ugly linker errors:

ld.lld: warning: ignoring unknown argument: -exclude-symbols:___chkstk_ms
ld.lld: error: -exclude-symbols:___chkstk_ms is not allowed in .drectve
ld.lld: warning: ignoring unknown argument: -exclude-symbols:__udivti3
ld.lld: error: -exclude-symbols:__udivti3 is not allowed in .drectve
ld.lld: warning: ignoring unknown argument: -exclude-symbols:__umodti3
ld.lld: error: -exclude-symbols:__umodti3 is not allowed in .drectve

Looks possibly related to this issue but I’m not sure how I can tweak e.g. the compiler/linker flags to get everything working there…

1 Like

OK it seems be kinda working, looks like the trick was supplying a module definition file entry in my .cabal file, and list there all of my foreign export functions explicitly…so far so good. (Fortunately in my case I have a small fixed number of exported functions!)

2 Likes