Opened 3 years ago

Closed 3 years ago

#9873 closed bug (fixed)

Use CONF_GCC_LINKER_OPTS_STAGE2 only in stage2

Reported by: nomeata Owned by:
Priority: normal Milestone: 7.10.1
Component: Build System Version: 7.9
Keywords: Cc: bgamari
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:


On ARM, we want to make sure that GHC uses the gold linker.

In order to achieve that, we need to get -fuse-ld=gold into SettingsCCompilerLinkFlags in the settings.

This field is filled with only CONF_GCC_LINKER_OPTS_STAGE2. So we want that flag to show up there.

But this variable is used in other places as well. For example, the configuration of tinfo fails:

$ make libraries/terminfo/dist-boot/ 
===--- building phase 0
make -r --no-print-directory -f phase=0 phase_0_builds
libraries/terminfo/ libraries/terminfo/dist-boot/ Datei oder Verzeichnis nicht gefunden
"inplace/bin/ghc-cabal" configure libraries/terminfo dist-boot "" --with-ghc="/usr/bin/ghc" --with-ghc-pkg="/usr/bin/ghc-pkg"  --package-db=/home/jojo/build/haskell/ghc/libraries/bootstrapping.conf --disable-library-for-ghci --enable-library-vanilla --disable-library-profiling --disable-shared --with-hscolour="/usr/bin/HsColour" --configure-option=CFLAGS=" -fno-stack-protector   " --configure-option=LDFLAGS=" -fuse-ld=gold  " --configure-option=CPPFLAGS="   " --gcc-options=" -fno-stack-protector     -fuse-ld=gold  "   --constraint "binary =="   --constraint "Cabal =="   --constraint "hpc =="   --constraint "bin-package-db =="   --constraint "hoopl =="   --constraint "transformers =="   --constraint "terminfo ==" --with-gcc="/usr/bin/gcc" --configure-option=--with-cc="/usr/bin/gcc" --with-ar="/usr/bin/ar" --with-alex="/usr/bin/alex" --with-happy="/usr/bin/happy"
Configuring terminfo-
configure: WARNING: unrecognized options: --with-compiler, --with-gcc
checking for gcc... /usr/bin/gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables... 
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether /usr/bin/gcc accepts -g... yes
checking for /usr/bin/gcc option to accept ISO C89... none needed
checking how to run the C preprocessor... /usr/bin/gcc -E
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking ncurses.h usability... yes
checking ncurses.h presence... yes
checking for ncurses.h... yes
checking for setupterm in -ltinfo... yes
configure: creating ./config.status
config.status: creating terminfo.buildinfo
configure: WARNING: unrecognized options: --with-compiler, --with-gcc
ghc-cabal: Missing dependency on a foreign library:
* Missing C library: tinfo
This problem can usually be solved by installing the system package that
provides this library (you may need the "-dev" version). If the library is
already installed but in a non-standard location then you can use the flags
--extra-include-dirs= and --extra-lib-dirs= to specify where it is.
libraries/terminfo/ recipe for target 'libraries/terminfo/dist-boot/' failed
make[1]: *** [libraries/terminfo/dist-boot/] Error 1
Makefile:71: recipe for target 'libraries/terminfo/dist-boot/' failed
make: *** [libraries/terminfo/dist-boot/] Error 2

The problem (unfortunately, not very visible) is that ghc-cabal calls gcc to test if the C libaries are available. It uses the linker flags that it’s being told to use from the host GHC (here: 7.6.3), which contains the usual:

$ ghc --info |fgrep 'C compiler flags'
 ,("C compiler flags"," -fno-stack-protector  -Wl,--hash-size=31 -Wl,--reduce-memory-overheads")

But to that it adds -fuse-ld-gold because ghc-cabal is gets " --gcc-options=" -fno-stack-protector -fuse-ld=gold " passed.

So the build system should not pass flags from CONF_GCC_LINKER_OPTS_STAGE2 anywhere besides gcc when used *by the stage 2 ghc* during linking.

The chain of variables leading to this can be seen here:

