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

Support using TH and FFI with static C dependencies #1582

Merged
merged 2 commits into from
Aug 18, 2021

Conversation

jcpetruzza
Copy link
Contributor

Consider the following scenario:

  • Package H1 uses FFI and needs to be linked against a pre-built static library X
  • Package H2 depends on H1 and uses TH (but TH code doesn't depend on X)
  • The ghc in the toolchain doesn't have a static runtime

In this case, as far as I can see, it is not currently possible to build H2 using haskell_library: during the compile step, -lX is passed to ghc, and the moment TH is used, ghc will try to load libX.a and fail. For example, on the added test-case, I currently see:

$ bazel build //tests/library-with-static-cc-dep:mypkg
INFO: Analyzed target //tests/library-with-static-cc-dep:mypkg (10 packages loaded, 372 targets configured).
INFO: Found 1 target...
ERROR: /home/daniel/repos/rules_haskell/tests/library-with-static-cc-dep/BUILD.bazel:10:16: HaskellBuildLibrary //tests/library-with-static-cc-dep:mypkg failed: (Exit 1): ghc_wrapper failed: error executing command bazel-out/host/bin/haskell/ghc_wrapper bazel-out/k8-fastbuild/bin/tests/library-with-static-cc-dep/compile_flags_mypkg_HaskellBuildLibrary ... (remaining 1 argument(s) skipped)

Use --sandbox_debug to see verbose messages from the sandbox
<command line>: User-specified static library could not be loaded (bazel-out/k8-fastbuild/bin/tests/library-with-static-cc-dep/libcbits-static.a)
Loading static libraries is not supported in this configuration.
Try using a dynamic library instead.
...

Cabal on the other hand doesn't pass -lX to ghc in this case, so falling back to haskell_cabal_library is the only workaround I see.

To fix this in haskell_library, the proposed solution is to optimistically ignore the static dependencies during the compile
action whenever the ghc runtime will not be able to load them. The only visible difference to the user should be when their TH
code in H2 depends in fact on X (a case that could never work under this scenario anyway): now they will get a symbol-not-found error, instead of a failure to load the static lib.

Copy link
Member

@aherrmann aherrmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! Yes, this looks like a reasonable solution to me. Thank you for including a test as well!

haskell/private/cc_libraries.bzl Outdated Show resolved Hide resolved
Copy link
Member

@aherrmann aherrmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! Looks good!

buildifier was complaining, I pushed the result of bazel run //:buildifier-fix.

@aherrmann aherrmann added the merge-queue merge on green CI label Aug 18, 2021
jcpetruzza and others added 2 commits August 18, 2021 10:25
Consider the following scenario:

  - Package H1 uses FFI and needs to be linked against
    a pre-built static library X
  - Package H2 depends on H1 and uses TH (but TH code doesn't
    depend on X)
  - The ghc in the toolchain doesn't have a static runtime

In this case, as far as I can see, it is not currently possible
to build H2 using `haskell_library`: during the compile step,
`-lX` is passed to ghc, and the moment TH is used, ghc will try
to load `libX.a` and fail. For example, on the added test-case,
I currently see:

```
$ bazel build //tests/library-with-static-cc-dep:mypkg
INFO: Analyzed target //tests/library-with-static-cc-dep:mypkg (10 packages loaded, 372 targets configured).
INFO: Found 1 target...
ERROR: /home/daniel/repos/rules_haskell/tests/library-with-static-cc-dep/BUILD.bazel:10:16: HaskellBuildLibrary //tests/library-with-static-cc-dep:mypkg failed: (Exit 1): ghc_wrapper failed: error executing command bazel-out/host/bin/haskell/ghc_wrapper bazel-out/k8-fastbuild/bin/tests/library-with-static-cc-dep/compile_flags_mypkg_HaskellBuildLibrary ... (remaining 1 argument(s) skipped)

Use --sandbox_debug to see verbose messages from the sandbox
<command line>: User-specified static library could not be loaded (bazel-out/k8-fastbuild/bin/tests/library-with-static-cc-dep/libcbits-static.a)
Loading static libraries is not supported in this configuration.
Try using a dynamic library instead.
...
```

Cabal on the other hand doesn't pass `-lX` to ghc in this case,
so falling back to `haskell_cabal_library` is the only workaround I see.

To fix this in haskell_library, the proposed solution is to
optimistically ignore the static dependencies during the compile
action whenever the ghc runtime will not be able to load them.
The only visible difference to the user should be when their TH
code in H2 depends in fact on X (a case that could never work under
this scenario anyway): now they will get a symbol-not-found error,
instead of a failure to load the static lib.
@aherrmann
Copy link
Member

@Mergifyio refresh

@mergify
Copy link
Contributor

mergify bot commented Aug 18, 2021

Command refresh: success

Pull request refreshed

@mergify mergify bot merged commit 8f166a3 into tweag:master Aug 18, 2021
@mergify mergify bot removed the merge-queue merge on green CI label Aug 18, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants