Bug 84995 - Documentation gcc-ar and gcc-ranlib vs {libdir}/bfd-plugins
Summary: Documentation gcc-ar and gcc-ranlib vs {libdir}/bfd-plugins
Status: REOPENED
Alias: None
Product: gcc
Classification: Unclassified
Component: lto (show other bugs)
Version: 7.3.1
: P3 normal
Target Milestone: 8.0
Assignee: Not yet assigned to anyone
URL:
Keywords: documentation
Depends on:
Blocks:
 
Reported: 2018-03-20 16:22 UTC by Дилян Палаузов
Modified: 2019-02-03 10:00 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2018-03-21 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Дилян Палаузов 2018-03-20 16:22:16 UTC
While ar, ranlib and nm work with LTO, if the plugin is installed in {libdir}/bfd-plugin, the gcc manual (Optimizing options) recommends the use of gcc-ar and gcc-ranlib.

Why doesn't the manual recommend installing instead the plugin under /bfd-plugin?  

Providing that both gcc and clang offer LTO and provide linker plugins, none of them installs by default the plugins under {libdir}/bfd-plugins, gcc recommends the usage of gcc-ar/gcc-ranlib, clang installs instead clang-ar/clang-ranlib, how are ./configure scripts supposed to be written in portable way to enable LTO compilation?

If several gcc versions are installed on a system and hence /usr/local/libexec/gcc/x86_64-pc-linux-gnu/7.3.1/liblto_plugin.so.0.0.0 and /usr/local/libexec/gcc/x86_64-pc-linux-gnu/6.4.1/liblto_plugin.so.0.0.0 co-exist, will gcc-ar always use /gcc/x86_64-pc-linux-gnu/6.4.1/liblto_plugin.so.0.0.0, if the code is compiled with x86_64-pc-linux-gnu-gcc-6.4.1?
Comment 1 Richard Biener 2018-03-21 08:30:33 UTC
Suggesting the plugin install into the auto-load path is reasonable.  Saying a few words of how that's supposed to work with different versions from different GCC would also be required.
Comment 2 Дилян Палаузов 2018-03-21 18:47:52 UTC
gcc-ar always uses the latest plugin:

$ cat t.c
  #include <stdio.h>
  int main() {
    printf("Z\n");
  }

$ x86_64-pc-linux-gnu-gcc-6.4.1  -flto t.c -C -o t.o
$ strace gcc-ar rc t.a t.o   prints:
stat("/usr/local/lib/gcc/x86_64-pc-linux-gnu/7.3.1/../../../../x86_64-pc-linux-gnu/bin/liblto_plugin.so", 0x7fff52b52030) = -1 ENOENT (No such file or directory)
stat("/usr/local/libexec/gcc/x86_64-pc-linux-gnu/7.3.1/liblto_plugin.so", {st_mode=S_IFREG|0755, st_size=95328, ...}) = 0
access("/usr/local/libexec/gcc/x86_64-pc-linux-gnu/7.3.1/liblto_plugin.so", R_OK) = 0

$ strace gcc-nm t.a    prints:

stat("/usr/local/lib/gcc/x86_64-pc-linux-gnu/7.3.1/../../../../x86_64-pc-linux-gnu/bin/liblto_plugin.so", 0x7ffd682c9970) = -1 ENOENT (N
o such file or directory)
stat("/usr/local/libexec/gcc/x86_64-pc-linux-gnu/7.3.1/liblto_plugin.so", {st_mode=S_IFREG|0755, st_size=95328, ...}) = 0
access("/usr/local/libexec/gcc/x86_64-pc-linux-gnu/7.3.1/liblto_plugin.so", R_OK) = 0

it seems that the last installed liblto_plugin.so version is used, even if old gcc did the object file.
Comment 3 Martin Liška 2018-03-27 08:47:46 UTC
Let me document the behavior.
Comment 4 Martin Liška 2018-03-28 16:42:02 UTC
Working on that I've just noticed Richi that gcc/doc/invoke.texi contains:

  9485  Link-time optimization does not work well with generation of debugging
  9486  information.  Combining @option{-flto} with
  9487  @option{-g} is currently experimental and expected to produce unexpected
  9488  results.

Now having early-lto debug info, would you change it?
Comment 5 Martin Liška 2018-03-29 13:02:59 UTC
Author: marxin
Date: Thu Mar 29 13:02:23 2018
New Revision: 258953

