【Linux】Makeflie CMake快速上手指南
🦄个人主页:修修修也
🎏所属专栏:Linux
⚙️操作环境:Xshell (操作系统:Ubuntu 22.04 server 64bit)
目录
📌快速上手Makefile
基本结构
变量
自动变量
常用目标
📌快速上手CMake
CMake与Makefile的关系
CMake的使用步骤
常用命令
高级功能
常用工具
结语
📌快速上手Makefile
Makefile 是一种用于自动化编译和构建程序的工具,尤其在 C/C++ 项目中广泛使用。它通过定义规则(rules)来指定如何从源代码生成目标文件或可执行文件。
基本结构
Makefile的核心格式为:
目标(target):依赖(dependencies) 命令(command)
- 目标(target): 通常是生成的文件名(如main.o或main)。
- 依赖(dependencies): 生成目标所需的文件(如main.c或main.o文件)。
- 命令(command): 生成目标的Shell命令(以Tab开头)。
在目录中创建makefile文件,示例如下:
hello:hello.c gcc hello.c -o hello
此时我们目录中有.c文件hello.c:
此时我们可以直接输入make命令,使.c文件自动编译,效果如下:
如果有还不太了解gcc/g++编译器编译命令的可以先移步:【Linux】手把手教你从零上手gcc/g++编译器
变量
变量可以简化重复内容(如编译器, 编译选项), 如:
CC = gcc CFLAGS = -Wall hello:hello.c $(CC) $(CFLAGS) hello.c -o hello
运行展示如下:
自动变量
$@
:当前目标名(如app
)。
$^
:所有依赖(如main.c utils.c
)。
$<
:第一个依赖(如main.c
)。示例如下:
hello:hello.c gcc $^ -o $@
运行结果如下:
常用目标
- all: 默认目标,通常编译所有内容
- clean: 清理生成的文件
- .PHONY: 声明伪目标(不生成文件)
假设现在有两个程序一个服务器程序一个客户端程序需要一起编译生成并需要及时清理,那么makefile文件的编写参考:
.PHONY:all all:server client server:Server.cc g++ -o $@ $^ -std=c++11 client:Client.cc g++ -o $@ $^ -lpthread -std=c++11 .PHONY:clean clean: rm -f server client
更多Makefile相关内容可以查阅官方手册:GNU Make 官方文档
📌快速上手CMake
CMake 是一个跨平台的自动化构建工具,用于管理代码的编译、链接和安装流程。它通过生成标准的构建文件(如 Makefile、Visual Studio 项目、Ninja 文件等),简化了跨平台项目的构建过程。
CMake与Makefile的关系
Makefile:需要手动编写规则,直接调用编译器。
CMake:通过高级的配置文件
CMakeLists.txt
生成 Makefile(或其他构建系统文件),无需手动处理底层编译细节。优势:
跨平台(Windows、Linux、macOS 等)。
支持复杂的项目结构(多目录、多库)。
自动管理依赖关系(如头文件、第三方库)。
CMake的使用步骤
1.编写CMakeLists.txt文件
每个项目目录都需要一个
CMakeLists.txt
,定义构建规则。示例如下:
cmake_minimum_required(VERSION 3.15) //最低CMake版本(不能比当前机器CMake版本高) project(test) //项目名称 add_executable(hello hello.c) //生成可执行文件(参数是其依赖关系)
2.执行cmake命令生成makefile文件:
3.执行make命令生成可执行程序:
可以看到,我们直接执行cmake命令会生成大量的与程序本身无关的杂乱文件,这会干扰我们操作,所以我们可以通过以下步骤生成一下构建系统避免污染源代码:
1.创建构建目录(推荐
build
目录,避免污染源码):mkdir build && cd build //创建build目录并进入build
2.运行cmake生成构建文件:
camke .. // 根据上级目录的 CMakeLists.txt 生成 Makefile
3.调用构建工具(如make或ninja)编译:
make #执行生成的Makefile
运行效果如下:
常用命令
(1) 基本配置
project(<PROJECT_NAME>)
: 定义项目名称和支持的语言(如CXX
表示 C++)。
add_executable(<target> <source_files>)
: 生成可执行文件。
add_library(<target> <source_files>)
: 生成静态库(.a
/.lib
)或动态库(.so
/.dll
)。
target_link_libraries(<target> <libraries>)
: 链接库到目标(可执行文件或库)。set(EXECUTABLE_OUTPUT_PATH 输出路径) : 指定可执行程序输出的路径,如果这个路径中的子目录不存在,会自动生成,无需自己手动创建。( 由于可执行程序是基于cmake命令生产的makefile文件然后执行make命令得到的,所以如果此处指定可执行程序生成路径的时候使用的是相对路径./xxx/xxx,那么这个路径中的./对应的就是makefile文件所在的那个目录。)
(2) 变量与选项
定义变量:
#方式1:各个源文件直接使用空格间隔 set(SRC_FILES main.cpp utils.cpp) #方式2:各个源文件之间使用分号;间隔 set(SRC_FILES main.cpp;utils.cpp) #使用set定义的变量如下,格式为 ${变量名} add_executable(my_app ${SRC_FILES})
条件判断:
if(WIN32) # Windows 平台特定配置 endif()
指定使用的C++标准:
在编写C++程序的时候,可能会用到C++11, C++14, C++17, C++20等新特性,那么就需要在编译的时候在编译命令中制定出要使用哪个标准,在CMake中想要指定C++标准有两种方式:
1.在CMakeLists.txt中通过set命令指定:
#增加-std=c++11 set(CMAKE_CXX_STANDARD 11) #增加-std=c++14 set(CMAKE_CXX_STANDARD 14) #增加-std=c++17 set(CMAKE_CXX_STANDARD 17)
2.在执行cmake命令时指定出这个宏的值
#增加-std=c++11 cmake CMakeLists.txt文件路径 -DCMAKE_CXX_STANDARD=11 #增加-std=c++14 cmake CMakeLists.txt文件路径 -DCMAKE_CXX_STANDARD=14 #增加-std=c++17 cmake CMakeLists.txt文件路径 -DCMAKE_CXX_STANDARD=17
(3) 查找依赖
查找系统已安装的库:
find_package(OpenCV REQUIRED) target_link_libraries(my_app ${OpenCV_LIBS})
自定义库路径:
set(OPENCV_DIR "/path/to/opencv") find_package(OpenCV REQUIRED PATHS ${OPENCV_DIR})
高级功能
(1) 多目录项目
主目录的
CMakeLists.txt
:add_subdirectory(src) # 进入子目录 src add_subdirectory(libs) # 进入子目录 libs
子目录的
CMakeLists.txt
定义各自的构建规则。(2) 安装与打包
定义安装规则:
install(TARGETS my_app DESTINATION bin) # 安装可执行文件到 bin 目录 install(FILES include/utils.h DESTINATION include) # 安装头文件
生成安装包:
include(InstallRequiredSystemLibraries) set(CPACK_PACKAGE_NAME "MyApp") include(CPack)
(3) 测试支持
启用测试:
enable_testing() add_test(NAME my_test COMMAND my_app --test)
常用工具
ccmake
:命令行交互界面,调整 CMake 变量。
cmake-gui
:图形化界面,配置项目选项。
CTest
:运行测试套件。
CPack
:生成安装包(如.deb
、.zip
)。
结语
希望这篇关于 快速上手Makefile & CMake 的博客能对大家有所帮助,欢迎大佬们留言或私信与我交流.学海漫浩浩,我亦苦作舟!关注我,大家一起学习,一起进步!
相关文章推荐
【Linux】手把手教你从零上手Vim编辑器
【Linux】手把手教你从零上手gcc/g++编译器
【Linux】实现一个简易的shell命令行
【Linux】基本指令(下)
【Linux】基本指令(中)
【Linux】基本指令(上)