Chapter 16. Using Libraries with GCC
Chapter 16. Using Libraries with GCC This chapter describes how to use libraries in code. 16.1. Library Naming Conventions A special file name convention is used for libraries: A library known as foo is expected to exist as the file lib foo .so or lib foo .a . This convention is automatically understood by the linking input options of gcc , but not by the output options: When linking against the library, the library can be specified only by its name foo with the -l option as -l foo : When creating the library, the full file name lib foo .so or lib foo .a must be specified. Additional Resources Section 17.2, "The soname Mechanism" 16.2. Static and dynamic linking Developers have a choice of using static or dynamic linking when building applications with fully compiled languages. This section lists the differences, particularly in the contexti of using the C and C++ languages on Red Hat Enterprise Linux. To summarize, Red Hat discourages the use of static linking in applications for Red Hat Enterprise Linux. Comparison of static and dynamic linking Static linking makes libraries part of the resulting executable file. Dynamic linking keeps these libraries as separate files. Dynamic and static linking can be compared in a number of ways: Resource use Static linking results in larger executable files which contain more code. This additional code coming from libraries cannot be shared across multiple programs on the system, increasing file system usage and memory usage at run time. Multiple processes running the same statically linked program will still share the code. On the other hand, static applications need fewer run-time relocations, leading to reduced startup time, and require less private resident set size (RSS) memory. Generated code for static linking can be more efficient than for dynamic linking due to the overhead introduced by position-independent code (PIC). Security Dynamically linked libraries which provide ABI compatibility can be updated without changing the executable files depending on these libraries. This is especially important for libraries provided by Red Hat as part of Red Hat Enterprise Linux, where Red Hat provides security updates. Static linking against any such libraries is strongly discouraged. Additionally, security measures such as load address randomization cannot be used with a statically linked executable file. This further reduces security of the resulting application. Compatibility Static linking appears to provide executable files independent of the versions of libraries provided by the operating system. However, most libraries depend on other libraries. With static linking, this dependency becomes inflexible and as a result, both forward and backward compatibility is lost. Static linking is guaranteed to work only on the system where the executable file was built. Warning Applications linking static libraries from the GNU C library ( glibc ) still require glibc to be present on the system as a dynamic library. Furthermore, the dynamic library variant of glibc available at the application's run time must be a bitwise identical version of the one present while linking the application. As a result, static linking is guaranteed to work only on the system where the executable file was built. Support coverage Most static libraries provided by Red Hat are in the Optional channel and not supported by Red Hat. Functionality Some libraries, notably the GNU C Library ( glibc ), offer reduced functionality when linked statically. For example, when statically linked, glibc does not support threads and any form of calls to the dlopen() function in the same program. As a result of the listed disadvantages, static linking should be avoided at all costs, particularly for whole applications and the glibc and libstdc++ libraries. Note The compat-glibc package is included with Red Hat Enterprise Linux 7, but it is not a run time package and therefore not required for running anything. It is solely a development package, containing header files and dummy libraries for linking. This allows compiling and linking packages to run in older Red Hat Enterprise Linux versions (using compat-gcc-\ * against those headers and libraries). For more information on use of this package, run: rpm -qpi compat-glibc-* . Reasons for static linking Static linking might be a reasonable choice in some cases, such as: A library which is not enabled for dynamic linking Fully static linking can be required for running code in an empty chroot environment or container. However, static linking using the glibc-static package is not supported by Red Hat. Additional Resources Red Hat Enterprise Linux 7: Application Compatibility GUIDE 16.3. Using a Library with GCC A library is a package of code which can be reused in your program. A C or C++ library consists of two parts: The library code Header files Compiling Code That Uses a Library The header files describe the interface of the library: The functions and variables available in the library. Information from the header files is needed for compiling the code. Typically, header files of a library will be placed in a different directory than your application's code. To tell GCC where the header files are, use the -I option: Replace include_path with the actual path to the header file directory. The -I option can be used multiple times to add multiple directories with header files. When looking for a header file, these directories are searched in the order of their appearance in the -I options. Linking Code That Uses a Library When linking an executable file, both the object code of your application and the binary code of the library must be available. The code for static and dynamic libraries is present in different forms: Static libraries are available as archive files. They contain a group of object files. The archive file has the file name extension .a . Dynamic libraries are available as shared objects. They are a form of executable file. A shared object has the file name extension .so . To tell GCC where the archives or shared object files of a library are, use the -L option: Replace library_path with the actual path to the library directory. The -L option can be used multiple times to add multiple directories. When looking for a library, these directories are searched in the order of their -L options. The order of options matters: GCC cannot link against a library foo unless it knows the directory of this library. Therefore, use the -L options to specify library directories before using the -l options for linking against libraries. Compiling and Linking Code Which Uses a Library in One Step When the situation allows the code to be compiled and linked in one gcc command, use the options for both situations mentioned above at once. Additional Resources Using the GNU Compiler Collection (GCC) - 3.16 Options for Directory Search Using the GNU Compiler Collection (GCC) - 3.15 Options for Linking 16.4. Using a Static Library with GCC Static libraries are available as archives containing object files. After linking, they become part of the resulting executable file. Note Red Hat discourages the use of static linking for various reasons. See Section 16.2, "Static and dynamic linking" . Use static linking only when necessary, especially against libraries provided by Red Hat. Prerequisites GCC is installed on your system Understanding of static and dynamic linking A set of source or object files forming a valid program, requiring some static library foo and no other libraries The foo library is available as a file libfoo.a , and no file libfoo.so is provided for dynamic linking. Note Most libraries which are part of Red Hat Enterprise Linux are supported for dynamic linking only. The steps below only work for libraries which are not enabled for dynamic linking. See Section 16.6, "Using Both Static and Dynamic Libraries with GCC" . Procedure To link a program from source and object files, add a statically linked library foo , which is named libfoo.a : Change to the directory containing your code. Compile the program source files with headers of the foo library: Replace header_path with the path to the directory containing the header files for the foo library. Link the program with the foo library: Replace library_path with the path to the directory containing the file libfoo.a . To execute the program, run: Caution The -static GCC option related to static linking forbids all dynamic linking. Instead, use the -Wl,-Bstatic and -Wl,-Bdynamic options to control linker behavior more precisely. See Section 16.6, "Using Both Static and Dynamic Libraries with GCC" . 16.5. Using a Dynamic Library with GCC Dynamic libraries are available as standalone executable files, required at both linking time and run time. They stay independent of your application's executable file. Prerequisites GCC is installed on the system A set of source or object files forming a valid program, requiring some dynamic library foo and no other libraries The foo library available as a file libfoo.so Linking a Program Against a Dynamic Library To link a program against a dynamic library foo : When a program is linked against a dynamic library, the resulting program must always load the library at run time. There are two options for locating the library: Using an rpath value stored in the executable file itself Using the LD_LIBRARY_PATH variable at runtime Using an rpath Value Stored in the Executable File The rpath is a special value saved as a part of an executable file when it is being linked. Later, when the program is loaded from its executable file, the runtime linker will use the rpath value to locate the library files. While linking with GCC , to store the path library_path as an rpath : The path library_path must point to a directory containing the file libfoo.so . Caution There is no space after the comma in the -Wl,-rpath= option To run the program later, execute: Using the LD_LIBRARY_PATH Environment Variable If no rpath is found in the program's executable file, the runtime linker will use the LD_LIBRARY_PATH environment variable. The value of this variable must be changed for each program according to the path where the shared library objects are located. To run the program without rpath set, with libraries present in the library_path , execute: Leaving out the rpath value offers flexibility, but requires setting the LD_LIBRARY_PATH variable every time the program is to run. Placing the Library into the Default Directories The runtime linker configuration specifies a number of directories as a default location of dynamic library files. To use this default behaviour, copy your library to the appropriate directory. A full description of the dynamic linker behavior is out of scope for this document. For more information, see the following resources: Linux manual pages for the dynamic linker: Contents of the /etc/ld.so.conf configuration file: Report of the libraries recognized by the dynamic linker without additional configuration, which includes directories: 16.6. Using Both Static and Dynamic Libraries with GCC Sometimes it is required to link some libraries statically and some dynamically. Prerequisites Understanding of static and dynamic linking Introduction gcc recognizes both dynamic and static libraries. When the -l foo option is encountered, gcc will first attempt to locate a shared object (a .so file) containing a dynamically linked version of the foo library, and then look for the archive file ( .a ) containing a static version of the library. Thus, the following situations can result from this search: Only the shared object is found and gcc links against it dynamically Only the archive is found and gcc links against it statically Both the shared object and archive are found; gcc selects by default dynamic linking against the shared object Neither shared object nor archive is found and linking fails Because of these rules, the best way to select the static or dynamic version of a library for linking is having only that version found by gcc . This can be controlled to some extent by using or leaving out directories containing the library versions when specifying the -L path options. Additionally, because dynamic linking is the default, the only situation where linking must be explicitly specified is when a library with both versions present should be linked statically. There are two possible solutions: Specifying the static libraries by file path instead of the -l option Using the -Wl option to pass options to the linker Specifying the static libraries by file Usually, gcc is instructed to link against a library foo with the -l foo option. However, it is possible to specify the full path to the file lib foo .a containing the library instead: From the file extension .a , gcc will understand that this is a library to link with the program. However, specifying the full path to the library file is a less flexible method. Using the -Wl option The gcc option -Wl is a special option for passing options to the underlying linker. Syntax of this option differs from the other gcc options. The -Wl option is followed by a comma-separated list of linker options, while other gcc options require a space-separated list of options. The ld linker used by gcc offers the options -Bstatic and -Bdynamic to specify whether libraries following this option should be linked statically or dynamically, respectively. After passing -Bstatic and a library to the linker, the default dynamic linking behaviour must be restored manually for the following libraries to be linked dynamically with the -Bdynamic option. To link a program, linking a library first statically ( libfirst.a ) and second dynamically ( libsecond.so ), run: Note gcc can be configured to use linkers other than the default ld . The -Wl option applies to the gold linker, too. Additional Resources Using the GNU Compiler Collection (GCC) - 3.15 Options for Linking Documentation for binutils 2.32 - 2.1 Command Line Options
gcc ... -l foo gcc ... -I include_path gcc ... -L library_path -l foo gcc ... -I header_path -c gcc ... -L library_path -l foo ./program gcc ... -L library_path -l foo gcc ... -L library_path -l foo -Wl,-rpath= library_path ./program export LD_LIBRARY_PATH= library_path :USDLD_LIBRARY_PATH ./program man ld.so cat /etc/ld.so.conf ldconfig -v gcc ... path/to/libfoo.a gcc ... -Wl,-Bstatic -l first -Wl,-Bdynamic -l second