已使用AI重构结构,笔记会更有条理。
🚀 一、Makefile 是干什么的?
Makefile 是一个“构建脚本”,告诉
make
命令如何一步步编译代码、生成程序、运行测试、清理文件等。
🧱 二、基本结构
一个最小的 Makefile:
main: main.c
gcc -o main main.c
目标:
main
依赖:
main.c
命令:
gcc -o main main.c
(注意:必须以Tab开头!)
执行:
make # 自动查找默认目标(第一个),即编译 main
🧩 三、变量(变量就是字符串)
CC = gcc
CFLAGS = -Wall -O2
main: main.c
$(CC) $(CFLAGS) -o main main.c
变量使用:$(变量名)
常见变量:
CC
:编译器CFLAGS
:编译参数LDFLAGS
:链接参数
🔁 四、规则(规则 = 目标 + 依赖 + 命令)
目标: 依赖1 依赖2 ...
命令1
命令2
每次 make
会检查:
如果 目标文件不存在 或者 依赖文件比目标文件更新,就执行命令。
🎯 五、目标(Target)
常见目标类型:
.PHONY
:告诉 make 这个目标不是文件名
.PHONY: clean test
🔗 六、依赖(Dependencies)
告诉 make 哪些文件变了就需要重新构建:
main: main.o utils.o
意思是:
如果 main.o 或 utils.o 被修改,就需要重新编译 main。
🔧 七、通配符 & 模板规则
%
:通配符规则(模式匹配)
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
表示:任何 .o
文件都由对应 .c
文件编译而来。
$<
:第一个依赖(如main.c
)$@
:目标名(如main.o
)
🧹 八、clean 目标(清理构建文件)
.PHONY: clean
clean:
rm -f *.o main
✅ 九、test 目标(运行测试)
.PHONY: test
test: test.o lib.o
$(CC) -o test test.o lib.o
./test
🧪 十、一个完整小例子
CC = gcc
CFLAGS = -Wall -Wextra -O2
OBJS = main.o utils.o
TARGET = main
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) -o $@ $^
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
.PHONY: clean test
clean:
rm -f *.o $(TARGET)
test: test.o utils.o
$(CC) $(CFLAGS) -o test test.o utils.o
./test
🧠 Bonus:常用自动变量
📦 总结口诀
目标: 依赖
命令(必须Tab开头)
变量用 $(XXX),通配符用 %,clean 记得加 .PHONY
CMake
当然可以!下面这份是为你量身定制的 ✨CMake 基础入门笔记✨,对应你提到的核心命令讲解,清晰、实用、能直接上手项目。
📘 CMake 基础入门笔记(含关键命令)
🎯 什么是 CMake?
CMake 是一个跨平台的构建系统生成工具,不是构建器(Make才是),它生成 Makefile、Ninja 等构建脚本。
📦 一、最基本结构
cmake_minimum_required(VERSION 3.10)
project(MyProject)
add_executable(main main.c)
cmake_minimum_required
:指定最低 CMake 版本project
:定义项目名(可选加语言)add_executable
:添加一个可执行程序
🔨 二、add_executable(添加可执行程序)
add_executable(目标名 源文件1 源文件2 ...)
示例:
add_executable(my_app main.cpp utils.cpp)
🧱 三、add_library(添加库文件)
可以添加静态库或动态库(默认动态)。
# 静态库
add_library(mylib STATIC functions.c)
# 动态库
add_library(mylib SHARED functions.c)
🔗 四、target_link_libraries(链接库)
用于把库链接到目标(可执行文件或其他库):
target_link_libraries(目标名 私有/公开/接口 库名1 库名2 ...)
简单用法:
target_link_libraries(my_app mylib)
高级写法(指定链接范围):
PRIVATE
:仅当前目标用PUBLIC
:当前和依赖它的目标都能用INTERFACE
:仅依赖者用(本目标不用)
target_link_libraries(my_app PRIVATE mylib)
📁 五、target_include_directories(添加头文件路径)
告诉编译器去哪找 .h
文件:
target_include_directories(目标名 PRIVATE/INTERFACE/PUBLIC 路径1 路径2 ...)
示例:
target_include_directories(my_app PRIVATE ${CMAKE_SOURCE_DIR}/include)
🗃 六、文件组织建议
project/
├── CMakeLists.txt
├── src/
│ ├── main.cpp
│ └── functions.cpp
├── include/
│ └── functions.h
└── build/
对应 CMakeLists.txt:
cmake_minimum_required(VERSION 3.10)
project(MyProject)
# 设置头文件路径
include_directories(include)
# 添加源代码
add_executable(my_app src/main.cpp src/functions.cpp)
或者更现代方式:
add_executable(my_app
src/main.cpp
src/functions.cpp
)
target_include_directories(my_app PRIVATE include)
🛠 七、构建流程(CLI)
mkdir build
cd build
cmake ..
make
🧹 八、常用小技巧
设置 C++ 标准
set(CMAKE_CXX_STANDARD 17)
设置编译选项
target_compile_options(my_app PRIVATE -Wall -Wextra)
设置输出路径
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
🧪 九、完整案例
cmake_minimum_required(VERSION 3.14)
project(MyApp CXX)
set(CMAKE_CXX_STANDARD 17)
add_library(mylib STATIC src/functions.cpp)
target_include_directories(mylib PUBLIC include)
add_executable(my_app src/main.cpp)
target_link_libraries(my_app PRIVATE mylib)
🧠 总结一张表
📌 下一步推荐学啥?
FetchContent
:下载并集成外部项目(如 gtest、fmt)install()
:安装头文件、库find_package()
:查找系统库或其他 CMake 项目option()
:添加可选编译选项
🚀 CMake 高级功能详解笔记
📦 一、FetchContent(自动拉取依赖源码)
用途:从 Git 或 URL 自动下载并构建第三方库(如 gtest、fmt、nlohmann/json)
基本用法:
include(FetchContent)
FetchContent_Declare(
json
GIT_REPOSITORY https://github.com/nlohmann/json.git
GIT_TAG v3.11.2
)
FetchContent_MakeAvailable(json)
target_link_libraries(my_app PRIVATE nlohmann_json::nlohmann_json)
✅ FetchContent_MakeAvailable()
会自动 clone + add_subdirectory。
🧩 二、find_package(集成系统或已安装的库)
find_package(OpenCV REQUIRED)
target_link_libraries(my_app PRIVATE ${OpenCV_LIBS})
target_include_directories(my_app PRIVATE ${OpenCV_INCLUDE_DIRS})
📌 常用于已安装库 + .cmake
支持库(OpenCV、Boost、fmt、gtest 等)
🛠 三、install(安装程序/库/头文件)
install(TARGETS my_app DESTINATION bin)
install(TARGETS mylib DESTINATION lib)
install(DIRECTORY include/ DESTINATION include)
构建后使用:
cmake --install build/
可以配合 CPack
打包为 .tar.gz
、.deb
、.msi
等格式。
📦 四、打包(CPack)
在 CMakeLists.txt 末尾添加:
include(CPack)
设置包信息:
set(CPACK_PACKAGE_NAME "MyApp")
set(CPACK_PACKAGE_VERSION "1.0.0")
set(CPACK_GENERATOR "TGZ;DEB") # 支持 .tgz, .deb, .rpm, .msi, ...
打包命令:
cpack # 自动生成安装包
🌍 五、跨平台工具链支持
示例:交叉编译(如 ARM、嵌入式)
创建 toolchain-arm.cmake
文件:
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
然后构建时使用:
cmake -DCMAKE_TOOLCHAIN_FILE=toolchain-arm.cmake ..
📚 CMake 项目结构推荐(现代)
my_project/
├── CMakeLists.txt
├── include/
│ └── mylib/
│ └── mylib.h
├── src/
│ └── mylib.cpp
├── app/
│ └── main.cpp
├── test/
│ └── test.cpp
└── cmake/
└── toolchain-arm.cmake
评论