如何使用 CMake 和 SVN 对源外构建目录进行版本控制

How to version control out-of-source build directory using CMake and SVN

CMake 推荐外源构建。通常我拥有的是每个构建的小型构建脚本,因此我不必手动执行 CMake 命令。例如,我的构建目录可能如下所示:

build
|--linux
|  |--build.sh
|--arm
   |--build.sh

其中 arm/build.sh 可能看起来像:

cmake \
    -D CMAKE_CXX_COMPILER=${CROSS_COMPILE}g++ \
    -D CMAKE_C_COMPILER=${CROSS_COMPILE}gcc \
    -D CMAKE_CXX_FLAGS="-mcpu=cortex-a9" \
    -D CMAKE_C_FLAGS="-mcpu=cortex-a9" \
    -D CMAKE_BUILD_TYPE="" \
    -G "Unix Makefiles" ../..

我喜欢这种方法如何通知开发人员支持哪些平台,总体来说它很好——直到我想对 build.sh 脚本进行版本控制。我遇到的问题是,当我将 build 添加到版本控制时,我选择了所有 CMake 构建文件和构建目录。我知道我可以 "ignore" 相关的目录和文件,但考虑一下如果我添加一个新的构建或添加一个新的库到我的顶层会发生什么 - 然后我在 SVN 中为每个更新忽略 属性每次构建。

这感觉不太容易维护,我相信有更好的方法。有没有人对为每个构建编写 CMake 命令脚本同时在构建后保持 'clean' SVN 状态有任何建议?

如果我理解正确你的问题("I will have a lot of files in tree, but want to version only small predefined subset of it"),你可以使用lazy-way

  1. 忽略 build 目录中的 所有
  2. 手动添加svn add FILE只需要文件
  3. 出现新配置时重复上一步

因此,随着时间的推移,您将获得永久性 svn:ignore 并且所有构建工件 将不会 出现在 repo

您应该将构建脚本或脚本放在源代码所在的位置。如果您正在执行外源构建并不重要,可重用的构建脚本属于源代码(就像 makefile,CMakeLists.txt)。

Cmake 发行版通常在 Modules 文件夹中带有一个 FindSubversion.cmake。您只需像这样使用它:

   find_package( Subversion )
   if( SUBVERSION_FOUND )
     Subversion_WC_INFO( ${CMAKE_CURRENT_SOURCE_DIR} MyProj )
     add_definitions( -DSVN_WC_REVISION=${MyProj_WC_REVISION}" )
   endif( SUBVERSION_FOUND )

现在您已在源代码中将 SVN_WC_REVISION 定义为预处理器宏。它可用于您的 "about" 对话或您的 .rc 文件,您可以在其中将元数据属性添加到您的 DLL。此外,您没有在构建后遗留下来的本地修改文件。 就这么简单!

这是来自分布式 FindSubversion.cmake 的一些参考 material:

The minimum required version of Subversion can be specified using the
standard syntax, e.g.  find_package(Subversion 1.4)

If the command line client executable is found two macros are defined:
   Subversion_WC_INFO(<dir> <var-prefix>)
   Subversion_WC_LOG(<dir> <var-prefix>)

Subversion_WC_INFO extracts information of a subversion working copy
at a given location.  This macro defines the following variables:
   <var-prefix>_WC_URL - url of the repository (at <dir>)
   <var-prefix>_WC_ROOT - root url of the repository
   <var-prefix>_WC_REVISION - current revision
   <var-prefix>_WC_LAST_CHANGED_AUTHOR - author of last commit
   <var-prefix>_WC_LAST_CHANGED_DATE - date of last commit
   <var-prefix>_WC_LAST_CHANGED_REV - revision of last commit
   <var-prefix>_WC_INFO - output of command `svn info <dir>'

Subversion_WC_LOG retrieves the log message of the base revision of a
subversion working copy at a given location.  This macro defines the
variable:
   <var-prefix>_LAST_CHANGED_LOG - last log of base revision

Example usage:

   find_package(Subversion)
   if(SUBVERSION_FOUND)
     Subversion_WC_INFO(${PROJECT_SOURCE_DIR} Project)
     message("Current revision is ${Project_WC_REVISION}")
     Subversion_WC_LOG(${PROJECT_SOURCE_DIR} Project)
     message("Last changed log is ${Project_LAST_CHANGED_LOG}")
   endif()

我知道有点晚了,但我希望这能帮助你或其他像我一样偶然发现你的问题的人,因为我正在研究答案(只是在我自己的机器上的 Cmake 模块中本地找到答案文件夹)。