From the GCC manual, there is the following overall option:
-wrapper
Invoke all subcommands under a wrapper program.
The name of the wrapper program and its parameters
are passed as a comma separated list.
gcc -c t.c -wrapper gdb,--args
This will invoke all subprograms of gcc under gdb --args', thus
the invocation of cc1 will begdb --args cc1 ...'.
I'm having trouble understanding the example and the purpose of the flag.
gcc -c t.c will create a t.o.
and then what? the object file is sent to gdb?
or is gdb given the responsibility of creating the object file (asummingly adding debugging information)?
Yes, for debugging the compiler itself. Or otherwise "trace" what is going on in the compiler - you could for example print the arguments passed to cc1 itself by adding a program that does that and then runs cc1.
gdb is not in charge of generating anything, it is just wrapping around cc1 whihc is the "compiler proper" - when you run gcc -c t.c the compiler first runs cpp -o t.i t.c to preprocess the t.c file. Then it runs cc1 -o t.s t.i and finally as -o t.o t.s (or something along those lines. With the wrapper, it would run those commands as, for example, gdb --args cc1 -o t.s t.i.
Edit: This is of course much simplified compared to a "real" compile - there's a whole bunch of arguments passed to cc1, etc.
During compilation gcc invokes some other programs (actual assembler, linker etc), and with -wrapper flag they are invoked within said wrapper. In your example, all subcommands are executed within gdb, which is useful for debugging gcc.
Another example: to get list of all invoked subcommands one can wrap them within echo (of course, they are not executed this way):
$ gcc 1.c -wrapper echo
/usr/lib/gcc/x86_64-linux-gnu/4.6/cc1 -quiet -imultilib . -imultiarch x86_64-linux-gnu 1.c -quiet -dumpbase 1.c -mtune=generic -march=x86-64 -auxbase 1 -fstack-protector -o /tmp/cc7cQrsT.s
as --64 -o /tmp/ccaLYkv9.o /tmp/cc7cQrsT.s
/usr/lib/gcc/x86_64-linux-gnu/4.6/collect2 --sysroot=/ --build-id --no-add-needed --as-needed --eh-frame-hdr -m elf_x86_64 --hash-style=gnu -dynamic-linker /lib64/ld-linux-x86-64.so.2 -z relro /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.6/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/4.6 -L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../.. /tmp/ccaLYkv9.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.6/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crtn.o
You could have tried it on a simple hello world.
gcc will call different subcommands. Each of these subcommands will be prefixed with the wrapper. Giving gdb as a wrapper means that you want to debug the compiler.
Related
When I need to use, for example, the gnu function gsl_sf_bessel_J0 in a program, I simply compile it with gcc -lgsl -o gsl_test.c gsl_test. Why do I have to include -lgsl for it to work? Is there any way I can set it as a default so I don't have to type it out everytime?
If you compile with the -v flag, you'll see the command the GCC front-end invokes to link your final executable*. If your program uses a function like gsl_sf_bessel_J0 that isn't in one of the default libraries (possibly limited to libc and maybe also libm), you need to explicitly link it.
If you don't like typing it all the time, make a simple Makefile. Your case is simple enough that you can handle it with just environment variables, actually:
$ export CC=gcc
$ export LDLIBS=-lgsl
$ make gsl_test
gcc gsl_test.c -lgsl -o gsl_test
$
make's default built-in rules will do the rest.
*: for reference, my compiler links your example as:
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld"
-demangle
-dynamic
-arch x86_64
-macosx_version_min 10.12.0
-o gsl_test
/var/folders/cp/wvm69p1n7_bbjpxxqmttwn700000gn/T/gsl_test-0afe3a.o
-lgsl
-lSystem
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/8.0.0/lib/darwin/libclang_rt.osx.a
Recently I was creating a loadable module and found that both
gcc -fPIC --shared -o foo.so.1 foo.c
and
gcc -fPIC --shared -c foo.c
ld --shared -o foo.so.2 foo.o
can achieve the same effect.
I also discovered that foo.so.1 is larger than foo.so.2 by about 3KB, and
gcc -### -fPIC --shared -o foo.so.1 foo.c
revealed that GCC added stuffs other than foo.c into foo.so.1 (e.g, crtendS.o and crtn.o):
/usr/lib/gcc/x86_64-linux-gnu/4.7/collect2 "--sysroot=/" --build-id --no-add-needed --eh-frame-hdr -m elf_x86_64 "--hash-style=both" -shared -o foo.so.1 /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.7/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/4.7 -L/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.7/../../.. /tmp/cc3JBdCJ.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.7/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crtn.o
Since both foo.so.1 and foo.so.2 can be loaded via dlopen, I was wondering:
What's the difference between these 2 linking methods?
Do crtendS.o and crtn.o make any difference to functions in created libraries?
There's no difference in principle. When you "link by gcc" it actually calls ld. If you get a message at the linking stage when "linking by gcc" you'll immediately see that it is actually from ld. If you want to pass some ld-specific command-line options to ld, gcc's command-line interface has features intended specifically for that purpose (-Xlinker and -Wl options).
As for the additional objects files... they probably contain global load-time library initialization/de-initialization code implicitly added by the compiler. (Requested by the standard library?) You can find some information about it here: https://gcc.gnu.org/onlinedocs/gccint/Initialization.html
I use the following LLVM tools to convert a cpp project which is written in multiple files into "ONE" single assembly file.
clang *.cpp -S -emit-llvm
llvm-link *.s -S -o all.s
llc all.s -march=mips
Is there any way of doing this in GCC? In particular, is there any way of linking GCC generated assembly files into one assembly file? i.e., what is the equivalent of LLVM-LINK?
Perhaps LTO (Link Time Optimization) is what you want.
Then, compile each compilation unit with gcc -flto e.g.
gcc -flto -O -Wall -c src1.c
g++ -flto -O -Wall -c src2.cc
and use also -flto (and the same optimizations) to link them:
g++ -flto -O src1.o src2.o -lsomething
LTO works in GCC by putting, in each generated assembly file and object file, some representation of the internal GCC representations (like Gimple). See its documentation
You might want to use MELT to customize GCC (or simply use its probe to understand the Gimple, or try just gcc -fdump-tree-all).
I'm trying to create a shared library with my gcc. It's a gcc for vxworks (thats probably the problem...).
I use the gcc as following:
./gcc -shared -B/path/to/gnutools/bin -o test.so test.c
Result:
/path/to/ld: -r and -shared may not be used together
collect2: ld returned 1 exit status
If I try the same with the linux gcc, there's no problem. So i guess the gcc for VxWorks automatically passes the -r (or -i, which is the same and results in the same) flag to the linker. Is there a way to suppress this?
Greetz
marty
PS: making it static is not really an alternative...
Try compile object file separately with -fPIC and then link:
gcc -Wall -fPIC -c -o test.o test.c
gcc -Wall -shared -o test.so test.o
Another suggestion is to use libtool (at least to figure out the correct flags).
A workaround may be to go directly with ld:
ld -shared -o test.so test.o -lc
I compiled with gcc
gcc -l. 'net-snmp-config --cflags'
-fPlC -shared -c -o matsu_object.o tsu_object.c
but this error occurred
gcc: -lcrypto: Because a link was
not completed, the input file of the
linker was not used
What's wrong?
Did you mistype the question? There's no way for that to output the message you write, and I would expect that the proper command is something more like
gcc -L. `net-snmp-config --cflags` -fPIC -shared -c -o matsu_object.o tsu_object.c
Notice the -L uppercase, backticks instead of single quotes, and upper-case I in PIC.
Also, you don't say what you're trying to do, but net-snmp-config should also take at least one of --libs or --agent-libs as well.
Ah, I didn't read closely enough...
-c means "compile", that is: generate from tsu_object.c, a compiled matsu_object.o.
Without -c, the compiler actually links, that is: generate from *.o, a.out or other specified file.
-shared (and linker flags like -l and -L) are only meaningful when linking. They're meaningless when compiling, as you are doing here because of -c.
Please correct the command-line in the question to accurately reflect what you're running, and give some more explanation as to what you're trying to do.
I think you are using ticks ' instead of back ticks `. Does --cflags really give linker options? I think you are at the link step here. Also what is the effect of -c at a link. I thought -c was compile only and not attempt to link.
You used single quotes instead of backquotes.
Instead of this:
gcc -l. 'net-snmp-config --cflags' -fPlC -shared -c -o matsu_object.o tsu_object.c
You should type:
gcc -l. `net-snmp-config --cflags`-fPlC -shared -c -o matsu_object.o tsu_object.c
net-snmp-config is a program. When you run it with --cflags, it evaluates to the correct cflags that you should be using to compile your program.
But you know what? You should be using autoconf. Even for something this small, it usually makes sense to do the work. Most people I know need to compile on more than one platform...