CMake输出/build立目录

我对cmake非常陌生,阅读了一些关于如何使用它的教程,并编写了一些复杂的50行CMake脚本,以便为3个不同的编译器编写一个程序。 这大概就是我在cmake上的所有知识。

现在我的问题是,我有一些源代码,我的文件夹,我不想碰/混乱,当我做的程序。 我想要所有的cmake,并把输出文件和文件夹放到../Compile/中,所以我在cmake脚本中改变了一些variables,并且在我的笔记本电脑上做了这样的工作,

Compile$ cmake ../src Compile$ make 

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

现在我转移到另一台电脑,并重新编译CMake 2.8.11.2,我几乎回到了一个! 它总是将这个东西编译到我的CMakeLists.txt所在的src文件夹中。

我在cmake脚本中select目录的部分是这样的:

 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 

我错过了什么吗?

(把我的意见转化为答案)

几乎没有必要设置所有你设置的variables。 CMake将它们设置为合理的默认值。 您绝对不能修改CMAKE_BINARY_DIRCMAKE_CACHEFILE_DIR 。 将这些视为只读。

只需删除所有set()命令,然后执行:

 cd Compile rm -rf * cmake ../src 

只要你在运行CMake的时候不在源代码目录中,除非你的CMakeList明确地告诉它,否则它不会修改源代码目录。

一旦你有了这个工作,你可以看看默认情况下CMake把东西放在哪里,只有当你对默认位置(例如EXECUTABLE_OUTPUT_PATH的默认值)不满意时,才会修改你需要的东西。 并尝试expression它们相对于CMAKE_BINARY_DIRCMAKE_CURRENT_BINARY_DIRPROJECT_BINARY_DIR

如果你看看CMake文档,你会看到variables被分成了语义部分。 除了非常特殊的情况外,您应该将CMakeLists中的“提供信息的variables”列出的所有内容视为只读。

这听起来像你想要一个源代码构build 。 有几种方法可以创build出源构build。

  1. 做你正在做的,跑步

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

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

    一旦你创build了它,cmake会记住源文件夹的位置 – 所以你可以在构build树上重新运行cmake

     cmake /path/to/my/build/folder 

    甚至

     cmake . 

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

  2. 使用一些未公开的选项来设置源文件夹和生成文件夹 :

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

    这将完成与(1)完全相同的事情,但不依赖于当前的工作目录。

CMake默认将所有的输出放在构build树中 ,所以除非你在你的cmake文件中宽松地使用${CMAKE_SOURCE_DIR}或者${CMAKE_CURRENT_SOURCE_DIR} ,否则它不应该触及你的源码树

最大的问题是如果你以前在源代码树中生成了一个构build树(也就是说你有一个源代码版本)。 完成上述(1)的第二部分后,cmake不会对源或构build位置进行任何更改。 因此, 您无法使用源内部版本为源目录创build源外构build 。 您可以通过从源目录中删除(至less) CMakeCache.txt来相当容易地解决这个问题。 CMake生成的其他一些文件(大部分在CMakeFiles目录中)也应该删除,但是这些文件不会导致cmake将源树视为构build树。

由于源代码构build通常比源代码构build更受欢迎,因此您可能需要修改cmake以要求源代码构build:

 # 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." ) 

上面的macros来自一个叫做MacroOutOfSourceBuild的常用模块。 在谷歌上有很多MacroOutOfSourceBuild.cmake源代码,但是我似乎无法find原来的代码,而且它足够短,可以包含在这里。

不幸的是,cmake通常在macros被调用的时候写了几个文件,所以虽然它会阻止你实际执行构build,但仍然需要删除CMakeCache.txtCMakeFiles

您可能会发现设置二进制文件,共享和静态库的写入path很有用 – 在这种情况下,请参阅如何将cmake输出转换为“bin”目录? (免责声明,我有这个问题的顶级投票答案…但这就是我知道的)。

从CMake Wiki开始: http : //www.cmake.org/Wiki/CMake_Useful_Variables

CMAKE_BINARY_DIR,如果你正在build立源代码,这是一样的CMAKE_SOURCE_DIR,否则这是你的构build树的顶级目录

比较这两个variables来确定是否已经开始源外构build

首先,你不应该在你的脚本中build立目录名称。 与../编译必须改变。

这是因为它取决于用户在哪里编译。

而不是使用预定义variables之一: http ://www.cmake.org/Wiki/CMake_Useful_Variables(寻找CMAKE_BINARY_DIR和CMAKE_CURRENT_BINARY_DIR)