The creation and use of GCC compiled C (C++) static link library (gcc -L, gcc -l) and dynamic link library (gcc -fPIC -shared)

1. Library files

The so-called library file, readers can be equivalent to a compressed package file, the file usually contains more than one object file (that is, binary file).

It is worth mentioning that the code stored in each object file in the library file is not a complete program, but a practical functional module. For example, a Clanguage library provides a number of functions (such as scanf(), printf(), strlen()etc.), C++library functions provide not only have to use, there are a large number of pre-designed classes (such as stringString class).

The generation of the library file greatly improves the programmer's development efficiency, because many functions do not need to be developed from 0 at all, just call the library file containing the function directly. Also, call the library method is also very simple to Clanguage printf()output function, for example, the program just introduced <stdio.h>the header file, you can call the printf()function.

Why is the header file involved when calling the library file? First of all, header files and library files are not the same thing. The biggest difference between them is:

  • The header file only stores the declaration part of these functional modules such as variables, functions or classes;
  • The library file is responsible for storing the specific implementation parts of each module;

Readers can understand this way: all library files are provided with corresponding header files as the interface to call it. In other words, library files cannot be used directly, and can only be called indirectly through header files.

The biggest advantage of the combined access mechanism of header files and library files is that sometimes we only want others to use the functions we have implemented, and do not want to disclose the source code of the functions. We can make them as library files so that users can obtain It is a binary file, and the header file only contains the declaration part, so that the purpose of "hiding the source code" is realized without affecting the user's use.

In fact, library files are just a general term, referring to a type of compressed package, they all contain functional and practical object files. You should know that although the library file is used in the linking phase of the program, the compiler provides two ways to achieve linking, which are called static linking and dynamic linking.

  • The library files that use static linking to achieve linking operations are called static link libraries;
  • A library file that uses dynamic linking to achieve linking operations is called a dynamic link library;

In C, C++the actual development process, in addition to using the system library files, we can create a static link library or DLL according to actual needs, manually.

2. Static Link Library

The static link library realizes the link operation in a very simple way, that is, where the function module in the library file is used in the program file, the GCCcompiler will directly copy the template code to the appropriate location of the program file, and finally generate an executable file.

Using static library files to implement program linking operations has both advantages and disadvantages:

  • The advantage is that the generated executable file can run independently without the support of any static library file (strong portability);
  • The disadvantage is that if the same function module in the library is called multiple times in the program file, the module code will inevitably be copied multiple times, and the generated executable file will contain multiple pieces of identical code, causing code redundancy.

Compared with the executable file generated by the dynamic link library, the executable file generated by the static link library has a larger volume.

  • In the Linuxrelease version of the system, the extension of static link library files usually .arepresent;
  • In the Windowssystem, the suffix static link library file name .lib;

2.1 Create a static link library

A static link library is actually equivalent to a compressed package, which can contain multiple source files. But it should be noted that not any source file can be processed into a static link library, it needs to meet at least the following two conditions:

  • Source files only provides the code can be reused, such as functions, etc. designed, can not contain mainthe main function;
  • While the source file realizes the module function, it also provides an interface to access it, that is, the header file that contains the declaration part of each function module;

Sample code structure:

wohu@ubuntu:~/cpp/src$ tree
.
├── function.h
├── greeting.cpp
├── main.cpp
└── name.cpp

0 directories, 4 files
wohu@ubuntu:~/cpp/src$ 

function.h Code

void sayGreetings();
void sayName();

greeting.cppThe code, which contains it #include "function.h", does not need to include the header file when the static library is not created.

#include <iostream>
#include "function.h"

void sayGreetings()
{
    
    
    std::cout << "hello,world" << std::endl;
}

name.cppThe code, which is included #include "function.h", does not need to include the header file when the static library is not created.

#include <iostream>
#include "function.h"

void sayName()
{
    
    
    std::cout << "My name is wohu" << std::endl;

}

main.cpp Code

#include <iostream>
#include "function.h"

int main()
{
    
    
    sayGreetings();
    sayName();
    return 0;
}

For name.cppand greeting.cppare in line with the above two conditions, it can be processed into a static link library. And according to actual needs, we can compress them collectively into a static link library, or each can be compressed into a static link library.

The process of packaging the source file as a static link library is very simple, just go through the following 2 steps:

  1. Compile all specified source files into corresponding target files
wohu@ubuntu:~/cpp/src$ g++ -c greeting.cpp  name.cpp 
wohu@ubuntu:~/cpp/src$ ls
function.h  greeting.cpp  greeting.o  main.cpp  name.cpp  name.o
wohu@ubuntu:~/cpp/src$ 
  1. Then using arcompressed instructions, the generated object files into a static link library, the basic format is as follows:
ar rcs 静态链接库名称 目标文件1 目标文件2 ...

About arcompression packing instructions, as well as rcsthe meaning and function of each option, please refer to the Linux ar command

