我对 CMake 还很陌生,阅读了一些关于如何使用它的教程,并编写了一些复杂的 50 行 CMake 脚本,以便为 3 个不同的编译器制作一个程序。这可能总结了我对 CMake 的所有知识。
现在我的问题是我有一些源代码,当我制作程序时我不想触摸/弄乱其文件夹。我希望所有 CMake 和make
要进入的输出文件和文件夹../Compile/
,所以我为此更改了 CMake 脚本中的一些变量,当我在笔记本电脑上执行类似操作时,它在一段时间内有效:
Compile$ cmake ../src
Compile$ make
有了这个,我现在所在的文件夹中有一个干净的输出,这正是我正在寻找的。
现在我搬到另一台计算机,并重新编译了 CMake 2.8.11.2,我几乎回到了原点!它总是将东西编译成src
我的文件夹CMakeLists.txt
位于。
我在 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
我错过了什么吗?
听起来你想要一个脱离源代码构建。您可以通过多种方式创建源代码外版本。
-
做你正在做的事,奔跑
cd /path/to/my/build/folder
cmake /path/to/my/source/folder
这将导致 cmake 生成一个建树 in /path/to/my/build/folder
为了源树 in /path/to/my/source/folder
.
创建后,cmake 会记住源文件夹所在的位置 - 因此您可以重新运行
在构建树上进行 cmake
cmake /path/to/my/build/folder
or even
cmake .
如果您的当前目录已经是构建文件夹。
-
对于 CMake 3.13 或更高版本,请使用这些选项用于设置源文件夹和构建文件夹
cmake -B/path/to/my/build/folder -S/path/to/my/source/folder
-
对于较旧的 CMake,请使用一些用于设置源和构建文件夹的未记录选项:
cmake -B/path/to/my/build/folder -H/path/to/my/source/folder
这将执行与 (1) 完全相同的操作,但不依赖当前工作目录。
CMake 将其所有输出放入建树默认情况下,所以除非你经常使用${CMAKE_SOURCE_DIR}
or ${CMAKE_CURRENT_SOURCE_DIR}
在你的 cmake 文件中,它不应该触及你的源树.
可能出错的最大的事情是如果您之前在源树中生成了构建树(即您有一个在源代码中建造)。完成此操作后,上面 (1) 的第二部分就会生效,并且 cmake 不会对源或构建位置进行任何更改。因此,您无法使用源内构建为源目录创建源外构建。您可以通过删除(至少)来相当轻松地解决此问题CMakeCache.txt
从源目录。还有一些其他文件(主要在CMakeFiles
目录),您也应该删除 CMake 生成的文件,但这些不会导致 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
and CMakeFiles
.
您可能会发现设置二进制文件、共享库和静态库的写入路径很有用 - 在这种情况下,请参阅如何将 cmake 输出放入“bin”目录?(免责声明,我对这个问题有最高票数的答案......但这就是我所知道的)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)