Default Libraries Linked in by Gcc

Default libraries linked in by gcc?

The -v option to gcc will cause it to dump information about the default options it will use including the library paths and default libraries and object files that will be linked in.

If you give the -Wl,--verbose option, gcc will pass the --verbose to the linker which will dump exactly where it's looking for libraries, including both failed and successful searches.

Combine both options, and you'll see exactly what libraries are linked in, and why they're being linked in.

gcc -v foo.c -Wl,--verbose

Libraries that are linked by default

  1. linux-gate.so isn't really a shared lib, but a part of the kernel that acts like one and makes fast system calls possible. ld-linux.so is a piece of code that makes loading other shared libraries possible. libc.so is the C library, containing standard functions like printf and strcpy.
  2. main doesn't belong to any library. It belongs to your program, in the sense that its assembled version is stored entirely in the test binary file.
  3. return is not a function but a C language construct.
  4. No, it also links in libgcc, which is apparently not a shared library on your system (or it would show up) and some startup code. g++ would additionally link in libstdc++.so (the C++ standard library) and libm.so (the math part of the C standard library).

GCC Default Link -l

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

How to let gcc print ALL libraries linked?

$ gcc -o hello -Xlinker -v hello.c 
collect2 version 4.6.3 (x86-64 Linux/ELF)
/usr/bin/ld --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 -o hello /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/../../.. -v /tmp/ccvjXRF7.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
GNU ld (GNU Binutils for Ubuntu) 2.22

-Xlinker --verbose will give even more info, including exactly which libraries are resolved and included. An excerpt:

attempt to open /usr/lib/gcc/x86_64-linux-gnu/4.6/libgcc.so failed
attempt to open /usr/lib/gcc/x86_64-linux-gnu/4.6/libgcc.a succeeded
attempt to open /usr/lib/gcc/x86_64-linux-gnu/4.6/libgcc_s.so succeeded
-lgcc_s (/usr/lib/gcc/x86_64-linux-gnu/4.6/libgcc_s.so)
attempt to open /usr/lib/gcc/x86_64-linux-gnu/4.6/crtend.o succeeded
/usr/lib/gcc/x86_64-linux-gnu/4.6/crtend.o
attempt to open /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crtn.o succeeded
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crtn.o
ld-linux-x86-64.so.2 needed by /lib/x86_64-linux-gnu/libc.so.6
found ld-linux-x86-64.so.2 at /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2

To list just the dynamically linked libaries, run ldd on the resulting binary.

$ ldd hello
linux-vdso.so.1 => (0x00007fff68dad000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fac49f46000)
/lib64/ld-linux-x86-64.so.2 (0x00007fac4a323000)

How does gcc decide which libraries to implicitly include?

When configuring a toolchain, the authors decide which libraries that should be linked to by default.

Often this is includes runtime startup/initializing code and a library named libc which includes an implementation of the C standard, and any other code the authors deem relevant (e.g. libc might also implement Posix, any custom board specific functions etc.) and for embedded targets it's not unusual to also link to a library implementing an RTOS for the target.

You can use the -nodefaultlibs flag to gcc to omit these default libraries at the linking stage.

In the case of assert(), it is a standard C macro/function , which is normally implemented in libc. assert() might print to stdout if it fails, so using assert() could pull in the entire stdio facility that implements FILE* handling/buffering, printf etc., all which is implemented in libc.

You can see the libraries that gcc links to by default if you run gcc -v for the linking stage.

Why does gcc/clang know to link to libc by default?

Why does gcc/clang know to link automatically?

The GCC developers built this into GCC as a convenience. Which libraries are linked by default is partly affected by the language being compiled, which is deduced from the file names and may be controlled with the -x switch.

Where is this behavior mentioned?

This page in the GCC documentation mentions there are some libraries linked in by default and says you can disable or modify this behavior with -nostdlib and other switches, but I do not see an explicit list of the libraries that are linked in by default. It might vary by system/platform as well as by language. You can use the -v switch to ask GCC to show you the commands it is executing, and the link command (using ld) should reveal the libraries.

gcc or g++ path search order on default directories when linking libraries

From the binutils ld manual section 3.4.2 Commands Dealing with Files:

SEARCH_DIR(path)

The SEARCH_DIR command adds path to the list of paths where ld looks for archive libraries. Using SEARCH_DIR(path) is exactly like using `-L path' on the command line (see Command Line Options). If both are used, then the linker will search both paths. Paths specified using the command line option are searched first.

So, yes, as the default directories are given in the default linker script using this SEARCH_DIR() command, they will be searched in the order the SEARCH_DIR() commands appear.

E.g., in my mingw installation, the default linker script starts like this:

/* Default linker script, for normal executables */
/* Copyright (C) 2014-2017 Free Software Foundation, Inc.
Copying and distribution of this script, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. */
OUTPUT_FORMAT(pei-i386)
SEARCH_DIR("=/mingw32/i686-w64-mingw32/lib");
SEARCH_DIR("=/mingw32/lib");
SEARCH_DIR("=/usr/local/lib");
SEARCH_DIR("=/lib");
SEARCH_DIR("=/usr/lib");

--> A library in /usr/local/lib can override libraries in /lib and /usr/lib, but not libraries provided by mingw itself.

Where/When to link against the Standard C Library when compiling C programs?

Essentially every hosted C implementation requires you to link programs with an implementation of the standard C library.

Some commands for building programs have the inclusion of the standard C library built-in as a default, so you do not need to add it explicitly on the command library. Some commands do not have it as a default, so you do need to add it on the command line.



Related Topics



Leave a reply



Submit