The important point is that the static link library cannot be named arbitrarily, and the following naming rules must be followed:

libxxx.a
  • LinuxUnder the system, the suffix of the static link library is .a;
  • WindowsUnder the system, the suffix of the static link library is .lib;

Among them, xxxon behalf of that we played for the library name, such as Linuxthe system comes with some static link library name libc.a, , libgcc.a, libm.atheir names are c, gccand m.

Next, pack greeting.oand name.opackage into a static link library:

wohu@ubuntu:~/cpp/src$ ar rcs libmyfunction.a name.o greeting.o 
wohu@ubuntu:~/cpp/src$ ls
function.h  greeting.cpp  greeting.o  libmyfunction.a  main.cpp  name.cpp  name.o
wohu@ubuntu:~/cpp/src$ 

Among them, libmyfunction.athat is name.o, greeting.opackaged together generated static link library, myfunctiona library name our custom.

2.2 Use static link library

The use of the static link library is very simple, that is, in the linking stage of the program, the static link library and other object files are linked together to generate an executable file.

Using the previous code as an example, we will first main.cppfile is compiled into object files:

wohu@ubuntu:~/cpp/src$ g++ -c main.cpp 
wohu@ubuntu:~/cpp/src$ ls
function.h  greeting.cpp  greeting.o  libmyfunction.a  main.cpp  main.o  name.cpp  name.o
wohu@ubuntu:~/cpp/src$ 

On this basis, we can directly execute the following commands to complete the link operation:

wohu@ubuntu:~/cpp/src$ g++ -static main.o libmyfunction.a 
wohu@ubuntu:~/cpp/src$ ls
a.out  function.h  greeting.cpp  greeting.o  libmyfunction.a  main.cpp  main.o  name.cpp  name.o
wohu@ubuntu:~/cpp/src$ 

Among them, -staticthe option to force GCCthe compiler to use a static link library.

Note that if GCCthe compiler can not find the tips libmyfunction.a, you can also use the following link operation is accomplished:

wohu@ubuntu:~/cpp/src$ g++ -static main.o -L /home/wohu/cpp/src -lmyfunction
wohu@ubuntu:~/cpp/src$ ls
a.out  function.h  greeting.cpp  greeting.o  libmyfunction.a  main.cpp  main.o  name.cpp  name.o

among them,

  • -L(Uppercase L) option is used to GCCspecify the storage location of the static compiler link library (can use pwd command to view specific storage location);
  • -l(Lowercase L) option is used to indicate the name of the required static link library, pay attention to names used herein refers to the xxxpart, and will recommend -land xxxdirect conjunction (ie -lxxx), without intermediate spaces.

As a result, it generates a.outan executable file:

wohu@ubuntu:~/cpp/src$ ./a.out 
hello,world
My name is wohu
wohu@ubuntu:~/cpp/src$ 

3. Dynamic Link Library

Dynamic link library, also known as shared link library. Different from static link library, when the dynamic link library is used to realize the link operation, where the function module of the library file is needed in the program file, the GCCcompiler will not directly copy the code of the function module to the file, but will copy the location information of the function module Record to the file, and directly generate the executable file.

Obviously, the executable file generated in this way cannot run independently. When the executable file generated by the dynamic link library is run, the GCCcompiler will load the corresponding dynamic link library into the memory together. Since the position information of the required function module is recorded in the executable file in advance, the existing dynamic link library It can also run successfully with the support of.

The advantages and disadvantages of using the dynamic link library to realize the connection operation of the program are just the opposite of the static link library:

  • The advantage is that because the executable file records the address of the function module, the real implementation code will be loaded into the memory when the program is running, which means that even if the function module is called multiple times, the same implementation code is used (This is also the reason why the dynamic link library is called a shared link library).
  • The disadvantage is that the executable file generated by this method cannot be run independently, and the corresponding library file must be used (poor portability).

Compared with the executable file generated by the static link library, the executable file generated by the dynamic link library has a smaller volume, because a bunch of redundant codes will not be copied inside.

  • In the Linuxrelease version of the system, the extension dynamic link library is usually .sorepresented;
  • In the Windowssystem, the suffix dynamic link library named .dll;

GCCWhen the compiler generates an executable file, it will give priority to the use of the dynamic link library to achieve the link operation by default. Unless there is no dynamic link library required by the program file in the current system environment, the GCCcompiler will select the corresponding static link library. If both are not (or GCCcompiler not found), the link fails.

3.1 Create a dynamic link library

In general, there are two ways to create a dynamic link library.

  1. Directly create dynamic link library source files, using the gccbasic format of the command is implemented as follows:
gcc -fpic -shared 源文件名... -o 动态链接库名

among them,

  • -shared Option is used to generate dynamic link library;
  • -fpic(Also written as -fPICfunction) option is to make GCCthe compiler generate dynamic link library (archive multiple object files), indicates the address of each object file functions, classes, and other functional modules use a relative address, rather than absolute address. In this way, no matter where the link library is loaded into the memory in the future, it can be used normally.

