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

rules_haskell is incompatible with Bazel's new "trim_test_configuration" default setting #1536

Closed
fweikert opened this issue Apr 13, 2021 · 3 comments · Fixed by #1545
Closed

Comments

@fweikert
Copy link
Contributor

Describe the bug
Using a Bazel binary built at commit bazelbuild/bazel@ebac27e or later will crash certain rules_haskell targets with the following error:

ERROR: /usr/local/google/home/fwe/git/rules_haskell/tests/binary-with-sysdeps/BUILD.bazel:8:13: in _haskell_test rule //tests/binary-with-sysdeps:binary-with-sysdeps: 
Traceback (most recent call last):
	File "/usr/local/google/home/fwe/git/rules_haskell/haskell/private/haskell_impl.bzl", line 77, column 39, in haskell_test_impl
		return _haskell_binary_common_impl(ctx, is_test = True)
	File "/usr/local/google/home/fwe/git/rules_haskell/haskell/private/haskell_impl.bzl", line 173, column 25, in _haskell_binary_common_impl
		cc = cc_interop_info(ctx)
	File "/usr/local/google/home/fwe/git/rules_haskell/haskell/cc.bzl", line 166, column 40, in cc_interop_info
		cc_libraries = get_cc_libraries(cc_libraries_info, [lib for li in cc_common.merge_cc_infos(cc_infos = ccs).linking_context.linker_inputs.to_list() for lib in li.libraries]),
	File "/usr/local/google/home/fwe/git/rules_haskell/haskell/private/cc_libraries.bzl", line 49, column 43, in get_cc_libraries
		if not cc_libraries_info.libraries[cc_library_key(lib_to_link)].is_haskell
Error: key struct(dynamic_library = <generated file _solib_k8/[email protected]_S_S_Czlib___Uexternal_Szlib.hs/libz.so>, interface_library = None, pic_static_library = None, static_library = <generated file external/zlib.hs/libz.a>) not found in dictionary
ERROR: Analysis of target '//tests/binary-with-sysdeps:binary-with-sysdeps' failed; build aborted: Analysis of target '//tests/binary-with-sysdeps:binary-with-sysdeps' failed
INFO: Elapsed time: 7.251s
INFO: 0 processes.
FAILED: Build did NOT complete successfully (71 packages loaded, 9505 targets configured)

To Reproduce

  1. Download Bazelisk from https://github.com/bazelbuild/bazelisk
  2. git clone rules_haskell repository
  3. From within the repository run USE_BAZEL_VERSION="last_green" bazelisk build //tests/binary-with-sysdeps:binary-with-sysdeps

Expected behavior
Build succeeds

Environment

Additional context

cc @sdtwigg

@fweikert
Copy link
Contributor Author

There's some disagreement on whether this constitutes a Bazel bug or a problem in rules_haskell that was unearthed by the recent changes.

@aherrmann
Copy link
Member

@fweikert Thanks for raising this and for repro.

I reran the repro with the following debugging code in place:

