Generate a library and so library in linux environment

1. Method of compiling link library (a library and so library)
Generally , the link library in the Linux environment is divided into a library and so library, which represent static link library and dynamic link library respectively. Its function is to compile the C program into a kind of Executable link file, c main program file calls the function interface of these programs can use a library or so library, in the main program only need to include the header file containing the function interface declaration provided in the library.
In the linux environment, use the ar command to create a static library file. The following are the options of the command:          
d ----- delete the file from the specified static library file          
m ----- move the file to the specified static library file          
p ----- output the file specified in the static library file to standard output          
q ----- quickly append the file to the static library file          
r ----- insert the file into the static library file          
t - ----Display the list of files in the static library file           x ----- There are several modifiers
for extracting files from the static library file.       Modify the above basic options. For details, please man ar The command line format of the ar command is as follows:       ar [ -]{dmpqrtx}[abcfilNoPsSuvV] [membername] [count] archive files... The parameter archive defines the name of the library, files is the list of object files contained in the library file, and separates each file with a space. For example, to create a static library The command for the file is as follows: 



ar -r libapue.a error.o errorlog.o lockreg.o
Dynamic library
1. Create a shared library gcc -fPIC -shared -o libapue.so error.o errorlog.o This creates a shared library!.
2. Compile the shared library Assuming that the shared library is located in the current directory (that is, in the same directory as the program file) gcc -o test -L. -lapue test.c This will compile an executable file that does not contain function code, but you run You will find that the linux dynamic loader cannot hit the libapue.so file. You can use the ldd command to check what shared libraries the executable file depends on: ldd test How can the dynamic loader find the library file? There are two ways to solve it: LD_LIBRARY_PATH environment Variables and /etc/ld.so.conf file    
1). Environment variable export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:."    
2). Modify /etc/ld.so.conf file. Located in /etc/ld.so.conf General application The library files of the program are not placed in the same directory as the system library files. Generally, the shared library files of the application are placed under /usr/local/lib, create a new directory of its own, apue, and then copy the libapue.so just now. That's it. At the same time, add a new line in /etc/ld.so.conf: /usr/local/lib/apue and then add the compile option when compiling the program: -L/usr/local/lib/apue -lapue This will do Use this libapue.so shared library.

There are three ways to link the standard library under Linux (full static, semi-static (libgcc, libstdc++), full dynamic) and their respective advantages and disadvantages.

Standard library connection method Example connection options advantage shortcoming
fully static -static -pthread -lrt -ldl Standard library incompatibilities of applications under different Linux versions do not occur. The generated files are relatively large, and the
application functions are limited (cannot call dynamic libraries, etc.)
full dynamic -pthread -lrt -ldl Makefile is the smallest of the three
It is easy to cause the incompatibility of the standard library dependencies of applications under  different Linux versions.
Semi-static (libgcc, libstdc++) -static-libgcc -L. -pthread -lrt -ldl It has great flexibility and can adopt different linking strategies for different standard libraries,
so as to avoid incompatibility problems.
It combines the advantages of full static and full dynamic linking methods.
It is difficult to identify which libraries are prone to incompatibility problems, and
currently only rely on experience accumulation.
Some functionality is lost depending on the selected standard library version.
Second, a library and so library generation example
1. Generate a library
First , you need to write a few source files of the functions you want to call, such as print.cpp, sum.ccpp and so on. The code is as follows:
//print.h
#include <stdio.h>
void printhello();
//print.cpp
#include "print.h"
void printhello()
{
 printf("Hello, world\n");
}
//sum.h
#include <stdio.h>
void sum(int a,int b);
//sum.cpp
#include "sum.h"
void sum(int a,int b)
{
 int r = 0;
 r = a + b;
 return r;
}
Start compiling, compiling the source files into .o files. The command line instructions are as follows:
g++ -c print.cpp sum.cpp
Then start to generate the a library, the instructions are as follows:
ar rcs libtest.a print.o sum.o
Note: The link library prefix must start with lib After
getting the libtest.a library file , and then link the .a library to the main program, write the main program main.cpp and the header file main.h.
//main.h
int printhello();
int sum(int a,int b);
//main.cpp
#include "main.h"
int main(void)
{
 printhello();
 int a = sum(10,1);
 printf("%d\n",a);
 return 0;
}
load a library, generate an executable file and execute it, the instructions are as follows: g++ main.cpp -L. -ltest -o test
2. Generate the so library The instructions for generating the .so library
using the print.cpp and sum.cpp written above are as follows:
g++ print.cpp sum.cpp -fPIC -shared -o libtest.so
The prefix of the same so library must be lib , and then link the .so library to the main program main.c. You need to pay attention here. Because of the characteristics of the dynamic library, the compiler will go to the specified directory to find the dynamic library. The address of the directory is /etc/ld.so.conf In the libc.conf file in the .d/ directory, you can add a line of address to indicate the location of your so library. After changing the content in the conf file, remember to enter the command line: ldconfig.
You can also copy the so library to the default directory. Here is the so library copied to the default directory, the executable file is generated and run, the instructions are as follows:
g++ main.cpp -L. -ltest -o test
The difference between the static link library and the dynamic link library is that before the main program runs, the link of the static link library is fixedly written in the program, while the dynamic link library is loaded and linked every time the program runs.
When loading the dynamic link library, you may encounter an error that cannot be loaded. The reason is that your dynamic library is not found in the dynamic link library path loaded by the system by default. There are three solutions:
1. When executing gcc main.c Before -L. -ltest -o main, execute export LD_LIBRARY_PATH=$(pwd):$LD_LIBRARY_PATH
2. Write the directory where your so is located to the /etc/ld.so.conf file, and then execute ldconfig.
3. Put your so in the path location in /etc/ld.so.conf.
3. Convert Linux static library to dynamic library
Use ar -x command to convert .a file to .so file.
ar -x mylib.a
gcc -shared *.o -o mylib.so
How to combine multiple static libraries into one in linux

Fourth, the gcc system is forced to link the static library (both .so and .a)
1. There are many ways -
static
If you need to link to a program that does not depend on any so files, use ldd to view it and display it as "not a dynamic executable", but this option is not recommended.
2. The common practice
is to directly link the full path of the .a file. This is nothing to say, just link it as a .o file.
g++ test-boost.cpp -o test -I /home/johnchen/boost_1_56_0/include /home/johnchen/boost_1_56_0/lib/libboost_system.a /home/johnchen/boost_1_56_0/lib/libboost_filesystem.a
3. Elegance
since it is Libraries, -l and -L are decent practices. For example, there are libxxx.a files and libxxx.so files in the same directory. Gcc will link so by default. The way to change this default behavior is to change "-lxxx" to "-l:libxxx.a"
g++ test-boost.cpp -o test -I /home/johnchen/boost_1_56_0/include -L /home/johnchen/boost_1_56_0/lib -l:libboost_system.a -l:libboost_filesystem.a

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325505524&siteId=291194637