11

Instead of giving -Wl,-rpath=$HOME/local/gcc52/lib64 to each invocation of GCC 5.2 which I built from the source, I modified its spec file in this way:

*link_command:
%{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:    %(linker) -rpath=%:getenv(HOME /local/gcc52/lib64) ...

But this depends on my specific installation under $HOME/local/gcc52. Are there better way to refer to the installation path of the invoked GCC itself?

This manual page did not help me much:

nodakai
  • 7,773
  • 3
  • 30
  • 60
  • 1
    Sometimes `-L` is required along with `-Wl,-rpath`. So I guess the broader question is: after installing the compiler locally, how do we get everything to 'just work' on this one machine, ignoring the system libraries/headers? – Aaron McDaid Jan 07 '16 at 15:39
  • Have you tried with a specs file? – fhossfel Jul 03 '17 at 00:15
  • https://stackoverflow.com/a/17224826 presents a solution for creating a spec file with the right path after GCC has been installed. The spec file would need recreating if you move the GCC installation later. – Jonathan Wakely Jul 03 '17 at 09:52
  • @JonathanWakely Thanks for the info, but that's actually a bad news for me because both that guy and I independently reached to the conclusion that the specs file had to be tweaked per installation (though that doesn't eliminate the possibility of finding a portable solution.) – nodakai Jul 03 '17 at 13:44
  • @nodakai When you’re compiling GCC, you can specify `--with-specs` to `configure`. You already need to specify the `--prefix`, so that shouldn’t be any more difficult. Unrelated to that, I’m curious about your spec string: why do you modify `link_command` instead of just `link`? I haven’t thoroughly tested it yet, but with a small amount of testing I’ve done so far it looks like just adding the line `*link: + %{!static:-rpath PREFIX/lib64 -enable-new-dtags}`, where PREFIX is whatever you pass to `--prefix`, does the job. – Daniel H Dec 19 '17 at 02:17
  • @nodakai Update: The `--with-specs` option didn’t work the way I thought, but if you work with spec files I still think modifying the `link` string and using the appending feature with `+` is a better option. – Daniel H Dec 19 '17 at 18:27
  • @DanielH Thank you for the info, let me see how it fits with my use cases. – nodakai Dec 20 '17 at 15:03

2 Answers2

4

When you’re compiling GCC, you need to pass the prefix you want to configure anyway. At that time, you can also give it the --with-specs option. Based on my experiments, the option --with-specs='%{!static:%x{-rpath='$prefix'/lib64} %x{-enable-new-dtags}}' (where $prefix should be replaced by the same path you pass to--prefix`) works (you need something more complicated for multilib support, of course).

Things to note:

  • This isn’t properly documented anywhere, but it appears that, unlike with regular spec files, the --with-specs configure option applies to the command-line arguments passed to GCC itself. Thus, you can’t just try to modify the *link spec string.
  • The %x sequence doesn’t change the GCC command line, but accumulates arguments to pass to the linker. That’s why I pass -rpath and -enable-new-dtags directly instead of via -Wl.
  • There are a bunch of suggestions online for what specs to pass. I didn’t see this one anywhere, so it take it with a grain of salt. The reason I used my own is that all the others either modify a spec string like *link, which you cannot do with --with-specs, or they add options to the GCC command line using -Wl, which I’m fairly sure somebody said they had trouble with because in some cases it confused GCC when they weren’t linking. YMMV.
  • If you use bootstrapping (which you usually are unless building a cross-compiler, in which case I could be wrong but I don’t think this particular rpath trick is useful anyway), this will add a RUNPATH to the GCC programs and shared libraries as well. This seems to be the correct option, because they were compiled against the libraries that are now in $prefix/lib64, but it’s worth noting.
  • I added -enable-new-dtags, which puts this in DT_RUNPATH instead of DT_RPATH. This is the newer attribute which all the documentation says should be preferred, <sarcasm>which is why it requires an extra flag which isn’t clearly cross-referenced in the docs</sarcasm>. Among the differences between RPATH and RUNPATH are:

    • If RUNPATH is present, RPATH will be completely ignored.
    • The RPATH overrides LD_LIBRARY_PATH; the RUNPATH does not.
    • They work somewhat differently for dependencies of dependencies (RUNPATH is only searched for direct dependencies; RPATH is searched for indirect dependencies as long as nothing in the dependency chain has a RUNPATH). More details are available here.
    • I think that’s everything, but I wouldn’t be surprised if I’m missing something.

    As the article I linked above indicates, not everybody prefers RUNPATH to RPATH, but here it shouldn’t be an issue unless you mix code from different compilers requiring different compiler support libraries in a complicated way, and if you do that I don’t think there’s any one-size-fits-all solution.

Daniel H
  • 7,223
  • 2
  • 26
  • 41
1

As far as I can tell, GCC is very much dependent on the installation folder it was compiled for. I build RTEMS cross-compilation toolchains very frequently, and one of the first things I learned was that there are many places in the generated cross-compiler where the installation prefix (i.e. whatever was passed to --exec-prefix) is "burned" in.

"Learned" - as in, I tried to move the compiler's folder to a different path, and all hell broke loose :-)

My point: modifying specs files to make them point to paths in your install seems absolutely normal, as far as GCC is concerned.

ttsiodras
  • 10,602
  • 6
  • 55
  • 71