我最近遇到了一个我不知道的CMake功能。它是FetchContent。我敢肯定,这对大多数人来说不是什么新闻,因为它是在CMake 3.14 1中添加的,并且自2019年2月以来一直存在,所以已经有两年了,但这是一个启示。
它可以……不,应该……不,它必须成为C和C ++包管理器未来的垫脚石。
…问题解决后,我将在后续文章中进一步探讨
实际上,这非常简单。通过使用两个CMake函数:FetchContent_Declare和FetchContent_MakeAvailable,两个用户可以声明一个命名的内容项,然后可以…好……在配置时获取。与file(DOWNLOAD ...)相对,此处的关键是允许三点重要:
定义产生内容的方式(不仅是来源,还包括来源类型)
包括(FetchContent)FetchContent_Declare(googletest GIT_REPOSITORY https://github.com/google/googletest.git GIT_TAG版本1.8.0)FetchContent_Declare(Catch2 GIT_REPOSITORY https://github.com/catchorg/Catch2.git GIT_TAG v2.5.0) #在以下调用之后,将定义由googletest和#Catch2定义的CMake目标,并且可用于其余版本FetchContent_MakeAvailable(googletest Catch2)
我知道了。柯南,vcpkg和其他3个都很棒,但是它们是外部的。当然,我已经尝试了流行的C ++程序包管理器,但是我一直不愿意在我的项目中开始使用它。它们可能具有CMake集成,但不是由CMake触发的。他们尝试-并且成功-不仅仅是CMake。事实是,无论是否喜欢,CMake都是(或至少真的接近)了C ++ 4的事实上的标准构建系统。CMake在许多方面都很糟糕,但是事实证明,它是我们最好的。我有5。
哦,这个包有CMakeLists.txt吗?只要下载二进制文件并添加到add_subdirectory…,就无需下载二进制文件。它会继承项目中所需的一切。
当然,您可以根据平台,三元组和其他程序包管理器的其他配置来定义不同的程序包,但是您使用的是它们的语言。然后,您必须在CMake文件中重新实现相同的配置分析,或者使用那些包管理器中的某些导出,这并不总是那么容易。如果您的软件包管理器在CMake中,则您不可避免地已经拥有配置构建的所有工具。有关编译器,标准,目标平台,体系结构,链接以及其他所有信息的信息已经存在。
……一切正常,一切都是最新的,一切都在那里。您已准备好进行构建。
当然,您可以使用原始调用,即使它们还不是程序包管理器。 Adobe正是这样做的。
而且,尽管该功能已经存在了一段时间,但我只知道一个内置的软件包管理器:CPM。
现在,CPM非常棒,我已经开始在个人项目中使用它。我制作的所有新内容都使用CPM,并且也迁移了一些旧内容。但是,它不是一个成熟而完整的软件包管理器。它不会因软件包版本不一致而出错(尽管它可以检测到它们),并且它不是为处理二进制软件包而构建的。仅来源。但是,这可能就是您需要的东西。这足以满足我的大多数需求。我全力推荐用于个人和/或小型项目。
有个大问题。不是使用CPM,而是使用FetchContent本身。 FetchContent不能成为当今构建的API包管理器。
这个问题就是性能。 FetchContent太慢,无法用于严重的负载。这不是一个无法解决的问题,但是据我了解,这个问题很可能必须重新实施。这是一张与我一起在不同机器上进行实验的表格,其中包含大约7个内容项目或数据包运行FetchContent所需的时间。这是我使用的CMakeLists.txt。请注意,这些时间并非来自获取软件包。它们来自“空头”运行。一种标识一切都是最新的,什么也没做的。
这是在配置时,因此每次触摸CMake脚本时,它将被执行。如您所见,即使每个项目大约200毫秒的最佳时间也是很糟糕的,但是Windows超过1秒的时间却非常糟糕。对于具有数百个甚至数十个依赖项的项目来说,每个依赖项花1秒只是为了确认它是最新的,这简直是禁止的。
我在CMake的跟踪器8上打开了一个有关的问题,希望可以通过某种方式解决。我什至对仅使用CMake用户代码如何从外部解决此问题有一些想法,但我希望不会有这个想法。
我坚信这是C ++软件包管理的未来。如果性能问题已解决(或解决),我认为几年后C ++软件包管理将基于FetchContent。 CPM会成为新的事实上的标准还是其他尚未编写的软件,我不知道,但这就是事实!我能感觉到!
aka CMake Pi(3.14%的人确定我是第一个开这个玩笑的人)↩
我知道。从技术上讲,CMake是“构建系统生成器”,而不是“构建系统”,但是实际上,对于大多数意图和目的,您都可以将其视为构建系统。 ↩