Refer:
Http://www.cnblogs.com/hanyan225/archive/2010/10/01/1839906.html
Http://www.west263.com/info/html/wangzhanyunying/jianzhanjingyan/20080417/70218.html
Http://www.cnblogs.com/lidp/archive/2009/12/02/1697479.html
GNU binutils: http://en.wikipedia.org/wiki/GNU_Binutils
Linux static Link (Library), Dynamic Link (Library), executable file loading problems (creation, options, environment variables, etc)
(1) Concepts
Function libraries are generally divided into two types: static linking lib and Dynamic Linking Lib, both Windows and Linux. Of course, the organizational structure and calling method may be different. Here we only describe it for Linux. Therefore, both the dynamic link library and the static Link Library are compiled. Therefore, the link process for the compiler to obtain the static Link Library is static link, and the dynamic link is the same.
The dynamic link library generally uses. So as the suffix, and the static link library uses. A as the suffix.
To use libraries of different versions in the same system, you can add the version number as the suffix after the library file name, but because the program connection uses. So as the file suffix by default. To use these libraries, we usually use the symbolic connection method. As follows:
Ln-s libtest. so.1.0 libtest. So
(2) differences between static and dynamic libraries
First, let's look back at a program, from source code to running, including: compile, Link, load, and execute ), the GNU tool is generally the compiler Compiler (GCC), linker (LD), and loader (the dynamic link library loader is lD. so (ld-linux.version.so), in the/lib directory, such as/lib/ld-linux.so.2, so can not run the ld-linux.so directly in the command line, need the complete path, the loader generally does not need us to run directly, dynamic Loading is included in the loading process of executable programs ). Compilation and links are often referred to as compilation, during which compile
Time), while loading and running are collectively referred to as running, and the period is runtime or execution time (runtime/execution time ).
Static Link Library: compile time is used ). When you link a static library, the linker finds the functions to be linked and copies them to the execution file. This copy is complete, so after the link is successful, static databases are not required for running programs.
Dynamic Link Library: used during compilation and runtime. During compilation, the linker finds the required function (or other object files) and generates position independent code (PIC )), there is no real copy implementation. during runtime (runtime/execution-Time), when a program needs to call a Dynamic Linked Library Function during running, the operating system first checks all running programs to see if the library function has been copied in the memory. If so, let them share the copy. Only no links are loaded.
Note: in Linux, the default link operation is to first consider the dynamic link library, that is, if there is a static and dynamic library at the same time, if not specified, it will be connected to the dynamic library.
(3) how to generate static and dynamic libraries and NM commands
The Code is as follows (both test1 and Test2 are Foo functions, and the printed content is different. The following content uses these two link libraries to learn other content ):
// File: test1.cpp#include <stdio.h>void foo(){printf("This is foo in test1\n");}
// File: test1.h#ifndef TEST1_H#define TEST1_Hvoid foo();#endif
// File: test2.cpp#include <stdio.h>void foo(){printf("This is foo in test2\n");}
// File: test2.h#ifndef TEST2_H#define TEST2_Hvoid foo();#endif
1. Static link.:
First, compile the intermediate file. O:
#lstest1.cpp test1.h test2.cpp test2.h#gcc -c test1.cpp -o test1.o#gcc -c test2.cpp -o test2.o#lstest1.cpp test1.h test1.o test2.cpp test2.h test2.o#
Then, use the AR command to package the. A file:
#ar crv libtest1.a test1.oa - test1.o#lslibtest1.a test1.cpp test1.h test1.o test2.cpp test2.h test2.o
(Libtest2.a can be obtained in the same way. Note: a. A is obtained from a. o)
Command:Ar
Note: If you need To Package Multiple. O files into one. A, you can list all. O files directly. In addition, the AR command has many options,. A already exists. Insert a module (. o), how to deal with existing. O and other processing conditions are not discussed in detail here. Generally, the CRV option is used. C indicates that no matter whether. A already exists or not to create a new. A file, r indicates to insert a module (replace) into the library ). If the inserted Module name already exists in the Database, replace the module with the same name. If one of the modules does not exist in the library, ar displays an error message and does not replace other modules with the same name. By default, new members are added at the end of the database, and other options can be used to change the position of the added member. V indicates that detailed operation information is displayed. Specific Use of AR reference: http://www.west263.com/info/html/wangzhanyunying/jianzhanjingyan/20080417/70218.html
The nm command is used to list the symbols of the target document, not only for. A, but also for. So. It is not described in detail. Generally, Nm file or nm-o file are commonly used (the information will be more detailed), as shown below:
#ar crv libtest1.a test1.oa - test1.o#ar crv libtest2.a test2.oa - test2.o#ar crv libtest12.a test1.o test2.o a - test1.oa - test2.o#nm libtest1.a test1.o:0000000000000000 T _Z3foov U puts#nm libtest2.a test2.o:0000000000000000 T _Z3foov U puts#nm libtest12.a test1.o:0000000000000000 T _Z3foov U putstest2.o:0000000000000000 T _Z3foov U puts#
2. Obtain the dynamic link. So:
First, use the-FPIC option of GCC to compile the intermediate file of the PIC (location-independent code.
Then, use the-shared option of GCC to link the. o file.
As follows:
# Gcc-C-FPIC test1.cpp-O test1.o # gcc-C-FPIC test2.cpp-O test2.o # gcc-shared test1.o-O libtest1.so # gcc-shared test2.o-O libtest2.so # gcc-shared test1.o test2.o-O libtest12.sotest2. o: In function 'foo () ': test2.cpp :(. text + 0x0): Multiple definition of 'foo () 'test1. o: test1.cpp :(. text + 0x0): first defined herecollect2: LD returns 1 #
(We can also see from here that the dynamic link library generated by GCC will check whether there are repeated definitions, and the static packaging ar command above will not check .)
Note: you must use the-FPIC option for compiling. Otherwise, a link error occurs when you use-shared to generate a dynamic link library. Of course, the above is a separate compilation and link, and can also be completed together, without the-C option, such as gcc-FPIC-shared test. C-o libtest. So.
Common usage of nm when viewing. So:
The preceding section describes how to use nm to view the. A file. For. So, the following options are usually used:
(Reference: http://blog.sina.com.cn/s/blog_5dc87df60100bike.html
Http://www.cppblog.com/noflybird/archive/2010/05/06/114618.aspx
Http://apps.hi.baidu.com/share/detail/20625788)
-C: use C/C ++ to display the function name (the function name will be slightly changed after compilation, demangle and mangle ).
-G: displays only external symbols.
I usually use the function defined in the dynamic link library as shown in the following figure (you can also use this function to view. A better ):
nm -C -g libtest1.so -A
Or use t to filter the result:
nm -C -g libtest1.so -A | grep T
As follows:
#nm -C -g libtest1.so -A | grep Tlibtest1.so:000000000000057c T foo()libtest1.so:00000000000005cc T _finilibtest1.so:0000000000000460 T _init
Summary:
1. how to generate a static Link Library: first compiled by GCC. o file, use the AR command to package. o file (ar crv xxx. a xxx. O xxx1.o xxx2.o ...).
2. How to generate a dynamic link library: Use gcc-FPIC to compile the. o file and use the-shared option to link it.
3. view the symbolic file of the static and dynamic link libraries: Nm. You can also view the symbolic files of other files. For example, in the form of nm-C-G libtest1.so/libtest1.a-A | grep T.
4. After the above tossing, get the following file (which will be used below ):
#lslibtest12.a libtest1.a libtest1.so libtest2.a libtest2.so test1.h test2.h#
(4) "original" use of static and dynamic link libraries
Test procedure:
// File: main.cpp#include "test1.h"int main(){foo();return 0;}
1. Link to static Library:
Directly participate in the link:
#lslibtest12.a libtest1.a libtest2.a main.cpp test1.h test2.h#gcc main.cpp libtest1.a #./a.out This is foo in test1#
Of course, you can also separate the compilation and link. First, GCC-C main. cpp-O main. O gets main. O, and then GCC main. O libtest1.a.
This is the simplest way to link to a static library. It is directly used as an input parameter (input file) of GCC for the link. The more complex case is that the library to be linked is not in the current directory. Of course, you must specify the file path (relative path or absolute path) as follows:
#lslib main.cpp test1.h test2.h#gcc main.cpp ./lib/libtest1.a#./a.out This is foo in test1#
2. Link to dynamic library:
Directly participate in the Link, just like the static Link Library, gcc xxx. cpp xxx. so libs/ABC/xxx. so ....., the database to be linked is passed as the input file parameter to GCC.
#lslib main.cpp test1.h test2.h#gcc main.cpp lib/libtest1.so #./a.out This is foo in test1#
Conclusion: The above is the most "original" Method for connecting static and dynamic libraries. That is, the library file is used as the GCC input file. The rule is similar to the source file and the target file, whether relative or absolute paths are used, GCC must be able to find them directly. In this way, you cannot use-l or copy libtest1.so to/lib or/usr/lib to simplify it to "GCC main. CPP libtest1.so "(of course, libtest1.so is not in the current directory ). Note: This is very basic, but after a long time, I am confused, thinking that-l can also play a role in this primitive situation (GCC main. cpp
Libtest1.so-L./lib, in which libtest1.so is in the Lib folder ).
(5) use-L and-l to link static and dynamic libraries
The original link to a dynamic library has one drawback: You must specify the relative or absolute path of the library to be linked. In one case, if our program needs to be linked to some libraries, for example, Linux provides many libraries, such as pthread libraries, if you need to link them, of course, you can use the complete path. As follows:
#gcc /lib64/libpthread.so.0 main.cpp lib/libtest1.so #
This disadvantage is obvious. For improvement, GCC provides the-l method to simplify this problem. In the GCC option, use-lxxxx to specify the name of the library to be linked, and the corresponding library name is libxxx. so or libxxx. so. At the same time, this library exists in the "System Library directory. For Linux, the default system library directories are/lib and/usr/lib (or/lib64 and/usr/lib64, which are not discussed here ). In addition, the-L option is used to add a specified directory to the "System Library" category, which is actually added to the library search path of the linker.
Therefore, for the above example, you can:
A. Copy libtest1.so to/lib or/usr/lib. You can use gcc-ltest1 main. cpp to compile it.
B. If libtest1.so is not in the search path (/lib and/usr/lib), an error similar to/usr/bin/ld: cannot find-ltest1. You can use-L to add the specified directory to the search path, for example:
#lslib main.cpp test1.h test2.h#gcc -ltest1 main.cpp -Llib#gcc -ltest1 main.cpp -L./lib#
As for the static library, the rules are the same as those above. The system library directory and-l are abbreviated as well as-L to add search paths. However, by default, GCC is dynamically linked. To use static links, you must use the-static option. After the-static option is used, all the libraries specified by-l will search for the corresponding. A static library in the search path. In addition, it should be noted that-static will also change the link mode of the default Link Library of GCC, and will also link static libraries (about the default Link Library of GCC, such as libc, by default, dynamic libraries are used. If-static is used, it is linked to libc. A static library, which is the default Link Library of GCC will be introduced below ).
(6) GCC-include and-I Parameters
This content has nothing to do with the content here, but it is generally discussed with-L, so I will explain it here. -Include is used to include header files. It has the same function as # include, and is rarely used. It is generally used in code # include. -I is used to specify the search path for the additional "system header file", which corresponds to features similar to the-L option.
For # include with <>, the header file will be searched by the system header file (/usr/include). If some header files are not in the path of the system header file, you must use-I to specify them.
PS:-I and-l can both be specified under a command line to add multiple paths, such as gcc-LXXX Foo. CPP-llib1/-llib2/-llib3.
(7) load and run executable files and LDD commands
The above content is about how to compile and link and get executable files. In fact, some executable files in the above example cannot be executed.
For programs that link static libraries, since static links directly copy code to executable files, the linked executable files can be independent of static libraries. A runs directly, so the problem is mainly about running the program using the dynamic library. For programs that use dynamic libraries, an important step in the program loading process is the loading of dynamic libraries (sometimes referred to as dynamic links of dynamic libraries ), loader for/lib/ld-linux.so (refer to http://blog.csdn.net/gengshenghong/article/details/7096511's (3) understanding ).
The search path sequence of a dynamic library is as follows:
1. The dynamic library search path specified when the target code is compiled;
2. The dynamic library search path specified by the Environment Variable LD_LIBRARY_PATH;
3. configuration file/etc/lD. so. the dynamic library search path specified in conf; // you only need to append the full path of a library in this file, such as "/root/test/CONF/lib, then ldconfig is modified to take effect.
4. Default dynamic library search path/LIB;
5. The default dynamic library search path is/usr/lib.
Let's take a look at the following example to illustrate a problem:
#tree.├── lib│ ├── libtest1.so│ └── libtest2.so├── libtest1.so├── libtest2.so├── main.cpp├── test1.h└── test2.h1 directory, 7 files#gcc main.cpp libtest1.so #./a.out ./a.out: error while loading shared libraries: libtest1.so: cannot open shared object file: No such file or directory#gcc main.cpp ./libtest1.so #./a.out This is foo in test1#gcc main.cpp lib/libtest1.so #./a.out This is foo in test1#gcc main.cpp /home/sgeng2/labs_temp/temp/libtest1.so #./a.out This is foo in test1
Here, the GCC main. cpp libtest1.so compilation is successful. If you run the command, you can use./If you cannot find the shared library. Of course, in any of the above cases, deleting. So after the link will certainly not work. So, what if it is the following situation:
#lslib libtest1.so libtest2.so main.cpp test1.h test2.h#gcc main.cpp ./libtest1.so #./a.out This is foo in test1#../temp/a.out This is foo in test1#cd ..#temp/a.out temp/a.out: error while loading shared libraries: ./libtest1.so: cannot open shared object file: No such file or directory#
You will find that the GCC Mai. CPP. /libtest1.so after compilation, this ". the/libtest1.so "information is saved. Therefore, you can only run. out. If CD is switched to another directory, it will still be searched. /libtest1.so cannot be found. If the LIB/libtest1.so link is used here, the same is true. During running, a lib/libtest1.so file is required in the current working directory. If the path is absolute, so of course, as long. so is not deleted and can be run. It can be seen that this is the most "original" link method, which is still silly and limited.
Summary: This method uses the "original" method to link the executable file ,. the so path information is saved in the executable file and needs to be searched during loading. whether so exists. The above mentioned "search sequence of search paths of dynamic libraries", which is used for dynamic link libraries linked using-L and-l, the "original" method is not changed here, for example, using gcc main. CPP. after compiling/libtest1.so, it is useless to copy libtest1.so to/usr/lib. (In my personal understanding, this original compilation method of the specified path should belong to the "dynamic library search path specified during compilation of the target code". Of course, generally speaking, the dynamic library search path specified when the target code is compiled refers to another option, which is described in the next section ).
LDD command: The LDD command is used to display all dependencies in an executable file. the so location in the current system is simply understood as it simulates the loading of executable files and outputs each file. so file path, such as the Order of all the above paths, put in different paths. so, the path obtained by LDD will display the path found by the actual loader. If you cannot find. So or. So, the LDD will also report an error.
(8) The dynamic library search path specified when the target code is compiled "-wl,-rpath ,"
GCC provides-wl,-rpath, and XXX to specify the path for searching the dynamic library when the program is running. It has no relationship with-L.-WL and-rpath are specified during compilation, however, it is used for the loader during runtime, so it is a special option and is easy to be confused with-L. Note:-wl,-rpath, and path specified by XXX. If a relative path is used, the relative path is used for searching during running. so, in fact, it is essentially the same as the "original" method mentioned above.
This option can specify multiple paths separated. For example, GCC-wl,-rpath, path1: path2: path3 main. cpp-ltest-llib.
Summary:
1. for static libraries, you can use the "original" method (specify the path as the GCC input parameter) to link the static library, or use the-L &-l method. However, you must use the-static option. In addition, the default GCC link method is dynamic. Therefore, if-static is used, the default GCC Link Library is also linked to the static version.
2. when using the "original" method (specifying the path as the GCC input parameter) to link a dynamic library, there are too many runtime restrictions and how to compile the link is required, it is necessary to ensure that the dynamic link library can be found according to the current path at runtime. Of course, this method is rarely used. Generally, it uses-L &-L to link the dynamic link library.
3. use-L for link. so, the compiler will find the path specified by-L in/lib,/usr/lib, and-l. so file. The search sequence is-l specified path;/usr/lib;/lib.
4. When using-l link. So. Search by path. so file to load and run. When loading, the search path of the dynamic library is sequential: the dynamic library search path specified when the target code is compiled; the dynamic library search path specified by the Environment Variable LD_LIBRARY_PATH; configuration file/etc/lD. so. the dynamic library search path specified in conf; the default dynamic library search path/LIB; the default dynamic library search path/usr/lib.
5. -wl,-rpath is used to specify the dynamic library search path when compiling the target code. It has nothing to do with-L. A specified path is used for loading during runtime. so search. A specified path is used for the compile-time link. so.
(9) link multiple databases (multiple databases have the same function definition)
For example, the two. A files define the function Foo and then participate in the link. Which one is actually used? What if it is two. So? One. A and one. So?
(10) supplement:
1. About the search path
The above has summarized the related header file and library file search path issues. It should be noted that the actual GCC search path may also be related to other factors, for example, some environment variable settings, and GCC will add the Lib folder or include folder in the installation directory to the search path, including changing the default settings through options such as sysroot, for more information, see http://blog.csdn.net/gengshenghong/article/details/7108634. Of course, to better understand this information, GCC also provides several related commands to view relevant information.
Gcc-print-search-dirs: print the search path for installation, programs, and libraries. The output example is as follows:
# GCC -- print-search-dirs installation:/usr/lib/GCC/x86_64-redhat-linux/4.6.0/Program: =/usr/libexec/GCC/x86_64-redhat-linux/4.6.0 /: /usr/libexec/GCC/x86_64-redhat-linux/4.6.0/:/usr/libexec/GCC/x86_64-redhat-linux/:/usr/lib/GCC/x86_64-redhat-linux/4.6.0 /: /usr/lib/GCC/x86_64-redhat-linux/:/usr/lib/GCC/x86_64-redhat-linux/4.6.0 /.. /.. /.. /.. /x86_64-redhat-linux/bin/x86_64-redhat-linux/4.6.0/:/usr/lib/GCC/x86_64-redhat-linux/4.6.0 /.. /.. /.. /.. /x86_64-redhat-linux/bin/Library: =/usr/lib/GCC/x86_64-redhat-linux/4.6.0/:/usr/lib/GCC/x86_64-redhat-linux/4.6.0 /.. /.. /.. /.. /x86_64-redhat-linux/lib/x86_64-redhat-linux/4.6.0/:/usr/lib/GCC/x86_64-redhat-linux/4.6.0 /.. /.. /.. /.. /x86_64-redhat-linux/lib /.. /lib64/:/usr/lib/GCC/x86_64-redhat-linux/4.6.0 /.. /.. /.. /x86_64-redhat-linux/4.6.0/:/usr/lib/GCC/x86_64-redhat-linux/4.6.0 /.. /.. /.. /.. /lib64/:/lib/x86_64-redhat-linux/4.6.0/:/lib /.. /lib64/:/usr/lib/x86_64-redhat-linux/4.6.0/:/usr/lib /.. /lib64/:/usr/lib/GCC/x86_64-redhat-linux/4.6.0 /.. /.. /.. /.. /x86_64-redhat-linux/lib/:/usr/lib/GCC/x86_64-redhat-linux/4.6.0 /.. /.. /.. /:/lib/:/usr/lib /#
Gcc-V file. C: displays the detailed information when file. C is compiled. (the detailed information about the search header files, LIBRARY_PATH, and compiler_path are displayed. You can also directly use gcc-V to display the basic configuration information of GCC.
Gcc-dumpspecs: displays all built-in spec strings.
Gcc-DM-e file. C: displays all macro definitions in pre-processing file. C.
In short, the GCC search path is still a bit complex, and you do not need to remember all the details, but at least you need to know what needs to be considered.
2. -- sysroot option of GCC
This option is generally used for cross-compilation. It is used to specify the header file required for compilation and the link library (root directory.
3. GCC environment variables and configuration options
Http://www.linuxsir.org/bbs/thread304996.html
Http://blog.csdn.net/yangruibao/article/details/6869323
Http://jimobit.blog.163.com/blog/static/28325778200991524826935/