1.关于makefile的理解
对于类unix系统,一般通过makefile文件来编译程序。对于c语言而言,其编译过程包含以下几个部分:预处理,编译,汇编,链接。
第一个阶段预处理阶段对#的代码进行处理得到纯c文件;
第二个阶段编译阶段会将其纯c文件编译为以s为后缀名的汇编文件,第三个阶段汇编阶段则是把汇编文件编译为二进制代码目标文件,以o为后缀名(object目标的意思)。第四个阶段链接阶段则会将多个目标文件和库文件合并为一个可执行文件或共享库文件
经过以上四个阶段,会得到一个完整的可执行文件,在Windows上通常为.exe文件,在Linux上无后缀名,但这些文件都可以直接被运行。
在Linux系统上通过g++命令来编译程序,具体语法不过多阐述。
但是对于大型项目,通常需要编译多个文件,如果每次编译都要把文件名输入一次很麻烦,因此unix就有了Makefile功能。就是在Makefile里面通过特定的语法来描述需要编译链接哪些文件,只要写好了Makefile文件,后面每次直接在命令行中输入make命令就可以直接编译。make命令会搜索该目录下的Makefile文件并执行里面的语句。但是如果把同一套代码放到不同的操作系统或者放到不同的文件夹里,都需要重新编写Makefile文件,极其不便,因此cmake工具孕育而生。
cmake是一套跨平台软件,该软件可以为同一套代码在不同平台生成对应的Makefile文件。只要写好一个cmakefilelists.txt文件,然后在不同的平台运行cmake软件就可以生成该平台对应的Makefile文件,再通过make命令就可以编译了。
但是前文说到,Makefile功能只在类unix系统上存在,Windows系统上没有。于是有人开发了第三方类似的软件,其中MinGW就是其中之一。MinGw提供了Windows平台上的gcc,make等功能,和unix系统上的功能一致。注意在Windows下make命令为mingw32-make.
# 将xx.cpp源文件预处理成xx.i文件(文本文件)
g++ -E main.cpp -o main.i
# 将xx.i文件编译为xx.s的汇编文件(文本文件)
g++ -S main.i -o main.s
# 将xx.s文件汇编成xx.o的二进制目标文件
g++ -c main.s -o main.o
# 将xx.o二进制文件进行链接,最终生成可执行程序
g++ main.o -o main
直接编译
g++ main.cpp -o main
2.cmake安装
ubuntu上请执行
sudo apt install cmake -y
或者编译安装:
# 以v3.25.1版本为例
git clone -b v3.25.1 https://github.com/Kitware/CMake.git
cd CMake
# 你使用`--prefix`来指定安装路径,或者去掉`--prefix`,安装在默认路径。
./bootstrap --prefix=<安装路径> && make && sudo make install
# 验证
cmake --version
vscode安装twxs.cmake插件可以做高亮提示
如何第一次使用cmake,首先写好CMakeLists.txt文件
# CMake 最低版本号要求
cmake_minimum_required(VERSION 3.10)
# first_cmake是项目名称,VERSION是版本号,DESCRIPTION是项目描述,LANGUAGES是项目语言
project(first_cmake
VERSION 1.0.0
DESCRIPTION "项目描述"
LANGUAGES CXX)
# 添加一个可执行程序,first_cmake是可执行程序名称,main.cpp是源文件
add_executable(first_cmake main.cpp)
# 第一步:配置,-S 指定源码目录,-B 指定构建目录
cmake -S . -B build -G "MinGW Makefiles"
# 第二步:生成,--build 指定构建目录
cmake --build build
# 运行
./build/first_cmake
3.CMakeLists.txt语法
注释:
写一个CMakeLists.txt基础三部分
1 指定版本
# CMake 最低版本号要求
cmake_minimum_required(VERSION 3.10)
2 设置项目
project(ProjectName
VERSION 1.0.0
DESCRIPTION "项目描述"
LANGUAGES CXX)
3 添加可执行文件目标
add_executable(first_cmake main.cpp)
构建静态库
#account_dir/CMakeLists.txt
# 最低版本要求
cmake_minimum_required(VERSION 3.10)
# 项目信息
project(Account)
# 添加静态库,Linux下会生成libAccount.a
add_library(Account STATIC Account.cpp Account.h)
编译静态库后,会在build下生成 build/libAccount.a 静态库文件。这里我们用到add_library, 和add_executable一样,Account为最终生成的库文件名(lib库名称.a),第二个参数是用于指定链接库为动态链接库(SHARED)还是静态链接库(STATIC),后面的参数是需要用到的源文件。
链接静态库
# test_account/CMakeLists.txt
# 最低版本要求
cmake_minimum_required(VERSION 3.10)
# 项目名称
project(test_account)
# 添加执行文件
add_executable(test_account test_account.cpp)
# 添加头文件目录,如果不添加,找不到头文件
target_include_directories(test_account PUBLIC "../account_dir")
# 添加库文件目录,如果不添加,找不到库文件
target_link_directories(test_account PUBLIC "../account_dir/build")
# 添加目标链接库
target_link_libraries(test_account PRIVATE Account)
构建动态库
# 添加动态库,Linux下会生成libAccount.so
add_library(Account SHARED Account.cpp Account.h)
链接动态库
#6.build_together/CMakeLists.txt`
# 最低版本要求
cmake_minimum_required(VERSION 3.10)
# 项目信息
project(test_account)
# 添加动态库
add_library(Account SHARED "./account_dir/Account.cpp" "./account_dir/Account.h")
# 添加可执行文件
add_executable(test_account "./test_account/test_account.cpp")
# 添加头文件
target_include_directories(test_account PUBLIC "./account_dir")
# 添加链接库
target_link_libraries(test_account Account)