diff --git a/haskell/private/cc_libraries.bzl b/haskell/private/cc_libraries.bzl
index 3ac12fef..2b36ca9c 100644
--- a/haskell/private/cc_libraries.bzl
+++ b/haskell/private/cc_libraries.bzl
@@ -43,6 +43,7 @@ def get_cc_libraries(cc_libraries_info, libraries_to_link):
       list of LibraryToLink, C libraries.

     """
+    print("!!! get_cc_libraries", "".join(["\n  {}".format(k) for k in cc_libraries_info.libraries.keys()]))
     return [
         lib_to_link
         for lib_to_link in libraries_to_link

The output is

DEBUG: .../haskell/private/cc_libraries.bzl:46:10: !!! get_cc_libraries
  struct(dynamic_library = <generated file _solib_k8/[email protected]_S_S_Czlib___Uexternal_Szlib.hs/libz.so>, interface_library = None, pic_static_library = None, static_library = <generated file external/zlib.hs/libz.a>)
  struct(dynamic_library = <generated file _solib_k8/external_Srules_Uhaskell_Ughc_Ulinux_Uamd64/libHSbase-4.13.0.0-ghc8.8.3.so>, interface_library = None, pic_static_library = None, static_library = <source file lib/base-4.13.0.0/libHSbase-4.13.0.0.a>)
  struct(dynamic_library = <generated file _solib_k8/external_Srules_Uhaskell_Ughc_Ulinux_Uamd64/libHSinteger-gmp-1.0.2.0-ghc8.8.3.so>, interface_library = None, pic_static_library = None, static_library = <source file lib/integer-gmp-1.0.2.0/libHSinteger-gmp-1.0.2.0.a>)
  struct(dynamic_library = <generated file _solib_k8/external_Srules_Uhaskell_Ughc_Ulinux_Uamd64/libHSghc-prim-0.5.3-ghc8.8.3.so>, interface_library = None, pic_static_library = None, static_library = <source file lib/ghc-prim-0.5.3/libHSghc-prim-0.5.3.a>)
  struct(dynamic_library = <generated file _solib_k8/external_Srules_Uhaskell_Ughc_Ulinux_Uamd64/libHSrts_thr-ghc8.8.3.so>, interface_library = None, pic_static_library = None, static_library = <source file lib/rts/libHSrts_thr.a>)
  struct(dynamic_library = <generated file _solib_k8/external_Srules_Uhaskell_Ughc_Ulinux_Uamd64/libffi.so.7>, interface_library = None, pic_static_library = None, static_library = <source file lib/rts/libCffi_thr.a>)
Error: key struct(dynamic_library = <generated file _solib_k8/[email protected]_S_S_Czlib___Uexternal_Szlib.hs/libz.so>, interface_library = None, pic_static_library = None, static_library = <generated file external/zlib.hs/libz.a>) not found in dictionary

The failing code uses a struct over None or File as dictionary keys. The error message indicates that the looked up key is missing, however, the debug output suggests that it is actually present. I suspect that using File as dictionary keys is the issue here and something about --trim_test_configuration changes the identity of File between inserting them into the dictionary and looking them up. @fweikert does that make sense?

For context, the whole thing is part of a compatibility layer between Bazel's way of handling C libraries and what the Haskell compiler GHC expects. See #1241 and #1256 for details. In short, we generate symlinks for static libraries in an aspect to replicate Bazel's mangling of dynamic libraries, because GHC expects static and dynamic libraries to have the same name. We then keep a mapping from original LibraryToLink to a version with the mangled symlinks for later use.

Perhaps using File in a dictionary key is not such a good idea. It seems that a possible workaround for this issue is to use the File's path attribute instead.

aherrmann added a commit that referenced this issue Apr 16, 2021
The function `cc_library_key` generates the dictionary keys by which
`LibLibraryToLink` are mapped to their corresponding
`HaskellCcLibraryInfo`. Before this used a `struct` over `None` or
`File` objects. This changes uses `None` or `string` instead, where
`string` is the `.path` attribute of the `File` object.

Using a `File` object in a dictionary key fails if the `File` object
used at lookup time is semantically the same, but has a different
identity due to implementation details in Bazel.

Closes #1536
@fweikert
Copy link
Contributor Author

cc @sdtwigg as expert

MMesch pushed a commit that referenced this issue Apr 22, 2021
The function `cc_library_key` generates the dictionary keys by which
`LibLibraryToLink` are mapped to their corresponding
`HaskellCcLibraryInfo`. Before this used a `struct` over `None` or
`File` objects. This changes uses `None` or `string` instead, where
`string` is the `.path` attribute of the `File` object.

Using a `File` object in a dictionary key fails if the `File` object
used at lookup time is semantically the same, but has a different
identity due to implementation details in Bazel.

Closes #1536
@mergify mergify bot closed this as completed in #1545 Apr 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants