gentooLTO icon indicating copy to clipboard operation
gentooLTO copied to clipboard

Overriding strip-flags in sys-devel/binutils-2.36.1-r1 leads to linker issue when upgrading compiler from GCC10 to GCC11

Open parona-source opened this issue 4 years ago • 5 comments

sys-devel/binutils-2.36.1-r1 tries to link against the installed sys-devel/binutils-2.36.1-r1's static library and fails due differing LTO versions.

This error would come up normally when your compiler flags include -flto and you use sys-config/ltoize overrides. And then when you have built sys-devel/binutils-2.36.1-r1 with GCC10 and then upgrade to GCC11 and rebuild sys-devel/binutils-2.36.1-r1 it will lead to this issue. One example of this bug is mentioned here https://github.com/InBetweenNames/gentooLTO/issues/541.

The issue from my understanding is that sys-config/ltoize should either respect the ebuilds strip-flags (and therefore sys-devel/binutils should be a flag-o-matic.conf exemption) or that sys-devel/binutils has an underlying issue with including the final install path in linker search and therefore linking against libraries there rather than the just built libraries in the temporary install image (noticed this behavior in 2.35.2 as well, so its not new to this version).

Excerpt from the sys-devel/binutils ebuild:

# Keep things sane
strip-flags

A quick way to reproduce this error relatively safely is to be on a different sys-devel/binutils version and then:

  1. Override strip-flags manually in the ebuild or let sys-config/ltoize do it for you.
  2. Build and install (but do not merge) sys-devel/binutils-2.36.1-r1 with GCC10 and -flto=auto compiler flag
  3. Copy over libiberty.a from the portage sandboxes install image to where it would be normally installed /usr/lib64/binutils/x86_64-pc-linux-gnu/2.36.1/libibery.a.
  4. Try to build and install (but do not merge) sys-devel/binutils-2.36.1-r1 with GCC11 and -flto=auto compiler flag

This will lead to this error:

make[4]: Entering directory '/var/tmp/portage/sys-devel/binutils-2.36.1-r1/work/build/opcodes'
make[4]: Nothing to be done for 'install-exec-am'.
 /bin/mkdir -p '/var/tmp/portage/sys-devel/binutils-2.36.1-r1/image/usr/lib64/binutils/x86_64-pc-linux-gnu/2.36.1/include'
 /usr/lib/portage/python3.9/ebuild-helpers/xattr/install -c -m 644 /var/tmp/portage/sys-devel/binutils-2.36.1-r1/work/binutils-2.36.1/opcodes/../include/dis-asm.h '/var/tmp/portage/sys-devel/binutils-2.36.1-r1/image/usr/lib64/binutils/x86_64-pc-linux-gnu/2.36.1/include'
 /bin/mkdir -p '/var/tmp/portage/sys-devel/binutils-2.36.1-r1/image/usr/lib64/binutils/x86_64-pc-linux-gnu/2.36.1'
 /bin/sh ./libtool   --mode=install /usr/lib/portage/python3.9/ebuild-helpers/xattr/install -c   libopcodes.la '/var/tmp/portage/sys-devel/binutils-2.36.1-r1/image/usr/lib64/binutils/x86_64-pc-linux-gnu/2.36.1'
