I kept thinking we had a proper bug for this, but we didn't AFAIK. I shorehorned it into bug 866422 for a while. With static libraries and -flto, bitcode is included in the static archive (.a) and then when an application links using them later on, they're glued together and treated as the whole program. It allows more optimisation, but it's very brittle. The archives aren't compatible across GCC versions, even minor versions (depends on if a commit which changes certain interals gets backported). The interface version isn't always updated for such commits which causes a segfault/ICE instead of a nicer error for mismatched versions. We don't generally bother with static libraries and we can take the loss on optimising them, especially given it also often blows up memory usage with LTO too.
Fedora has two approaches: 1) For GCC, it checks that -ffat-lto-objects was used (they warn if not - https://fedoraproject.org/wiki/Changes/LTOBuildImprovements), and strips the bitcode from the static libraries using https://src.fedoraproject.org/rpms/redhat-rpm-config/blob/rawhide/f/brp-strip-lto 2) For LLVM, they try to convert the bitcode to ELF (https://src.fedoraproject.org/rpms/redhat-rpm-config/blob/rawhide/f/brp-llvm-compile-lto-elf).
So naively, a paired set of functions? In src_configure: lto-guarantee-fat() { if tc-is-lto; then append-cflags $(test-flags-CC -ffat-lto-objects) append-cxxflags $(test-flags-CXX -ffat-lto-objects) fi } in src_install, manually strip with -R .gnu.lto_* -R .gnu.debuglto_* -N __gnu_lto_v1 Or hook this up to portage's global stripping routine. See bug 920745.
openSUSE does https://en.opensuse.org/openSUSE:LTO#Static_libraries (https://github.com/openSUSE/brp-check-suse/blob/master/brp-15-strip-debug).
(In reply to Eli Schwartz from comment #2) I suppose this isn't that bad... especially given not _that_ many packages even install static libraries. We need to see if we can make the same approach work for LLVM too, ideally. I wouldn't want to have to do two approaches...
I was and potentially am still partial to post-processing static libraries by compiling them (or their contents) with '-x lto'. I haven't experimented with this at all, however, so it is entirely possible that it's not possible for some reason. The reason for me holding on to it is because it'd be less error-prone (maintainers wouldn't have to know ahead of time whether static libraries are being installed) and maybe faster. If someone plays around with this, please consider it.
(In reply to Arsen Arsenović from comment #5) > I was and potentially am still partial to post-processing static libraries > by compiling them (or their contents) with '-x lto'. > [...] > The reason for me holding on to it is because it'd be less error-prone > (maintainers wouldn't have to know ahead of time whether static libraries > are being installed) and maybe faster. I don't think it's less error prone because if we were to do it, it'd have to be in Portage (so PM-specific) and also figure out a way for ebuilds to control it... > > If someone plays around with this, please consider it. But I haven't given up on the idea and I will keep your preference in mind, of course
(In reply to Sam James from comment #6) > (In reply to Arsen Arsenović from comment #5) > > I was and potentially am still partial to post-processing static libraries > > by compiling them (or their contents) with '-x lto'. > > [...] > > > The reason for me holding on to it is because it'd be less error-prone > > (maintainers wouldn't have to know ahead of time whether static libraries > > are being installed) and maybe faster. > > I don't think it's less error prone because if we were to do it, it'd have > to be in Portage (so PM-specific) and also figure out a way for ebuilds to > control it... But the default is, IMO, far better. Packages that fail to build in that way are likely exceptions rather than the rule. But yes, the rest stands.. > > > > If someone plays around with this, please consider it. > > But I haven't given up on the idea and I will keep your preference in mind, > of course Thanks :-)
This came up during the 23.0 profile migration as well. The global USE default now enables zstd, which therefore toggles the gcc IUSE and enables zstd-compressed LTO bytecode. GCC promptly emits an ICE when linking against existing static archives that were built with a GCC that was configured to use zlib instead of zstd. This is a general problem if you rebuild the compiler with changed USE...
find /usr/lib* -name '*.a' | xargs equery belongs | sort -u 38 packages on my system. It is not a pleasant idea when doing a profile migration and --emptytree if you have to build all of those with LTO disabled before migrating, then rebuild them again with LTO to taste.
jakub has also suggested the fat-lto-object approach. maybe we should make a 'dot-a.eclass' for adding + processing installed lto objects and object archives, plus a QA check that detects packages forgetting to use them. this seems PM-independent but still solid enough