我对 CMake 很陌生,阅读了一些关于如何使用它的教程,并编写了一些复杂的 50 行 CMake 脚本,以便为 3 种不同的编译器制作程序。这可能总结了我在 CMake 中的所有知识。
现在我的问题是我有一些源代码,当我制作程序时我不想碰/弄乱它的文件夹。我希望所有 CMake 和 make
输出文件和文件夹都进入 ../Compile/
,因此我为此更改了 CMake 脚本中的一些变量,并且它起作用了有一段时间我在笔记本电脑上做了这样的事情:
Compile$ cmake ../src
Compile$ make
我现在所在的文件夹中有一个干净的输出,这正是我正在寻找的。p>
现在我转移到另一台计算机,重新编译 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 .您可以通过多种方式创建非源代码构建。
做你该做的,跑
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 .
如果你的当前目录已经是构建文件夹。
对于 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
对于较旧的 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.txt
和 CMakeFiles
.
您可能会发现设置二进制库、共享库和静态库的写入路径很有用 - 在这种情况下,请参阅 how do I make cmake output into a 'bin' dir? (免责声明,我在该问题上获得最高票数的答案......但这就是我所知道的)。
关于CMake如何将构建目录设置为与源目录不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18826789/