libtool: install: warning: relinking `libopcodes.la'
libtool: install: (cd /var/tmp/portage/sys-devel/binutils-2.36.1-r1/work/build/opcodes; /bin/sh /var/tmp/portage/sys-devel/binutils-2.36.1-r1/work/build/opcodes/libtool  --tag CC --mode=relink gcc-11.0.1 -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow -Wstack-usage=262144 -flto=auto -release 2.36.1.gentoo-sys-devel-binutils-st -Wl,-O1 -Wl,--as-needed -o libopcodes.la -rpath /usr/lib64/binutils/x86_64-pc-linux-gnu/2.36.1 dis-buf.lo disassemble.lo dis-init.lo i386-dis.lo i386-opc.lo ../bfd/libbfd.la -L/var/tmp/portage/sys-devel/binutils-2.36.1-r1/work/build/opcodes/../libiberty/pic -liberty -Wl,-lc,--as-needed,-lm,--no-as-needed -inst-prefix-dir /var/tmp/portage/sys-devel/binutils-2.36.1-r1/image)
libtool: relink: gcc-11.0.1 -shared  -fPIC -DPIC  .libs/libctf_la-ctf-archive.o .libs/libctf_la-ctf-dump.o .libs/libctf_la-ctf-create.o .libs/libctf_la-ctf-decl.o .libs/libctf_la-ctf-error.o .libs/libctf_la-ctf-hash.o .libs/libctf_la-ctf-labels.o .libs/libctf_la-ctf-dedup.o .libs/libctf_la-ctf-link.o .libs/libctf_la-ctf-lookup.o .libs/libctf_la-ctf-open.o .libs/libctf_la-ctf-sha1.o .libs/libctf_la-ctf-string.o .libs/libctf_la-ctf-subr.o .libs/libctf_la-ctf-types.o .libs/libctf_la-ctf-util.o .libs/libctf_la-ctf-open-bfd.o   -Wl,-rpath -Wl,/usr/lib64/binutils/x86_64-pc-linux-gnu/2.36.1 -Wl,--as-needed -L/var/tmp/portage/sys-devel/binutils-2.36.1-r1/image/usr/lib64/binutils/x86_64-pc-linux-gnu/2.36.1 -L/usr/lib64/binutils/x86_64-pc-linux-gnu/2.36.1 -lbfd -L/var/tmp/portage/sys-devel/binutils-2.36.1-r1/work/build/bfd/../libiberty/pic -L/var/tmp/portage/sys-devel/binutils-2.36.1-r1/work/build/libctf/../libiberty/pic -liberty -lz -ldl  -Wl,--version-script=/var/tmp/portage/sys-devel/binutils-2.36.1-r1/work/binutils-2.36.1/libctf/libctf.ver -Wl,-O1   -Wl,-soname -Wl,libctf.so.0 -o .libs/libctf.so.0.0.0
libtool: relink: gcc-11.0.1 -shared  -fPIC -DPIC  .libs/dis-buf.o .libs/disassemble.o .libs/dis-init.o .libs/i386-dis.o .libs/i386-opc.o   -Wl,-rpath -Wl,/usr/lib64/binutils/x86_64-pc-linux-gnu/2.36.1 -Wl,--as-needed -L/var/tmp/portage/sys-devel/binutils-2.36.1-r1/image/usr/lib64/binutils/x86_64-pc-linux-gnu/2.36.1 -L/usr/lib64/binutils/x86_64-pc-linux-gnu/2.36.1 -lbfd -L/var/tmp/portage/sys-devel/binutils-2.36.1-r1/work/build/bfd/../libiberty/pic -lz -ldl -L/var/tmp/portage/sys-devel/binutils-2.36.1-r1/work/build/opcodes/../libiberty/pic -liberty  -Wl,-O1 -Wl,-lc -Wl,--as-needed -Wl,-lm -Wl,--no-as-needed   -Wl,-soname -Wl,libopcodes-2.36.1.gentoo-sys-devel-binutils-st.so -o .libs/libopcodes-2.36.1.gentoo-sys-devel-binutils-st.so
lto1: fatal error: bytecode stream in file '/usr/lib64/binutils/x86_64-pc-linux-gnu/2.36.1/libiberty.a' generated with LTO version 9.0 instead of the expected 11.0
compilation terminated.
lto-wrapper: fatal error: gcc-11.0.1 returned 1 exit status
compilation terminated.
/usr/lib/gcc/x86_64-pc-linux-gnu/11.0.1/../../../../x86_64-pc-linux-gnu/bin/ld: error: lto-wrapper failed
collect2: error: ld returned 1 exit status
libtool: install: error: relink `libctf.la' with the above command before installing it
make[3]: *** [Makefile:552: install-libLTLIBRARIES] Error 1
make[3]: Leaving directory '/var/tmp/portage/sys-devel/binutils-2.36.1-r1/work/build/libctf'
make[2]: *** [Makefile:1206: install-am] Error 2
make[2]: Leaving directory '/var/tmp/portage/sys-devel/binutils-2.36.1-r1/work/build/libctf'
make[1]: *** [Makefile:10515: install-libctf] Error 2
make[1]: *** Waiting for unfinished jobs....
lto1: fatal error: bytecode stream in file '/usr/lib64/binutils/x86_64-pc-linux-gnu/2.36.1/libiberty.a' generated with LTO version 9.0 instead of the expected 11.0
compilation terminated.

build.log

parona-source avatar May 04 '21 13:05 parona-source

build.log I confirm that I ran across this very same error. I solved by running

mv /usr/lib64/binutils/x86_64-pc-linux-gnu/2.36.1/libibery.a /home

and then trying to compile binutils again.

My GentooLTO-related changes to /etc/portage/make.conf:

CMAKE_MAKEFILE_GENERATOR=ninja CFLAGS="-march=native -O3 ${SAFEST_FAST_MATH} ${GRAPHITE} ${DEVIRTLTO} ${IPAPTA} ${SEMINTERPOS} ${FLTO} -fuse-linker-plugin -pipe" PORTDIR="/var/db/repos/gentoo" DISTDIR="/var/cache/distfiles" PKGDIR="/var/cache/binpkgs" PORTAGE_TMPDIR="/tmp"