For example, the front of the project greeting.cpp, name.cppthese two source files to generate a dynamic link library, execute the command as follows:

wohu@ubuntu:~/cpp/src$ g++ -fPIC -shared name.cpp  greeting.cpp  -o libmyfunction.so 
wohu@ubuntu:~/cpp/src$ ls
function.h  greeting.cpp  libmyfunction.a  libmyfunction.so  main.cpp  name.cpp
wohu@ubuntu:~/cpp/src$ 

Note that the naming of dynamic link libraries and statically linked libraries are identical, but in the Linuxrelease system, its extension with .sorepresentation; Windowssystem suffix .dll.

  1. First use gcc -cinstruction to specify the source files are compiled into object files, and then build a dynamic link library file from the target

Note that when the follow-up to generate dynamic link library and can be used normally, the source files are compiled into object files, also need to use the -fpicoption.

wohu@ubuntu:~/cpp/src$ g++ -c -fPIC name.cpp greeting.cpp  
wohu@ubuntu:~/cpp/src$ ls
function.h  greeting.cpp  greeting.o  libmyfunction.a  main.cpp  name.cpp  name.o
wohu@ubuntu:~/cpp/src$ 

On this basis, use the object file generated in the previous step to generate a dynamic link library:

wohu@ubuntu:~/cpp/src$ g++ -shared greeting.o name.o -o libmyfunction.so
wohu@ubuntu:~/cpp/src$ ls
function.h  greeting.cpp  greeting.o  libmyfunction.a  libmyfunction.so  main.cpp  name.cpp  name.o
wohu@ubuntu:~/cpp/src$ 

3.2 Use dynamic link library

Through the study in the previous chapters, we know that the use scenario of dynamic link library is to participate in linking with other source files or target files in the project. Using the previous example, for example, we will be in front greeting.cpp, name.cpppacked into a libmyfunction.sodynamic link library, in which case the project remaining main.cppsource files, so it evolved into the implementation of the demo project main.cppand libmyfunction.solink, and then generate an executable file.

Note that the function.h header file does not directly participate in the compilation, because in the preprocessing stage of the program, the header files that need to be used in the project have been processed.

Execute the following instructions to successfully generate an executable file with the help of the dynamic link library:

wohu@ubuntu:~/cpp/src$ g++ main.cpp  libmyfunction.so -o main
wohu@ubuntu:~/cpp/src$ ls
function.h  greeting.cpp  greeting.o  libmyfunction.a  libmyfunction.so  main  main.cpp  name.cpp  name.o
wohu@ubuntu:~/cpp/src$ 

Note that the generated executable files mainusually can not be directly implemented, such as:

wohu@ubuntu:~/cpp/src$ ./main 
./main: error while loading shared libraries: libmyfunction.so: cannot open shared object file: No such file or directory
wohu@ubuntu:~/cpp/src$ 

We can see, the implementation process can not find libmyfunction.sodynamic link library. By executing ldd maininstruction, you can view all dynamic link library file is currently in the implementation need to use, as well as the storage location of each library file:

wohu@ubuntu:~/cpp/src$ ldd main 
        linux-vdso.so.1 =>  (0x00007fffb17ea000)
        libmyfunction.so => not found
        libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f548673a000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5486370000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f5486067000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f5486abc000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f5485e51000)
wohu@ubuntu:~/cpp/src$ 

You can see, mainthe executable file needs the support of seven dynamic link library, including libmyfunction.so, but the file can not be found, so mainthe implementation will fail.

When running the executable file generated by the dynamic link library, you must ensure that the program can find the dynamic link library when it is running. The commonly used solutions are as follows:

  • The link library file to the standard library directory (eg /usr/lib, /usr/lib64, /lib, /lib64);
  • Type in the terminal
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:xxx

Wherein xxxthe absolute path stored in dynamic link library file (in this embodiment is only valid in the current terminal, the terminal is invalid after closing);

  • Modify ~/.bashrcor ~/.bash_profilefile, the file is added in the last line
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:xxx

Which xxx, after an absolute path to the dynamic link library file storage, preservation, execute source bashrccommand (this way only the current logged in user valid).

In this example, the second option is used, which is to enter at the terminal

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/wohu/cpp/src

To the mainsuccessful implementation.

wohu@ubuntu:~/cpp/src$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/wohu/cpp/src
wohu@ubuntu:~/cpp/src$ ldd main 
        linux-vdso.so.1 =>  (0x00007ffddc5fa000)
        libmyfunction.so (0x00007f017bec9000)
        libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f017bb47000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f017b77d000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f017b474000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f017c0cb000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f017b25e000)
wohu@ubuntu:~/cpp/src$ ./main 
hello,world
My name is wohu
wohu@ubuntu:~/cpp/src$ 

Guess you like

Origin blog.csdn.net/wohu1104/article/details/110789570