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

Fix static linking with Haskell prebuilt packages #569

Merged
merged 6 commits into from
Jan 16, 2019

Conversation

aherrmann
Copy link
Member

Currently, static linking (linkstatic = True) of Haskell binary targets fails if the target has an indirect dependency on a prebuilt package imported using haskell_import. The reason is that haskell_import has no access to the package id and the package id of prebuilt package dependencies is not inserted into the depends: section of the package configuration file of Haskell targets. GHC then does not add linker flags for the corresponding static libraries and liking fails on missing symbols. See FormationAI/hazel#64 .

This PR fixes that by inserting the package id of prebuilt packages into the depends: section of Haskell targets.

The corresponding package id is obtained using ghc-pkg field id on the prebuilt package. The outcome is stored in a file and a reference to that file is stored in the HaskellPrebuiltPackageInfo provider. This way ghc-pkg only has to be executed once per prebuilt package.

The implementation of haskell_import, which is now a little more complex, has been moved into haskell/private/haskell_impl.bzl to follow the convention of other more complex rule implementations.

This change also allows to only reference direct prebuilt dependencies on linking, resolving an XXX comment in haskell/private/packages.bzl.

Finally, this PR adds a regression test.

@aherrmann
Copy link
Member Author

This issue was not previously triggered by the rules_haskell test cases, because these either don't have indirect dependencies on prebuilt dependencies, or they use the @hackage//:XYZ form of prebuilt dependency targets, in which case the package id is available from Nix and was already added to the depends: section prior to this PR. The issue surfaced in Hazel, because it uses the simpler haskell_import form and cannot generally rely on Nix to provide the package id of GHC core packages.

Note, that linker errors due to missing symbols only occur if Haskell code actually references functions from the imported prebuilt dependency.

Copy link
Contributor

@guibou guibou left a comment

Choose a reason for hiding this comment

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

LGTM. Thank you!

@aherrmann aherrmann force-pushed the static-linking-core-libraries branch from bf2b994 to 8a580ee Compare January 15, 2019 12:58
Copy link
Contributor

@Profpatsch Profpatsch left a comment

Choose a reason for hiding this comment

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

A few minor things.

Also cc @regnat, is that change relevant for your newer haskell_import and has to be added there as well?

inputs = [hs.tools.ghc_pkg],
outputs = [id_file],
command = """
$1 --simple-output -v1 field $2 id > $3
Copy link
Contributor

Choose a reason for hiding this comment

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

I’d add quotes around the variables here as well.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

Previously, static linking (linkstatic = True) of Haskell binary targets
fails if the target has an indirect dependency on a prebuilt package
imported using haskell_import. The reason is that haskell_import has no
access to the package id and the package id of prebuilt package
dependencies is not inserted into the `depends:` section of the package
configuration file of Haskell targets. GHC then does not add linker
flags for the corresponding static libraries and liking fails on missing
symbols. See FormationAI/hazel#64 .

This change fixes that by inserting the package id of prebuilt packages
into the depends: section of Haskell targets.

The corresponding package id is obtained using `ghc-pkg field id` on the
prebuilt package.
Generate the package id file for prebuilt packages in the
`haskell_import` implementation and store the file in the
`HaskellPrebuiltPackageInfo` provider.
By setting `use_direct = True` on expose_packages when linking.
Indirect dependencies on `haskell_import` targets caused missing symbol
linker errors when statically linking. This test-case triggers this
issue.
@aherrmann aherrmann force-pushed the static-linking-core-libraries branch from 8a580ee to d06bd91 Compare January 15, 2019 14:37
@aherrmann
Copy link
Member Author

@Profpatsch

Also cc @regnat, is that change relevant for your newer haskell_import and has to be added there as well?

If you're referring to haskell_import implemented in haskell/import.bzl, then no. That one takes package_id as an attribute and generates a full HaskellBuildInfo. The @hackage//:XYZ targets mentioned above are generated that way.

@aherrmann aherrmann merged commit d2abf00 into master Jan 16, 2019
@aherrmann aherrmann deleted the static-linking-core-libraries branch January 16, 2019 09:11
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.

4 participants