InBetweenNames / gentooLTO

A Gentoo Portage configuration for building with -O3, Graphite, and LTO optimizations
GNU General Public License v2.0
571 stars 96 forks source link

Best way to support fat lto objects? #520

Open jonesmz opened 4 years ago

jonesmz commented 4 years ago

I use my Gentoo system for development of C++ application.

Adopting the gentooLTO portage overlay has resulted in static libraries that can't be compiled against if you build without LTO. E.g. for a debug build or something.

On clang 9, I get errors like "plugin needed to handle lto object",

and on GCC 9 I get errors like: "Internal compiler error in add_symbol to partition_1 at lto/lto-partition.c".

I can compile normally if I build my C++ application with LTO turned on though.

Currently my plan is to add "-ffat-lto-objects" to my make.conf and rebuild.

Is there a better way?

Jannik2099 commented 4 years ago

That clang error is not fat-lto related. You can use clang with ld, where you need a linker plugin, or use it with lld, where you don't. The message should not pop up with -fuse-ld=lld in LDFLAGS Note that clang with lld doesn't use -ffat-lto-objects, but rather -flto=full

What you're describing usually shouldn't be happening since we compile a fair bit of software without lto. I'm an absolute noob when it comes to this though.

Yes, compiling with fat lto globally would solve your issue, but I'm thinking there must be another way

InBetweenNames commented 4 years ago

Yeah, static libraries are hard to work with when you have different compilers -- when you add LTO into the mix, it's impossible. There's no ABI guarantee between compilers to do this. GIMPLE is just fundamentally different from the LLVM IR, and both are embedded in static archives with LTO. As you have noted, -ffat-lto-objects will let you work around this to a degree (it will probably work, but I've never actually tried linking a GCC produced static archive against an LLVM one, or vice versa).

With Clang, see about the llvmgold plugin offered in Portage. It might help. Clang is designed to use lld as the linker these days, with the ld.gold stuff not being used by default anymore. Of course, setting your system linker to lld will prevent you from using LTO with GCC, as lld doesn't support linker plugins (despite what the command line options say).

Regarding the GCC errors, are you mixing different GCC versions on your system? And also, have you run lto-rebuild -r to ensure your static libraries are all built with the latest GCC?

jonesmz commented 4 years ago

it will probably work, but I've never actually tried linking a GCC produced static archive against an LLVM one, or vice versa.

This has worked fine for me since at least gcc 7 / clang 7, on the same Gentoo system. I'm sure it's possible for it to screw up, but I only use Clang builds for purposes of static analysis and debugging. The release builds that get shipped are with GCC proper.

With Clang, see about the llvmgold plugin offered in Portage. It might help.

Sure, will try.

Regarding the GCC errors, are you mixing different GCC versions on your system?

No, everything is GCC 9.

And also, have you run lto-rebuild -r to ensure your static libraries are all built with the latest GCC?

emerge -1 --ignore-default-opts --jobs --keep-going -e @world after applying the gentooLTO overlay.

jonesmz commented 4 years ago

Reporting back, -ffat-lto-objects does fix the clang problems.

However, I'm still unable to compile with GCC 9 when LTO is disabled for the program I'm trying to build, which is really odd.

jiblime commented 4 years ago

Given that you are not using an ebuild that would inherit your flags in make.conf, the program shouldn't be aware of LTO.

What packages are required to build your application? It is possible that those need -ffat-lto-objects and is revealing something broken