前言

做点cmake的小尝试和笔记,学习和熟悉cmake的用法。

cmake

案例1:只需要头文件的库

假设要依赖一个库 MathUtils,它只提供了一些头文件,比如一堆静态函数做数学运算,它没有静态/动态库文件,就只需要告诉编译器头文件的位置:

target_include_directories(MyTarget PRIVATE /path/to/MathUtils/include)

按照我5年码龄的浅浅经验,这种只需要依赖头文件的库,一般是数学运算库,或者是项目内部自己写的库。举例:glm(OpenGL math)、stb_img(加载图片)。

这种基于头文件实现的库(Header-only library),既不算静态库,也不算动态库。从本质上来说,它不是二进制库(没有编译后的 .lib、.a 或 .so 文件)。而是一个完全依赖预处理和编译的源代码形式的库。

案例2:只需要链接的库

如果使用的是vs已经装好的库(例如 OpenGL),头文件已经在系统路径/usr/include 中,就只需要链接库:

target_link_libraries(MyTarget PRIVATE OpenGL::GL)

案例3:需要头文件+链接的库

如果头文件不在系统路径里,就需要再加一行链接头文件的指令

target_include_directories(glad PUBLIC ${THIRD_PARTY_DIR}/glad/include)
target_link_libraries(${PROJECT_NAME} PRIVATE glad)

案例4:需要下载源码、本地编译,然后头文件+链接的依赖库

include(FetchContent)
FetchContent_Declare(
    glfw
    GIT_REPOSITORY https://github.com/glfw/glfw.git
    GIT_TAG        3.3.8
)
FetchContent_MakeAvailable(glfw)
target_link_libraries(${PROJECT_NAME} PRIVATE  glfw)

我目前遇到的大多数开源仓库都是这样的。

案例5:需要配置环境变量的

Autodesk的fbx

set(FBX_SDK_ROOT "E:/software/FBXSDK2020.3.7")
target_include_directories(${PROJECT_NAME} PRIVATE ${FBX_SDK_ROOT}/include)
target_link_libraries(${PROJECT_NAME} PRIVATE ${FBX_SDK_ROOT}/lib/x64/debug/libfbxsdk.lib)

Qt

set(QT_PREFIX_PATH "D:/Softwares/Qt/5.15.2/msvc2019_64")
include_directories(${QT_PREFIX_PATH}/include)
target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Widgets)

💡Tips:
include_directories用于全局地包含头文件。
target_link_libraries用于指定项目去包含头文件,适用于更复杂的项目cmake,也是现代CMake中的推荐方式。

附录:配置OpenGL项目

# 最低 CMake 版本要求
cmake_minimum_required(VERSION 3.10)

# 项目名称和语言
project(Template LANGUAGES CXX)

# 设置 C++ 标准
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(THIRD_PARTY_DIR ${CMAKE_SOURCE_DIR}/thirdparty)

# 添加源文件
add_executable(${PROJECT_NAME} src/main.cpp)

# 静态库
add_library(glad STATIC ${THIRD_PARTY_DIR}/glad/src/glad.c)

# 自动下载外部库
include(FetchContent)
FetchContent_Declare(
    glfw
    GIT_REPOSITORY https://github.com/glfw/glfw.git
    GIT_TAG        3.3.8
)
FetchContent_MakeAvailable(glfw)

# 查找其它库
find_package(OpenGL REQUIRED)

# 引用头文件
target_include_directories(glad PUBLIC ${THIRD_PARTY_DIR}/glad/include)
target_include_directories(${PROJECT_NAME} PRIVATE ${THIRD_PARTY_DIR}/glm/include)
target_include_directories(${PROJECT_NAME} PRIVATE ${THIRD_PARTY_DIR}/stb)

# 链接库
target_link_libraries(${PROJECT_NAME} PRIVATE OpenGL::GL glfw glad)

# 特殊用例:FBX SDK
set(FBX_SDK_ROOT "E:/software/FBXSDK2020.3.7")
target_include_directories(${PROJECT_NAME} PRIVATE ${FBX_SDK_ROOT}/include)
target_link_libraries(${PROJECT_NAME} PRIVATE ${FBX_SDK_ROOT}/lib/x64/debug/libfbxsdk.lib)

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