At my company we have a really annoying problem with our linker (ld 2.17). It links very very slow on a relatively fast system (Core Duo, 2GB Ram) and I don't really now how to fix this. It takes about five to ten minutes to compile a relatively big project (which takes about 5 seconds to link on my Gentoo system).
Personally i think it is a huge productivity killer, at least for me. We tried to use a more recent version of ld (2.19) but without any success. I asked in #debian on #freenode, but this problem seems to be very unique. I did not find any information about similar problems on the net. It only happens when we build with debug symbols. I changed the gcc debug-information flags to -g, -g3, and -ggdb, but that did not help either.
So my question is, how do you profile and debug a linker? I have never done anything like it, and I am unable to find any documentation about it. Basically any reasonable gprof gmon.out would be very helpful, as I could ask the binutils developers about a concrete problem. I am just completely oblivious about this.
Edit: We 'fixed' our problem switching to debian lenny on most systems. Thanks for the answers!
You can try gold (binutils-gold) instead of ld.
It is supposed to be faster.
Here is a quote from Wikipedia Gold(linker)
The motivation for writing gold was to
make a linker that is faster than the
GNU linker[3], especially for large
applications coded in C++.
The author of gold (Ian Lance Taylor) has published an (longish) article about linkers where he explains his motifs in writing gold and why most linkers are slow. If you are interested in the inner workings of linkers this article is worth reading.
If you're observing the slowdown running gcc (as opposed to directly running the linker as ld), try compiling with
$ gcc -save-temps -v [... rest of your command line ...]
This will print out all the intermediary commands, such as the internal collect2 and final ld, as well as ensure that the objects passed to those commands will remain on disk even after the command has completed.
Then you should be able to run the commands individually to find the worst stage, and then run it with different options or profiling.
For example,
$ echo 'int main() {}' > test.c
$ gcc -save-temps -v test.c
Using built-in specs.
Target: x86_64-pc-linux-gnu
Configured with: /var/tmp/paludis/sys-devel-gcc-4.3.3-r2/work/gcc-4.3.3/configure --prefix=/usr --bindir=/usr/x86_64-pc-linux-gnu/gcc-bin/4.3.3 --includedir=/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/include --datadir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.3.3 --mandir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.3.3/man --infodir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.3.3/info --with-gxx-include-dir=/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/include/g++-v4 --host=x86_64-pc-linux-gnu --build=x86_64-pc-linux-gnu --disable-altivec --disable-fixed-point --enable-nls --without-included-gettext --with-system-zlib --disable-checking --disable-werror --enable-secureplt --enable-multilib --enable-libmudflap --disable-libssp --enable-libgomp --enable-cld --disable-libgcj --enable-objc-gc --enable-languages=c,c++,objc,obj-c++,treelang,fortran --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu --with-bugurl=http://bugs.gentoo.org/ --with-pkgversion='Gentoo 4.3.3-r2 p1.1, pie-10.1.5'
Thread model: posix
gcc version 4.3.3 (Gentoo 4.3.3-r2 p1.1, pie-10.1.5)
COLLECT_GCC_OPTIONS='-save-temps' '-v' '-mtune=generic'
/usr/libexec/gcc/x86_64-pc-linux-gnu/4.3.3/cc1 -E -quiet -v test.c -D_FORTIFY_SOURCE=2 -mtune=generic -fpch-preprocess -o test.i
ignoring nonexistent directory "/usr/local/include"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../x86_64-pc-linux-gnu/include"
#include "..." search starts here:
#include search starts here:
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/include
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/include-fixed
/usr/include
End of search list.
COLLECT_GCC_OPTIONS='-save-temps' '-v' '-mtune=generic'
/usr/libexec/gcc/x86_64-pc-linux-gnu/4.3.3/cc1 -fpreprocessed test.i -quiet -dumpbase test.c -mtune=generic -auxbase test -version -o test.s
GNU C (Gentoo 4.3.3-r2 p1.1, pie-10.1.5) version 4.3.3 (x86_64-pc-linux-gnu)
compiled by GNU C version 4.3.3, GMP version 4.2.4, MPFR version 2.4.1-p5.
warning: GMP header version 4.2.4 differs from library version 4.3.1.
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 20f3dbffbfd03e5311a257ae1239cd71
COLLECT_GCC_OPTIONS='-save-temps' '-v' '-mtune=generic'
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../x86_64-pc-linux-gnu/bin/as -V -Qy -o test.o test.s
GNU assembler version 2.19.1 (x86_64-pc-linux-gnu) using BFD version (GNU Binutils) 2.19.1
COMPILER_PATH=/usr/libexec/gcc/x86_64-pc-linux-gnu/4.3.3/:/usr/libexec/gcc/x86_64-pc-linux-gnu/4.3.3/:/usr/libexec/gcc/x86_64-pc-linux-gnu/:/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/:/usr/lib/gcc/x86_64-pc-linux-gnu/:/usr/libexec/gcc/x86_64-pc-linux-gnu/4.3.3/:/usr/libexec/gcc/x86_64-pc-linux-gnu/:/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/:/usr/lib/gcc/x86_64-pc-linux-gnu/:/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../x86_64-pc-linux-gnu/bin/
LIBRARY_PATH=/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/:/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/:/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../x86_64-pc-linux-gnu/lib/:/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-save-temps' '-v' '-mtune=generic'
/usr/libexec/gcc/x86_64-pc-linux-gnu/4.3.3/collect2 --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../lib64/crti.o /usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/crtbegin.o -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3 -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3 -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../x86_64-pc-linux-gnu/lib -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../.. test.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/crtend.o /usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../lib64/crtn.o
$ ls
a.out test.c test.i test.o test.s
$ /usr/libexec/gcc/x86_64-pc-linux-gnu/4.3.3/collect2 --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../lib64/crti.o /usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/crtbegin.o -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3 -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3 -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../x86_64-pc-linux-gnu/lib -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../.. test.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/crtend.o /usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../lib64/crtn.o
$ .../collect2 -v ...
collect2 version 4.3.3 (x86-64 Linux/ELF)
/usr/bin/ld -v --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../lib64/crti.o /usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/crtbegin.o -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3 -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3 -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../x86_64-pc-linux-gnu/lib -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../.. test.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/crtend.o /usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/../../../../lib64/crtn.o
GNU ld (GNU Binutils) 2.19.1
$
If you need help building a debug version of ld, here's a quick recipe to get you going.
$ sudo apt-get install build-essential dpkg-dev
$ sudo apt-get build-dep binutils
$ apt-get source binutils
$ cd binutils-*
$ DEB_BUILD_OPTIONS='debug noopt nostrip' dpkg-buildpackage -uc -us
$ cd ..
$ sudo dpkg -i *.deb
Instead of that quick hack, though, I'd recommend using schroot or sbuild to avoid polluting your own system.
To answer the profiling question; you should look at OProfile - this is a system-level profiler that can profile multiple running processes. It should allow you to identify which sub-process of the link is taking the most time, and furthermore will show which functions the most time is being spent.
I'd like to suggest two ways to check:
use strace to check what files linker is loading/parsing to link; with this you may know is there any unnecessary path is searched by linker.
use ld with -verbose option to know what ld is doing. Five minutes compare to five seconds should not be the linker's problem, it should be some problem of your host machine or some option.
Related
I am working with the ARM-gcc cross compiler and am having issues linking to any implementation within libc.
Compiling prog.c, writing to prog.o...
~/.programs/arm-gcc/bin/arm-none-eabi-gcc -Wall -fno-common -mcpu=cortex-m4 -mthumb -O0 -g -DF_CPU=72000000 -I~/.programs/arm-gcc/arm-none-eabi/include -I../include -I. -I../src/include -c prog.c -o prog.o > prog.lst
Compiling ../common/sysinit.c, writing to sysinit.o...
~/.programs/arm-gcc/bin/arm-none-eabi-gcc -Wall -fno-common -mcpu=cortex-m4 -mthumb -O0 -g -DF_CPU=72000000 -I~/.programs/arm-gcc/arm-none-eabi/include -I../include -I. -I../src/include -c ../common/sysinit.c -o sysinit.o > sysinit.lst
Assembling ../common/crt0.s, writing to crt0.o...
~/.programs/arm-gcc/bin/arm-none-eabi-as -mcpu=cortex-m4 -o crt0.o ../common/crt0.s > crt0.lst
Compiling uart.c, writing to uart.o...
~/.programs/arm-gcc/bin/arm-none-eabi-gcc -Wall -fno-common -mcpu=cortex-m4 -mthumb -O0 -g -DF_CPU=72000000 -I~/.programs/arm-gcc/arm-none-eabi/include -I../include -I. -I../src/include -c uart.c -o uart.o > uart.lst
~/.programs/arm-gcc/bin/arm-none-eabi-ld prog.o sysinit.o crt0.o uart.o -Map=prog.map -T../common/Teensy31_flash.ld -L~/.programs/arm-gcc/arm-none-eabi/lib -o prog.elf
prog.o: In function `print_char':
/home/user/workspace/prog/src/prog.c:47: undefined reference to `sprintf'
/home/user/workspace/prog/src/prog.c:48: undefined reference to `printf'
/home/user/workspace/prog/src/prog.c:49: undefined reference to `strlen'
prog.o: In function `main':
/home/user/workspace/prog/src/prog.c:72: undefined reference to `memset'
make: *** [makefile:133: prog.elf] Error 1
I threw in a few calls to stdlib to make the point. I have tried to explicitly link against libc using -lc but am met with:
/home/prog/.programs/arm-gcc/bin/arm-none-eabi-ld: cannot find -lc
The archive directory is passed to the linker via:
L~/.programs/arm-gcc/arm-none-eabi/lib
I have checked the contents of this directory and verified the archive to be present:
$ ls ~/.programs/arm-gcc/arm-none-eabi/lib
aprofile-validation.specs libc_s.a linux.specs
aprofile-ve.specs libg.a nano.specs
armv6-m libgloss-linux.a nosys.specs
armv7-ar libg_s.a pid.specs
armv7e-m libm.a rdimon-crt0.o
armv7-m libnosys.a rdimon.specs
cpu-init librdimon.a rdpmon-crt0.o
crt0.o librdimon_s.a rdpmon.specs
fpu librdpmon.a redboot-crt0.o
iq80310.specs libstdc++.a redboot.ld
ldscripts libstdc++.a-gdb.py redboot.specs
libarm_cortexM0l_math.a libstdc++_s.a redboot-syscalls.o
libarm_cortexM4lf_math.a libsupc++.a thumb
libarm_cortexM4l_math.a libsupc++_s.a
libc.a linux-crt0.o
And, finally, the libc does export sprintf (and others)
$ nm libc.a | grep "sprintf"
...
lib_a-sprintf.o:
00000000 T sprintf
00000000 T _sprintf_r
U sprintf
U _sprintf_r
...
Info on the ARM-GCC build I am using:
$ ./arm-none-eabi-gcc -v
Using built-in specs.
COLLECT_GCC=./arm-none-eabi-gcc
COLLECT_LTO_WRAPPER=/home/user/.programs/arm-gcc/bin/../lib/gcc/arm-none-eabi/5.4.1/lto-wrapper
Target: arm-none-eabi
Configured with: /home/build/work/GCC-5-0-build/src/gcc/configure --target=arm-none-eabi --prefix=/home/build/work/GCC-5-0-build/install-native --libexecdir=/home/build/work/GCC-5-0-build/install-native/lib --infodir=/home/build/work/GCC-5-0-build/install-native/share/doc/gcc-arm-none-eabi/info --mandir=/home/build/work/GCC-5-0-build/install-native/share/doc/gcc-arm-none-eabi/man --htmldir=/home/build/work/GCC-5-0-build/install-native/share/doc/gcc-arm-none-eabi/html --pdfdir=/home/build/work/GCC-5-0-build/install-native/share/doc/gcc-arm-none-eabi/pdf --enable-languages=c,c++ --enable-plugins --disable-decimal-float --disable-libffi --disable-libgomp --disable-libmudflap --disable-libquadmath --disable-libssp --disable-libstdcxx-pch --disable-nls --disable-shared --disable-threads --disable-tls --with-gnu-as --with-gnu-ld --with-newlib --with-headers=yes --with-python-dir=share/gcc-arm-none-eabi --with-sysroot=/home/build/work/GCC-5-0-build/install-native/arm-none-eabi --build=i686-linux-gnu --host=i686-linux-gnu --with-gmp=/home/build/work/GCC-5-0-build/build-native/host-libs/usr --with-mpfr=/home/build/work/GCC-5-0-build/build-native/host-libs/usr --with-mpc=/home/build/work/GCC-5-0-build/build-native/host-libs/usr --with-isl=/home/build/work/GCC-5-0-build/build-native/host-libs/usr --with-cloog=/home/build/work/GCC-5-0-build/build-native/host-libs/usr --with-libelf=/home/build/work/GCC-5-0-build/build-native/host-libs/usr --with-host-libstdcxx='-static-libgcc -Wl,-Bstatic,-lstdc++,-Bdynamic -lm' --with-pkgversion='GNU Tools for ARM Embedded Processors' --with-multilib-list=armv6-m,armv7-m,armv7e-m,armv7-r,armv8-m.base,armv8-m.main
Thread model: single
gcc version 5.4.1 20160609 (release) [ARM/embedded-5-branch revision 237715] (GNU Tools for ARM Embedded Processors)
The ~ in -L~/.programs/arm-gcc/arm-none-eabi/lib doesn't get expanded. It is the shell that expands ~ into /home/user, but only when it is at the beginning of a word.
Actually, it isn't necessary to add this -L option, because this is already in gcc's default search path. However, you link directly with ld instead of with gcc. That is not a good idea. It is better to link with gcc and allow it to add the default search paths and other required libraries, like libc and libgcc. Since you supply your own crt0, add -nostartfiles to the arguments. So link with:
~/.programs/arm-gcc/bin/arm-none-eabi-gcc prog.o sysinit.o crt0.o uart.o \
-Wl,-Map=prog.map -Wl,-T../common/Teensy31_flash.ld -nostartfiles -o prog.elf
I am confused by this command. The man page http://linux.die.net/man/1/ld says it "emulates the emulation linker. You can list the available emulations with the --verbose or -V options." But what does the "available emulations" mean?
For example, I use the following command to link objects:
ld -r -nostdlib -L/media/wind/lab/xen/xen/xen-4.4.0/stubdom/cross-root-x86_64/x86_64-xen-elf/lib \
-m elf_x86_64 --verbose ./arch/x86/x86_64.o ./mini-os_app.o ./blkfront.o ./events.o ./fbfront.o \
./gntmap.o ./gnttab.o ./hypervisor.o ./kernel.o ./lock.o ./main.o ./mm.o ./netfront.o ./sched.o \
./lib/ctype.o ./lib/math.o ./lib/printf.o ./lib/stack_chk_fail.o ./lib/string.o ./lib/sys.o \
./lib/xmalloc.o ./lib/xs.o ./xenbus/xenbus.o ./console/console.o ./console/xencons_ring.o \
./console/xenbus.o ./lwip.a -L./arch/x86 -lx86_64 -lc -lglib-2.0 -lvmi -o ./mini-os.o
GNU ld (GNU Binutils for Ubuntu) 2.22
Supported emulations:
elf_x86_64
elf32_x86_64
elf_i386
i386linux
elf_l1om
elf_k1om
using internal linker script:
==================================================
(>>> scripts displayed here, neglected <<<)
==================================================
...
attempt to open /media/wind/lab/xen/xen/xen-4.4.0/stubdom/mini-os-x86_64-vmi/arch/x86/libx86_64.a succeeded
(>>> lots of *.o listed here for libc.a <<<)
(/media/wind/lab/xen/xen/xen-4.4.0/stubdom/mini-os-x86_64-vmi/arch/x86/libx86_64.a)mm.o
(/media/wind/lab/xen/xen/xen-4.4.0/stubdom/mini-os-x86_64-vmi/arch/x86/libx86_64.a)sched.o
(/media/wind/lab/xen/xen/xen-4.4.0/stubdom/mini-os-x86_64-vmi/arch/x86/libx86_64.a)setup.o
(/media/wind/lab/xen/xen/xen-4.4.0/stubdom/mini-os-x86_64-vmi/arch/x86/libx86_64.a)time.o
(/media/wind/lab/xen/xen/xen-4.4.0/stubdom/mini-os-x86_64-vmi/arch/x86/libx86_64.a)traps.o
...
attempt to open /media/wind/lab/xen/xen/xen-4.4.0/stubdom/cross-root-x86_64/x86_64-xen-elf/lib/libglib-2.0.a succeeded
(>>> why no *.o files listed here? <<<)
attempt to open /media/wind/lab/xen/xen/xen-4.4.0/stubdom/cross-root-x86_64/x86_64-xen-elf/lib/libvmi.a succeeded
(/media/wind/lab/xen/xen/xen-4.4.0/stubdom/cross-root-x86_64/x86_64-xen-elf/lib/libvmi.a)libvmi_la-accessors.o
(/media/wind/lab/xen/xen/xen-4.4.0/stubdom/cross-root-x86_64/x86_64-xen-elf/lib/libvmi.a)libvmi_la-convenience.o
(/media/wind/lab/xen/xen/xen-4.4.0/stubdom/cross-root-x86_64/x86_64-xen-elf/lib/libvmi.a)libvmi_la-core.o
(/media/wind/lab/xen/xen/xen-4.4.0/stubdom/cross-root-x86_64/x86_64-xen-elf/lib/libvmi.a)libvmi_la-events.o
(/media/wind/lab/xen/xen/xen-4.4.0/stubdom/cross-root-x86_64/x86_64-xen-elf/lib/libvmi.a)libvmi_la-memory.o
(/media/wind/lab/xen/xen/xen-4.4.0/stubdom/cross-root-x86_64/x86_64-xen-elf/lib/libvmi.a)libvmi_la-read.o
(/media/wind/lab/xen/xen/xen-4.4.0/stubdom/cross-root-x86_64/x86_64-xen-elf/lib/libvmi.a)libvmi_la-interface.o
(/media/wind/lab/xen/xen/xen-4.4.0/stubdom/cross-root-x86_64/x86_64-xen-elf/lib/libvmi.a)libvmi_la-kvm.o
(/media/wind/lab/xen/xen/xen-4.4.0/stubdom/cross-root-x86_64/x86_64-xen-elf/lib/libvmi.a)libvmi_la-memory_cache.o
(/media/wind/lab/xen/xen/xen-4.4.0/stubdom/cross-root-x86_64/x86_64-xen-elf/lib/libvmi.a)libvmi_la-xen.o
(/media/wind/lab/xen/xen/xen-4.4.0/stubdom/cross-root-x86_64/x86_64-xen-elf/lib/libvmi.a)lt1-libvmi_la-core.o
(/media/wind/lab/xen/xen/xen-4.4.0/stubdom/cross-root-x86_64/x86_64-xen-elf/lib/libvmi.a)lt2-libvmi_la-memory.o
(/media/wind/lab/xen/xen/xen-4.4.0/stubdom/cross-root-x86_64/x86_64-xen-elf/lib/libvmi.a)libvmi_la-symbols.o
(/media/wind/lab/xen/xen/xen-4.4.0/stubdom/cross-root-x86_64/x86_64-xen-elf/lib/libvmi.a)lt3-libvmi_la-core.o
(/media/wind/lab/xen/xen/xen-4.4.0/stubdom/cross-root-x86_64/x86_64-xen-elf/lib/libvmi.a)libvmi_la-kpcr.o
(/media/wind/lab/xen/xen/xen-4.4.0/stubdom/cross-root-x86_64/x86_64-xen-elf/lib/libvmi.a)lt4-libvmi_la-memory.o
(/media/wind/lab/xen/xen/xen-4.4.0/stubdom/cross-root-x86_64/x86_64-xen-elf/lib/libvmi.a)libvmi_la-peparse.o
(/media/wind/lab/xen/xen/xen-4.4.0/stubdom/cross-root-x86_64/x86_64-xen-elf/lib/libvmi.a)libvmi_la-process.o
(/media/wind/lab/xen/xen/xen-4.4.0/stubdom/cross-root-x86_64/x86_64-xen-elf/lib/libvmi.a)grammar.o
(/media/wind/lab/xen/xen/xen-4.4.0/stubdom/cross-root-x86_64/x86_64-xen-elf/lib/libvmi.a)lexicon.o
(/media/wind/lab/xen/xen/xen-4.4.0/stubdom/cross-root-x86_64/x86_64-xen-elf/lib/libvmi.a)libvmi_la-cache.o
(/media/wind/lab/xen/xen/xen-4.4.0/stubdom/cross-root-x86_64/x86_64-xen-elf/lib/libvmi.a)libvmi_la-strmatch.o
(/media/wind/lab/xen/xen/xen-4.4.0/stubdom/cross-root-x86_64/x86_64-xen-elf/lib/libvmi.a)libvmi_la-file.o
As showed in the above outputs, it seems that each *.a library should have their own *.o listed. But what is the meaning if no *.o listed for a certain *.a library,such as glib-2.0.a showed above ?
Thank you in advance!
The ld -m option is used while linking .o files to create an executable file for a hardware platform provided as an argument with -m option.
E.g. if you specify ld -m elf_x86_64 ..., an executable file is created (assuming no error occurred) that can run on a x86_64 system. This is generally used during cross compiling. i.e. in the situation when you are trying to create an executable for a platform different from the one it is being built.
I'm new to linux. Can anyone explain to me the following verbose mode output for my hello world program? Also, what do the files crt1.o, crti.o, crtend.o, crtbegin.o and crtn.o and lc and lgcc do? Any other explanatory links are also welcome.
$ gcc -v hello.c
Reading specs from /usr/lib/gcc-lib/i686/3.3.1/specs
Configured with: ../configure --prefix=/usr
Thread model: posix
gcc version 3.3.1
/usr/lib/gcc-lib/i686/3.3.1/cc1 -quiet -v -D__GNUC__=3
-D__GNUC_MINOR__=3 -D__GNUC_PATCHLEVEL__=1
hello.c -quiet -dumpbase hello.c -auxbase hello -Wall
-version -o /tmp/cceCee26.s
GNU C version 3.3.1 (i686-pc-linux-gnu)
compiled by GNU C version 3.3.1 (i686-pc-linux-gnu)
GGC heuristics: --param ggc-min-expand=51
--param ggc-min-heapsize=40036
ignoring nonexistent directory "/usr/i686/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/usr/include
/usr/lib/gcc-lib/i686/3.3.1/include
/usr/include
End of search list.
as -V -Qy -o /tmp/ccQynbTm.o /tmp/cceCee26.s
GNU assembler version 2.12.90.0.1 (i386-linux)
using BFD version 2.12.90.0.1 20020307 Debian/GNU
Linux
/usr/lib/gcc-lib/i686/3.3.1/collect2
--eh-frame-hdr -m elf_i386 -dynamic-linker
/lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o
/usr/lib/gcc-lib/i686/3.3.1/crtbegin.o
-L/usr/lib/gcc-lib/i686/3.3.1
-L/usr/lib/gcc-lib/i686/3.3.1/../../.. /tmp/ccQynbTm.o
-lgcc -lgcc_eh -lc -lgcc -lgcc_eh
/usr/lib/gcc-lib/i686/3.3.1/crtend.o
/usr/lib/crtn.o
The first part is the version and configuration data for the compiler driver (that's the gcc binary, which is not actually the compiler itself):
Reading specs from /usr/lib/gcc-lib/i686/3.3.1/specs
Configured with: ../configure --prefix=/usr
Thread model: posix
gcc version 3.3.1
Then it prints the command it uses to call the real compiler, cc1:
/usr/lib/gcc-lib/i686/3.3.1/cc1 -quiet -v -D__GNUC__=3
-D__GNUC_MINOR__=3 -D__GNUC_PATCHLEVEL__=1
hello.c -quiet -dumpbase hello.c -auxbase hello -Wall
-version -o /tmp/cceCee26.s
And cc1 prints it's version and config info.
GNU C version 3.3.1 (i686-pc-linux-gnu)
compiled by GNU C version 3.3.1 (i686-pc-linux-gnu)
GGC heuristics: --param ggc-min-expand=51
--param ggc-min-heapsize=40036
Then cc1 tells you what directories it will search for include files.
ignoring nonexistent directory "/usr/i686/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/usr/include
/usr/lib/gcc-lib/i686/3.3.1/include
/usr/include
End of search list.
The compiler is now complete, so gcc tells you the assembler command it will use.
as -V -Qy -o /tmp/ccQynbTm.o /tmp/cceCee26.s
And the assembler, as, gives its version info.
GNU assembler version 2.12.90.0.1 (i386-linux)
using BFD version 2.12.90.0.1 20020307 Debian/GNU
Linux
The assembler is now done so gcc gives the linker command. It's using collect2 as an intermediary to the real linker ld, but that's not important here.
/usr/lib/gcc-lib/i686/3.3.1/collect2
--eh-frame-hdr -m elf_i386 -dynamic-linker
/lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o
/usr/lib/gcc-lib/i686/3.3.1/crtbegin.o
-L/usr/lib/gcc-lib/i686/3.3.1
-L/usr/lib/gcc-lib/i686/3.3.1/../../.. /tmp/ccQynbTm.o
-lgcc -lgcc_eh -lc -lgcc -lgcc_eh
/usr/lib/gcc-lib/i686/3.3.1/crtend.o
/usr/lib/crtn.o
The linker gives no verbose output (try -Wl,-v), so that's it.
The "crt" files mean "C RunTime". They are small sections of code inserted at the start of your program, and at the end. They take care of initialising your global variables, heap, and stack. They call atexit functions after you return from main. And some more besides.
Hope that helps.
Can anyone tell me where to find the following files in Cygwin setup.exe?
sys/socket.h
netinet/in_systm.h
netinet/in.h
netinet/ip.h
arpa/inet.h
netdb.h
here is what -v is printing out
$ make
gcc -g -c -v it.c
Using built-in specs.
Target: i686-w64-mingw32
Configured with: ../gcc44-svn/configure --target=i686-w64-mingw32 --host=i686-w6
4-mingw32 --disable-multilib --disable-nls --disable-win32-registry --prefix=/mi
ngw32 --with-gmp=/mingw32 --with-mpfr=/mingw32 --enable-languages=c,c++
Thread model: win32
gcc version 4.4.3 (GCC)
COLLECT_GCC_OPTIONS='-g' '-c' '-v' '-mtune=generic'
c:/strawberry/c/bin/../libexec/gcc/i686-w64-mingw32/4.4.3/cc1.exe -quiet -v -ip
refix c:\strawberry\c\bin\../lib/gcc/i686-w64-mingw32/4.4.3/ it.c -quiet -dumpba
se it.c -mtune=generic -auxbase it -g -version -o C:\Users\AppData\Local\
Temp\ccuWjX0W.s
ignoring nonexistent directory "/mingw32/include"
ignoring duplicate directory "c:/strawberry/c/lib/gcc/../../include"
ignoring duplicate directory "c:/strawberry/c/lib/gcc/../../lib/gcc/i686-w64-min
gw32/4.4.3/include"
ignoring duplicate directory "c:/strawberry/c/lib/gcc/../../lib/gcc/i686-w64-min
gw32/4.4.3/include-fixed"
ignoring duplicate directory "c:/strawberry/c/lib/gcc/../../lib/gcc/i686-w64-min
gw32/4.4.3/../../../../i686-w64-mingw32/include"
#include "..." search starts here:
#include <...> search starts here:
c:\strawberry\c\bin\../lib/gcc/i686-w64-mingw32/4.4.3/../../../../include
c:\strawberry\c\bin\../lib/gcc/i686-w64-mingw32/4.4.3/include
c:\strawberry\c\bin\../lib/gcc/i686-w64-mingw32/4.4.3/include-fixed
c:\strawberry\c\bin\../lib/gcc/i686-w64-mingw32/4.4.3/../../../../i686-w64-ming
w32/include
/mingw/include
End of search list.
GNU C (GCC) version 4.4.3 (i686-w64-mingw32)
compiled by GNU C version 4.4.3, GMP version 4.3.2, MPFR version 2.4.2-p
3.
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 4728d1fc720cf46696475c98813fbdef
i think it is looking in strawberry for the files.
NOTE: netinet/in_system.h is actually spelled netinet/in_systm.h; I've edited your question to correct it.
These should all be part of the cygwin package. You can't have a working Cygwin installation without that package.
They're all under /usr/include.
$ cygcheck -c cygwin
Cygwin Package Information
Package Version Status
cygwin 1.7.16-1 OK
$ cygcheck -l cygwin | wc -l
280
$ cygcheck -l cygwin | egrep 'sys/socket.h|netinet/in_systm.h|netinet/in.h|netinet/ip.h|arpa/inet.h|netdb.h'
/usr/include/netdb.h
/usr/include/netinet/in.h
/usr/include/netinet/in_systm.h
/usr/include/netinet/ip.h
/usr/include/arpa/inet.h
/usr/include/sys/socket.h
$
If those files are missing, you might try reinstalling the cygwin package -- but first make sure you're looking for them in the right place, under /usr/include.
I have a new c++ project built with autoconf, automake and libtool. Functionality is divided up into support libraries and user binaries. There is also a set of unittests binaries which link against these libraries, are built and run at make check time, but are not installed.
I said the the project is new. I'm actually just now getting around to extracting the first library that should be installed. Until now the (small amount of) written code was just compiled directly into a unittests.
My attempted Makefile.am snippet looks like this:
lib_LTLIBRARIES += libfoo.la
libfoo_la_SOURCES = foo.cc
In make check, I get this:
/bin/bash ./libtool --tag=CXX --mode=link g++ -Wall -Wextra -Werror -ansi -fprofile-arcs -ftest-coverage -g -O0 -fprofile-arcs -ftest-coverage -L/usr/local/lib -Wl,-rpath /usr/local/lib -o libfoo.la -rpath /usr/local/lib foo.lo -lboost_thread-mt -lboost_system-mt -pthread
libtool: link: g++ -fPIC -DPIC -shared -nostdlib /usr/lib/gcc/x86_64-linux-gnu/4.6.1/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.6.1/crtbeginS.o .libs/foo.o -L/usr/local/lib -lboost_thread-mt -lboost_system-mt -L/usr/lib/gcc/x86_64-linux-gnu/4.6.1 -L/usr/lib/gcc/x86_64-linux-gnu/4.6.1/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.6.1/../../../../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.1/../../.. -lstdc++ -lm -lc -lgcc_s /usr/lib/gcc/x86_64-linux-gnu/4.6.1/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/4.6.1/../../../x86_64-linux-gnu/crtn.o -fprofile-arcs -O0 -fprofile-arcs -Wl,-rpath -pthread -pthread -Wl,-soname -Wl,libfoo.so.0 -o .libs/libfoo.so.0.0.0
/usr/bin/ld: cannot find libfoo.so.0: No such file or directory
collect2: ld returned 1 exit status
Notice the missing library is precisely the one I'm trying to compile.
(The library is not libfoo, but I am able to reproduce the same error with this stub library. The Makefile.am and error lines above are literal and unedited.)
If I change the automake lines to
check_LTLIBRARIES += libfoo.la
libfoo_la_SOURCES = foo.cc
then the compile looks like this:
/bin/bash ./libtool --tag=CXX --mode=link g++ -Wall -Wextra -Werror -ansi -fprofile-arcs -ftest-coverage -g -O0 -fprofile-arcs -ftest-coverage -L/usr/local/lib -Wl,-rpath /usr/local/lib -o libfoo.la foo.lo -lboost_thread-mt -lboost_system-mt -pthread
libtool: link: ar cru .libs/libfoo.a .libs/foo.o
libtool: link: ranlib .libs/libfoo.a
libtool: link: ( cd ".libs" && rm -f "libfoo.la" && cp -p "../libfoo.la" "libfoo.la" )
..and everything works fine (except my library isn't installed, being in check_.)
Notice the only difference in the command lines is some additional arguments in the 2nd one:
... -Wl,-rpath /usr/local/lib -o libfoo.la -rpath /usr/local/lib foo.lo -lboost_thread-mt ...
I don't know offhand if this new argument shouldn't be there, but it does appear to be causing the problem. Does anyone know what I'm missing?
Some more details:
On osx lion, this works fine (and the command lines are different.) This error manifests on
ubuntu 12.04, possibly other linuxes.
noinst_LTLIBRARIES and EXTRA_LTLIBRARIES work like check_LTLIBRARIES: no extra arguments, and it links. It seems libtool 'convenience' libraries are specifically the ones without these arguments.
automake 1.11.1
autoconf 2.68
libtool 2.4
EDIT
(Manually) dropping -Wl,-rpath /usr/local/lib from the arguments also fixes the problem.
I did it to myself. While bringing in autoconf support for boost, I encountered a bug described here. My work-around followed the suggestion of one post:
diff --git a/m4/boost.m4 b/m4/boost.m4
index 3d4e47c..9dd0c43 100644
--- a/m4/boost.m4
+++ b/m4/boost.m4
## -403,7 +403,7 ## dnl generated only once above (before we start the for loops).
LDFLAGS=$boost_save_LDFLAGS
LIBS=$boost_save_LIBS
if test x"$Boost_lib" = xyes; then
- Boost_lib_LDFLAGS="-L$boost_ldpath -Wl,-R$boost_ldpath"
+ Boost_lib_LDFLAGS="-L$boost_ldpath -Wl,-rpath $boost_ldpath"
Boost_lib_LDPATH="$boost_ldpath"
break 6
else
The -rpath introduced here is the same one apparently causing the issue. If I revert this change, the problem goes away (I am of course left with the first issue, but that's another story.)