xmake v2.3.4 发布, 更加完善的工具链支持 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
waruqi
V2EX    程序员

xmake v2.3.4 发布, 更加完善的工具链支持

  •  
  •   waruqi
    waruqi 2020-06-08 07:45:43 +08:00 1929 次点击
    这是一个创建于 1956 天前的主题,其中的信息可能已经有所发展或是发生改变。

    为了让 xmake 更好得支持交叉编译,这个版本我重构了整个工具链,使得工具链的切换更加的方便快捷,并且现在用户可以很方便地在 xmake.lua 中扩展自己的工具链。

    关于平台的支持上,我们新增了对*BSD 系统的支持,另外,此版本还新增了一个 ninja 主题风格,实现类似 ninja 的编译进度显示,例如:

    新特性介绍

    工具链改进

    工具链和平台完全分离

    之前的版本,平台和工具链绑定的过于紧密,例如xmake f -p windows 平台,默认只能使用 msvc 的编译,想要切到 clang 或者其他编译器,就只能走交叉编译平台:xmake f -p cross

    但是这样的话,一些 windows 平台特有的设置就丢失了,而且用户也没法使用if is_plat("windows") then来判断 windows 平台做特定的设置。

    其实平台和工具链是完全可以独立开来的,新版本经过重构后,即使是 windows 平台以及其他任何平台,也可以方便快速的切换到 clang, llvm 等其他工具链。

    $ xmake f -p windows --toolchain=clang 

    内置工具链

    虽然 xmake 的交叉编译配置支持所有工具链,也提供一定程度的智能分析和工具链探测,但通用方案多少对特定工具链支持需要追加各种额外的配置,例如额外传递一些--ldflags=, --cxflags=参数什么的。

    而新版本 xmake 内置了一些常用工具链,可以省去交叉编译工具链复杂的配置过程,只需要传递工具链名到--toolchain=xxx即可。

    切换到 llvm 工具链:

    $ xmake f -p cross --toolchain=llvm --sdk="C:\Program Files\LLVM" $ xmake 

    切换到 GNU-RM 工具链:

    $ xmake f -p cross --toolchain=gnu-rm --sdk=/xxx/cc-arm-none-eabi-9-2019-q4-major $ xmake 

    就可以快速切换的指定的交叉编译工具链,对于内置的工具链,可以省去大部分配置,通常只需要--toolchain=--sdk=即可,其他的配置都会自动设置好,确保编译正常。

    那 xmake 还支持哪些内置工具链呢?我们可以通过下面的命令查看:

    $ xmake show -l toolchains xcode Xcode IDE vs VisualStudio IDE yasm The Yasm Modular Assembler clang A C language family frontend for LLVM go Go Programming Language Compiler dlang D Programming Language Compiler sdcc Small Device C Compiler cuda CUDA Toolkit ndk Android NDK rust Rust Programming Language Compiler llvm A collection of modular and reusable compiler and toolchain technologies cross Common cross compilation toolchain nasm NASM Assembler gcc GNU Compiler Collection mingw Minimalist GNU for Windows gnu-rm GNU Arm Embedded Toolchain envs Environment variables toolchain fasm Flat Assembler 

    工具链的同步切换

    新版本 xmake 还支持工具链的完整同步切换,这个是什么意思呢?

    比如,我们要从默认的 gcc 切换到 clang 编译,可能需要切一些工具集,xmake f --cc=clang --cxx=clang --ld=clang++ --sh=clang++,因为编译器切了,对应的链接器,静态库归档器什么的都得同时切才行。

    这么挨个切一边,确实很蛋疼,作者本人也是受不了了,所以重构工具链的时候,这块也重点改进了下,现在只需要:

    $ xmake f --toolchain=clang $ xmake 

    就可以完全把所有 clang 工具集整体切过去,那如何重新切回 gcc 呢,也很方便:

    或者

    $ xmake f --toolchain=gcc $ xmake 

    自定义工具链

    另外,我们现在也可以在 xmake.lua 中自定义 toolchain,然后通过xmake f --toolchain=myclang指定切换,例如:

    toolchain("myclang") set_kind("standalone") set_toolset("cc", "clang") set_toolset("cxx", "clang", "clang++") set_toolset("ld", "clang++", "clang") set_toolset("sh", "clang++", "clang") set_toolset("ar", "ar") set_toolset("ex", "ar") set_toolset("strip", "strip") set_toolset("mm", "clang") set_toolset("mxx", "clang", "clang++") set_toolset("as", "clang") -- ... 

    其中set_toolset用于挨个设置不同的工具集,比如编译器、链接器、汇编器等。

    xmake 默认会从xmake f --sdk=xx的 sdk 参数中去探测工具,当然我们也可以在 xmake.lua 中对每个自定义工具链调用set_sdk("/xxx/llvm")来写死工具链 sdk 地址。

    关于这块的详情介绍,可以到自定义工具链章节查看

    更多详情见:#780

    针对特定 target 设置工具链

    除了自定义工具链,我们也可以对某个特定的 target 单独切换设置不同的工具链,和 set_toolset 不同的是,此接口是对完整工具链的整体切换,比如 cc/ld/sh 等一系列工具集。

    这也是推荐做法,因为像 gcc/clang 等大部分编译工具链,编译器和链接器都是配套使用的,要切就得整体切,单独零散的切换设置会很繁琐。

    比如我们切换 test 目标到 clang+yasm 两个工具链:

    target("test") set_kind("binary") add_files("src/*.c") set_toolchains("clang", "yasm") 

    或者可以通过set_toolset来对每个 target 的工具链中的特定工具单独设置。

    target("test") set_kind("binary") set_toolset("cxx", "clang") set_toolset("ld", "clang++") 

    ninja 构建主题

    构建进度风格类似 ninja,采用单行进度条,不再回滚进度,用户可以根据自己的喜好设置。

    除了进度展示不同外,其他都跟默认主题的配置相同。

    $ xmake g --theme=ninja 

    设置构建行为策略

    xmake 有很多的默认行为,比如:自动检测和映射 flags 、跨 target 并行构建等,虽然提供了一定的智能化处理,但重口难调,不一定满足所有的用户的使用习惯和需求。

    因此,从 v2.3.4 开始,xmake 提供默认构建策略的修改设置,开放给用户一定程度上的可配置性。

    使用方式如下:

    set_policy("check.auto_ignore_flags", false) 

    只需要在项目根域设置这个配置,就可以禁用 flags 的自动检测和忽略机制,另外set_policy也可以针对某个特定的 target 局部生效。

    target("test") set_policy("check.auto_ignore_flags", false) 

    !> 另外,如果设置的策略名是无效的,xmake 也会有警告提示。

    如果要获取当前 xmake 支持的所有策略配置列表和描述,可以执行下面的命令:

    $ xmake l core.project.policy.policies { "check.auto_map_flags" = { type = "boolean", description = "Enable map gcc flags to the current compiler and linker automatically.", default = true }, "build.across_targets_in_parallel" = { type = "boolean", description = "Enable compile the source files for each target in parallel.", default = true }, "check.auto_ignore_flags" = { type = "boolean", description = "Enable check and ignore unsupported flags automatically.", default = true } } 

    check.auto_ignore_flags

    xmake 默认会对所有add_cxflags, add_ldflags接口设置的原始 flags 进行自动检测,如果检测当前编译器和链接器不支持它们,就会自动忽略。

    这通常是很有用的,像一些可选的编译 flags,即使不支持也能正常编译,但是强行设置上去,其他用户在编译的时候,有可能会因为编译器的支持力度不同,出现一定程度的编译失败。

    但,由于自动检测并不保证 100%可靠,有时候会有一定程度的误判,所以某些用户并不喜欢这个设定(尤其是针对交叉编译工具链,更容易出现失败)。

    目前,v2.3.4 版本如果检测失败,会有警告提示避免用户莫名躺坑,例如:

    warning: add_ldflags("-static") is ignored, please pass `{force = true}` or call `set_policy("check.auto_ignore_flags", false)` if you want to set it. 

    根据提示,我们可以自己分析判断,是否需要强制设置这个 flags,一种就是通过:

    add_ldflags("-static", {force = true}) 

    来显示的强制设置上它,跳过自动检测,这对于偶尔的 flags 失败,是很有效快捷的处理方式,但是对于交叉编译时候,一堆的 flags 设置检测不过的情况下,每个都设置 force 太过于繁琐。

    这个时候,我们就可以通过set_policy来对某个 target 或者整个 project 直接禁用默认的自动检测行为:

    set_policy("check.auto_ignore_flags", false) target("test") add_ldflags("-static") 

    然后我们就可以随意设置各种原始 flags,xmake 不会去自动检测和忽略他们了。

    check.auto_map_flags

    这是 xmake 的另外一个对 flags 的智能分析处理,通常像add_links, add_defines这种 xmake 内置的 api 去设置的配置,是具有跨平台特性的,不同编译器平台会自动处理成对应的原始 flags 。

    但是,有些情况,用户还是需要自己通过 add_cxflags, add_ldflags 设置原始的编译链接 flags,这些 flags 并不能很好的跨编译器

    就拿-O0的编译优化 flags 来说,虽然有set_optimize来实现跨编译器配置,但如果用户直接设置add_cxflags("-O0")呢? gcc/clang 下可以正常处理,但是 msvc 下就不支持了

    也许我们能通过if is_plat() then来分平台处理,但很繁琐,因此 xmake 内置了 flags 的自动映射功能。

    基于 gcc flags 的普及性,xmae 采用 gcc 的 flags 命名规范,对其根据不同的编译实现自动映射,例如:

    add_cxflags("-O0") 

    这一行设置,在 gcc/clang 下还是-O0,但如果当前是 msvc 编译器,那边会自动映射为 msvc 对应-Od编译选项来禁用优化。

    整个过程,用户是完全无感知的,直接执行 xmake 就可以跨编译器完成编译。

    !> 当然,目前的自动映射实现还不是很成熟,没有 100%覆盖所有 gcc 的 flags,所以还是有不少 flags 是没去映射的。

    也有部分用户并不喜欢这种自动映射行为,那么我们可以通过下面的设置完全禁用这个默认的行为:

    set_policy("check.auto_map_flags", false) 

    build.across_targets_in_parallel

    这个策略也是默认开启的,主要用于跨 target 间执行并行构建,v2.3.3 之前的版本,并行构建只能针对单个 target 内部的所有源文件, 跨 target 的编译,必须要要等先前的 target 完全 link 成功,才能执行下一个 target 的编译,这在一定程度上会影响编译速度。

    然而每个 target 的源文件是可以完全并行化处理的,最终在一起执行 link 过程,v2.3.3 之后的版本通过这个优化,构建速度提升了 30%。

    当然,如果有些特殊的 target 里面的构建源文件要依赖先前的 target (尤其是一些自定义 rules 的情况,虽然很少遇到),我们也可以通过下面的设置禁用这个优化行为:

    set_policy("build.across_targets_in_parallel", false) 

    新增编译模式

    mode.releasedbg

    为当前工程 xmake.lua 添加 releasedbg 编译模式的配置规则,例如:

    add_rules("mode.releasedbg") 

    !> 与 release 模式相比,此模式还会额外开启调试符号,这通常是非常有用的。

    相当于:

    if is_mode("releasedbg") then set_symbols("debug") set_optimize("fastest") set_strip("all") end 

    我们可以通过:xmake f -m releasedbg来切换到此编译模式。

    mode.minsizerel

    为当前工程 xmake.lua 添加 minsizerel 编译模式的配置规则,例如:

    add_rules("mode.minsizerel") 

    !> 与 release 模式相比,此模式更加倾向于最小代码编译优化,而不是速度优先。

    相当于:

    if is_mode("minsizerel") then set_symbols("hidden") set_optimize("smallest") set_strip("all") end 

    我们可以通过:xmake f -m minsizerel来切换到此编译模式。

    显示指定信息和列表

    显示 xmake 自身和当前项目的基础信息

    $ xmake show The information of xmake: version: 2.3.3+202006011009 host: macosx/x86_64 programdir: /Users/ruki/.local/share/xmake programfile: /Users/ruki/.local/bin/xmake globaldir: /Users/ruki/.xmake tmpdir: /var/folders/32/w9cz0y_14hs19lkbs6v6_fm80000gn/T/.xmake501/200603 workingdir: /Users/ruki/projects/personal/tbox packagedir: /Users/ruki/.xmake/packages packagedir(cache): /Users/ruki/.xmake/cache/packages/2006 The information of project: tbox version: 1.6.5 plat: macosx arch: x86_64 mode: release buildir: build configdir: /Users/ruki/projects/personal/tbox/.xmake/macosx/x86_64 projectdir: /Users/ruki/projects/personal/tbox projectfile: /Users/ruki/projects/personal/tbox/xmake.lua 

    显示工具链列表

    $ xmake show -l toolchains xcode Xcode IDE vs VisualStudio IDE yasm The Yasm Modular Assembler clang A C language family frontend for LLVM ... 

    显示指定 target 配置信息

    $ xmake show --target=tbox The information of target(tbox): kind: static targetfile: build/macosx/x86_64/release/libtbox.a rules: mode.release, mode.debug, mode.profile, mode.coverage options: info, float, wchar, exception, force-utf8, deprecated, xml, zip, hash, regex, coroutine, object, charset, database packages: mbedtls, polarssl, openssl, pcre2, pcre, zlib, mysql, sqlite3 links: pthread syslinks: pthread, dl, m, c cxflags: -Wno-error=deprecated-declarations, -fno-strict-aliasing, -Wno-error=expansion-to-defined, -fno-stack-protector defines: __tb_small__, __tb_prefix__="tbox" mxflags: -Wno-error=deprecated-declarations, -fno-strict-aliasing, -Wno-error=expansion-to-defined headerfiles: src/(tbox/**.h)|**/impl/**.h, src/(tbox/prefix/**/prefix.S), src/(tbox/math/impl/*.h), src/(tbox/utils/impl/*.h), build/macosx/x86_64/release/tbox.config.h includedirs: src, build/macosx/x86_64/release at: /Users/ruki/projects/personal/tbox/src/tbox/xmake.lua sourcebatch(cc): with rule(c.build) -> src/tbox/string/static_string.c -> build/.objs/tbox/macosx/x86_64/release/src/tbox/string/static_string.c.o -> build/.deps/tbox/macosx/x86_64/release/src/tbox/string/static_string.c.o.d -> src/tbox/platform/sched.c -> build/.objs/tbox/macosx/x86_64/release/src/tbox/platform/sched.c.o -> build/.deps/tbox/macosx/x86_64/release/src/tbox/platform/sched.c.o.d -> src/tbox/stream/stream.c -> build/.objs/tbox/macosx/x86_64/release/src/tbox/stream/stream.c.o -> build/.deps/tbox/macosx/x86_64/release/src/tbox/stream/stream.c.o.d -> src/tbox/utils/base32.c -> build/.objs/tbox/macosx/x86_64/release/src/tbox/utils/base32.c.o -> build/.deps/tbox/macosx/x86_64/release/src/tbox/utils/base32.c.o.d 

    显示内置编译模式列表

    $ xmake show -l modes 

    显示内置编译规则列表

    $ xmake show -l rules 

    显示其他信息

    还在完善中,详情见: https://github.com/xmake-io/xmake/issues/798

    或者运行:

    $ xmake show --help 

    更新内容

    新特性

    • #630: 支持*BSD 系统,例如:FreeBSD, ..
    • 添加 wprint 接口去显示警告信息
    • #784: 添加set_policy()去设置修改一些内置的策略,比如:禁用自动 flags 检测和映射
    • #780: 针对 target 添加 set_toolchains/set_toolsets 实现更完善的工具链设置,并且实现 platform 和 toolchains 分离
    • #798: 添加xmake show插件去显示 xmake 内置的各种信息
    • #797: 添加 ninja 主题风格,显示 ninja 风格的构建进度条,xmake g --theme=ninja
    • #816: 添加 mode.releasedbg 和 mode.minsizerel 编译模式规则
    • #819: 支持 ansi/vt100 终端字符控制

    改进

    • #771: 检测 includedirs,linkdirs 和 frameworkdirs 的输入有效性
    • #774: xmake f --menu可视化配置菜单支持窗口大小 Resize 调整
    • #782: 添加 add_cxflags 等配置 flags 自动检测失败提示
    • #808: 生成 cmakelists 插件增加对 add_frameworks 的支持
    • #820: 支持独立的工作目录和构建目录,保持项目目录完全干净

    Bugs 修复

    • #786: 修复头文件依赖检测
    • #810: 修复 linux 下 gcc strip debug 符号问题
    4 条回复    2020-06-21 16:47:00 +08:00
    Cyshall
        1
    Cyshall  
       2020-06-08 09:05:53 +08:00 via Android
    作者对该工具用作生产环境有信心吗?
    waruqi
        2
    waruqi  
    OP
       2020-06-08 09:08:04 +08:00 via Android
    @Cyshall 为啥没信心
    jianixrabbit
        3
    jianixrabbit  
       2020-06-21 15:56:52 +08:00
    在已更新的 msys2 上安装报错呢:
    Dependencies Installation Fail
    The getter currently only support these package managers
    * apt
    * yum
    * zypper
    * pacman
    Please install following dependencies manually:
    * git
    * build essential like `make`, `gcc`, etc
    * libreadline-dev (readline-devel)
    * ccache (optional)

    进群要缴费了?
    waruqi
        4
    waruqi  
    OP
       2020-06-21 16:47:00 +08:00 via Android
    @jianixrabbit 可以到 github issues 反馈,或者到 2 群,2 群不收费 readme 上有写,1 群 500 满员了 所以我开启付费入群 补贴下群费
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2873 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 14:12 PVG 22:12 LAX 07:12 JFK 10:12
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86