前言
编译器的主要工作流程:
源码(Source Code)>> 预处理器(Preprocessor)>> 编译器(Compiler)>> 汇编程序(Assembler)>> 目标代码(Target Code)>> 链接器(Linker)>> 可执行程序(Executables)
一. GCC / G++
语法: gcc/g++ [options] file...
gcc [-E | -S | -c] [-std=standrad]
[-g] [-Idir] [-Ldir]
[-o outfile]
基本选项
-E Preprocess only; do not compile, assemble or link 预处理
-S Compile only; do not assemble or link 编译,生成 .s 汇编代码
-c Compile and assemble, but do not link 编译和汇编,生成 .o 的 obj 文件
-o <file> Place the output into <file> 链接,将 .o 链接到指定的可执行文件,若不指定可执行文件的名称,默认为 a.out目录选项
-Idir 指定头文件的搜索目录
-Ldir 指定库文件的搜索目录
-llibraray 指定编译时使用的库
链接方式选项
-static 编译为静态库
-shared 编译为动态库
-dPIC 编译器就输出位置无关目标代码,使用于生成动态链接库(DLL - Dynamic Linking Library)
二. Make / Makefile、CMake / CMakeLists.txt、qmake
整个逻辑如下图所示(参考知乎问题:make makefile cmake qmake都是什么,有什么区别?):
三. CMakeLists.txt
0. 基本语法规则
- 变量使用 ${} 取值,IF控制语句中直接使用变量名
- 指令(参数1 参数2 ...)
- 参数之间用
- 指令大小写无关,参数和变量大小写相关,但推荐全部使用大写
1. 指定 cmake 最小版本
CMAKE_MINIMUM_REQUIRED(VERSION 3.5.1)此命令是可选的,一般不需要写这句话,但当使用了高版本的 cmake,则需要提醒用户需要升级 cmake
2. 设置项目名称
PROJECT(hello)自动引入两个变量 hello_BINARY_DIR 和 hello_SOURCE_DIR
3. 生成可执行文件
ADD_EXECUTABLE(hello hello_world.cpp)4. 设置编译类型
1. ADD_LIBRARY(hello hello.cpp) # 默认生成静态库 2. ADD_LIBRARY(hello STATIC hello.cpp) # 指定为静态库 3. ADD_LIBRARY(helloshared SHARED hello.cpp) # 指定为共享库假设 hello.cpp 文件中没有 main 函数,意味着这个库中没有可执行文件。添加上述命令,cmake 后会依次生成下面几个文件:
libhello.a libhello.a libhello_shared.so
静态库以 .a 为后缀名,共享库以 .so 为后缀名,所有库都是一些函数打包后的集合,静态库每次被调用都会生成一个副本,而共享库则只有一个副本,更省空间。
库文件是一个压缩包,里面有编译好的二进制函数,仅有 .a 或 .so 库文件,别人并不知道里面的函数是什么样的,或如何调用;这就需要提供一个头文件,有了库文件和头文件,就可以调用这个库。
5. 设置变量
(1)set 直接设置变量的值
SET(SRC_LIST a.cpp b.cpp) ADD_EXECTUABLE(demo ${SRC_LIST})(2)set 追加设置变量的值
SET(SRC_LIST a.cpp) SET(SRC_LIST ${SRC_LIST} b.cpp) ADD_EXECTUABLE(demo ${SRC_LIST})(3)LIST 追加或删除变量的值
SET(SRC_LIST a.cpp) LIST(APPEND SRC_LIST b.cpp) LIST(REMOVE_ITEM SRC_LIST b.cpp) ADD_EXECTUABLE(demo ${SRC_LIST})6. 指定源文件
(1)明确指定(用空格或分号隔开)
ADD_LIBRARY(hello hello.cpp a.cpp b.cpp)(2)所有源文件
AUX_SOURCE_DIRECTORY(dir VAR) 发现一个目录下所有的源代码文件并将列表存储在一个变量中。AUX_SOURCE_DIRECTORY(. SRC_LIST) # 搜索当前目录下的所有.cpp文件ADD_LIBRARY(hello ${SRC_LIST})7. 查找指定的库文件
FIND_LIBRARY(VAR name path)查找到指定的预编译库,并将它的路径存储在变量中。默认的搜索路径为 cmake 包含的系统库。
类似的命令还有 find_file()、find_path()、find_program()、find_package()等。
8. 设置包含的目录
INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include或
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I${CMAKE_CURRENT_SOURCE_DIR}")9. 设置链接库搜索目录
LINK_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR}/libs )或
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_CURRENT_SOURCE_DIR}/libs")10. 设置 Target 需要链接的库
TARGET_LINK_LIBRARIES(target_lib link_lib_path)(1)指定链接静态库或共享库
TARGET_LINK_LIBRARIES(hello libhello.a)TARGET_LINK_LIBRARIES(hello libhello_shared.so)(2)设置全路径
TARGET_LINK_LIBRARIES(hello ${CMAKE_CURRENT_SOURCE_DIR}/libs/libhello.a)TARGET_LINK_LIBRARIES(hello ${CMAKE_CURRENT_SOURCE_DIR}/libs/libhello_shared.so)
(1)编写 hello_world.cpp 源文件和 CMakeLists.txt 文件
(2)在当前路径下执行 cmake . 命令,可以发现生成了 CMakeFIles 文件夹和CMakeCache.txt, cmake_install.cmake, Makefie 文件
(3)在当前路径下执行 make 命令,生成了可执行文件
参考:
[1]. 《视觉 SLAM 十四讲》高翔
[2]. 博客:https://blog.csdn.net/afei__/article/details/81201039
Linux 编译工具 gcc/g++、Make/Makefile、CMake/CMakeLists.txt、qmake
原文:https://www.cnblogs.com/dinghongkai/p/11316528.html