[SOLVED] Trouble building "unix" package on MacOS: "ld: unknown option: -no_fixup_chains"

In my cross-platform GHC quest, today I am trying to get GHC up and running on MacOS. The Mac I have access to is running MacOS 10.13.6, which I realize is a bit old, but GHC claims to support back to MacOS 10.7.

For the record, here are all the versions I’m using:

Janes-iMac:~ mignon$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.13.6
BuildVersion:   17G14033
Janes-iMac:~ mignon$ uname -a
Darwin Janes-iMac.lan 17.7.0 Darwin Kernel Version 17.7.0: Mon Aug 31 22:11:23 PDT 2020; root:xnu-4570.71.82.6~1/RELEASE_X86_64 x86_64
Janes-iMac:~ mignon$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 9.4.7
Janes-iMac:~ mignon$ cabal --version
cabal-install version 3.10.1.0
compiled using version 3.10.1.0 of the Cabal library
Janes-iMac:~ mignon$ gcc --version
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 10.0.0 (clang-1000.10.44.4)
Target: x86_64-apple-darwin17.7.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
Janes-iMac:~ mignon$ ld -v
@(#)PROGRAM:ld  PROJECT:ld64-409.12
BUILD 17:47:51 Sep 25 2018
configured to support archs: armv6 armv7 armv7s arm64 i386 x86_64 x86_64h armv6m armv7k armv7m armv7em
LTO support using: LLVM version 10.0.0, (clang-1000.10.44.4) (static support for 21, runtime is 21)
TAPI support using: Apple TAPI version 10.0.0 (tapi-1000.10.8)
Janes-iMac:~ mignon$

I am able to build a simple “Hello, World!” program, as well as many libraries from Hackage. However, I am unable to build the unix package:

Starting     unix-2.8.2.1 (all, legacy fallback)
Building     unix-2.8.2.1 (all, legacy fallback)

Failed to build unix-2.8.2.1.
Build log ( /Users/mignon/.cabal/logs/ghc-9.4.7/nx-2.8.2.1-ab3b6c44.log ):
Configuring unix-2.8.2.1...
configure: WARNING: unrecognized options: --with-compiler
checking for gcc... /usr/bin/gcc
checking whether the C compiler works... yes
[...snip...]
checking for library containing dlopen... none required
checking for library containing sem_close... none required
checking whether sem_getvalue is declared... yes
configure: creating ./config.status
config.status: creating unix.buildinfo
config.status: creating include/HsUnixConfig.h
configure: WARNING: unrecognized options: --with-compiler
Preprocessing library for unix-2.8.2.1..
linking dist/build/System/Posix/Resource_hsc_make.o failed (exit code 1)
rsp file was: "dist/build/System/Posix/hsc2hscall74173-2.rsp"
command was: /usr/bin/gcc dist/build/System/Posix/Resource_hsc_make.o dist/build/System/Posix/Resource_hsc_utils.o -o dist/build/System/Posix/Resource_hsc_make --target=x86_64-apple-darwin -Wl,-no_fixup_chains --target=x86_64-apple-darwin -L/Users/mignon/.ghcup/ghc/9.4.7/lib/ghc-9.4.7/lib/../lib/x86_64-osx-ghc-9.4.7/time-1.12.2 -L/Users/mignon/.cabal/store/ghc-9.4.7/flpth-1.4.100.4-db0bbe6a/lib -L/Users/mignon/.ghcup/ghc/9.4.7/lib/ghc-9.4.7/lib/../lib/x86_64-osx-ghc-9.4.7/exceptions-0.10.5 -L/Users/mignon/.ghcup/ghc/9.4.7/lib/ghc-9.4.7/lib/../lib/x86_64-osx-ghc-9.4.7/stm-2.5.1.0 -L/Users/mignon/.ghcup/ghc/9.4.7/lib/ghc-9.4.7/lib/../lib/x86_64-osx-ghc-9.4.7/mtl-2.2.2 -L/Users/mignon/.ghcup/ghc/9.4.7/lib/ghc-9.4.7/lib/../lib/x86_64-osx-ghc-9.4.7/transformers-0.5.6.2 -L/Users/mignon/.ghcup/ghc/9.4.7/lib/ghc-9.4.7/lib/../lib/x86_64-osx-ghc-9.4.7/bytestring-0.11.5.2 -L/Users/mignon/.ghcup/ghc/9.4.7/lib/ghc-9.4.7/lib/../lib/x86_64-osx-ghc-9.4.7/template-haskell-2.19.0.0 -L/Users/mignon/.ghcup/ghc/9.4.7/lib/ghc-9.4.7/lib/../lib/x86_64-osx-ghc-9.4.7/pretty-1.1.3.6 -L/Users/mignon/.ghcup/ghc/9.4.7/lib/ghc-9.4.7/lib/../lib/x86_64-osx-ghc-9.4.7/ghc-boot-th-9.4.7 -L/Users/mignon/.ghcup/ghc/9.4.7/lib/ghc-9.4.7/lib/../lib/x86_64-osx-ghc-9.4.7/deepseq-1.4.8.0 -L/Users/mignon/.ghcup/ghc/9.4.7/lib/ghc-9.4.7/lib/../lib/x86_64-osx-ghc-9.4.7/array-0.5.4.0 -L/Users/mignon/.ghcup/ghc/9.4.7/lib/ghc-9.4.7/lib/../lib/x86_64-osx-ghc-9.4.7/base-4.17.2.0 -liconv -L/Users/mignon/.ghcup/ghc/9.4.7/lib/ghc-9.4.7/lib/../lib/x86_64-osx-ghc-9.4.7/ghc-bignum-1.3 -L/Users/mignon/.ghcup/ghc/9.4.7/lib/ghc-9.4.7/lib/../lib/x86_64-osx-ghc-9.4.7/ghc-prim-0.9.1 -L/Users/mignon/.ghcup/ghc/9.4.7/lib/ghc-9.4.7/lib/../lib/x86_64-osx-ghc-9.4.7/rts-1.0.2 -L/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib -lm -ldl -lffi
error: ld: unknown option: -no_fixup_chains
clang: error: linker command failed with exit code 1 (use -v to see invocation)

I have been unable to figure out where the -no_fixup_chains linker option is coming from. I grepped through the source of the unix package and didn’t see it there. Maybe it’s coming from Cabal? But strange that Cabal is only specifying this option on the unix package, and not on any of the other packages I tried to build.

2 Likes

If you run ghc --info then you will see the option is in the C compiler link flags. What GHC version is this?

How did you install GHC? Can you paste the config.log from the installation?

There is a ./configure check which should determine whether this option is needed/supported on your system.

1 Like

As I posted up top, this is GHC 9.4.7.

I installed GHC with ghcup, which is currently the only recommended way on https://www.haskell.org/downloads/.

Where would I find this config.log? In the ~/.ghcup/logs/ directory, there is only one file, which is named ghcup.log, with the following contents:

Debug: Identified Platform as: Darwin
Debug: last access was 14414.756932s ago, cache interval is 300s
Info: downloading: https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-0.0.7.yaml as file /Users/mignon/.ghcup/cache/ghcup-0.0.7.yaml
Debug: Read etag: "767733b65e6b7e893666d11a8c39feba1dc7a638400dff8daaf128e14a274665"
Debug: Status code was 304, not overwriting
Debug: Parsed etag: "767733b65e6b7e893666d11a8c39feba1dc7a638400dff8daaf128e14a274665"
Debug: Writing etagsFile /Users/mignon/.ghcup/cache/ghcup-0.0.7.yaml.etags
Debug: Decoding yaml at: /Users/mignon/.ghcup/cache/ghcup-0.0.7.yaml
Debug: Requested to install cabal version 3.10.1.0
Info: downloading: https://downloads.haskell.org/~cabal/cabal-install-3.10.1.0/cabal-install-3.10.1.0-x86_64-darwin.tar.xz as file /Users/mignon/.ghcup/tmp/ghcup-a0f837b8815df9e2/cabal-install-3.10.1.0-x86_64-darwin.tar.xz
Info: verifying digest of: cabal-install-3.10.1.0-x86_64-darwin.tar.xz
Info: Unpacking: cabal-install-3.10.1.0-x86_64-darwin.tar.xz to /Users/mignon/.ghcup/tmp/ghcup-30a9564119f4fb5f
Info: Installing cabal
Debug: last access was 41.166191s ago, cache interval is 300s
Debug: Decoding yaml at: /Users/mignon/.ghcup/cache/ghcup-0.0.7.yaml
Debug: rm -f /Users/mignon/.ghcup/bin/cabal
Debug: ln -s cabal-3.10.1.0 /Users/mignon/.ghcup/bin/cabal
Debug: last access was 10.00211s ago, cache interval is 300s
Debug: Decoding yaml at: /Users/mignon/.ghcup/cache/ghcup-0.0.7.yaml

I can’t find a file named config.log anywhere, but I’m not even sure where I’m supposed to be looking.

I’m not seeing -no_fixup_chains in the output of ghc --info:

Janes-iMac:~ mignon$ ghc --info | fgrep no_fixup_chains
Janes-iMac:~ mignon$

It looks like the -no-fixup-chains option is coming from hsc2hs. (So this is why this is only happening with the unix package and not with other packages.)

Janes-iMac:~ mignon$ find .ghcup -type f -print0 | xargs -0 fgrep no_fixup_chains
.ghcup/ghc/9.4.7/bin/hsc2hs-ghc-9.4.7:HSC2HS_EXTRA="--cflag=--target=x86_64-apple-darwin --lflag=--target=x86_64-apple-darwin --lflag=-Wl,-no_fixup_chains"
Janes-iMac:~ mignon$

So, I’m sure this is Not The Recommended Way To Do It™, but I just edited the file ~/.ghcup/ghc/9.4.7/bin/hsc2hs-ghc-9.4.7 and removed the offending option, and now it works great. The unix package built with no problem.

2 Likes

They should be in /Users/mignon/.ghcup/tmp/ghcup-XXXXXXX/config.log. I guess you could clear that tmp directory and reinstall GHC to easily find out which one you need to look at.

I think the problem is that that wrapper script is generated when the bindist is created, and it needs to be generated when the bindist is installed.

I opened an issue on the GHC tracker: #24050: hsc2hsWrapper needs to be generated at install time · Issues · Glasgow Haskell Compiler / GHC · GitLab

5 Likes

For what it’s worth, ~/.ghcup/tmp is empty:

Janes-iMac:~ mignon$ ls -al ~/.ghcup/tmp
total 0
drwxr-xr-x   2 mignon  staff   68 Oct  3 02:04 .
drwxr-xr-x  13 mignon  staff  442 Oct  2 22:03 ..
Janes-iMac:~ mignon$

and there is no config.log anywhere under ~/.ghcup

Janes-iMac:~ mignon$ find .ghcup -name "*.log"
.ghcup/logs/ghcup.log
Janes-iMac:~ mignon$

But anyway, I have a solution that works for me for now.

This will keep all temporary files:

ghcup --keep=always install ghc

GHCup log dir is ~/.ghcup/logs.

2 Likes

Could you maybe share the solution/work-around you’ve found? I’m curious.

I just opened up the file ~/.ghcup/ghc/9.4.7/bin/hsc2hs-ghc-9.4.7 in Emacs, and changed the line:

HSC2HS_EXTRA="--cflag=--target=x86_64-apple-darwin --lflag=--target=x86_64-apple-darwin --lflag=-Wl,-no_fixup_chains"

to:

HSC2HS_EXTRA="--cflag=--target=x86_64-apple-darwin --lflag=--target=x86_64-apple-darwin"
1 Like

Similar error with macos 10.15.7 using ghc-9.4.7. The compilation fell over on the clock package with:

Configuring library for clock-0.8.4..
Preprocessing library for clock-0.8.4..
linking dist/build/System/Clock_hsc_make.o failed (exit code 1)
rsp file was: "dist/build/System/hsc2hscall87685-2.rsp"
command was: /usr/bin/gcc dist/build/System/Clock_hsc_make.o dist/build/System/Clock_hsc_utils.o -o dist/build/System/Clock_hsc_make --target=x86_64-apple-darwin -Wl,-no_fixup_chains --target=x86_64-apple-darwin -L/Users/admin/.ghcup/ghc/9.4.7/lib/ghc-9.4.7/lib/../lib/x86_64-osx-ghc-9.4.7/base-4.17.2.0 -liconv -L/Users/admin/.ghcup/ghc/9.4.7/lib/ghc-9.4.7/lib/../lib/x86_64-osx-ghc-9.4.7/ghc-bignum-1.3 -L/Users/admin/.ghcup/ghc/9.4.7/lib/ghc-9.4.7/lib/../lib/x86_64-osx-ghc-9.4.7/ghc-prim-0.9.1 -L/Users/admin/.ghcup/ghc/9.4.7/lib/ghc-9.4.7/lib/../lib/x86_64-osx-ghc-9.4.7/rts-1.0.2 -L/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib -lm -ldl -lffi
error: ld: unknown option: -no_fixup_chains
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Upgraded to ghc-9.6.2 and got a successful build.

1 Like

That is quite mysterious that it works on 9.6.2… in fact a bit worrying that it does.

What is the contents of the hsc2hs wrapper script that @ppelleti was describing editing?

Full contents:

#!/bin/sh
exedir="/Users/tonyday/.ghcup/ghc/9.6.2/lib/ghc-9.6.2/bin"
exeprog="./hsc2hs-ghc-9.6.2"
executablename="/Users/tonyday/.ghcup/ghc/9.6.2/lib/ghc-9.6.2/bin/./hsc2hs-ghc-9.6.2"
bindir="/Users/tonyday/.ghcup/ghc/9.6.2/bin"
libdir="/Users/tonyday/.ghcup/ghc/9.6.2/lib/ghc-9.6.2/lib"
docdir="/Users/tonyday/.ghcup/ghc/9.6.2/share/doc/ghc-9.6.2"
includedir="/Users/tonyday/.ghcup/ghc/9.6.2/include"

HSC2HS_EXTRA="--cflag=--target=x86_64-apple-darwin --lflag=--target=x86_64-apple-darwin"
tflag="--template=$libdir/template-hsc.h"
Iflag="-I$includedir/"

read_response() {
    response_file=$1
    if [ -f "$response_file" ]; then
        while read -r arg; do
            case "$arg" in
                -t*)          tflag=;;
                --template=*) tflag=;;
                @*)           read_response "${arg#"@"}" ;;
                --)           break;;
            esac
        done < "$response_file"
    fi
}

for arg do
    case "$arg" in
        -t*)          tflag=;;
        --template=*) tflag=;;
        @*)           read_response "${arg#"@"}" ;;
        --)           break;;
    esac
done

exec "$executablename" ${tflag:+"$tflag"} $HSC2HS_EXTRA ${1+"$@"} "$Iflag"

Similar issue when building GHC via Homebrew on macOS 10.15.7. Editing hsc2hs-ghc-9.4.7, as suggested by @ppelletiin, in the build temp folder (private/tmp/ghc-20231025-34404-m1k5l2/ghc-9.6.2/binary/bin/hsc2hs-ghc-9.4.7) as soon as it was created resolved the issue.