rules/$1_$2_CONFIGURE_OPTS += --configure-option=LDFLAGS="$$($1_$2_CONFIGURE_LDFLAGS)"
rules/$1_$2_CONFIGURE_OPTS += --gcc-options="$$($1_$2_CONFIGURE_CFLAGS) $$($1_$2_CONFIGURE_LDFLAGS)"

I’m currently experimenting with a patch that simply does not use CONF_GCC_LINKER_OPTS_STAGE anywhere besides when defining SettingsCCompilerLinkFlags, but I’m afraid that this might introduce new unwanted behaviour. But since ghc-cabal reads gcc-flags from ghc --info, maybe that channel of information is sufficient.

Attachments (1)

saner-linker-opt-handling.patch (3.8 KB) - added by nomeata 3 years ago.

Download all attachments as: .zip

Change History (13)

Changed 3 years ago by nomeata

comment:1 Changed 3 years ago by nomeata

This is the patch I use in the Debian package for now. Maybe it is good enough already?

comment:2 Changed 3 years ago by erikd

I just tried building git head with this patch applied. The build machine has Debian testing (armhf) with from binutils version Are these versions correct?

The build failed the first time it tried to run the inplace/bin/ghc-stage2 binary.

Last edited 3 years ago by erikd (previous) (diff)

comment:3 Changed 3 years ago by nomeata

Did you also apply the patch that actually makes it use gold?

Index: ghc-
--- ghc-  2014-12-08 18:49:28.207171714+0100
+++ ghc-       2014-12-08 19:03:06.815522917+0100
@@ -553,6 +553,10 @@
         $3="$$3 -D_HPUX_SOURCE"
         $5="$$5 -D_HPUX_SOURCE"
+    arm*)
+        # On arm, link using gold
+        $3="$$3 -fuse-ld=gold"
+        ;;
     # If gcc knows about the stack protector, turn it off.

And how does it fail? Did it run dll-split successfully? Might be a different issue. You should talk to gamari about it.

comment:4 Changed 3 years ago by erikd

Nope missed that bit. Retrying now.

comment:5 Changed 3 years ago by erikd

It fails the first time it tries to run an executable generated by the stage1 compiler.

During some earlier testing I had disabled compiling the dyn way, so the first failure was with the inplace/bin/ghc-stage2 binary. If I re-enable the dyn way, the first failure is when the build tries to run inplace/bin/dll-split.

comment:6 Changed 3 years ago by nomeata

Without a build logs, it’s hard to help here. Any please open a new ticket or discuss it on ghc-dev, this on is about a deficiency in the build system.

comment:7 Changed 3 years ago by erikd

Mine was a separate problem so I raised ticket #9920.

comment:8 Changed 3 years ago by thomie

Status: newpatch

comment:9 Changed 3 years ago by Erik de Castro Lopo <erikd@…>

In 71fcc4c096ec0b575522e4c2d0104ef7a71a13c5/ghc:

Use the gold linker for linux/ARM and android/ARM targets.

Fixes #8976 and #9873 by making use of the Binutils
linker explicit whenever the target is linux/ARM or android/ARM.
This does not affect iOS where Apple provides its own linker.

In order to achieve this, we need to add `-fuse-ld=gold` to
the SettingsCCompilerLinkFlags setting and set
SettingsLdCommand to `` (or `${target}` when
cross-compiling). In addition, simplifying the use of

This patch was tested by ensuring that the following worked
as expected:

  * Native builds on linux/x86_64 (nothing changed).
  * Native builds on linux/arm (and uses the gold linker).
  * Linux to linux/arm cross compiles (and uses the cross
    gold linker).

Contributions by Ben Gamari, Joachim Breitner and Reid Barton.

Reviewers: nomeata, bgamari, austin, rwbarton

Subscribers: thomie

Differential Revision:

GHC Trac Issues: #8976 #9873

comment:10 Changed 3 years ago by erikd

Resolution: fixed
Status: patchclosed

comment:11 Changed 3 years ago by erikd

Status: closedmerge

comment:12 Changed 3 years ago by thoughtpolice

Milestone: 7.10.1
Status: mergeclosed
Note: See TracTickets for help on using tickets.