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
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 likeprintf
andstrcpy
.main
doesn't belong to any library. It belongs to your program, in the sense that its assembled version is stored entirely in thetest
binary file.return
is not a function but a C language construct.- 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 inlibstdc++.so
(the C++ standard library) andlibm.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
How to Create and Initialize an Array of Values Using Template Metaprogramming
C++ Overloaded Virtual Function Warning by Clang
Forcing Nvidia Gpu Programmatically in Optimus Laptops
How to Convert Typename T to String in C++
Garbage Collection Libraries in C++
Using Emit VS Calling a Signal as If It's a Regular Function in Qt
What's the Best Way to Check If a File Exists in C++? (Cross Platform)
Dereferencing a Pointer When Passing by Reference
Check the File-Size Without Opening File in C++
Which Is Faster/Preferred: Memset or for Loop to Zero Out an Array of Doubles
C++ Concatenating _File_ and _Line_ MACros
Why Should I Initialize Member Variables in the Order They'Re Declared In
Static_Assert on Initializer_List::Size()
How to Initialize All Elements in an Array to the Same Number in C++
C++11 Memory_Order_Acquire and Memory_Order_Release Semantics