URL: https://gcc.gnu.org/viewcvs?rev=258953&root=gcc&view=rev
Log:
Documentation tweaks.

2018-03-29  Martin Liska  <mliska@suse.cz>

        PR lto/84995.
        * doc/invoke.texi: Document how LTO works with debug info.
        Describe auto-load support of binutils.  Mention 'x86-64'
        as valid option value of -march option.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/doc/invoke.texi
Comment 6 Martin Liška 2018-03-29 13:05:27 UTC
Fixed, no ambition to backport that.
Comment 7 Дилян Палаузов 2019-01-10 15:00:37 UTC
Why doesn’t GCC “make install” put the linker plugin under $libdir/bfd-plugins and how are program ./configure’s supposed to be written in a way, that LTO works with both Clang and GCC?
Comment 8 Martin Liška 2019-01-11 11:52:36 UTC
(In reply to Дилян Палаузов from comment #7)
> Why doesn’t GCC “make install” put the linker plugin under
> $libdir/bfd-plugins and how are program ./configure’s supposed to be written
> in a way, that LTO works with both Clang and GCC?

It's a location which is automatically used by nm,ar,ranlib,ld when searching for plugins. Should work automatically when using clang, then object files will use proper llvm LTO plugin.
Comment 9 Дилян Палаузов 2019-01-11 12:05:42 UTC
Yes, $(libdir)/bfd-plugins is a location automatically scanned by ar/nm/ranlib.

The question is, why GCC’s “make install” does not put there its linker plugin.

As long as nobody installs the linker plugins under $(libdir)/bfd-plugins, how are program ./configure’s supposed to be written in a way, that LTO works with both Clang and GCC?
Comment 10 Martin Liška 2019-01-14 16:04:46 UTC
(In reply to Дилян Палаузов from comment #9)
> Yes, $(libdir)/bfd-plugins is a location automatically scanned by
> ar/nm/ranlib.
> 
> The question is, why GCC’s “make install” does not put there its linker
> plugin.

Looks at what we do in SUSE, you can have multiple packages of gcc (like gcc7, gcc8). But there's a packages 'gcc' that's responsible for creation of the following symlink:

/usr/lib/bfd-plugins/liblto_plugin.so.0.0.0 ->
/usr/lib64/gcc/x86_64-suse-linux/8/liblto_plugin.so.0.0.0

so then nm,ranlib,.. is relying on the 'system' compiler.

> 
> As long as nobody installs the linker plugins under $(libdir)/bfd-plugins,
> how are program ./configure’s supposed to be written in a way, that LTO
> works with both Clang and GCC?

Richi can you please elaborate on that?
Comment 11 Дилян Палаузов 2019-01-14 23:54:32 UTC
According to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70345#c4 it does not matter whether liblto_plugin.so.0.0.0 from GCC7 or 8 is installed under $libdir/bfd-plugins: both work for both compiler versions.
Comment 12 Richard Biener 2019-01-15 08:34:44 UTC
In theory liblto_plugin is backwards compatible (newer versions work with older compilers).  Still a make install cannot simply replace the installed version since it may end up replacing a newer one.  So it is up to the system integrator to install it.

It might have been "easier" to bundle liblto_plugin with the BFD linker itself
since it is as much dependent on the BFD plugin interface evolution as the
compiler LTO symtab format.

I agree that documenting bfd-plugin as install location (if you have sysadmin
rights) would be an improvement (as well as the compatibility promise).

But I don't know of any testing of that compatibility guarantee...
Comment 13 Дилян Палаузов 2019-01-15 09:05:19 UTC
At https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70345#c4 is written that “Right now the plugin from any gcc can be used with any gcc.”  This is not the same as the last comment.  Please clarify again, if any gcc plugin can be used with any gcc.

If several plugins can be installed simultaneously and the first one that claims the .o file wins, why aren’t plugins for both GCC7 and GCC8 installed at the same time?  Just for gcc8 files, the gcc7 plugin will not claim the responsibility.
Comment 14 Richard Biener 2019-01-15 09:31:18 UTC
(In reply to Дилян Палаузов from comment #13)
> At https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70345#c4 is written that
> “Right now the plugin from any gcc can be used with any gcc.”  This is not
> the same as the last comment.  Please clarify again, if any gcc plugin can
> be used with any gcc.

Well, liblto_plugin.so is only half of the story.  Yes, using any version
will probably "work" but you might get better experience with using a newer
version (though that newer version might present older GCC with resolution
files they do not understand).

> If several plugins can be installed simultaneously and the first one that
> claims the .o file wins, why aren’t plugins for both GCC7 and GCC8 installed
> at the same time?  Just for gcc8 files, the gcc7 plugin will not claim the
> responsibility.

It doesn't work that way since any liblto_plugin.so version will accept
any GCC LTO files.  It is the lto-wrapper binary that is found to the
one matching the GCC driver version used to invocate the link that
ultimately determines your luck - here strict version matching is required.
Thus LTO linking objects from mixed GCC version is doomed to fail
fatally.

Note plugin auto-loading will only work reliably for ar/nm/ranlib because
of this and indeed for those the version of the plugin doesn't really matter.
Comment 15 Дилян Палаузов 2019-01-15 10:07:10 UTC
Why isn’t liblto_plugin.so tweaked to claim only the GCC LTO files, it can handle?  E.g. liblto_plugin.so from GCC7 does not claim files for GCC 8 LTO?

I do not get the conclusion here:
 * liblto_plugin.so from $libdir/bfd-plugins is only magially called by ar/nm/ranlib and there the version number does not matter;
 * in case where liblto_plugin.so is not called by ar/nm/ranlib the version number matters, but no auto-loading happens, so installing it under $libdir/bfd-plugins is irrelevant

So when will it be problematic to do auto loading by ar/nm/ranlib and when can installing the plugin under $libdir/bfd-plugins create problems?
Comment 16 Jan Hubicka 2019-01-15 10:50:41 UTC
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84995
> 
> Richard Biener <rguenth at gcc dot gnu.org> changed:
> 
>            What    |Removed                     |Added
> ----------------------------------------------------------------------------
>                  CC|                            |hubicka at gcc dot gnu.org
> 
> --- Comment #14 from Richard Biener <rguenth at gcc dot gnu.org> ---
> (In reply to Дилян Палаузов from comment #13)
> > At https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70345#c4 is written that
> > “Right now the plugin from any gcc can be used with any gcc.”  This is not
> > the same as the last comment.  Please clarify again, if any gcc plugin can
> > be used with any gcc.
> 
> Well, liblto_plugin.so is only half of the story.  Yes, using any version
> will probably "work" but you might get better experience with using a newer
> version (though that newer version might present older GCC with resolution
> files they do not understand).

I think we only extended resolution file for new resolution types passed
by newer linkers, so it should be backward compatible to original
implementation. Notable changes was made to pass -flinker-output.

Both however matters only for the cases where linker is invoked from gcc
command, not for ar/ranlib/nm.

We may want to update symbol table eventually but I do not think it
would be big deal to keep plugin understand old format becuse it is
simple.
> 
> > If several plugins can be installed simultaneously and the first one that
> > claims the .o file wins, why aren’t plugins for both GCC7 and GCC8 installed
> > at the same time?  Just for gcc8 files, the gcc7 plugin will not claim the
> > responsibility.
> 
> It doesn't work that way since any liblto_plugin.so version will accept
> any GCC LTO files.  It is the lto-wrapper binary that is found to the
> one matching the GCC driver version used to invocate the link that
> ultimately determines your luck - here strict version matching is required.
> Thus LTO linking objects from mixed GCC version is doomed to fail
> fatally.
> 
> Note plugin auto-loading will only work reliably for ar/nm/ranlib because
> of this and indeed for those the version of the plugin doesn't really matter.

Plugin interface should be good enough to allow LTO optimizing one
binary with multiple compilers (multiple versions of GCC or GCC+LLVM
combination) where obviously no cross-module optimization between
compilers will happen but still each compiler will get acurate
resolution data that will let it to optimize well within the portion of
binary it understands.

We are missing way to specify multiple plugins to linker and some other
supporting bits I believe.

Honza
Comment 17 Richard Biener 2019-01-15 11:16:03 UTC
(In reply to Jan Hubicka from comment #16)
> 
> Plugin interface should be good enough to allow LTO optimizing one
> binary with multiple compilers (multiple versions of GCC or GCC+LLVM
> combination) where obviously no cross-module optimization between
> compilers will happen but still each compiler will get acurate
> resolution data that will let it to optimize well within the portion of
> binary it understands.
> 
> We are missing way to specify multiple plugins to linker and some other
> supporting bits I believe.

Yes, the main issue is how we find lto-wrapper (COLLECT_GCC*
environment) and that lto-wrapper does _not_ work across GCC versions.

I guess lto-plugin would ideally partition the set of files according
to the LTO byte-code version and we'd have a way to lookup gcc and
lto-wrapper by LTO byte-code version.

> Honza
Comment 18 Дилян Палаузов 2019-01-16 10:36:17 UTC
I will sum up the discussion so far on this and other tickets:

When one distributes source code software packages, the developers directly or indirectly use AR to create static libraries, when the user wants static libraries.  Think on autoconf/libtool packages, where the users of those packages = software developers do not deal with AR.

When a mortal user wants to build something with LTO, the user has to pass -flto to the compiler, for any source code package.  Doing the LTO build process more complex than that leads to a situation, where LTO is not utilized, due to the complixity of running it.

Some distributions install the linker plugin under $libdir/bfd-plugins and make ar/nm/ranlib deal transparently with -flto, but putting the plugin under $libdir/bfd-plugin for using ar/ranlib/nm is apparently kind of secret or too complicated, as not all distributions do this.  So sticking to AR for building with LTO is currently not portable.

When CMake is used, it chooses the appropriate gcc-ar-4, gcc-ar, llvm-ar-4.0 or llvm-ar (see https://gitlab.kitware.com/cmake/cmake/commit/630235bd9e049a8da47 and https://gitlab.kitware.com/cmake/cmake/commit/75accaae8b6a691b031f2) and ensures, that the just passing -flto will enable LTO.  As can be seen from the commits above, instead of installing the linker plugin under $libdir/bfd-plugins, distributions rename gcc-ar to something different.

CPython’s autoconf tries to detect if LTO is used and either switches to llvm-lto or (with GCC) uses fat lto objects, but does not use gcc-ar.  Likewise valgrind’s ./configure uses gcc-ar, but not llvm-ar, so does libical’s Cmakefile (to enable LTO in old cmake versions).  So the solution of compiling platform independent software is not in the distributions, the solution is to do incomplete hacks in the configure steps, and apparently meson has some knowledge how to do this (büt does not append the version number), cmake has the most complete knowledge and experimenting with autoconf nobody provides portable software where LTO is works both under LLVM and GCC.  Thus the intention of tweaking ./configure is to achieve portability but nobody managed to achieve it in an optimal way yet.

Installing the linker plugin under $libdir/bfd-plugins by the compiler will suggest to all distributions that the linker plugin has to be there and the distributions will ensure that at all time there is a linker plugin, while it is in practice irrelevant from which GCC version the linker plugin comes.  It is irrelevant, because the plugin there is only used by ar/nm/ranlib and the differences between the versions of liblto_plugin are insignificant to ar/nm/ranlib.

There are now two options:
* installing the linker plugin by gcc’s “make install” in $libdir/bfd-plugin which will lead in mid-term to having AR deal with LTO in a portable way
* not installing the linker plugin by gcc’s “make install” in $libdir/bfd-plugin.  The only portable/cross-platform way to build with LTO is using cmake.  Seriously.

That said, there are advantages when gcc’s “make install” inserts its plugin in $libdir/bfd-plugins and no disadvantages.  While not doing so has only disadvantages.

Please explain whe gcc’s “make install” does not insert its linker plugin on the rigth place and how are supposed software developers to write software/build systems, that support LTO on any platform.

Finally, not installing the plugin under $libdir/bfd-plugins because of differences in the versions, forces users to use gcc-ar, but it has the very same problems with differences in the versions.
Comment 19 Liviu Ionescu 2019-02-03 10:00:42 UTC
I'm the maintainer of GNU MCU Eclipse ARM Embedded GCC, a distribution based on Arm Embedded GCC, and I confirm that I got bitten by this issue too.

FYI, Eclipse uses arm-none-eabi-ar to build static Arm libraries, and when I tried to use LTO, the result was an error like 'plugin needed to handle lto object'.

The workaround was to update my distribution build scripts to copy (on Windows) or link (on Linux and macOS) the LTO plugin to lib/bfd-plugins, a local folder present in the distribution.

In my oppinion, the LTO plugin should be copied to bfd-plugins by the 'make install', and not be left at the discretion of the distribution.