Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to specify alternate linker command when linking with 'cc'

Tags:

c++

c

linker

When you use cc(1) to link a program, it will invoke a default linker command. For instance, your version of the compiler may have been built to use /usr/bin/ld by default on a unix-like platform.

Is there a way to specify a different linker command that cc(1) (or c++(1)) should use (e.g., /usr/local/bin/ld instead of /usr/bin/ld)? I'm interested mostly in gcc and clang.

I'm not looking for methods that involve running the various compilation steps separately (e.g., pre-process, compile, assemble, link).

For example, I was hoping something like this might do the job:

env LD=/usr/local/bin/ld cc foo.c -o foo

But that doesn't work for gcc or clang. It would work, of course, if you had a makefile that built an object file first, then invoked ${LD} to link (e.g., env LD=/usr/local/bin/ld make)

Update (with one possible motivation): To easily test with a different linker than the default linker. For example, it would be nice to be able to do this:

cc --linker=/usr/local/bin/ld foo.c -o foo

Instead, you have to do generate the object file, run cc -v to figure out the arguments to ld, manually run the ld you want with those arguments:

cc -c foo.c
cc -v foo.c -o /dev/null

Now look at the linker invocation and manually copy/paste replacing linker and temporary object file. Something like this (example taken from a test on fedora 23) where you replace /usr/libexec/gcc/x86_64-redhat-linux/5.3.1/collect2 with /usr/local/bin/ld (although it's not exactly the same as collect2):

/usr/local/bin/ld -plugin /usr/libexec/gcc/x86_64-redhat-linux/5.3.1/liblto_plugin.so -plugin-opt=/usr/libexec/gcc/x86_64-redhat-linux/5.3.1/lto-wrapper -plugin-opt=-fresolution=/tmp/jhein/ccM2XKIg.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --no-add-needed --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o c /usr/lib/gcc/x86_64-redhat-linux/5.3.1/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-redhat-linux/5.3.1/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/5.3.1/crtbegin.o -L/usr/lib/gcc/x86_64-redhat-linux/5.3.1 -L/usr/lib/gcc/x86_64-redhat-linux/5.3.1/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/5.3.1/../../.. c.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-redhat-linux/5.3.1/crtend.o /usr/lib/gcc/x86_64-redhat-linux/5.3.1/../../../../lib64/crtn.o

As you can see, that's not easy. Note there is documentation in the gcc info page about how collect2 looks for a linker program. But according to those docs, the first place it looks is not an environment variable or something you can specify on the command line (e.g., --linker). The docs say it looks first for a "a hard coded linker file name". If that documentation is correct, to coerce it not to use that linker (i.e., trick it), you would have to rename the default linker (e.g., sudo mv /usr/bin/ld /usr/bin/ld.tmp-disable).

Update 2: Using -B seems to work well enough for my needs. See below where I posted an answer. I can't accept my own answer, but I would if I could - it seems to solve the issue well.

like image 432
Juan Avatar asked Nov 07 '16 17:11

Juan


People also ask

What is a linker command?

Linker command files allow you to put linker options and directives in a file; this is useful when you invoke the linker often with the same options and directives. Linker command files are also useful because they allow you to use the MEMORY and SECTIONS directives to customize your application.

What option should be added to a gcc command in order to link in functions from a library?

In addition, you must add the - lm flag to the gcc compiler command in order to use math functions in your C code.

Which gcc option is used to specify the library?

The -l option tells gcc to link in the specified library.

What linker does gcc use?

GNU linker. But gcc does not link object files. Instead it uses collect2 which is just wrapper for the GNU ld linker: ~$ /usr/lib/gcc/x86_64-linux-gnu/4.9/collect2 --version collect2 version 4.9.


1 Answers

Certain linkers are easy to use - just gcc -fuse-ld=lld main.c. This appears to have been added somewhere in gcc version 4. -fuse-ld also works with clang 10.0.1.

Supported linkers are listed on https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html

-fuse-ld=bfd

Use the bfd linker instead of the default linker.

-fuse-ld=gold

Use the gold linker instead of the default linker.

-fuse-ld=lld

Use the LLVM lld linker instead of the default linker.

Hopefully this helps people coming from searches, as OP long ago had their question answered.

like image 125
asky Avatar answered Sep 21 '22 19:09

asky