Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make it possible to directly link a haskell library with an external static C library(.a). #4042

Open
crocket opened this issue Oct 27, 2016 · 10 comments

Comments

@crocket
Copy link

crocket commented Oct 27, 2016

Since it's not possible, https://github.com/jakubfijalkowski/hlibsass#static-shared-or-external-version-of-libsass says

By default, hLibsass uses a local (built during cabal configure), static version of libsass. This is the recommended approach, as it ensures that the package uses compatible version of the library. However, this implies that the libsass.a file will be copied to the installation directory of the package (probably to a sandbox, so this should not be a problem) and GHCi won't work neither for this package nor any other that depends on hLibsass (it will either segfault or complain about unresolved symbols).

hLibsass may be configured to use a shared version of LibSass. Just specify the sharedLibsass flag during configure/install and hLibsass will build the shared version. This will build a .so (or .a + .dll) file that will be copied to the installation directory and allow GHCi to work properly (except on Windows - but that's because of an import library that hLibsass needs to link against). This may require adjusting LD_LIBRARY_PATH (it should work without this, but I was unable to make it work all the time). You may use tools/libpath.sh to extract correct path from ghc-pkg.

hLibsass may use LibSass version installed in the system - specify externalLibsass flag and the build process will not build local version of LibSass and just relay on the existing one.

This issue is also related to jakubfijalkowski/hlibsass#4

If a haskell binding to a C/C++ library is directly linked with a static library, we can avoid this issue.

@23Skidoo 23Skidoo added this to the Triaged milestone Oct 27, 2016
@ezyang
Copy link
Contributor

ezyang commented Oct 27, 2016

This end goal seems reasonable, but we need some clear UI design and also what is "this actually going to do" upwork before someone can tackle this bug.

@crocket
Copy link
Author

crocket commented Oct 27, 2016

Currently, only executables are linked with .a files.
Since libraries cannot be linked with .a files, .a files should be installed in the same directory as the binding libraries so that executables can find .a and link it with its binding.

Also, GHCi fails to load .a files. Thus, any haskell binding that comes with a static C library crashes GHCi.

.so files installed in the same directories as their binding libraries can be loaded by GHCi, but .so files will cause troubles for packaging haskell programs for linux distributions. Thus, it's ideal to link .a with its binding library so that neither .a nor .so should be installed together with binding libraries.

http://codinginfinity.me/post/2015-04-18/haskell_and_cpp for details

The goal is to emulate what node-gyp does. node-gyp builds C libraries locally and binds them to binding libraries so that C libraries don't have to be installed globally. This is clean.

Cabal currently doesn't have a clean support for embedding C libraries into haskell bindings.

c-sources is good for small C snippets, but it is prohibitively expensive to manage medium or large C libraries with c-sources. Even for small C libraries, c-sources is not useable when customized Makefile is needed.

@domenkozar
Copy link
Collaborator

I've just hit this using https://github.com/serokell/rocksdb-haskell/. If it's linked dynamically, for some reason the .so is linked as relative.

@ryanartecona
Copy link

I also hit this issue yesterday, also with hlibsass.

@domenkozar
Copy link
Collaborator

I've extracted the dynamically linked C dep problems to #4183, this issue can be about the statically linked part.

@ttuegel
Copy link
Member

ttuegel commented Dec 21, 2016

If I understand the goal correctly, we could accomplish this by introducing a build info field extra-static-libraries which works like extra-libraries, but always links the target libraries statically (irrespective of --enable-shared).

@Ericson2314
Copy link
Collaborator

I think the ideal we want is that packages providing bindings can link statically or dynamically with the foreign library. I rather have something like "extra-static-libraries" be a property of the build rather than the (binding) library.

@ttuegel
Copy link
Member

ttuegel commented Dec 22, 2016

I think the ideal we want is that packages providing bindings can link statically or dynamically with the foreign library. I rather have something like "extra-static-libraries" be a property of the build rather than the (binding) library.

For the case that @crocket described, the package provides a static library to use with the bindings. That's not something the user can select at build time; the package has to be created with that in mind. What you are describing is the user selecting whether to statically or dynamically link system libraries, and I agree that is something that should be determined at build-time.

@AleXoundOS
Copy link

Any progress on this issue?

@t3hmrman
Copy link

t3hmrman commented Jan 3, 2020

Just checking in to say that I've run into this as well -- ended up just generating a (Rust) "cdylib"(.so) rather than a "staticlib" (.a) for my project, and I plan on hiding the rust integration behind a flag.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants