CMake如何将构建目录设置为与源目录不同

标签 cmake

我对 CMake 很陌生,阅读了一些关于如何使用它的教程,并编写了一些复杂的 50 行 CMake 脚本,以便为 3 种不同的编译器制作程序。这可能总结了我在 CMake 中的所有知识。

现在我的问题是我有一些源代码,当我制作程序时我不想碰/弄乱它的文件夹。我希望所有 CMake 和 make 输出文件和文件夹都进入 ../Compile/,因此我为此更改了 CMake 脚本中的一些变量,并且它起作用了有一段时间我在笔记本电脑上做了这样的事情:

Compile$ cmake ../src
Compile$ make

我现在所在的文件夹中有一个干净的输出,这正是我正在寻找的。

现在我转移到另一台计算机,重新编译 CMake 2.8.11.2,我几乎回到了原点!它总是将东西编译到我的 CMakeLists.txt 所在的 src 文件夹中。

我在 CMake 脚本中选择目录的部分是这样的:

set(dir ${CMAKE_CURRENT_SOURCE_DIR}/../Compile/)
set(EXECUTABLE_OUTPUT_PATH ${dir} CACHE PATH "Build directory" FORCE)
set(LIBRARY_OUTPUT_PATH ${dir} CACHE PATH "Build directory" FORCE)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${dir})
set(CMAKE_BUILD_FILES_DIRECTORY ${dir})
set(CMAKE_BUILD_DIRECTORY ${dir})
set(CMAKE_BINARY_DIR  ${dir})
SET(EXECUTABLE_OUTPUT_PATH ${dir})
SET(LIBRARY_OUTPUT_PATH ${dir}lib)
SET(CMAKE_CACHEFILE_DIR ${dir})

现在它总是以:

-- Build files have been written to: /.../src

我错过了什么吗?

最佳答案

听起来你想要一个 out of source build .您可以通过多种方式创建非源代码构建。

  1. 做你该做的,跑

     cd /path/to/my/build/folder
     cmake /path/to/my/source/folder
    

    这将导致 cmake 在 /path/to/my/build/folder 中生成 构建树 /path/to/my/source/folder 中的源代码树 .

    创建后,cmake 会记住源文件夹的位置 - 因此您可以重新运行 cmake 在构建树上使用

     cmake /path/to/my/build/folder
    

    甚至

     cmake .
    

    如果你的当前目录已经是构建文件夹。

  2. 对于 CMake 3.13 或更高版本,请使用 these options to set the source and build folders

     cmake -B/path/to/my/build/folder -S/path/to/my/source/folder
    
  3. 对于较旧的 CMake,请使用一些 undocumented options to set the source and build folders :

     cmake -B/path/to/my/build/folder -H/path/to/my/source/folder
    

    它的作用与 (1) 完全相同,但不依赖于当前工作目录。

默认情况下,CMake 会将其所有输出放在 构建树 中,因此除非您大量使用 ${CMAKE_SOURCE_DIR}${CMAKE_CURRENT_SOURCE_DIR}在您的 cmake 文件中,它不应该触及您的 源代码树

最大的问题是如果您之前在源代码树中生成了构建树(即您有一个 in source 构建)。完成此操作后,上面 (1) 的第二部分就会启动,并且 cmake 不会对源代码或构建位置进行任何更改。因此,您不能为具有源内构建的源目录创建源外构建。您可以通过删除(至少)CMakeCache.txt 来轻松解决此问题。从源目录。还有一些 CMake 生成的其他文件(主要在 CMakeFiles 目录中)您也应该删除,但这些不会导致 cmake 将源代码树视为构建树。

由于源外构建通常比源内构建更受欢迎,您可能需要修改您的 cmake 以要求源外构建:

# Ensures that we do an out of source build

MACRO(MACRO_ENSURE_OUT_OF_SOURCE_BUILD MSG)
     STRING(COMPARE EQUAL "${CMAKE_SOURCE_DIR}"
     "${CMAKE_BINARY_DIR}" insource)
     GET_FILENAME_COMPONENT(PARENTDIR ${CMAKE_SOURCE_DIR} PATH)
     STRING(COMPARE EQUAL "${CMAKE_SOURCE_DIR}"
     "${PARENTDIR}" insourcesubdir)
    IF(insource OR insourcesubdir)
        MESSAGE(FATAL_ERROR "${MSG}")
    ENDIF(insource OR insourcesubdir)
ENDMACRO(MACRO_ENSURE_OUT_OF_SOURCE_BUILD)

MACRO_ENSURE_OUT_OF_SOURCE_BUILD(
    "${CMAKE_PROJECT_NAME} requires an out of source build."
)

以上宏来自一个常用的模块MacroOutOfSourceBuild . MacroOutOfSourceBuild.cmake 的来源很多。在谷歌上,但我似乎找不到原件,而且它足够短,可以完整包含在这里。

不幸的是,cmake 通常在调用宏时已经写入了一些文件,因此尽管它会阻止您实际执行构建,但您仍然需要删除 CMakeCache.txtCMakeFiles .

您可能会发现设置二进制库、共享库和静态库的写入路径很有用 - 在这种情况下,请参阅 how do I make cmake output into a 'bin' dir? (免责声明,我在该问题上获得最高票数的答案......但这就是我所知道的)。

关于CMake如何将构建目录设置为与源目录不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18826789/

相关文章:

c++ - 通过 CMake 构建的 ios 上 Qt 应用程序的运行时错误

c++ - 使用 cmake 2.8.8 链接 boost 库

c++ - CMake - 为生成的项目定义 dll 目录或文件

c++ - 使用 CMake 链接库 OpenSubdiv

gcc - CMake 和静态链接

cmake - 如何使用 CMake 从 CPack 二进制文件中排除文件/目录

visual-studio-2008 - CMake 为 Win32 和 x64 生成 Visual Studio 2008 解决方案

c++ - 如何修复 Clion 中目标错误的配方?

OpenCV 作为静态库(cmake 选项)

c++ - Travis CI 找不到头文件