首页
学习
活动
专区
圈层
工具
发布

cmake困境
EN

Stack Overflow用户
提问于 2020-04-29 14:45:52
回答 1查看 314关注 0票数 4

我正在做一个C++项目。到目前为止,它并不复杂,但依赖于一堆“流行的”库(nlohmann/json,ToruNiina/ to 11,仅举几个例子)。它们都有一些CMakeLists.txt,从我没有经历过的角度来看,我认为它们结构很好。

当然,现在我可以一个一个地编译库,或者在我的项目回购中包含一个“拷贝”,但是我想做得更好。在研究了可用的构建工具之后,我决定使用cmake来构建和管理一个C++项目。承诺是获得一个稳定的、得到广泛支持的工具,它将有助于简化和统一构建过程。此外,从项目性质来看,我没有特权将任何需求强加到目标机器上;我需要打包部署所需的一切。

我花了几天的时间阅读、观看和测试各种cmake教程、手册和手册。我不得不承认,我很快就开始感觉到,一种本应用来澄清开发过程的工具不断引入与其目的相反的新的模糊现象。起初,我把这归功于我缺乏经验,但.

我读过文章关于为什么不捆绑依赖关系的文章,但是后面跟着这样做的方法。我发现建议使用A对B,C对B,后来A对C。我花了一段时间才找出2.8和3.0之间的差异,朦胧 of target_link_libraries,设置cxx版本和/或编译器警告标志等等。

我的观点是,即使在cmake的海洋中进行了一次令人精疲力竭的探险之后,我仍然不确定一些基本的问题:

如何使用cmake? 什么是标准,什么是礼貌,什么不是标准? 我怎么知道某些东西是一种特性,一种过时的向后兼容性,或者两者都是?

现在我将在我的项目中说明这一点。我只需要这样的东西

代码语言:javascript
复制
cmake_minimum_required(VERSION 3.14)
project(CaseCore CXX)

add_executable(myBinary list/of/cpp/sources.cpp)
target_link_libraries(myBinary PUBLIC someExternalLibs likeForExample nlohmann_json::nlohmann_json oqs)

唯一的问题是库(反正没有其他问题的空间)。我想用这个项目来构建它们,并且不想制作一个本地副本(不要一直拖着一大堆不相关的文件)。首先,我创建了一些库repos,以便有一个可靠的源,并能够将较新的版本合并到我的叉中。

现在的决定是使用git submodule还是其他一些方案,我已经读到子模块的性能不太好,并且更喜欢由cmake来管理整个事情。我从ExternalProject_Add开始,但后来我发现了FetchContent,它帮助我轻松地将外部依赖项添加到cmake列表中。

代码语言:javascript
复制
FetchContent_Declare(nlohmann
    GIT_REPOSITORY https://github.com/my-reliable-fork-of/json
    GIT_TAG v3.7.3
)
message(STATUS  "Fetching Json...this may take a while")
FetchContent_MakeAvailable(nlohmann)

似乎和运作良好和最低限度。但是,为了找到/猜测要链接到可执行目标的目标,我总是必须搜索库本身。似乎有接近于零约定,除非相应的CMakeLists.txt足够简单地读取它,我倾向于猜测目标的名称,直到我找到它。

最近,我想链接来自这里的liboqs,而上面提到的场景并没有真正帮助我;出于某种原因,我可以链接oqs、#include "oqs/oqs.h",但是动态库没有创建,执行也停止了。我非常肯定,在花了一段时间搜索和处理各种cmake变量之后,我可以解决这个问题。然而,这并不是我所期望的cmake帮助我管理我的项目的方式,实际上恰恰相反。

为了澄清一下,我拒绝了其他方法,包括

代码语言:javascript
复制
add_subdirectory from local repo copy (git submodule)
ExternalProject_Add from local repo copy (git submodule)
ExternalProject_Add from online repo
find_package

因为他们似乎更晦涩/老派等等(尽管他们花了几个小时的研究,但他们似乎仍然像许多方式一样对我做同样的事情)。

现在我有了

我是不是做错了什么,还是真的是使用cmake应该是什么样子? 我真的需要“逆向工程”别人的CMakeLists才能使用库吗? 在这种情况下,我如何说服同事采用类似的工作程序呢?

最后

我如何调整我的工作,以缓解这些困难,为其他人?

我越爱C++就越用它。然而,我在解决dependencies...and上花费了大量高效的时间,我不想让这家伙更加生气。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-04-29 15:32:51

如何使用cmake?

典型的cmake用法与旧的自动工具用法相匹配:

代码语言:javascript
复制
$ cmake /path/to/src #replaces /path/to/src/configure
$ make
$ make install

有些目标发生了变化(例如,make checkmake test),cmake没有提供所有相同的标准目标(例如make distclean),但我上面的用法是大多数开发人员都会做的事情(而且由于cmake重新运行,这实际上只是大多数时候的第二步)。

如果您的CMakeLists.txt不支持这个工作流,那么您应该有一个很好的理由。大多数工具都会假设这样的工作流,因此您将严格限制自己。

什么是标准,什么是礼貌,什么不是标准?

除了以上这些,cmake几乎是野生的西部。由于更好的文档和培训,事情变得更加标准化了,但这还远远不够完美。

一个行为良好的cmake项目应该导出它的目标(大量关于堆栈溢出的问题和答案),并传播标志和依赖项。这使得依赖项目更容易使用导出的目标,幸运的是,这很容易做到。

我怎么知道某些东西是一种特性,一种过时的向后兼容性,或者两者都是?

我不知道这些区别是什么。通常,较新的方法利用target_*函数而不是全局函数(例如,target_include_directoriesinclude_directories)。target_*函数还用于传播标志,包括目录、编译器特性和我前面提到的依赖库。

我是不是做错了什么,还是真的和cmake一起工作应该是什么样子?

您讨论的是管理外部依赖关系,我将跳过这一点,以避免陷入意见。简短的版本是C和C++依赖关系很难实现,在一个项目中管理它们有很多竞争的方法。它们各有优缺点,但大多数仍然是为作者的用例设计的。您必须找出您需要的用例,并在此基础上选择工具和工作流。

我真的需要“逆向工程”别人的CMakeLists才能使用库吗?

行为良好的cmake项目将正确导出其目标,即使它们使用与您不同的依赖关系管理。如果他们不这样做,就向项目发送一个拉请求(导出并不困难,学习如何导出),或者只是针对它们提交错误文件,特别是当他们已经将cmake作为一个构建系统时。

在这种情况下,我如何说服同事采用类似的工作程序呢?

这取决于你的同事,里程也会不同。我与那些想要接受最佳实践和支持灵活性的同事打交道,我也遇到过那些只满足于为解决我们目前面临的问题所做的足够努力的同事。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61504626

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档