Consider the hello world C program:
hello.c:
#include "stdio.h"
int main()
{
printf("Hello, World!\n");
}
If I call:
$ gcc -c hello.c -o hello.o
It will produce an ELF Relocatable File hello.o
If I then call:
$ gcc hello.o -o hello [1]
It will link hello.o with ld and produce an ELF Executable File hello
However if I call ld directly [2]
instead of [1]
:
$ ld hello.o -o hello [2]
I get these errors:
/usr/bin/ld.bfd.real: warning: cannot find entry symbol _start
test.c:(.text+0xa): undefined reference to `puts'
gcc must be passing other options to ld (to link the C library for example).
Is there anyway to determine exactly what the command-line gcc is passing through to ld in command [1]
?
Yes, you can use gcc -v hello.o -o hello
to get the link line. For your example on my ubuntu machine, I get this link line (edited to be multiline for readability):
/usr/lib/gcc/x86_64-linux-gnu/4.4.5/collect2
--build-id
--eh-frame-hdr
-m elf_x86_64
--hash-style=gnu
-dynamic-linker
/lib64/ld-linux-x86-64.so.2
-o hello
-z relro
/usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib/crt1.o
/usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib/crti.o
/usr/lib/gcc/x86_64-linux-gnu/4.4.5/crtbegin.o
-L/usr/lib/gcc/x86_64-linux-gnu/4.4.5
-L/usr/lib/gcc/x86_64-linux-gnu/4.4.5
-L/usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib
-L/lib/../lib
-L/usr/lib/../lib
-L/usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../.. -L/usr/lib/x86_64-linux-gnu
hello.o
-lgcc
--as-needed -lgcc_s --no-as-needed
-lc
-lgcc
--as-needed -lgcc_s --no-as-needed
/usr/lib/gcc/x86_64-linux-gnu/4.4.5/crtend.o
/usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib/crtn.o
Note that collect2
is just an alias for ld
.
For oneline lovers:
echo "int main(void) {}" | gcc -o /dev/null -v -x c - &> /dev/stdout| grep collect | tr -s " " "\012"
Replace -x c
with -x c++
to get c++ flags.
Can be used also with clang, but in such case you should grep for /usr/bin/ld
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With