1

We're using GNU gcc 9.2 on Solaris 10 - we got it preconfigured from a third party. Our problem is the linker - we want to replace it with a more recent version from binutils 2.23 but this is not so easy to do. Gcc's current config:

Configured with: ../configure 
--prefix=/usr/local/gcc9 
--with-ld=/usr/ccs/bin/ld
--with-as=/usr/local/bin/as
--without-gnu-ld

As expected, gcc confirms the above info when asked where ld resides:

>> gcc -print-prog-name=ld
/usr/ccs/bin/ld

The linker we want to use is installed in a non-standard folder at /home/chip/binutils223/bin. Based on our research, gcc distributions with preconfigured tools are effectively locked and difficult to change. I suppose the tight integration between the compiler and various linkers/assemblers is the reason for this.

-specs=[file]

The only potential solution we found for changing the linker uses custom specs file to override gcc config parameters. We ran gcc -dumpspecs, it's quite noisy so we're only showing config parameters related to the linker:

>> gcc -dumpspecs
*linker:
collect2

*md_exec_prefix:
/usr/ccs/bin/

To be frank, the specs format is very strange and might as well be written in ancient hieroglyphics. Anyway, md_exec_prefix appears to hold the folder location where ld resides, so we wrote a custom specs file (myspecs.txt) to override it:

*md_exec_prefix:
/home/chip/binutils223/bin/

We then ran gcc with custom myspecs.txt ...

>> gcc -v simple.o -o simple -specs=myspecs.txt
Using built-in specs.
Reading specs from myspecs.txt
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=...
Target: sparc-sun-solaris2.10
Configured with: ../configure --prefix=/usr/local/gcc9 --without-gnu-ld --with-ld=/usr/ccs/bin/ld
...
/usr/ccs/bin/ld -V -Y P,/lib:/usr/lib -Qy -o simple /home/...
ld: Software Generation Utilities - Solaris Link Editors: 5.10-1.1522

Gcc is definitely reading the specs file, but unfortunately it's still using the legacy ld at /usr/ccs/bin/ld. Is this strategy worth pursuing, or is it a dead-end? Are there other alternatives?

Thanks for listening.

raffian
  • 31,267
  • 26
  • 103
  • 174

1 Answers1

0

We settled on the following solution; it's a hack but we had no other solutions because of the way gcc searches[1] for the linker when configured with --with-ld option:

The program collect2 is installed as ld in the directory where the passes of the compiler are installed. When collect2 needs to find the real ld, it tries the following file names:

  • a hard coded linker file name, if GCC was configured with the --with-ld option.
  • real-ld in the directories listed in the compiler’s search directories.
  • real-ld in the directories listed in the environment variable PATH.
  • The file specified in the REAL_LD_FILE_NAME configuration macro, if specified.
  • ld in the compiler’s search directories, except that collect2 will not execute itself recursively.
  • ld in PATH.

So that means the first search path in the list always triggers for our gcc built with --with-ld=/usr/ccs/bin/ld, and no standard option to override that behavior exists.

Solution

We symlinked collect2 to reference bintutil's ld. Based on preliminary testing this solution works for our needs. The following command was executed in the folder where gcc collect2 resides, for us that location was gcc9/libexec/gcc/sparc-sun-solaris2.10/9.2.0

ln -s /home/chip/binutils/sparc-sun-solaris2.10/bin/ld collect2

[1] - https://gcc.gnu.org/onlinedocs/gccint/Collect2.html

raffian
  • 31,267
  • 26
  • 103
  • 174