新手向:如何通过CMakeLists为C++项目添加外部库(含OpenCV示例及特殊场景处理)
解决C++外部库导入与构建工具疑问
作为C++新手,刚接触构建系统确实容易懵,我来一步步帮你理清这些问题:
先搞懂CMake和Makefile的区别
- Makefile:是直接给
make工具执行的脚本,里面写死了编译、链接的具体命令和依赖关系,语法比较底层,跨平台性差(Windows上需要MinGW等工具支持)。 - CMake:是一个构建文件生成器,你写的CMakeLists.txt是给CMake读的,它会根据你的配置自动生成对应平台的Makefile(或者Visual Studio工程、Ninja脚本等),跨平台性强,现在是C++项目的主流构建工具。
开发者通常存放库的位置
一般分三类场景:
- 系统级目录:比如
/usr/local/lib(库文件)、/usr/local/include(头文件),或者系统默认的/usr/lib、/usr/include。适合安装常用的公共库(比如你用Homebrew装的OpenCV就放在/usr/local/Cellar,Homebrew会自动在/usr/local下创建软链接,让CMake能找到)。 - 用户级目录:比如
~/.local/lib和~/.local/include,适合安装只给自己用的库,不会影响系统全局。 - 项目本地目录:比如在项目根目录下建
third_party文件夹,把库放在里面。适合项目专属的、不需要共享的库,方便和项目一起提交到版本控制,让其他开发者直接能用。
处理没有include文件夹的外部库
首先你得先理清这个库的文件结构:
- 先找头文件:头文件不一定叫
include,可能在src、headers、inc这类文件夹里,甚至和源文件混在一起。 - 再找库文件:静态库一般是
.a后缀,动态库是.so(Linux)、.dylib(macOS)、.dll(Windows),可能在lib、build、bin这类文件夹里。
找到了这两个关键路径后,分别用CMake或Makefile配置:
用CMake配置的通用方法
假设你的库叫foo,头文件在./third_party/foo/src,静态库文件在./third_party/foo/build/libfoo.a,CMakeLists.txt可以这么写:
cmake_minimum_required(VERSION 3.17) project(YourProject) set(CMAKE_CXX_STANDARD 11) # 添加头文件目录(PRIVATE表示只给当前项目用) target_include_directories(YourProject PRIVATE ${CMAKE_SOURCE_DIR}/third_party/foo/src) # 导入外部静态库 add_library(foo STATIC IMPORTED) # 指定库文件的路径 set_target_properties(foo PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/third_party/foo/build/libfoo.a ) # 生成可执行文件 add_executable(YourProject src/main.cpp) # 链接库到可执行文件 target_link_libraries(YourProject PRIVATE foo)
如果是动态库,把STATIC改成SHARED就行。
用Makefile配置的通用方法
同样用上面的foo库例子,Makefile内容如下:
# 指定编译器 CC = g++ # 编译参数:-std=c++11指定标准,-I指定头文件目录 CFLAGS = -std=c++11 -I./third_party/foo/src # 链接参数:-L指定库文件目录,-l指定库名(去掉lib前缀和.a/.so后缀) LDFLAGS = -L./third_party/foo/build -lfoo # 目标:生成可执行文件 all: YourProject # 链接步骤 YourProject: main.o $(CC) $(LDFLAGS) main.o -o YourProject # 编译步骤 main.o: src/main.cpp $(CC) $(CFLAGS) -c src/main.cpp -o main.o # 清理生成的文件 clean: rm -f YourProject *.o
关于你的OpenCV路径问题
你看到的/usr/local/Cellar/opencv是Homebrew的默认安装目录,Homebrew会把库安装在Cellar下,然后自动在/usr/local/lib和/usr/local/include创建软链接,所以find_package(OpenCV REQUIRED)能正常找到库,因为CMake会自动搜索这些系统标准路径。
内容的提问来源于stack exchange,提问作者Roy Amoyal
相关产品推荐
相关产品推荐

