-
Notifications
You must be signed in to change notification settings - Fork 174
CMake 脚本是如何工作的?
NetEase IM Demo 从 8.4.0 版本开始,由 CMake 管理项目工程,主要是期望解决仓库体积庞大下载耗时、失败等问题。它的工作步骤如下:
- 根据传递参数自动下载依赖的 SDK 二进制文件
- 根据仓库 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 命令来自动获取的,首先会判断当前分支是否包含版本号(如 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 等信息,会导致生成的版本号文件版本错误无法编译。