I changed TMPDIR to mount it on RAM.

King-Mucus avatar May 04 '21 22:05 King-Mucus

Just ran into this, above solution worked.

zkvsky avatar Jul 04 '21 09:07 zkvsky

I also had a similar issue with rebuilding binutils-2.37_p1 after upgrading to GCC11. Thank you for the workaround to move libiberty.a, it fixed the issue.

lto1: fatal error: bytecode stream in file '/usr/lib64/binutils/x86_64-pc-linux-gnu/2.37_p1/libiberty.a' generated with LTO version 9.3 instead of the expected 11.0

Emerged with GCC 10 (Thought it was odd that the fatal error message said 9.3)

$ readelf -p .comment /usr/lib64/binutils/x86_64-pc-linux-gnu/2.37_p1/libiberty.a

    String dump of section '.comment':
      [     1]  GCC: (Gentoo 10.3.0 p1) 10.3.0 

Emerged with GCC 11 after moving libiberty.a

$ readelf -p .comment /usr/lib64/binutils/x86_64-pc-linux-gnu/2.37_p1/libiberty.a

    String dump of section '.comment':
      [     1]  GCC: (Gentoo 11.2.0 p1) 11.2.0

Instead of overriding strip-flags, I use its included configure option to enable PGO to enable LTO. Figured that'd have someone's interest in testing.

/etc/portage/env/binutils.conf

EXTRA_ECONF="--enable-pgo-build=lto"

jiblime avatar Oct 01 '21 13:10 jiblime

Ran into this again with binutils-2.37_p1, why is this happening?

zkvsky avatar Nov 19 '21 19:11 zkvsky

Ran into this again with binutils-2.37_p1, why is this happening?

I ended up quickpkg'ing it from a stage 3 tarball, was a nice experience, no dependencies needed.

Maybe it has to do with USE multitarget and libiberty being static?

https://gcc.gnu.org/bugzilla//show_bug.cgi?id=41526


A possible workaround?

http://download.nust.na/pub3/solaris/sunfreeware/pub/freeware/forsunsites/libiberty.html

ebuild binutils-2.37_p1-r1.ebuild install
cd /var/tmp/portage/sys-devel/binutils-2.37_p1-r1/work/build/libiberty
ld.bfd -G -Bdynamic pic/*.o -o libiberty.so
mv libiberty.so /var/tmp/portage/sys-devel/binutils-2.37_p1-r1/image/usr/lib64
rm /var/tmp/portage/sys-devel/binutils-2.37_p1-r1/image/usr/lib64/binutils/x86_64-pc-linux-gnu/2.37_p1/libiberty.a
cd $OLDPWD
ebuild binutils-2.37_p1-r1.ebuild merge

Above solution goes against why it's static in the first place.

So far, I've found something that may help:

https://stackoverflow.com/questions/25878407/how-can-i-use-lto-with-static-libraries

https://hubicka.blogspot.com/2014/04/linktime-optimization-in-gcc-2-firefox.html

Although I wasn't able to confirm the above solution worked, or if it could.

If someone can test if this works (it didn't for me, but I might as well make an update): In the source libiberty/ directory prior to the compile phase, change AR_FLAGS=rc to rcs in Makefile.in, set $AR to gcc-ar and -ffat-lto-objects to your env.

What's certain is adding only -ffat-lto-objects from *FLAGS does not work. Does EXTRA_ECONF="--enable-pgo-build=lto" also break the build? It adds fat objects to be able to be read. I think.

Some notes:

It would be ideal if there was a way to detect $CC and apply llvm-ar or gcc-ar, depending on the compiler used. When the variables for $AR and such aren't set, the binutils versions are used, and they are not good AFAICT.

$ readlink -f /usr/bin/ar # binutils defaults to this, although the configure file *does* check for liblto_plugin.so
/usr/x86_64-pc-linux-gnu/binutils-bin/2.37_p1/ar

$ readlink -f /usr/bin/gcc-ar
/usr/x86_64-pc-linux-gnu/gcc-bin/11.2.1/gcc-ar

$ command -v llvm-ar
/usr/lib/llvm/13/bin/llvm-ar

$ man ar
...
s   Add an index to the archive, or update it if it already exists.  
     Note this command is an exception to the rule that there can only be one command letter, 
     as it is possible to use it as either a command or a modifier.  
     In either case it does the same thing.

$ man ranlib
...
The GNU ranlib program is another form of GNU ar; running ranlib is completely equivalent to executing ar -s

jiblime avatar Dec 30 '21 00:12 jiblime