GCC learning (two) header file and library production

One, -I header file path

1.1 Simple project structure does not require -I option

If the number of source code and header files in the project is small, the -I option is not needed at all. Put them in the same level directory, and the source files can find the header files normally:

//ttt.cpp
#include <stdio.h>
#include "data.h"
int main()
{
    
    
	printf("Hello world\n");
	printf("Data in header is %lf\n",pi);
}
// data.h
double pi=3.1415;

Type in the terminal:

gcc ttt.cpp

Then you can compile and link normally to form an executable file.

1.2 The project structure is more complex

With the progress of the project, in order to have a clearer structure, people often separate the header files, source files, and compiled results in different folders. Just for demonstration, put the ttt.cppand data,hinto the two folders src and include respectively. If you still use the (1.1) method, an error will occur:

junwuli@ubuntu:~/Desktop/gcctest/build$ gcc ../src/ttt.c 
../src/ttt.c:2:10: fatal error: data.h: No such file or directory
 #include "data.h"
          ^~~~~~~~
compilation terminated.

At this time, you need to use the -I option:

junwuli@ubuntu:~/Desktop/gcctest/build$ gcc ../src/ttt.c -I ../include/
junwuli@ubuntu:~/Desktop/gcctest/build$ ./a.out
Hello world
Data in header is 3.141500

Assuming that our main program does not want to write a relative path, but only wants to write a concise "head.h" instead of "./include/", we need to use this parameter.

gcc hello.c -Iinclude -o app

or

gcc hello.c -I include -o app

Second, the production and use of the library

Whether it is a static library or a dynamic library, it is necessary to compile the source files into object files, and then integrate the object files to form a library. The library here is similar to the warehouse in life, but the content stored is the target file, and what is in the warehouse depends on the header file.

Probably this is the process:

graph LR
源文件-->目标文件
目标文件-->库的打包

2.1 Library naming rules

Like variable naming, Linux library naming also reveals the attributes and names of the library.

libxxx.so.x.y.z
libxxx.a.x.y.z
section meaning
lib File attributes
xxx Library name
.so/.a Library type
.x.y.z Version number [2]

2.2 The production and use of static libraries

2.2.1 Making a static library

Take ac bc as an example to generate the target file :

gcc a.c b.c -c 

The target file ao bo with the same name is generated by default

According to the ao bo material generated in the previous step, package the target file

ar rcs libtest.a a.o b.o

Note: rcs stands for inserting target files to create archive files and indexing.

2.2.2 Use static libraries

libtest.a + header file, header file plus library use static library

gcc main.c -I ./include/ -L ./lib/ -ltest -o app

Note: nm(name) can view the content in lib

2.3 Dynamic library production and use

2.3.1 Making a dynamic library

Take ac bc as an example, the -fPIC option generates the target file[3] :

gcc a.c b.c -c -fPIC(-fpic)

According to the ao bo material generated in the previous step, the --shared option is used to package the target file

gcc -shared a.o b.o -o libxxx.so

in

2.3.2 Use dynamic libraries

Header file plus library settings use dynamic library

gcc main.c -I ./include/ -L ./lib/ -lxxx -o app

Just like the static library, specify the path of the library and the name of the library. If it is in the same level directory as the source file, OK, there is no problem at all, but if it is in the next level of lib, it will be prompted that it cannot be found!

ldd 用静态库编译的可执行文件

The above one can check the dependent library and whether it is found.

2.4 Dynamic library search path

The format of dynamic libraries, executable programs, and .o files are all ELF, and the system uses ld-linux.so.X[1] to complete. In order, they are:

  • DT_PRATH section of ELF file
  • Environment variable LD_LIBRARY_PATH
  • File list /etc/ld.so.cache
  • If /lib usr/lib is
    found at any step, it will be loaded into the memory for normal use, otherwise an error that the library cannot be found is reported.

Notes:

[1] One of the libraries installed by Glibc is ld-linux.so.X, where X is a number, and the name will be different on different platforms. For example, ubuntu18.04 is ld-linux-x86-64.so .2

[2] xindicates the major version number, different major versions are generally incompatible; yminor version number, incremental upgrade of the library, the original interface remains unchanged but some new interfaces are added, and the old version is compatible at the same time; the zrelease version number, some library functions are wrong, The performance is improved, and the interface does not increase or change.

[3] In order to be compatible with various systems, the -fPIC parameter should be used when generating position-independent code.

Reference article:

[1] "- fpic and -fPIC the difference between" Author: zhang_dawei666 (https://blog.csdn.net/xiangguiwang/article/details/81939237)

Expansion:

The difference between dynamic and static libraries: https://www.cnblogs.com/mhscn/p/4264357.html

Guess you like

Origin blog.csdn.net/weixin_39258979/article/details/106255077