为了让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的普及性,xmake采用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符号问题

xmake v2.3.4 发布, 更加完善的工具链支持的更多相关文章

  1. xmake v2.3.7 发布, 新增 tinyc 和 emscripten 工具链支持

    xmake 是一个基于 Lua 的轻量级跨平台构建工具,使用 xmake.lua 维护项目构建,相比 makefile/CMakeLists.txt,配置语法更加简洁直观,对新手非常友好,短时间内就能 ...

  2. xmake v2.5.9 发布,改进 C++20 模块,并支持 Nim, Keil MDK 和 Unity Build

    xmake 是一个基于 Lua 的轻量级跨平台构建工具,使用 xmake.lua 维护项目构建,相比 makefile/CMakeLists.txt,配置语法更加简洁直观,对新手非常友好,短时间内就能 ...

  3. xmake v2.5.2 发布, 支持自动拉取交叉工具链和依赖包集成

    xmake 是一个基于 Lua 的轻量级跨平台构建工具,使用 xmake.lua 维护项目构建,相比 makefile/CMakeLists.txt,配置语法更加简洁直观,对新手非常友好,短时间内就能 ...

  4. xmake v2.6.2 发布,新增 Linux 内核驱动模块构建支持

    Xmake 是一个基于 Lua 的轻量级跨平台构建工具. 它非常的轻量,没有任何依赖,因为它内置了 Lua 运行时. 它使用 xmake.lua 维护项目构建,相比 makefile/CMakeLis ...

  5. xmake v2.3.1 发布, 无缝对接其他构建系统

    最近对xmake内部做了不少的重构来改进,并且新增了不少实用的新特性,欢迎来体验. 项目源码 官方文档 一些新特性: 一键编译其他构建系统维护的项目,实现无缝对接,并且支持交叉编译(比如autotoo ...

  6. xmake v2.3.2 发布, 带来和ninja一样快的构建速度

    这个版本重点重构优化了下内部并行构建机制,实现多个target间源文件的并行编译,以及并行link的支持,同时优化了xmake的一些内部损耗,修复影响编译速度的一些bug. 通过测试对比,目前的整体构 ...

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

    Xmake 是一个基于 Lua 的轻量级跨平台构建工具. 它非常的轻量,没有任何依赖,因为它内置了 Lua 运行时. 它使用 xmake.lua 维护项目构建,相比 makefile/CMakeLis ...

  8. xmake v2.2.9 发布, 新增c++20 modules的实验性支持

    这个版本没啥太大新特性,主要对c++20 modules进行了实验性支持,目前支持clang/msvc编译器,除此之外改进了不少使用体验,并且提高了一些稳定性. 另外,这个版本新增了socket.io ...

  9. xmake v2.5.8 发布,新增 Pascal/Swig 程序和 Lua53 运行时支持

    xmake 是一个基于 Lua 的轻量级跨平台构建工具,使用 xmake.lua 维护项目构建,相比 makefile/CMakeLists.txt,配置语法更加简洁直观,对新手非常友好,短时间内就能 ...

随机推荐

  1. Linux基本命令(文件基操)

    1. 查询目录内容:ls [选项]  [文件或者目录] -a 显示所有文件,包括隐藏文件 -l 显示详细信息 -d 查看目录属性 -h 人性化显示文件大小 -i 显示节点ID,inode ls -ld ...

  2. mysql+redis缓存策略常见的错误

    什么时候应该更新缓存 应该是从数据库读取数据后,再更新缓存,从缓存读取到数据,就不需要再重新写缓存了,一个常见的错误是,每次访问接口都更新缓存,这样的话,如果接口一直有流量,那么db中的数据,就一直没 ...

  3. java十大排序

    0.1 算法分类 十种常见排序算法可以分为两大类: 比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也称为非线性时间比较类排序. 非比较类排序:不通过比较来决 ...

  4. DPDK LPM库(学习笔记)

    1 LPM库 DPDK LPM库组件为32位的key实现了最长前缀匹配(LPM)表查找方法,该方法通常用于在IP转发应用程序中找到最佳路由匹配. 2 LPM API概述 LPM组件实例的主要配置参数是 ...

  5. 在php文件中xml格式

    本人是小白,有错误的地方请指正,勿喷! 在写一个调查问卷的过程中用到了xml文件,如想要了解,可以通过以下链接简单学习:http://www.w3school.com.cn/xml/ 所用工具:php ...

  6. Spring 依赖注入(DI)简介

    依赖注入的英文表示为dependency injection,缩写为DI. Spring框架的核心功能之一就是通过依赖注入的方式来管理Bean之间的依赖关系. 当编写一个复杂的 Java 应用程序时, ...

  7. 处理TableVIew SectionHeader悬停问题

    1,plain类型的tableview  才会悬停  grouped类型不会悬停 2,通过改变contentInset达到部分悬停遮罩的处理,对所有的Sectionheader都有效,不可以单独处理某 ...

  8. Robot Framework(4)- 测试套件的基本使用

    如果你还想从头学起Robot Framework,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1770899.html 前言 因为是基于 ...

  9. C语言基础知识(二)——二维数组

    二维数组本质 二维数组本质就是一维数组,只不过**形式是二维**,类似矩阵,使用二维数组表示会更加形象. 二维数组实例 float rain[5][12]; //内含5个数组元素的数组,每个数组元素内 ...

  10. 【python 】文件下载进度条(装逼利器)

    基础版 import requests url = "http://mp.111ttt.cn/mp3free/81135985.mp3" rsp = requests.get(ur ...