tweag / rules_haskell

Haskell rules for Bazel.
https://haskell.build
Apache License 2.0
265 stars 79 forks source link

C-only cabal libraries fail to build with haddock = True #2200

Open avdv opened 4 months ago

avdv commented 4 months ago

Describe the bug

There are a few libraries that depend on internal C libraries packaged in another cabal package (depending on the OS / flags passed to cabal).

For instance, when using a recent stack snapshot that includes zlib 0.7.1.0, this version depends on the internal zlib-clib library either if explicitly requested using the bundled-c-zlib flag, or when disabling the pkg-config flag and the platform is Windows.

See https://github.com/haskell/zlib/pull/70

To Reproduce

stack_snapshot(
    name = "stackage",
    extra_deps = {"zlib": ["@zlib.dev//:zlib"]},
    packages = ["zlib"],

    # disable calling pkg-config
    flags = {"zlib": ["-pkg-config"]},

    snapshot = "nightly-2024-05-24",
)

Trying to build @stackage//:zlib results in:

ERROR: C:/users/runneradmin/_bazel_runneradmin/z5des2pa/external/stackage/BUILD.bazel:29:22: output 'external/stackage/zlib-clib-1.3.1/_install/zlib-clib-1.3.1_haddock/zlib-clib.haddock' was not created
ERROR: C:/users/runneradmin/_bazel_runneradmin/z5des2pa/external/stackage/BUILD.bazel:29:22: HaskellCabalLibrary @stackage//:zlib-clib failed: not all outputs were created or valid

The reason for this error is that the zlib-clib library is a C only library which does not produce any haddock.

Expected behavior

Environment

Additional context

The only possible workaround is to disable haddock generation altogether:

stack_snapshot(
   name = "stackage",
   ...
   haddock = False,
)
jonathanlking commented 3 months ago

I believe I'm experiencing the same issue on lts-22.26 with libyaml which now has a libyaml-clib.

In a slightly different case, attoparsec-aeson also fails to build, both with the same Haddock issue, but also with output 'external/stackage/attoparsec-aeson-2.1.0.0/_install/lib/libHSattoparsec-aeson-2.1.0.0.a' was not created, which makes sense as the package is empty, but it would be nice if then didn't stop aeson from building šŸ˜…

(Apologies if hijacking this issue, I can open a separate one if preferable!)

avdv commented 3 months ago

@jonathanlking Thank you, for providing more cases of the same issue.

(Apologies if hijacking this issue, I can open a separate one if preferable!)

Don't worry, that's not needed. I think these cases somehow should be handled in the same way. I guess what we would need is some way of disabling haddock for individual libraries for the stack_snapshot call.

This might get tedious if more libraries start to use c-only libraries, though. So a more general approach would be to somehow generate an empty haddock file if the cabal build failed to produce one. The best option probably would be if we could inspect the cabal build somehow and generate appropriate haskell_cabal_library calls -- but not sure that is possible.

avdv commented 3 months ago

In a slightly different case, attoparsec-aeson also fails to build, both with the same Haddock issue, but also with output 'external/stackage/attoparsec-aeson-2.1.0.0/_install/lib/libHSattoparsec-aeson-2.1.0.0.a' was not created, which makes sense as the package is empty, but it would be nice if then didn't stop aeson from building šŸ˜…

Oh yes, this is indeed another issue. Empty packages are handled with a blacklist here: https://github.com/tweag/rules_haskell/blob/8b868c5e713925232299e39b95a310572ff2aa94/haskell/cabal.bzl#L129-L142

Which is also kind of ugly. Maybe it also makes sense to support passing this information into stack_snapshot if a package is empty...