CMake如何将构建目录设置为与源目录不同

k3fezbri  于 2022-11-11  发布在  其他
关注(0)|答案(6)|浏览(264)

我对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

我错过了什么吗?

mkshixfv

mkshixfv1#

这听起来像你想要一个源代码外的构建。有几种方法可以创建一个源代码外的构建。
1.做你刚才做的事,快跑

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

这将使cmake为/path/to/my/source/folder中的 * 源树 * 生成/path/to/my/build/folder中的 * 构建树 *。
一旦您创建了它,cmake就会记住源文件夹的位置--这样您就可以在构建树上使用

cmake /path/to/my/build/folder

或者甚至

cmake .

如果您的当前目录已经是build文件夹。
1.对于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

1.对于较旧的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文件中大量使用${CMAKE_SOURCE_DIR}${CMAKE_CURRENT_SOURCE_DIR},否则它不应该触及您的 * 源代码树 *。
可能出错的最大问题是,如果您以前在源代码树中生成了构建树(例如,您有一个 in source build)。完成此操作后,(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,google上有很多MacroOutOfSourceBuild.cmake的源代码,但是我似乎找不到原始的,它很短,可以完整的包含在这里。
不幸的是,在调用宏之前,cmake通常已经编写了几个文件,因此,尽管它会阻止您实际执行构建,但您仍需要删除CMakeCache.txtCMakeFiles
您可能会发现设置二进制文件、共享库和静态库的写入路径很有用-在这种情况下,请参见how do I make cmake output into a 'bin' dir?(免责声明,我在这个问题上的投票结果最多......但这就是我了解它的原因)。

krcsximq

krcsximq2#

几乎不需要设置所有你正在设置的变量。CMake将它们设置为合理的默认值。你绝对不应该**修改CMAKE_BINARY_DIRCMAKE_CACHEFILE_DIR。将它们视为只读。
首先从src目录中删除现有的有问题的缓存文件:

cd src
rm CMakeCache.txt
cd ..

然后删除所有set()命令并执行以下操作:

cd Compile && rm -rf *
cmake ../src

只要您在源目录之外运行CMake,它就不会修改源目录,除非您的CMakeList明确告诉它这样做。
一旦你有了这个工作,你可以看看CMake默认放置东西的位置,只有当你对默认位置不满意时(比如默认值EXECUTABLE_OUTPUT_PATH),才修改你需要的位置。
如果你看CMake文档,你会发现变量被划分成语义部分。除了 * 非常 * 特殊的情况,你应该把所有列在“提供信息的变量”下的变量在CMakeLists中视为只读的。

fzwojiic

fzwojiic3#

把我的评论变成一个答案:
如果有人做了我所做的事情,那就是把所有的构建文件放在源目录中:

cd src
cmake .

cmake会在src目录中放置一组构建文件和缓存文件(CMakeCache.txtCMakeFilescmake_install.cmake等)。
为了改变到一个源代码外的版本,我必须删除所有这些文件。然后我可以做@Angew在他的回答中推荐的事情:

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

gudnpqoy4#

截至CMake Wiki
CMAKE_BINARY_DIR如果您正在源代码内生成,则此目录与CMAKE_SOURCE_DIR相同,否则此目录为生成树的顶级目录
比较这两个变量以确定是否启动了源代码外生成

uqdfh47h

uqdfh47h5#

您不应该依赖脚本中硬编码的构建目录名称,因此必须更改包含../Compile的行。
这是因为它应该由用户决定在哪里编译。
请使用以下预定义变量之一:http://www.cmake.org/Wiki/CMake_Useful_Variables(查找CMAKE_BINARY_DIRCMAKE_CURRENT_BINARY_DIR

mfpqipee

mfpqipee6#

从cmake 3.19开始,您还可以使用preset files,其中您还可以指定输出二进制dir:

{
  "version": 2,
  "cmakeMinimumRequired": {
    "major": 3,
    "minor": 19,
    "patch": 0
  },
  "configurePresets": [
    {
      "name": "default",
      "displayName": "Default",
      "description": "Default build cfg",
      "generator": "Unix Makefiles",
      "binaryDir": "${sourceDir}/Compile",
      "cacheVariables": {
      },
      "environment": {
      }
    }
  ]
}

然后运行带有--preset参数的cmake:

cmake --preset=default

然后,只需将cd添加到构建目录并运行make(在您的示例中):

cd ./Compile
make

相关问题