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

2023-12-13

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

我错过了什么吗?


听起来你想要一个脱离源代码构建。您可以通过多种方式创建源代码外版本。

  1. 做你正在做的事,奔跑

     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 .
    

    如果您的当前目录已经是构建文件夹。

  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 将其所有输出放入建树默认情况下,所以除非你经常使用${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(使用前将#替换为@)

CMake如何将构建目录设置为与源目录不同 的相关文章

随机推荐

  • 调用并行化 foreach 时出现问题

    我在使用 System Threading Tasks Parallel ForEach 时遇到问题 每个要更新的进度条的主体 但Invoke方法有时会冻结 我将代码附加到进度条和按钮的表单中 private void button1 Cl
  • 如何显示MySQL中未完成的事务

    我做了一些没有提交的查询 然后应用程序被停止 如何显示这些未结交易并提交或取消它们 如何显示这些未结交易并提交或取消它们 没有打开的事务 MySQL 将在断开连接时回滚事务 您无法提交事务 IFAIK 您使用显示线程 SHOW FULL P
  • C# 中根据空格分割字符串

    我有一个字符串 dexter 是好是坏 我想通过根据空格分割该字符串来创建一个列表 我使用以下代码实现了这一点 string ss dexter is good annd bad var s string IsNullOrEmpty ss
  • 从 Nunit 获取失败测试列表

    我有一个包含超过 8000 个测试的测试套件 并且很难看出哪些测试在代码更改之间中断 这些测试用例是从某些日志文件中自动提取的查询 有没有一种简单的方法来获取 NUnit 运行的失败测试列表 理想情况下 我想比较运行之间哪些测试受到影响 您
  • Protobuf-net 对 Dictionary/KeyValuePair 的支持是如何工作的?

    我试图了解 protobuf net 的 Dictionary KeyValuePair 支持 我们希望使用底层二进制流和从 java 生成的 proto 文件 但生成的 proto 文件包含看起来像名为 Pair String Int32
  • iOS 应用程序捆绑包 ID 错误和 iTunesConnect

    如本文所述SO entry 我在 iOS 应用程序应用程序上传器中遇到错误 这些是我的价值观 在钥匙串中我有这个证书 iPhone Distribution ExampleCompany DistCertificateID 在我的devel
  • 获取Linux中每个进程的堆和堆栈的大小

    我想知道Linux中每个进程的堆和堆栈的大小 有什么办法可以找到吗 我发现 sbrk 0 会给我堆的结尾 但是如何找到堆的起始位置来获取堆大小呢 另外 关于堆栈大小 是否有任何方法可以通过任何库调用或系统调用找到每个进程的堆栈开头和当前堆栈
  • Spring 4 i18n & l10n(无法更改 HTTP 接受标头)

    我需要帮助来解决此错误消息 我正在使用 spring 4 我想在我的项目中实现 i18n 和 l10n 当我尝试更改语言时 会出现此消息 下面是我的代码 请问 有人可以帮我解决这个问题吗 https i stack imgur com tK
  • didReceiveData 未获取所有数据

    我正在尝试使用 NSURLConnection 下载 JSON 但除非我强制应用程序暂停几秒钟 否则我获得的数据并不完整 它总是在 2600 字节左右 而我的响应应该在 70000 左右 任何线索为什么会发生这种情况 谢谢 void con
  • 未检测到文档的语法约束(DTD 或 XML 模式)

    我有这个 dtd http fast code sourceforge net template dtd但是当我包含在 xml 中时 我收到警告 未检测到文档的语法约束 DTD 或 XML 模式 xml 是
  • 使用正则表达式捕获 html 标签内的内容

    首先 我知道这是一种不好的做法 我已经回答了很多问题 甚至这么说 但需要澄清一下我被迫使用正则表达式 因为该应用程序将正则表达式存储在数据库中并且只能以这种方式运行 我绝对不能改变功能 现在我们已经解决了这个问题 因为我总是使用 DOM 方
  • 无法使 PubNub WebRTC 教程正常工作

    我正在尝试按照 PubNub 教程构建我的第一个 WebRTC 应用程序 https www pubnub com blog 2015 08 25 webrtc video chat app in 20 lines of javascrip
  • 使用 FluentFTP 以最大值同时从 FTP 下载多个文件

    我想从 FTP 目录递归下载多个下载文件 为此我使用 FluentFTP 库 我的代码是这样的 private async Task downloadRecursively string src string dest FtpClient
  • 在本地使用 mpi 安装 fftw-2.1.5

    我正在尝试使用 enable mpi 标志在带有 linux 的 IBM 集群上安装 fftw 2 1 5 库 但此后我一直未能这样做 我需要 fftw 版本 2 1 5 因为 GADGET2 代码需要该版本 并且具有 mpi 支持 首先
  • Python - BeautifulSoup html解析处理gbk编码不佳 - 中文网页抓取问题

    我一直在修改以下脚本 coding utf8 import codecs from BeautifulSoup import BeautifulSoup NavigableString UnicodeDammit import urllib
  • 字典、哈希集的访问时间

    访问时间是多少 在字典中查找值 检查HashSet是否有值 是像C 0x的unordered map那样O 1 吗 是的 当您使用 Contains 方法或字典的索引器时 来自文档 Dictionary Of TKey TValue 泛型类
  • 我可以在 JavaScript 中将新数组重新分配给数组变量吗?

    我对 JavaScript 中的数组以及在函数内操作它们有疑问 这是书上的练习雄辩的 JavaScript 它涉及两个功能 reverseArray 返回一个new与参数数组相反的数组 reverseArrayInPlace 只是反转参数数
  • Ruby:常量查找在instance_eval/class_eval 中如何工作?

    我正在研究 Pickaxe 1 9 并且对 instance class eval 块中的常量查找感到有点困惑 我用的是1 9 2 Ruby 似乎以与方法查找相同的方式处理 eval 块中的常量查找 在receiver singleton
  • Mac OS X:我可以在应用程序包中编写应用程序文件吗?

    该应用程序将位于 Applications 中 该应用程序将通过网络浏览器而不是通过 App Store 下载 使用的语言是 Tcl Tk 答 这适用于所有版本的 OS X 10 5 或更高版本吗 B 有没有更好的地方来存储应用程序文件 L
  • CMake如何将构建目录设置为与源目录不同

    我对 CMake 还很陌生 阅读了一些关于如何使用它的教程 并编写了一些复杂的 50 行 CMake 脚本 以便为 3 个不同的编译器制作一个程序 这可能总结了我对 CMake 的所有知识 现在我的问题是我有一些源代码 当我制作程序时我不想