终于,从Qt6开始CMake代替qmake,完成大一统

终于,从Qt6开始CMake代替qmake,完成大一统2021 年 1 月 27 日 星期三 乔格 博恩曼 J rgBornemann 一年半前 我们做出了一个重大决定 开始使用 CMake 来构建 Qt 6 做出此决定的主要原因是用户反馈 大多数 Qt 用户希望更轻松地将他们的 Qt 项目与其他软件集成在一起

欢迎大家来到IT世界,在知识的湖畔探索吧!

终于,从Qt6开始CMake代替qmake,完成大一统



欢迎大家来到IT世界,在知识的湖畔探索吧!

2021年1月27日,星期三,乔格·博恩曼(JörgBornemann)

比决定更大的是迁移到CMake所需的工作。现在,基本的迁移工作已经完成,现在该分享我们的发现了。

尽管已被许多项目很好地建立和使用,但CMake缺少了先前Qt构建工具所支持的一些关键功能。这就是为什么我们与Kitware合作消除障碍并改善CMake的原因,从而使Qt项目和更大的CMake社区受益。

构建Qt的过程很复杂,这归因于以下几点:

  • Qt支持许多平台。
  • Qt分为可独立构建或全部构建的模块。
  • Qt支持不同的构建方式(前缀,非前缀,不同的功能集)

让我们看一下Qt的构建工具开关引起或影响的CMake改进。

预编译头

在C ++项目中,可能会一遍又一遍地包含相同的头文件。对于库头尤其如此。如果工具链支持,则可以通过预编译头文件来加快编译速度。

在最长的时间内,CMake并未为此提供现成的支持。但是,在网上搜索代码片段以启用CMake中的预编译头的日子已经过去。从CMake 3.16开始,使用该target_precompile_headers命令可以添加要预编译的头文件列表。

有关详细信息,请参见原始公告。

Unity构建

加快编译速度的另一种方法是统一构建。这是无数技巧,也称为巨型构建合并构建单个编译单元

此技术创建一个包括所有其他源文件的源文件,并且仅编译一个源文件:

所有源文件的包含文件仅被处理一次,所有内容都以一个翻译单元结束,并且优化器对项目具有全局视图。

但是,并非每个C ++项目都可以不加修改地利用统一构建。按照原始CMake问题#19526的描述中的链接了解更多信息。

depfile支持AUTOMOC + Ninja

长期以来人们一直抱怨CMake的AUTOMOC,它会不必要地运行,或者在再次调用moc时无法正确检测到。原因之一是,MOMO输出的确切依赖关系对于AUTOMOC是不可见的。

从Qt 5.15开始,moc学会了写出准确的文件,这些文件构成了moc输出的依赖性。CMake 3.17学会了读取moc的depfiles并将其用于Ninja生成器。

总结一下:使用Ninja生成器的Qt> = 5.15和CMake> = 3.17时,AUTOMOC知道正确的依赖项,可以在正确的时间重新运行moc。

忍者多配置

在Windows和macOS上,传统上Qt是用两种配置(调试和发布)构建的,但在一个构建目录中。

直到版本3.17引入了一个名为“ Ninja Multi-Config”的新生成器后,CMake才提供实现此目的的方法,该生成器可以一次构建多个配置。

iOS多架构构建

适用于iOS的Qt提供了模拟器和设备版本,该版本将针对实际目标构建的Qt与针对iOS模拟器构建的Qt相结合。尽管CMake 3.17引入了Ninja Multi-Config,但它的iOS支持尚未为iOS多体系结构构建做好准备。

CMake 3.18解决了这个问题,我们可以很高兴地为模拟器和设备进行构建。

文件(配置)

在Qt构建中,在配置时会生成大量带有动态创建内容的文件。configure_file但是,该命令仅使用输入文件,不使用字符串。

解决此问题的一种方法是让输入文件只有一个变量

然后像这样调用configure_file

在CMake 3.18中,我们可以轻松实现相同目标:

file(CONFIGURE OUTPUT “output.txt” CONTENT “This is the generated content!”)

评估!与功能同盟!

在Qt构建中,我们用尽了CMake语言作为实际编程语言执行的能力。不仅应该由用户调用CMake函数,而且在引擎盖下还有更复杂的设备。

让我们烦恼的一件事是,不可能动态调用函数。在qmake中,可以调用在变量中定义的函数,并且Qt5版本广泛使用此功能。

有多种方法可以使此工作在CMake中进行,包括生成一个随后包含的文件,但是特别是在Windows上,这将极大地减慢项目配置步骤。

CMake 3.18随附cmake_language(EVAL)用于评估CMake代码并cmake_language(CALL)调用宏或函数。

稍后致电-延迟的代码

同样,qmake功能启发了CMake命令。

在QMake项目中,可以编写CONFIG += foo,然后在mkspecs/features/foo.prf处理实际的项目文件后加载。

这对于面向用户的API尤其有用。假设您正在为Android创建一个项目。

该qt_finalize_executable调用将根据目标的属性为目标生成适当的部署设置。如果用户忘记致电qt_finalize_executable,则不会生成部署设置,也不会出现错误或警告。

注意:这是一个示例。真正的API并非容易出错。请参阅b94b7687b0635ee74a3ccd83a234ead0600fd47f的提交消息,我们将如何处理。

但是,如果用户摆脱了打电话的负担,那会不会很棒qt_finalize_executable?在CMake 3.19中,Qt构建利用了新命令cmake_language(DEFER CALL)。这样一来,就可以在定义的时间调用函数,例如,在评估当前目录的项目文件之后。

不同目录范围的源文件上的属性

在某些地方,我们为模块创建目标,然后在子目录中将源文件添加到该目标。这样可以使源文件的名称与CMakeLists.txt文件保持接近。

但是,无法在这些位置指定每个源文件的属性-我们必须进入层次结构的顶层才能进行设置。我们并不经常这样做,但是有时在开发过程中会出现这种情况,以允许根据选项设置在编译时选择实验功能。

在CMake 3.18中,set_source_files_properties学会了在不同目录范围内设置属性:

该DIRECTORY选项获取指向处理后的源目录的路径的列表,并TARGET_DIRECTORY获取目标的列表,这些目标的源目录将用作设置源文件属性的作用域列表。

get_property()并且get_source_file_property()还具有相同的新参数,除了只能指定一个值而不是列表。

add_custom_command DEPFILE支持Makefile

CMake 3.20将为Unix Makefile生成器提供depfile支持。这也是将moc生成的depfile用于Makefile的前提。

闭幕致辞

工作尚未完成。CMake不断得到改进,越来越多的Qt模块向CMake的移植工作很可能会产生更多的想法。

请在我们的错误跟踪器中发布您发现的问题或建议 。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/99278.html

(0)
上一篇 3小时前
下一篇 2小时前

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们YX

mu99908888

在线咨询: 微信交谈

邮件:itzsgw@126.com

工作时间:时刻准备着!

关注微信