Ld
lastmod 2025-01-22created 2014-09-2580 edits
The GNU linker (or GNU ld) is the GNU Project's implementation of the Unix command ld. GNU ld runs the linker, which creates an executable file (or library) from the object files generated during compilation of software. A linker script can be passed to GNU ld to exercise greater control over the linking process. The GNU linker is part of the GNU Binary Utilities (binutils).
The suggested origins of the name "ld" include "LoaD" and "Link eDitor".
The GNU linker is free software and is distributed under the GNU General Public License.
Category
GNU Linker
BSD Linker
Used on Mac OSX and others. In GCC, see the Darwin Options. 1
Flags
-
-headerpad {size} - Specifies the minimum space for future expansion of the load commands. Only useful if intend to run install_name_tool to alter the load commands later. Size is a hexadecimal number.
-
-headerpad_max_install_names - Automatically adds space for future expansion of load commands such that all paths could expand to MAXPATHLEN. Only useful if intend to run install_name_tool to alter the load commands later.
- Since the executable's header information may be changed by install_name_tool and the like, this reserves the maximum space defined by
MAXPATHLEN. (Needs verification)
-
-compatibility_version {number} - Specifies the compatibility version number of the library. When a library is loaded by dyld, the compatibility version is checked and if the program's version is greater that the library's version, it is an error. The format of number is X[.Y[.Z]] where X must be a positive non-zero number less than or equal to 65535, and .Y and .Z are optional and if present must be non-negative numbers less than or equal to 255. If the compatibility version number is not specified, it has a value of 0 and no checking is done when the library is used. This option is also called -dylib_compatibility_ver-sion for compatibility.
- Specifies the compatibility version number of the library. The format of
{number}isX[.Y[.Z]], with the following constraints on the values.- 0 < X <= 65535
- [Optional] 0 <= .Y <= 255
- [Optional] 0 <= .Z <= 255
-
-current_version {number} - Specifies the current version number of the library.
- Specifies the current version of the library.
-
-search_paths_first - This is now the default (in Xcode4 tools). When processing -lx the linker now searches each directory in its library search paths for
libx.dylib' thenlibx.a' before the moving on to the next path in the library search path.
About the sections of the ld program
When working on bootloaders or other firmware, you end up manipulating ld scripts. People usually copy and reuse them, but with a little understanding they are easy to modify.
-
.text: code area. -
.bss: area for variables that exist outside functions and have no initial value. Even variables initialized to 0 are not included in the bss area. -
.data: area for variables that exist outside functions and have an initial value. Variables initialized to 0 are also included here. -
.rodata: read-only variables, variables declared const. -
.got: Global Offset Table, start addresses related to shared libraries.
LD_LIBRARY_PATH vs LIBRARY_PATH
Two-line summary:
-
LD_LIBRARY_PATH- searched when the program starts, -
LIBRARY_PATH- searched at link time.
For reference:
-
DYLD_LIBRARY_PATH- the macOS version ofLIBRARY_PATH. -
DYLD_FALLBACK_LIBRARY_PATH- paths to search if a library is not found inDYLD_LIBRARY_PATHabove.
See #rpath below for details.
Link order
An example related to link order follows.
main.c:
temp.h:
temp.c:
Assume each was built as an archive.
Linking as below then produces an error.
$ gcc temp.a main.a
main.a(main.o):main.c:(.text+0xe): undefined reference to `temp'
collect2.exe: error: ld returned 1 exit status
You must swap the order as below. Linking as below then produces an error.
In short, link in the order {referencing library} -> {implementing library}.
If you don't want to worry about the order, use --start-group and --end-group.
How does ld.so find shared libraries?
- By default it looks in
/libor/use/lib. It also looks in the paths specified in/etc/ld.so.conf, and searches the paths specified inLD_LIBRARY_PATHset up for each account. - For newly added libraries, add the relevant path under the
/etc/ld.so.conf.ddirectory. 2 - Caveat: it looks in the paths specified in
/etc/ld.so.conf, so when you change its contents or upgrade or install system libraries, you must run the ldconfig command to generate/etc/ld.so/chche, the shared library cache thatld.souses when searching paths.
Checking the library load order
Set the LD_DEBUG environment variable to files and run the file you want.
Linker search path list
- How to print the ld(linker) search path
- Why does g++ look in LIBRARY_PATH/../lib64 and where is this documented?
Use any one of the following methods.
ldconfig -v 2>/dev/null | grep -v ^$'\t'
ld --verbose | grep SEARCH_DIR | tr -s ' ;' \\012
gcc -print-search-dirs | sed '/^lib/b 1;d;:1;s,/[^/.][^/]*/\.\./,/,;t 1;s,:[^=]*=,:;,;s,;,; ,g' | tr \; \\012
gcc -Xlinker -v
gcc -Xlinker --verbose
gcc --print-search-dirs
List of found libraries
Use any one of the following methods.
soname
- Wikipedia (en) explanation of soname
- KLDP: question about library soname
- [Recommended] glibc shared library symbol versioning 3
- KLDP: Linux compiled binary compatibility problems
- (soname links here.)
In Unix operating systems, soname is a field within a shared object file. The soname provides the system with backward version compatibility information. In short, if a program requests version 1.0 of a shared object but the system only has version 2.0, the system can look at the soname field in the shared object to determine whether it can use version 2.0 instead of version 1.0.
How to use
- KLDP: About the -soname option when building shared libraries...
- Static and shared libraries (see the explanation of soname)
- [Recommended] Stackoverflow: "ld: unknown option: -soname" on OS X
GCC Version:
clang Version:
$ clang -dynamiclib test.o -o libtest.1.0.dylib -install_name,libtest.1.0.dylib -current_version 1.0.6 -compatibility_version 1.0
rpath
- Wikipedia (en) rpath
- Understanding libraries 1
- Using the GNU linker LD - Invocation (see the
-rpathand-rpath-linkoptions) - Stackoverflow: I don't understand -Wl,-rpath -Wl,
- @executable path, @load path and @rpath
- –rpath and dynamic library linking
- Understanding dynamic libraries (shared library) and the Linker/Loader
rpath is a term in programming which refers to a run-time search path hard-coded in an executable file or library, used during dynamic linking to find the libraries the executable or library requires.
In a word, it is a real-time library search path. The Linux dynamic linker uses these paths to find the required shared objects. It is also called RUNPATH.
You can check it with tools such as readelf on Linux systems and otool on darwin systems.
How to use
You can check or modify it with methods like the following.
$ objdump -x {file} | grep RPATH
$ readelf -d {file} | head -20
$ otool -D {file} ## to view the install name of a dylib
$ otool -L {file} ## to view the dependencies (<code>@rpath</code>가 붙는다.)
$ otool -l {file} | grep LC_RPATH -A2 ## to view the RPATHs
$ install_name_tool -id ... ## to change an install name
$ install_name_tool -change ... ## to change the dependencies
$ install_name_tool -rpath ... -add_rpath ... -delete_rpath ... ## to change RPATHs
How to assign
Assign the rpath as below. Put the directory path in the {dir} part.
- #GNU Linker:
-Wl,-rpath={dir} - #BSD Linker:
-Wl,-rpath,{dir}
Note that using the #BSD Linker method is also compatible with the #GNU Linker.
MacOSX RPath
You can specify the rpath using DYLD_LIBRARY_PATH, which plays the same role as LD_LIBRARY_PATH on Linux. However, it must be exported. Note that if a library is not found, DYLD_FALLBACK_LIBRARY_PATH is consulted.
You probably won't need them often, but commercial Unix systems use the following environment variables.
- Solaris:
LD_LIBRARY_PATH - AIX:
LIBPATH - HP-UX:
SHLIB_PATH
Install name
(This section can be reached via install_name.)
- [Recommended] Linking and Install Names on Mac OS X 4
- @executable path, @load path and @rpath
- Linking and Install Names on Mac OS X
A path name embedded in a dynamic library to tell the linker where to find that dynamic library at runtime.
-
@executable_path - Useful for frameworks embedded inside applications, because it allows you to specify the location of the framework relative to the application’s executable
- If, when writing an application, you cannot install a framework in
/Libraryor a similar location and must embed it inside the application, setting the install name to an absolute path becomes an awkward problem. - The Mac solution for this case is
@executable_path. If you set a library's install name to start with@executable_path, that string is replaced with the path from which the executable was loaded. - For example, if you link
Bar.appwithFoo.frameworkandBar.appis installed in/Applications,@executable_pathexpands to/Applications/Bar.app/Contents/MacOS. If you want to include the framework inContents/frameworks, just set the install name ofFoo.frameworksto@executable_path/../Frameworks/Foo.framework/Versions/A/Foo. - The dynamic linker expands this path to
/Applications/Bar.app/Contents/MacOS/../Frameworks/Foo.framework/Versions/A/Footo find the framework.
-
@loader_path - Available from Mac OS X 10.4 Tiger onwards; useful for frameworks embedded inside plug-ins, because it allows you to specify the location of the framework relative to the plug-in’s code (remember, plug-ins may not actually know where they are going to be installed, relative to the application, so knowing @executable_path doesn’t help us in this case)
- Sometimes the location of the executable alone is not enough. Consider a framework or plug-in that embeds another framework. Say
Foo.frameworkembedsBaz.framework. It isFoo.frameworkthat requestsBaz.frameworkto be loaded, but the dynamic linker uses the path ofBar.appfor@executable_path, and this cannot work properly. - Use
@loader_path, available since Mac OS 10.4. Its value is the full path, excluding the last path component, of whatever caused the target library to be loaded (whether a framework or a plug-in).
-
@rpath - @rpath instructs the dynamic linker to search a list of paths in order to locate the framework
- In theory the above should be enough, but in practice there are cases where it is a problem. The problem is that a single copy of a library can only be used in one way. If you want
Foo.frameworkto work both when embedded in some application and when installed in/Libary/Frameworks, you have to distribute two versions of the framework, each with its own install name. Or you have to modify the install name during installation with the install_name_tool command. In the end it is possible, but still an awkward problem. - Since Mac OS 1.05, you can solve this problem with
@rpath. If the install name starts with@rpath, the dynamic linker searches a list recording library locations. Because this list is included in the application, it is created when the application is built, not when the framework is built. So a single copy of a framework can be used for various purposes at the time the application is made. - To make this work, the install name of
Foo.frameworkmust be set to@rpath/Foo.framework/Versions/A/Foo. An application that embedsFoo.frameworkpasses the-rpath @executable_path/../Frameworksoption to the linker at build time. This makes the dynamic linker look for the framework at the given path instead of@rpath. An application that installsFoo.frameworkin/Library/Frameworkscan use the-rpath /Library/Frameworkslink option so that the dynamic linker looks in that path. If for some reason you don't want to choose between the two at build time, just pass both options to the linker, and the dynamic linker will try both paths to find the framework.
How to use
Documentation
- Ns-3_Application_Note_-_linker-problems.pdf
- A summary of linker-related problems.
See also
- gcc
- GNU Binutils
- autotools
- ldconfig: configures the cache of shared program libraries.
- ldd: checks shared library dependencies.
- ltrace: library call tracing.
- nm
- readelf
- otool
- install_name_tool
- objdump
- Shared Library
- [Recommended] CMake RPATH handling
- Nm#Find symbol bash script: finds object files (
*.o) in subdirectories and searches them for the desired symbol. - chrpath: a tool for editing the rpath in ELF binaries
Favorite site
References
-
Adding and managing System Libraries (ldconfig command, /etc/ld.so.conf.d files) ↩
-
Glibc_-_shared_library_symbol_version.pdf ↩
-
Out_of_Bedlam_-_Mac_OS_X_Linking_and_Install_Names.pdf ↩
-
Using_static_and_shared_libraries_across_platforms.pdf ↩
-
Korea.gnu.org.zip -
manual/release/ld/ld-sjp/ld-ko_toc.html↩