C++ CMake 输出/构建目录

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18826789/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 22:14:43  来源:igfitidea点击:

CMake output/build directory

c++buildmakefilecmakeoutput

提问by The Quantum Physicist

I'm pretty new to CMake, and read a few tutorials on how to use it, and wrote some complicated 50 lines of CMake script in order to make a program for 3 different compilers. This probably concludes all my knowledge in CMake.

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

Now my problem is that I have some source code, whose folder I don't want to touch/mess with when I make the program. I want that all CMake and makeoutput files and folders to go into ../Compile/, so I changed a few variables in my CMake script for that, and it worked for sometime when I did something like this on my laptop:

现在我的问题是我有一些源代码,当我制作程序时,我不想触摸/弄乱它的文件夹。我希望所有 CMake 和make输出文件和文件夹都进入.cmake ../Compile/,因此我为此更改了 CMake 脚本中的一些变量,并且当我在笔记本电脑上执行以下操作时,它工作了一段时间:

Compile$ cmake ../src
Compile$ make

Where with that I had a clean output in the folder I'm in right now, which is exactly what I'm looking for.

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

Now I moved to another computer, and recompiled CMake 2.8.11.2, and I'm almost back to square one! It always compiles the thing into the srcfolder where my CMakeLists.txtis located.

现在我搬到另一台电脑上,重新编译 CMake 2.8.11.2,我几乎回到了原点!它总是将事物编译到srcmy 所在的文件夹中CMakeLists.txt

The part where I choose the directory in my CMake script is this:

我在 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})

And now it always ends with:

现在它总是以:

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

Am I missing something?

我错过了什么吗?

采纳答案by Angew is no longer proud of SO

There's little need to set all the variables you're setting. CMake sets them to reasonable defaults. You should definitely notmodify CMAKE_BINARY_DIRor CMAKE_CACHEFILE_DIR. Treat these as read-only.

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

First remove the existing problematic cache file from the src directory:

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

cd src
rm CMakeCache.txt
cd ..

Then remove all the set()commands and do:

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

cd Compile
rm -rf *
cmake ../src

As long as you're outside of the source directory when running CMake, it will not modify the source directory unless your CMakeList explicitly tells it to.

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

Once you have this working, you can look at where CMake puts things by default, and only if you're not satisfied with the default locations (such as the default value of EXECUTABLE_OUTPUT_PATH), modify only those you need. And try to express them relative to CMAKE_BINARY_DIR, CMAKE_CURRENT_BINARY_DIR, PROJECT_BINARY_DIRetc.

完成此操作后,您可以查看 CMake 默认放置内容的位置,并且仅当您对默认位置(例如 的默认值EXECUTABLE_OUTPUT_PATH)不满意时,仅修改您需要的位置。并尝试相对表达出来CMAKE_BINARY_DIRCMAKE_CURRENT_BINARY_DIRPROJECT_BINARY_DIR等。

If you look at CMake documentation, you'll see variables partitioned into semantic sections. Except for veryspecial circumstances, you should treat all those listed under "Variables that Provide Information" as read-only inside CMakeLists.

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

回答by Adam Bowen

It sounds like you want an out of source build. There are a couple of ways you can create an out of source build.

听起来你想要一个out of source build。有几种方法可以创建源代码构建。

  1. Do what you were doing, run

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

    which will cause cmake to generate a build treein /path/to/my/build/folderfor the source treein /path/to/my/source/folder.

    Once you've created it, cmake remembers where the source folder is - so you can rerun cmake on the build tree with

    cmake /path/to/my/build/folder
    

    or even

    cmake .
    

    if your current directory is already the build folder.

  2. For CMake 3.13 or later, use these options to set the source and build folders

    cmake -B/path/to/my/build/folder -S/path/to/my/source/folder
    
  3. For older CMake, use some undocumented options to set the source and build folders:

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

    which will do exactly the same thing as (1), but without the reliance on the current working directory.

  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 或更高版本,使用这些选项来设置源和构建文件夹

    cmake -B/path/to/my/build/folder -S/path/to/my/source/folder
    
  3. 对于较旧的 CMake,请使用一些未记录的选项来设置源和构建文件夹

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

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

CMake puts all of its outputs in the build treeby default, so unless you are liberally using ${CMAKE_SOURCE_DIR}or ${CMAKE_CURRENT_SOURCE_DIR}in your cmake files, it shouldn't touch your source tree.

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

The biggest thing that can go wrong is if you have previously generated a build tree in your source tree (i.e. you have an in sourcebuild). Once you've done this the second part of (1) above kicks in, and cmake doesn't make any changes to the source or build locations. Thus, you cannot create an out-of-source build for a source directory with an in-source build. You can fix this fairly easily by removing (at a minimum) CMakeCache.txtfrom the source directory. There are a few other files (mostly in the CMakeFilesdirectory) that CMake generates that you should remove as well, but these won't cause cmake to treat the source tree as a build tree.

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

Since out-of-source builds are often more desirable than in-source builds, you might want to modify your cmake to require out of source builds:

由于外源构建通常比源内构建更可取,因此您可能需要修改 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."
)

The above macro comes from a commonly used module called MacroOutOfSourceBuild. There are numerous sources for MacroOutOfSourceBuild.cmakeon google but I can't seem to find the original and it's short enough to include here in full.

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

Unfortunately cmake has usually written a few files by the time the macro is invoked, so although it will stop you from actually performing the build you will still need to delete CMakeCache.txtand CMakeFiles.

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

You may find it useful to set the paths that binaries, shared and static libraries are written to - in which case see how do I make cmake output into a 'bin' dir?(disclaimer, I have the top voted answer on that question...but that's how I know about it).

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

回答by Avi Tevet

Turning my comment into an answer:

把我的评论变成答案:

In case anyone did what I did, which was start by putting all the build files in the source directory:

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

cd src
cmake .

cmake will put a bunch of build files and cache files (CMakeCache.txt, CMakeFiles, cmake_install.cmake, etc) in the srcdir.

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

To change to an out of source build, I had to remove all of those files. Then I could do what @Angew recommended in his answer:

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

mkdir -p src/build
cd src/build
cmake ..

回答by damkrat

As of CMake Wiki:

CMake Wiki 开始

CMAKE_BINARY_DIR if you are building in-source, this is the same as CMAKE_SOURCE_DIR, otherwise this is the top level directory of your build tree

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

Compare these two variables to determine if out-of-source build was started

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

回答by Micha? Walenciak

You should not rely on a hard coded build dir name in your script, so the line with ../Compilemust be changed.

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

It's because it should be up to user where to compile.

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

Instead of that use one of predefined variables: http://www.cmake.org/Wiki/CMake_Useful_Variables(look for CMAKE_BINARY_DIRand CMAKE_CURRENT_BINARY_DIR)

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