rules_haskell icon indicating copy to clipboard operation
rules_haskell copied to clipboard

Linker failure with rules_nixpkgs on MacOS

Open facundominguez opened this issue 5 months ago • 4 comments

Describe the bug

The failure first occurred in inline-java. When building with the macos-15 or macos-13 runner of github actions, the linker used by GHC or hsc2hs says:

error: ld: unknown option: -no_fixup_chains

I reduced the example to build a single module in this branch. And here are the logs of the run in inline-java's CI.

To Reproduce

In a macos-15 runner, clone the branch, then

echo common --repo_env=BAZEL_USE_CPP_ONLY_TOOLCHAIN=1 > .bazelrc.local
echo common --repo_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1 >> .bazelrc.local                                                                                                                  
echo common --incompatible_enable_cc_toolchain_resolution >> .bazelrc.local                                                                                                                   
echo common --toolchain_resolution_debug=cc >> .bazelrc.local                                                                                                                                 
echo common --crosstool_top=@nixpkgs_config_cc//:toolchain >> .bazelrc.local

then

nix-shell --run "bazel build //:inline-java"

Expected behavior

The build should succeed, the same as in the ubuntu runner.

Environment

  • OS: MacOS
  • Bazel version: 6.5.0
  • Version of rules_haskell: 1.0
  • Version of rules_nixpkgs: 0.13.0

Additional context

Apparently related issue: https://discourse.haskell.org/t/solved-trouble-building-unix-package-on-macos-ld-unknown-option-no-fixup-chains/7772/16

I'm configuring the nixpkgs cc toolchain explicitly because otherwise bazel complains about libtool not being available. But I'm finding confusing that the cc toolchain needs to be configured explicitly only in MacOS.

facundominguez avatar Jul 16 '25 17:07 facundominguez

Hi Facundo,

I took a quick look, and I saw that indeed the -no_fixup_chains linker option is present in /nix/store/q2nn3dq8nyxaqngmy2s9klb2qiyzfxfx-ghc-9.8.4/bin/hsc2hs.

Also, the cc nix toolchain is configured here:

https://github.com/tweag/inline-java/blob/c3a674b099d232fb9b94e558ba460d28316b7e4d/WORKSPACE#L46-L49

nixpkgs_cc_configure(
    name = "nixpkgs_config_cc",
    repository = "@rules_haskell//nixpkgs:default.nix",
)

What's a bit odd, is that you use a different repository instead of @nixpkgs -- is there a reason for this? This could lead to mismatches between what ghc expects from the cc toolchain and the tools that get configured for it.

I'm configuring the nixpkgs cc toolchain explicitly because otherwise bazel complains about libtool not being available. But I'm finding confusing that the cc toolchain needs to be configured explicitly only in MacOS.

Well, yes. On MacOS there is xcode and its tightly integrated into the system. And additionally, a GHC build has a fixed idea of the compiler and tools it is build with. Which means you cannot easily replace with compiler with something else. So, if you're using ghc from nixpkgs, you also should use configure cc toolchain from nixpkgs.

\edit: from https://github.com/haskell/zlib/issues/53#issuecomment-1627605160:

At some point in the macos 13.4.* sequence, support for no_fixup_chains was dropped.

Which would explain why this option is no longer available on macos-15. But apparently, it was available when the ghc package was build / installed, ie. inside of the nix build.

avdv avatar Jul 21 '25 12:07 avdv

Thanks Claudio.

Well, yes. On MacOS there is xcode and its tightly integrated into the system.

👍 I just found related explanations in the nixpkgs_cc_configure documentation.

What's a bit odd, is that you use a different repository instead of @nixpkgs -- is there a reason for this?

Not a good one. It probably was the result of copying it from elsewhere. I fixed that in the test example. CI is complaining of a different error now. I think what I'd like to say is: please use the same cc toolchain as used to build and configure ghc. But I don't know yet how.

Which would explain why this option is no longer available on macos-15.

I tried the macos-13 runner with identical result. Perhaps it is still too new.

facundominguez avatar Jul 21 '25 13:07 facundominguez

Not a good one. It probably was the result of copying it from elsewhere. I fixed that in the test example. CI is complaining of a different error now.

OK, at least some progress ;-)

error: function 'anonymous lambda' called with unexpected argument 'postLinkSignHook'
       at /nix/store/syvnmj3hhckkbncm94kfkbl76qsdqqj3-source/pkgs/build-support/bintools-wrapper/default.nix:8:1:

That seems to be related to https://github.com/tweag/rules_nixpkgs/commit/4026c2c2d95f1563b300f6a9c07f185586169077 which is included in rules_nixpkgs 0.13.

The problem here is that rules_haskell depends on rules_nixpkgs_* and will load version 0.12 in rules_haskell_dependencies() for any repository not yet defined.

So you end up with rules_nixpkgs_core 0.13 (since that is explicitly loaded in WORKSPACE), but rules_nixpkgs_cc 0.12.

One needs to move loading the rules_nixpkgs' toolchain repositories before calling rules_haskell_dependencies().

Next problem was that rules_haskell depends on a newer version of bazel_skylib, but rules_nixpkgs loads an old one by default which does not work.

I pushed a fix to your branch.

I think what I'd like to say is: please use the same cc toolchain as used to build and configure ghc. But I don't know yet how.

Yes, that probably would be best. Maybe we could add this as some default, which could be overridden if wanted.

avdv avatar Jul 21 '25 16:07 avdv

Thanks @avdv!

One needs to move loading the rules_nixpkgs' toolchain repositories before calling rules_haskell_dependencies()

Alas, this makes rules_haskell and rules_nixpkgs so difficult to configure. I hope bazel modules help with it.

If this is not documented somewhere, making the user aware would be a nice closed up to the issue. Maybe rules_nixpkgs could give a warning if it finds that an older version of rules_nixpkgs is already loaded.

Yes, that probably would be best. Maybe we could add this as some default, which could be overridden if wanted.

That looks like it could make things simpler as well.

facundominguez avatar Jul 21 '25 17:07 facundominguez