一、编译链接过程
名词解释
-
编译:由编译器对各个源文件进行词法分析、语法分析、语义分析等操作,最终生成多个目标文件。由于这些文件可能存在互相调用对方的函数或变量,还可能调用某些链接库文件中的函数或变量,编译器无法跨文件找到它们确切的存储地址,所以这些目标文件无法单独执行。
-
链接:对各个目标文件中缺失的函数和变量的存储地址,由链接器修复并将其组织成一个可执行文件。
-
库文件:供外部调用的函数和变量。(资源类型。其本质是将资源存为变量)
- 静态库:在程序链接的时候,会将程序中使用到函数的代码从库文件中拷贝到应用程序中。(windows下以.lib结尾,linux下以.a结尾。)每运行一个程序就会在内存中拷贝多拷贝一份静态库。
- 动态库:在程序的链接时候,会将程序中使用到函数作上标记,只有在程序开始启动运行的时候,才会动态地加载所需模块。(windows下叫DLL,linux下叫共享库以.so结尾so ==share object)不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例。
-
目标文件:编译过程中链接起来的生成可执行文件。
C语言编译过程
- 预处理过程:根据预处理指令重新生成一个C/C++程序。读取C/C++源程序,对其中的伪指令(以#开头的指令)进行处理。
- 编译过程:将预处理完的文件进行一系列词法分析、语法分析、语义分析及优化后,产生相应的汇编代码文件。
- 汇编过程:将编译完的汇编代码文件翻译成机器指令,并生成可重定位目标程序的.o文件,该文件为二进制文件,字节编码是机器指令。
- 链接过程:通过链接器将一个个目标文件和库文件链接在一起生成一个完整的可执行程序。
二、C/C++工具介绍
-
gcc:用于编译c语言源文件。gcc是GNU编译器子集,GNU工具链保护很多工具,例如:C ++(g++),Objective-C,Objective-C ++,Java(gcj),Fortran(gfortran),Ada(gnat),Go(gccgo),OpenMP,Cilk Plus和OpenAcc。
实例
/*hello.c*/ #include <stdio.h> int main(){ printf("Hello world!\n"); return 0; }
编译并执行
$ gcc hello.c -o hello $ ./hello # 执行 Hello world!
-
make和Makefile:当工程存在多个源文件时,每次需要编译时都键入编译命令,这非常麻烦。make工具(GNU Make)是简化此任务的解决方案.
Makefile:用于帮助我们自动构建和管理项目。可以看作提前写好如何编译工程中各个源文件的指令。
make:智能的批处理工具,它本身并没有编译和链接的功能,而是用类似于批处理的方式—通过调用makefile文件中用户指定的命令来进行编译和链接的
实例
/*hello.c*/ #include <stdio.h> int main(){ printf("Hello world!\n"); return 0; }
# Makefile all:hello hello.out: hello.o gcc -o hello hello.o hello.o: hello.c gcc -c hello.c clean: rm hello.o hello
执行make
$ make gcc -c hello.c gcc -o hello hello.o $ ./hello Hello world! $ make clean rm hello.o hello
-
cmake和CMakeLists组态档:cmake会按照CMakeLists去生成Makefile。Makefile在一些简单的工程完全可以人工编写,但是当工程非常大的时候,手写Makefile也非常麻烦。如果源代码想在不同平台编译,还必须注意不同平台的差异。且如果使用不同的 make 工具,也得为每一种标准写一次 Makefile。
实例
/*hello.c*/ #include <stdio.h> int main(){ printf("Hello world!\n"); return 0; }
# CMakeLists.txt # CMake 最低版本号要求 cmake_minimum_required (VERSION 3.13.0) # 项目信息 project (Hello) # 指定生成目标hello add_executable(hello hello.c)
执行cmake和make
$ cmake . $ make gcc -c hello.c gcc -o hello hello.o $ ./hello Hello world! $ make clean rm hello.o hello
-
qmake:基本功能和cmake是差不多的,可以自动生成对应平台的Makefile。且无论是否用Qt编写,它可以用于任何软件项目。但是qmake主要包含了自动包括moc和uic的构建规则。
-
qmake和cmake区别:cmake也是同样支持Qt程序的,cmake也能生成针对qt 程序的那种特殊makefile, 只是cmake的
CMakeLists.txt
写起来相对与qmake的.pro
文件复杂点。但是cmake功能比qmake强大。 一般的Qt工程直接使用qmake就可以了,但是QT6之后官方的构建工具换成了cmake,足以见得cmake的强大。