For most people who are not engaged in C language development on the Linux platform, the use of a tool set of GNU gcc and a shared library on the Linux platform is still very unfamiliar. In fact, I am not very familiar with it either, let's write some basic knowledge, and use the right as a memo.
I. Usage of GNU gcc compilation tools
Let's first write a simple C program: Hello. C code
- # Include <stdio. h>
- Void print_hello (){
- Printf ("Hello world \ n ");
- }
- Int main (INT argc, char argv []) {
- Print_hello ();
- Return 0;
- }
# Include <stdio. h> void print_hello () {printf ("Hello world \ n");} int main (INT argc, char argv []) {print_hello (); Return 0 ;}
Defines a print_hello function and calls the main function to print Hello world.
How to compile it? C code
- Gcc-O hello-O2 hello. c
Gcc-O hello-O2 hello. c
The-O parameter specifies the name of the generated executable program.-O2 indicates the optimization level. This command will compile and generate a hello executable program. Check the file: ls-l Hello C code.
- -Rwxr-XR-x 1 Robbin users 11939 hello
-Rwxr-XR-x 1 Robbin users 11939 hello
The size is 11 kb.
Let's see which systems are linked to the dynamic library. Run the LDD command: C code.
- LDD hello
LDD hello
Output Information: C code
- Libc. so.6 =>/lib64/tls/libc. so.6 (0x0000002a9566d000)
- /Lib64/ld-linux-x86-64.so.2 (0x0000002a95556000)
Libc. so.6 =>/lib64/tls/libc. so.6 (0x0000002a9566d000)/lib64/ld-linux-x86-64.so.2 (0x0000002a95556000)
Libc is a C standard function library, and LD is a dynamic linker.
Next, let's take a look at the symbols in the hello program. Run the NM command: C code.
- NM hello
NM hello
Output: C code
- 201710000005008f8 A _ bss_start
- 2017100000040043c t call_gmon_start
- ......
- 00000000004004f0 t Main
- 0000000000500658 D p.0
- 201710000004004e0 t print_hello
- U puts @ glibc_2.2.5
- 0000000000400410 T _ start
201710000005008f8 A _ 0000t call_gmon_start ...... 2017100000000004004f0 t main00000000000000500658 D p.0000000000000004004e0 t print_hello U puts @ glibc_2.2.5000000400410 T _ start
Some are omitted in the middle, but we can still find the function definition in the symbol table.
Hello, It has a size of 11 kb, which is too large. You can use the Strip command to reduce the size of the location symbol table.
- Strip hello
Strip hello
Then LS-l Hello, and the output is: C code
- -Rwxr-XR-x 1 webuser users 4464 hello
-Rwxr-XR-x 1 webuser users 4464 hello
It's only 4.4kb, And the slimming effect is obvious! However, this symbol table can no longer be seen. The output of NM hello is: NM: Hello: no symbols.
Finally, if we want to extract some text information from the executable program, we can also use the strings command: C code
- Strings hello
Strings hello
Output Information: C code
- /Lib64/ld-linux-x86-64.so.2
- SuSE
- Libc. so.6
- Puts
- _ Libc_start_main
- _ Gmon_start __
- Glibc_2.2.5
- T fff
- Hello World
/Lib64/ld-linux-x86-64.so.2SuSElibc.so.6puts _ libc_start_main _ gmon_start _ glibc_2.2.5t fffhello world
Kindly remind you that if you write helloworld. Java in Java, you can also use strings after compilation.
Ii. How to Use the dynamic shared library
This time, we split hello. c into two files: Hello. C and Main. C. The code for hello. C is: C code
- # Include <stdio. h>
- Void print_hello (){
- Printf ("Hello world \ n ");
- }
# Include <stdio. h> void print_hello () {printf ("Hello world \ n ");}
The main. C code is: C code
- Int main (INT argc, char argv []) {
- Print_hello ();
- Return 0;
- }
Int main (INT argc, char argv []) {print_hello (); Return 0 ;}
Hello. C is our dynamic shared library. In hello. C, we declare and implement various public functions. Finally, Main. C can call these public functions. First, we need to compile hello. c into a dynamic Shared Library:
C code
- Gcc-O libhello. So-O2-FPIC-shared hello. c
Gcc-O libhello. So-O2-FPIC-shared hello. c
-FPIC parameter Declaration: the code segment of the Linked Library can be shared.-shared parameter declaration is compiled as a shared library. Note that the name of the shared library we compiled this time is libhello. So, which is also a naming convention for the Linux Shared Library: The suffix uses so, and the name uses libxxxx format.
Then, when compiling main. C, we need more parameters to let GCC know how to find the Shared Library: C code
- Gcc-O main-O2-L.-lhello main. c
Gcc-O main-O2-L.-lhello main. c
-L the parameter specifies which additional path to search for the shared library. Now we specify the path under the current directory;
-L parameter specifies the shared library to which the link is located. If the parameter hello is passed, GCC will automatically link to libhello. so the shared library above (note the libxxxx mentioned above. so naming rules );
-The I parameter specifies which additional path to search for the H file. This is not used.
Finally, we have compiled the main file and executed it. The error is: reference./main: Error while loading shared libraries: libhello. So: cannot open shared object file: no such file or directory.
Why can't I find the shared library libhello. So? This is because libhello. So is not in the default shared library path of the operating system. We can temporarily specify the link path: C code
- Export LD_LIBRARY_PATH =.: $ LD_LIBRARY_PATH
Export LD_LIBRARY_PATH =.: $ LD_LIBRARY_PATH
In this way, the operation is successful. Let's take a look at the C code using LDD main.
- Libhello. So =>./libhello. So (0x0000002a9566d000)
- Libc. so.6 =>/lib64/tls/libc. so.6 (0x0000002a9576e000)
- /Lib64/ld-linux-x86-64.so.2 (0x0000002a95556000)
Libhello. So =>./libhello. So (0x0000002a9566d000) libc. so.6 =>/lib64/tls/libc. so.6 (bytes)/lib64/ld-linux-x86-64.so.2 (0x0000002a95556000)
The main program is linked to the shared library libhello. So.
Iii. Linux dynamic shared library settings
The executable program cannot find the dynamic shared library to be linked. This is an easy problem to compile and run the program on Linux. Through the small example above, we have a general understanding of the basic principles of shared libraries. Next we will discuss how to set up programs to find dynamic shared libraries.
The dynamic shared libraries in Linux are roughly divided into three types:
1. Shared operating system library and Basic System Tool Library
For example, libc. so, libz. so, libpthread. so and so on. These system libraries will be placed under the/lib and/usr/lib directories. For a 64-bit operating system, there will also be the/lib64 and/usr/lib64 directories. If the operating system has a graphical interface, the/usr/x11r6/lib directory is available. If the operating system is a 64-bit operating system, the/usr/x11r6/lib64 directory is also available. In addition, there may be other system library directories for specific Linux versions.
The complete and correct versions of these system library files Ensure that various programs on Linux can run normally.
2. Application-level system shared libraries
Libraries shared by many applications are usually stored in the/usr/local/lib and/usr/local/lib64 directories. Many programs that you compile and install automatically add/usr/local/lib to the GCC-l parameter during compilation, when running, shared libraries are automatically searched under/usr/local/lib.
The above two types of dynamic shared libraries will be automatically searched by the application, without additional settings and worries. Why? These directories are added to the search path of the Dynamic Link program by default. The search path of the shared library in Linux is defined in the configuration file/etc/lD. So. conf. The content format of this file is roughly as follows:
C code
- /Usr/x11r6/lib64
- /Usr/x11r6/lib
- /Usr/local/lib
- /Lib64
- /Lib
- /Usr/lib64
- /Usr/lib
- /Usr/local/lib64
- /Usr/local/ImageMagick/lib
/Usr/x11r6/lib64/usr/x11r6/lib/usr/local/lib/lib64/lib/usr/lib64/usr/lib/usr/local/lib64/usr/local /ImageMagick/lib
Suppose that the ImageMagick graphics library we compiled and installed is in the/usr/local/ImageMagick directory, and other applications want to use the dynamic sharing library of ImageMagick, then we only need to add the/usr/local/ImageMagick/lib directory to the/etc/lD. so. in the conf file, run the ldconfig command.
Ldcofig searches all the preceding directories and creates a cache file/etc/lD. So. cache for the shared library. To confirm that ldconfig has searched the ImageMagick library, we can use the strings command described above to extract text information from LD. So. cache and check it:
C code
- Strings/etc/lD. So. cache | grep ImageMagick
Strings/etc/lD. So. cache | grep ImageMagick
The output result is: C code.
- /Usr/local/ImageMagick/lib/libwand. so.10
- /Usr/local/ImageMagick/lib/libwand. So
- /Usr/local/ImageMagick/lib/libmagick. so.10
- /Usr/local/ImageMagick/lib/libmagick. So
- /Usr/local/ImageMagick/lib/libmagick ++. so.10
- /Usr/local/ImageMagick/lib/libmagick ++. So
/Usr/local/ImageMagick/lib/libwand. so.10/usr/local/ImageMagick/lib/libwand. so/usr/local/ImageMagick/lib/libmagick. so.10/usr/local/ImageMagick/lib/libmagick. so/usr/local/ImageMagick/lib/libmagick ++. so.10/usr/local/ImageMagick/lib/libmagick ++. so
It is successful!
3. Dynamic shared libraries exclusive to applications
Many shared libraries are only used by specific applications, so there is no need to add the path to the system library to avoid version conflicts between shared libraries of applications. Therefore, Linux can also set the environment variable LD_LIBRARY_PATH to temporarily specify the shared library search path for the application, just as in the example above, we can pre-set LD_LIBRARY_PATH in the startup script of the application to specify the shared library search path appended to the application so that the application can find it.