Skip to content

CMake 脚本是如何工作的?

Dylan Deng edited this page Jun 18, 2021 · 1 revision

NetEase IM Demo 从 8.4.0 版本开始,由 CMake 管理项目工程,主要是期望解决仓库体积庞大下载耗时、失败等问题。它的工作步骤如下:

  1. 根据传递参数自动下载依赖的 SDK 二进制文件
  2. 根据仓库 tag 版本号自动生成编译后的文件版本

目前脚本仅支持生成 Visual Studio 2017 32位 Debug/Release 的解决方案。如果您只安装了 Visual Studio 2019 则无法满足需求,您必须安装 Visual Studio 2017 IDE 并在生成工程时明确使用 -G 参数指定生成的解决方案版本 -G"Visual Studio 15 2017"。

关键脚本解释

依赖 SDK 下载流程

在使用 CMake 命令初始化工程时,您会根据参数指定要生成 Debug 还是 Release 版本的工程,如下所示:

cmake -B build -G"Visual Studio 15 2017" -T"v141_xp" -DCMAKE_BUILD_TYPE=Debug

其中 -DCMAKE_BUILD_TYPE=Debug 代表希望生成一个 Debug 调试版本的工程,CMake 脚本中会根据该参数自动下载并解压依赖的 SDK 和二进制文件:

# Download third parties
# 如果使用 Debug 模式生成工程,则会下载并解压 Debug 版本的依赖三方库文件
IF (CMAKE_BUILD_TYPE MATCHES Debug AND NOT BUILD_WITH_CONAN)
    IF (NOT EXISTS "${CMAKE_BINARY_DIR}/nim_demo_build_libraries_x86_debug.zip")
        MESSAGE(STATUS "Downloading third party libraries from ${DEBUG_THIRD_PARTY_LIBS}")
        FILE(DOWNLOAD ${DEBUG_THIRD_PARTY_LIBS} "${CMAKE_BINARY_DIR}/nim_demo_build_libraries_x86_debug.zip")
    ENDIF ()
    EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E tar -xf "${CMAKE_BINARY_DIR}/nim_demo_build_libraries_x86_debug.zip" WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
ENDIF ()
# 如果使用 Debug 模式生成工程,则会下载并解压 Release 版本的依赖三方库文件
IF (CMAKE_BUILD_TYPE MATCHES Release AND NOT BUILD_WITH_CONAN)
    IF (NOT EXISTS "${CMAKE_BINARY_DIR}/nim_demo_build_libraries_x86_release.zip")
        MESSAGE(STATUS "Downloading third party libraries from ${RELEASE_THIRD_PARTY_LIBS}")
        FILE(DOWNLOAD "${RELEASE_THIRD_PARTY_LIBS}" "${CMAKE_BINARY_DIR}/nim_demo_build_libraries_x86_release.zip")
    ENDIF ()
    EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E tar -xf "${CMAKE_BINARY_DIR}/nim_demo_build_libraries_x86_release.zip" WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
ENDIF ()

当您需要从 Debug 切换成 Release 的工程时,需要重新执行 CMake 命令来下载 Release 依赖的二进制文件。或通过 -B 参数指定不同的缓存目录来根据需要编译工程。如下所示:

# 将 Release 和 Debug 生成的解决方案文件存放到不同的缓存目录下
cmake -B build_debug -G"Visual Studio 15 2017" -T"v141_xp" -DCMAKE_BUILD_TYPE=Debug
cmake -B build_release -G"Visual Studio 15 2017" -T"v141_xp" -DCMAKE_BUILD_TYPE=Release

根据 Git tag 自动生成编译后文件的版本号

编译后产物的文件版本信息是通过 Git 命令来自动获取的,首先会判断当前分支是否包含版本号(如 release/8.5.0),如果不包含,则使用最新的 tag (describe --abbrev=0)作为版本号,相关脚本代码如下:

LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/.cmake/")
INCLUDE(GetGitRevisionDescription)
git_release_version(GIT_TAG)
IF (GIT_TAG STREQUAL "")
    git_latest_tag(GIT_TAG)
ENDIF ()
git_describe(GIT_DESCRIBE)
git_commit_counts(GIT_COMMIT_COUNT)
# Can not get git tag info in github actions
STRING(REPLACE "." "," GIT_TAG_WITH_COMMA ${GIT_TAG})
MESSAGE(STATUS "Current git tag: ${GIT_TAG}, commit count: ${GIT_COMMIT_COUNT}, describe: ${GIT_DESCRIBE}")

获取到正确的版本号后,我们根据默认的配置自动生成了带有版本号的 .rc 文件并加入工程的编译列表,相关脚本代码如下:

CONFIGURE_FILE(
    ${CMAKE_CURRENT_LIST_DIR}/nim.rc.in
    ${CMAKE_BINARY_DIR}/nim.rc
)
ADD_EXECUTABLE(${TARGET_NAME} ${NIM_DEMO_SOURCE} ${CMAKE_BINARY_DIR}/nim.rc)

所以您必须使用 git clone 的方式将工程下载到本地,而不是通过 zip 压缩包的方式下载源码,因为 zip 压缩包的方式不包含 git 仓库的提交、版本、tag 等信息,会导致生成的版本号文件版本错误无法编译。