CMake输出/构建目录

The*_*ist 98 c++ makefile build cmake output

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

现在我的问题是我有一些源代码,当我制作程序时,我不想触摸/弄乱它的文件夹.我想要所有cmake并使输出文件和文件夹进入../Compile/,所以我在我的cmake脚本中更改了一些变量,并且它在我的笔记本电脑上做了类似的事情时工作了一段时间:

Compile$ cmake ../src
Compile$ make
Run Code Online (Sandbox Code Playgroud)

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

现在我转移到另一台计算机,并重新编译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})
Run Code Online (Sandbox Code Playgroud)

现在它始终以:

-- Build files have been written to: /.../src
Run Code Online (Sandbox Code Playgroud)

我错过了什么吗?

Ada*_*wen 100

听起来你想要一个源代码构建.您可以通过两种方法创建源代码构建.

  1. 做你正在做的事,跑

    cd /path/to/my/build/folder
    cmake /path/to/my/source/folder
    
    Run Code Online (Sandbox Code Playgroud)

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

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

    cmake /path/to/my/build/folder
    
    Run Code Online (Sandbox Code Playgroud)

    甚至

    cmake .
    
    Run Code Online (Sandbox Code Playgroud)

    如果您当前的目录已经是build文件夹.

  2. 使用一些未记录的选项来设置源文件和构建文件夹:

    cmake -B/path/to/my/build/folder -S/path/to/my/source/folder
    
    Run Code Online (Sandbox Code Playgroud)

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

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

可能出错的最大问题是,如果您之前在源代码树中生成了构建树(即您具有源代码构建).一旦你完成了这个,上面的(1)的第二部分开始,并且cmake不会对源或构建位置进行任何更改.因此,您无法使用源内构建为源目录创建源外构建.您可以通过CMakeCache.txt从源目录中删除(至少)来相当容易地解决此问题.CMakeFilesCMake生成的其他一些文件(主要在目录中)也应该删除,但这些文件不会导致cmake将源树视为构建树.

由于源外构建通常比源内构建更令人满意,因此您可能希望将cmake修改为需要源代码构建:

cmake -B/path/to/my/build/folder -H/path/to/my/source/folder
Run Code Online (Sandbox Code Playgroud)

上面的宏来自一个常用的模块叫做MacroOutOfSourceBuild.MacroOutOfSourceBuild.cmake谷歌有很多来源,但我似乎无法找到原始的,它足够短,完全包括在这里.

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

您可能会发现设置二进制文件,共享库和静态库的写入路径很有用 - 在这种情况下,请参阅如何将cmake输出转换为"bin"目录?(免责声明,我对这个问题有最高投票答案......但这就是我对此的了解).


Rei*_*ica 54

几乎不需要设置您正在设置的所有变量.CMake将它们设置为合理的默认值.你绝对应该修改CMAKE_BINARY_DIRCMAKE_CACHEFILE_DIR.将它们视为只读.

首先从src目录中删除现有的有问题的缓存文件:

cd src
rm CMakeCache.txt
cd ..
Run Code Online (Sandbox Code Playgroud)

然后删除所有set()命令并执行:

cd Compile
rm -rf *
cmake ../src
Run Code Online (Sandbox Code Playgroud)

只要您在运行CMake时位于源目录之外,它就不会修改源目录,除非您的CMakeList明确告诉它.

一旦你有了这个工作,你可以看看CMake默认放置的地方,并且只有当你对默认位置(例如默认值EXECUTABLE_OUTPUT_PATH)不满意时,才修改你需要的那些.并试图表达他们对于CMAKE_BINARY_DIR,CMAKE_CURRENT_BINARY_DIR,PROJECT_BINARY_DIR等.

如果你看一下CMake文档,你会看到变量被划分为语义部分.除了非常特殊的情况,您应该将在"提供信息的变量"下列出的所有内容视为CMakeLists中的只读.

  • 也许最好不建议使用`rm -rf*`.如果`cd Compile`失败,那就不好了...... (10认同)
  • 我开始在src目录中使用带有构建的cmake ...这种技术最初失败了.一旦我删除了src目录中的所有cmake构建文件/缓存,这种技术就可以了.谢谢! (2认同)
  • @罗马我认为这样的命令行示例几乎是伪代码。它比键入“进入目录`Compile`,删除其中的所有内容,然后运行带有源目录路径的CMake”更为冗长和精确。我认为部分读者具有基本常识和判断力。 (2认同)

小智 6

CMake Wiki开始:

CMAKE_BINARY_DIR如果要在源代码中构建,这与CMAKE_SOURCE_DIR相同,否则这是构建树的顶级目录

比较这两个变量以确定是否已启动源外构建


Avi*_*vet 6

将我的评论变成答案:

万一有人做我做的事情,首先将所有构建文件放在源目录中:

cd src
cmake .
Run Code Online (Sandbox Code Playgroud)

cmake的会放了一堆的编译文件和缓存文件(CMakeCache.txtCMakeFilescmake_install.cmake等)的src目录。

要更改为非源构建,我必须删除所有这些文件。然后我可以做@Angew在他的回答中建议的操作:

mkdir -p src/build
cd src/build
cmake ..
Run Code Online (Sandbox Code Playgroud)


Mic*_*iak 5

您不应在脚本中依赖硬编码的构建目录名称,因此../Compile必须更改所在的行。

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

而不是使用以下预定义的变量之一:http : //www.cmake.org/Wiki/CMake_Useful_Variables (查找CMAKE_BINARY_DIRCMAKE_CURRENT_BINARY_DIR

  • 这正是我在寻找的东西-`CMAKE_CURRENT_BINARY_DIR`,通常会告诉您当前的二进制构建路径。可能可以用于设置依赖的库/ bin版本。 (2认同)