Xmake v2.7.3 发布,包组件和 C++ 模块增量构建支持( 二 )

上面是一个不完整的包配置,我仅仅摘取一部分跟包组件相关的配置 。
一个关于包组件的配置和使用的完整例子见:components example
配置组件的编译信息我们不仅可以配置每个组件的链接信息,还有 includedirs, defines 等等编译信息,我们也可以对每个组件单独配置 。
package("sfml")on_component("graphics", function (package, component)package:add("defines", "TEST")end)配置组件依赖package("sfml")add_components("graphics")add_components("audio", "network", "window")add_components("system")on_component("graphics", function (package, component)component:add("deps", "window", "system")end)上面的配置,告诉包 , 我们的 graphics 组件还会额外依赖 windowsystem 两个组件 。
因此,在用户端,我们对 graphics 的组件使用,可以从
add_packages("sfml", {components = {"graphics", "window", "system"})简化为:
add_packages("sfml", {components = "graphics")因为,只要我们开启了 graphics 组件 , 它也会自动启用依赖的 window 和 system 组件 , 并且自动保证链接顺序正确 。
另外,我们也可以通过 add_components("graphics", {deps = {"window", "system"}}) 来配置组件依赖关系 。
从系统库中查找组件我们知道,在包配置中 , 配置 add_extsources 可以改进包在系统中的查找,比如从 apt/pacman 等系统包管理器中找库 。
当然,我们也可以让每个组件也能通过 extsources 配置,去优先从系统库中找到它们 。
例如,sfml 包 , 它在 homebrew 中其实也是组件化的,我们完全可以让包从系统库中,找到对应的每个组件,而不需要每次源码安装它们 。
$ ls -l /usr/local/opt/sfml/lib/pkgconfig-r--r--r--1 rukiadmin317 10 19 17:52 sfml-all.pc-r--r--r--1 rukiadmin534 10 19 17:52 sfml-audio.pc-r--r--r--1 rukiadmin609 10 19 17:52 sfml-graphics.pc-r--r--r--1 rukiadmin327 10 19 17:52 sfml-network.pc-r--r--r--1 rukiadmin302 10 19 17:52 sfml-system.pc-r--r--r--1 rukiadmin562 10 19 17:52 sfml-window.pc我们只需要 , 对每个组件配置它的 extsources:
if is_plat("macosx") thenadd_extsources("brew::sfml/sfml-all")endon_component("graphics", function (package, component)-- ...component:add("extsources", "brew::sfml/sfml-graphics")end)默认的全局组件配置除了通过指定组件名的方式 , 配置特定组件,如果我们没有指定组件名 , 默认就是全局配置所有组件 。
package("sfml")on_component(function (package, component)-- configure all componentsend)当然,我们也可以通过下面的方式,指定配置 graphics 组件,剩下的组件通过默认的全局配置接口进行配置:
package("sfml")add_components("graphics")add_components("audio", "network", "window")add_components("system")on_component("graphics", function (package, component)-- configure graphicsend)on_component(function (package, component)-- component audio, network, window, systemend)C++ 模块构建改进增量构建支持原本以为 Xmake 对 C++ 模块已经支持的比较完善了,后来才发现,它的增量编译还无法正常工作 。
因此,这个版本 Xmake 对 C++ 模块的增量编译也做了很好的支持,尽管支持过程还是花了很多精力的 。
我分析了下,各家的编译器对生成带模块的 include 依赖信息格式(*.d),差异还是非常大的 。
gcc 的格式最复杂,不过我还是将它支持上了 。
build/.objs/dependence/linux/x86_64/release/src/foo.mpp.o: src/foo.mpp\build/.objs/dependence/linux/x86_64/release/src/foo.mpp.ogcm.cache/foo.gcm: bar.c++m cat.c++m\foo.c++m: gcm.cache/foo.gcm\.PHONY: foo.c++m\gcm.cache/foo.gcm:|build/.objs/dependence/linux/x86_64/release/src/foo.mpp.o\CXX_IMPORTS += bar.c++m cat.c++m\clang 的格式兼容性最好 , 没有做任何特殊改动就支持了 。
build//hello.pcm:/usr/lib/llvm-15/lib/clang/15.0.2/include/module.modulemapsrc/hello.mpp\msvc 的格式扩展性比较好,解析和支持起来比较方便:
{"Version": "1.2","Data": {"Source": "c:\users\ruki\desktop\user_headerunit\src\main.cpp","ProvidedModule": "","Includes": [],"ImportedModules": [{"Name": "hello","BMI": "c:\users\ruki\desktop\user_headerunit\src\hello.ifc"}],"ImportedHeaderUnits": [{"Header": "c:\users\ruki\desktop\user_headerunit\src\header.hpp","BMI": "c:\users\ruki\desktop\user_headerunit\src\header.hpp.ifc"}]}}循环依赖检测支持由于模块之间是存在依赖关系的,因此如果有几个模块之间存在循环依赖引用,那么是无法编译通过的 。

推荐阅读