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

Bazel-built Shared C Libraries and the GHCi linker #720

Open
moritzkiefer-da opened this issue Feb 27, 2019 · 4 comments
Open

Bazel-built Shared C Libraries and the GHCi linker #720

moritzkiefer-da opened this issue Feb 27, 2019 · 4 comments
Labels
P2 major: an upcoming release type: bug

Comments

@moritzkiefer-da
Copy link
Contributor

Let’s say I have two cc_librarys a and b where a depends on b. The shared libraries built by Bazel underlink, i.e., the shared library doesn’t declare that it depends on other shared libraries instead this is tracked internally by Bazel.

If I make a Haskell library that depends on a, I will end up with extra-libraries: a b in my package config. The GHCi linker (triggered by TH) will go through those libraries and call dlopen(libname, RTLD_LAZY|RTLD_LOCAL). It respects the order in extra-libraries so it will first try to load a. If you are lucky, RTLD_LAZY works and despite a referencing b. However, this won’t work in general as RTLD_LAZY only works for function references and even then it can be overridden by things like -Wl,-z,now which, to make matters worse, is passed by default by Bazel. In that case dlopen will error out with an undefined symbol error and builds fail.

Sadly, I don’t know a nice solution to this:

  • Changing the order in extra-libraries will break static linking afaict since in that case a should come first.
  • linkstatic = True works sometimes but it is annoying to have to patch upstream rules and the GHCi linker is also fairly fragile (currently it’s failing for me on the official grpc library patched with linkstatic = True with libgpr_base.a: unhandled ELF relocation(RelA) type 19).
  • Get Bazel to properly declare dependencies of the shared library. Then the system linker should handle this properly. This seems fairly hard to do atm, see Control linking of dependencies for cc_library  bazelbuild/bazel#492.

I don’t have a self-contained test case that I can make public right now but we’re seeing this with the official grpc library, i.e., "@com_github_grpc_grpc//:grpc" which we get viahttp_archive`:

http_archive(
    name = "com_github_grpc_grpc"
    strip_prefix = "grpc-1.19.0",
    urls = ["https://github.com/grpc/grpc/archive/v1.19.0.tar.gz"],
    sha256 = "1d54cd95ed276c42c276e0a3df8ab33ee41968b73af14023c03a19db48f82e73",
)
@Profpatsch Profpatsch added this to the REPL improvements milestone Feb 28, 2019
@Profpatsch Profpatsch added the P2 major: an upcoming release label Feb 28, 2019
@moritzkiefer-da
Copy link
Contributor Author

For now, I managed to work around this by creating a rule that creates fat static and dynamic libraries. Since these don’t depend on any other libraries this avoids the problem but obviously it’s not pretty.

Note also that while @Profpatsch tagged this as REPL improvements, this also affects TH so even if you’re willing to give up on a repl, this might mean that you are unable to build your code.

@mboes mboes removed this from the REPL improvements milestone Apr 6, 2019
@Profpatsch
Copy link
Contributor

Profpatsch commented Oct 7, 2019

Has this problem been solved by recent improvements to the REPL support in rules_haskell?

@aherrmann
Copy link
Member

@Profpatsch As @moritzkiefer-da pointed this does not only concern the REPL but also template Haskell. The issue still persists.

Changing the order in extra-libraries will break static linking afaict since in that case a should come first.

This would indeed break static linking.

Get Bazel to properly declare dependencies of the shared library.

Using the new Starlark C++ API it's possible to create a custom cc_library rule that does not underlink. Using aspects, it's also possible to adapt an existing cc_library target to do the same thing. However, this requires rebuilding the corresponding C library. So, that's probably not something we'd want rules_haskell to do automatically.

@aherrmann
Copy link
Member

In #1696 @jcpetruzza provided a great repro for this issue.
#1696 (comment) demonstrates that adding the "missing" NEEDED entry fixes the loading error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P2 major: an upcoming release type: bug
Projects
None yet
Development

No branches or pull requests

4 participants