关键词:
xmake 是一个基于 Lua 的轻量级跨平台构建工具,使用 xmake.lua 维护项目构建,相比 makefile/CMakeLists.txt,配置语法更加简洁直观,对新手非常友好,短时间内就能快速入门,能够让用户把更多的精力集中在实际的项目开发上。
这个版本,我们正式将默认的 Luajit 运行时切换到 Lua5.4 运行时,并且新增了 Rust 和 C++ 的混合编译支持,我们也集成了 Cargo 的包管理支持。
另外,我们新增了一个实用的 utils.glsl2spv
规则,用于实现对 glsl shader 的编译支持,并自动生成对应的 C 代码头文件,方便快速内嵌编译后的 .spv 文件数据到代码中。
新特性介绍
默认切换到 Lua5.4 运行时
历经几个版本的迭代测试,我们在 2.6.1 版本,正式切换到 Lua5.4 运行时。
不过,这对于用户来说是完全无感知的,基本上没有任何兼容性问题,因为 xmake 对大部分接口都是封装过的,完全消除了 Lua 版本间的兼容性问题。
对于构建性能方面,由于构建的性能瓶颈主要来自编译器,Lua 自身的性能损耗完全可以忽略,而且 xmake 用 c 重写了 lua 原生的所有 io 接口,并且对耗时的接口都用 c 实现了优化。
因此,通过对比测试,不管是使用 Lua 还是 Luajit,构建项目的耗时基本一致,没有明显差异。
为什么要切换?
因为 Luajit 对一些新架构基本不支持,例如:riscv, lonngarch,而且 luajit 作者基本已经不怎么维护它了,一些新架构支持和稳定性修复进展属于停滞状态。
为了能够更好的支持更多的平台,已经获取更快的迭代维护,我们选择使用 Lua 会带来非常多的好处。
添加 Cargo 包依赖
我们在这个版本中,新增了 Cargo 包依赖管理器的支持,不过目前主要用于 Rust 项目。
例子: https://github.com/xmake-io/xmake/tree/dev/tests/projects/rust/cargo_deps
add_rules("mode.release", "mode.debug")
add_requires("cargo::base64 0.13.0")
add_requires("cargo::flate2 1.0.17", configs = features = "zlib")
target("test")
set_kind("binary")
add_files("src/main.rs")
add_packages("cargo::base64", "cargo::flate2")
Rust 和 C++ 混合编译
使用 cxxbridge 在 c++ 中调用 rust
add_rules("mode.debug", "mode.release")
add_requires("cargo::cxx 1.0")
target("foo")
set_kind("static")
add_files("src/foo.rs")
set_values("rust.cratetype", "staticlib")
add_packages("cargo::cxx")
target("test")
set_kind("binary")
add_rules("rust.cxxbridge")
add_deps("foo")
add_files("src/main.cc")
add_files("src/bridge.rsx")
foo.rs
#[cxx::bridge]
mod foo
extern "Rust"
fn add(a: i32, b: i32) -> i32;
pub fn add(a: i32, b: i32) -> i32
return a + b;
我们还需要在 c++ 项目中添加桥接文件 bridge.rsx
#[cxx::bridge]
mod foo
extern "Rust"
fn add(a: i32, b: i32) -> i32;
main.cc
#include <stdio.h>
#include "bridge.rs.h"
int main(int argc, char** argv)
printf("add(1, 2) == %d\\n", add(1, 2));
return 0;
在 Rust 中调用 C++
add_rules("mode.debug", "mode.release")
target("foo")
set_kind("static")
add_files("src/foo.cc")
target("test")
set_kind("binary")
add_deps("foo")
add_files("src/main.rs")
main.rs
extern "C"
fn add(a: i32, b: i32) -> i32;
fn main()
unsafe
println!("add(1, 2) = ", add(1, 2));
foo.cc
extern "C" int add(int a, int b)
return a + b;
新增 glsl shader 编译规则
我们新增了一个 utils.glsl2spv
编译规则,可以在项目中引入 *.vert/*.frag
等 glsl shader 文件,然后实现自动编译生成 *.spv
文件。
另外,我们还支持以 C/C++ 头文件的方式,二进制内嵌 spv 文件数据,方便程序使用。
编译生成 spv 文件
xmake 会自动调用 glslangValidator 或者 glslc 去编译 shaders 生成 .spv 文件,然后输出到指定的 outputdir = "build"
目录下。
add_rules("mode.debug", "mode.release")
add_requires("glslang", configs = binaryonly = true)
target("test")
set_kind("binary")
add_rules("utils.glsl2spv", outputdir = "build")
add_files("src/*.c")
add_files("src/*.vert", "src/*.frag")
add_packages("glslang")
注,这里的 add_packages("glslang")
主要用于引入和绑定 glslang 包中的 glslangValidator,确保 xmake 总归能够使用它。
当然,如果用户自己系统上已经安装了它,也可以不用额外绑定这个包,不过我还是建议添加一下。
编译生成 c/c++ 头文件
我们也可以内部借助 bin2c 模块,将编译后的 spv 文件生成对应的二进制头文件,方便用户代码中直接引入,我们只需要启用 bin2c = true
。:w
add_rules("mode.debug", "mode.release")
add_requires("glslang", configs = binaryonly = true)
target("test")
set_kind("binary")
add_rules("utils.glsl2spv", bin2c = true)
add_files("src/*.c")
add_files("src/*.vert", "src/*.frag")
add_packages("glslang")
然后我们可以在代码这么引入:
static unsigned char g_test_vert_spv_data[] =
#include "test.vert.spv.h"
;
static unsigned char g_test_frag_spv_data[] =
#include "test.frag.spv.h"
;
跟 bin2c 规则的使用方式类似,完整例子见:glsl2spv example
改进 C++ Modules 构建
上个版本,我们重构了 C++20 Modules 构建支持,而在这个版本中,我们继续对它做了改进。
对于 msvc 编译器,我们已经能够在模块中导入 std 标准库模块,另外,我们修复了多个 target 之间存在依赖时,模块导入编译失败的问题。
改进 MDK 程序构建配置
上个版本,我们新增了 MDK 程序的构建支持,需要注意的是,目前一些 mdk 程序都使用了 microlib 库运行时,它需要编译器加上 __MICROLIB
宏定义,链接器加上 --library_type=microlib
等各种配置。
而在这个版本中,我们可以通过 set_runtimes("microlib")
直接设置到 microlib 运行时库,可以自动设置上所有相关选项。
控制台程序
target("hello")
add_deps("foo")
add_rules("mdk.console")
add_files("src/*.c", "src/*.s")
add_includedirs("src/lib/cmsis")
set_runtimes("microlib")
静态库程序
add_rules("mode.debug", "mode.release")
target("foo")
add_rules("mdk.static")
add_files("src/foo/*.c")
set_runtimes("microlib")
改进 OpenMP 项目配置
我们也改进了 openmp 项目的配置,更加简化和统一,我们不再需要额外配置 rules,仅仅通过一个通用的 openmp 包就可以实现相同的效果。
add_requires("openmp")
target("loop")
set_kind("binary")
add_files("src/*.cpp")
add_packages("openmp")
在之前的版本,我们需要这么配置,对比一下,就能看出新的配置更加的简洁。
add_requires("libomp", optional = true)
target("loop")
set_kind("binary")
add_files("src/*.cpp")
add_rules("c++.openmp")
add_packages("libomp")
更新内容
新特性
- #1799: 支持混合 Rust 和 C++ 程序,以及集成 Cargo 依赖库
- 添加
utils.glsl2spv
规则去编译 .vert/.frag shader 文件生成 spirv 文件和二进制 C 头文件
改进
- 默认切换到 Lua5.4 运行时
- #1776: 改进 system::find_package,支持从环境变量中查找系统库
- #1786: 改进 apt:find_package,支持查找 alias 包
- #1819: 添加预编译头到 cmake 生成器
- 改进 C++20 Modules 为 msvc 支持 std 标准库
- #1792: 添加自定义命令到 vs 工程生成器
- #1835: 改进 MDK 程序构建支持,增加
set_runtimes("microlib")
- #1858: 改进构建 c++20 modules,修复跨 target 构建问题
- 添加 $XMAKE_BINARY_REPO 和 $XMAKE_MAIN_REPO 仓库设置环境变量
- #1865: 改进 openmp 工程
- #1845: 为静态库安装 pdb 文件
Bugs 修复
- 修复语义版本中解析带有 0 前缀的 build 字符串问题
- #50: 修复 rule 和构建 bpf 程序 bug
- #1610: 修复
xmake f --menu
在 vscode 终端下按键无响应,并且支持 ConPTY 终端虚拟按键
xmakev2.6.1发布,使用lua5.4运行时,rust和c++混合编译支持(代码片段)
xmake是一个基于Lua的轻量级跨平台构建工具,使用xmake.lua维护项目构建,相比makefile/CMakeLists.txt,配置语法更加简洁直观,对新手非常友好,短时间内就能快速入门,能够让用户把更多的精力集中在实际的... 查看详情
Lua 5.4.0/LuaRocks 安装
...ua5.4.0/LuaRocks安装【英文标题】:Lua5.4.0/LuaRocksinstallation【发布时间】:2021-02-0916:36:39【问题描述】:你好,自从我开始学习Lua以来,我一直在使用Lua5.1.2,我想升级到更新的版本,但是没有任何关于如何做到这一点的教程,我也... 查看详情
lua5.4源码阅读—数据类型(代码片段)
Lua数据类型基础的数据类型宏定义:#defineLUA_TNONE (-1)//无效类型 #defineLUA_TNIL 0//空类型#defineLUA_TBOOLEAN 1//布尔#defineLUA_TLIGHTUSERDATA 2//指针(lua外部管理内存)#defineLUA_TNUMBER 3//数据#defineLUA_TSTRING 4 //字符串 查看详情
lua5.4源码阅读—表(代码片段)
lua中表的实现原理为:按照key的数据类型分成数组部分和散列表部分,数组部分用于存储key值在数组大小范围内的键值对,其余数组部分不能存储的键值对则存储在散列表部分。表的数据结构typedefstructTableCommonHeader;lu... 查看详情
Visual Studio 在发布时成功使用共享项目 wwwroot 文件,但在构建/运行时没有成功
】VisualStudio在发布时成功使用共享项目wwwroot文件,但在构建/运行时没有成功【英文标题】:VisualStudioSuccessfullyUsingSharedProjectwwwrootFilesonPublishbutnotonBuild/Run【发布时间】:2021-11-1223:58:30【问题描述】:背景我在VisualStudio2019中工作... 查看详情
使用 WebDeploy 发布 Web 应用程序时如何在 DB 上自动运行 Code First 迁移
】使用WebDeploy发布Web应用程序时如何在DB上自动运行CodeFirst迁移【英文标题】:HowtoautomaticallyrunCodeFirstMigrationsonDBwhenusingWebDeploytopublishwebapp【发布时间】:2016-07-3004:42:29【问题描述】:当我将Web应用程序发布到Azure时,我正在尝试... 查看详情
如何配置用户环境以使用最新的节点运行时
...英文标题】:Howtoconfigureuserenvironmenttousethelatestnoderuntime【发布时间】:2013-03-1812:41:54【问题描述】:我们使用nvmuse0.10.0初始化node.js,以便在我在Ubuntu中启动新终端时初始化bashshell【问题讨论】:你为什么要这样做?【参考方案1... 查看详情
使用 ReflectionClass 获取运行时属性
...属性【英文标题】:GettingruntimepropertieswithReflectionClass【发布时间】:2015-08-1609:17:51【问题描述】:所以我正在探索反射类的使用。我注意到了几件事。必须先设置我的属性的可访问性,然后才能在Origin类中使用Even属性的值或名... 查看详情
使用 xcodebuildcommand 从终端运行时 XCUITEST 未运行
...XCUITESTisnotrunningwhilerunningfromfromterminalusingxcodebuildcommand【发布时间】:2019-09-2205:33:07【问题描述】:我的UI-TEST方案中有50多个测试用例,我正在通过以下命令运行它xcodebuildtest-workspacetribo.xcworkspac 查看详情
为啥使用 tableView.dequeueReusableCellWithIdentifier 会出现运行时错误
...用tableView.dequeueReusableCellWithIdentifier会出现运行时错误【发布时间】:2015-06-2019:18:11【问 查看详情
使用 C++ 在运行时使用转义序列
...用转义序列【英文标题】:UsingescapesequenceatruntimewithC++【发布时间】:2014-11-1005:24:21【问题描述】:我对C++很陌生,我需要从MSVC++文本字段中读取输入并将其写入文件。我需要将\\n作为新行写入文件,而不是\\n。经过一番研究,... 查看详情
在运行时使用 JDBCTemplate 创建表
...mplate创建表【英文标题】:CreateTableWithJDBCTemplateonRuntime【发布时间】:2021-06-2805:44:19【问题描述】:我想在运行时创建一个表,在我的情况下,列和数据类型不是固定的,所以我不能编写一个常量查询,我需要在列名的基础上创... 查看详情
如何在运行 nativescript 时增加内存使用
...内存使用【英文标题】:Howtoincreasememoryuseonrunnativescript【发布时间】:2019-11-1713:39:12【问题描述】:我使用命令tnsrunandroid--bundle运行代码nativescript代码,它还运行内存4096MB。我的RAM是16。为什么它不能在4上运行?“跳过node_modules... 查看详情
使用 sudo 运行时获取 shell 脚本
...hell脚本【英文标题】:Sourcingashellscript,whilerunningwithsudo【发布时间】:2011-06-0504:56:26【问题描述】:我想编写一个shell脚本来设置一个mercurial存储库,并允许组中的所有用户“开发者”来执行这个脚本。脚本归用户“hg”所有,... 查看详情
使用 32 位 office 访问 64 位运行时
...问64位运行时【英文标题】:Access64bitruntimewith32bitoffice【发布时间】:2020-05-1115:51:22【问题描述】:我已将我的访问应用程序升级到64位,并且正在将客户端电脑更新到64位运行时。我通过使用不同版本的64位运行时(例如,201664... 查看详情
运行时使用的 Kettle Change 连接
...ttleChange连接【英文标题】:KettleChangeconnectionusedatruntime【发布时间】:2018-12-2015:03:01【问题描述】:我需要在运行时更改表格输入步骤使用的连接。我定义了3个连接:STG、DWH、DM。我想在运行时在它们之间进行选择。我无法使用... 查看详情
在运行时创建对象并使用它们
...使用它们【英文标题】:Createobjectsinruntimeandworkwiththem【发布时间】:2015-03-0909:45:45【问题描述】:我的程序运行时创建的对象有问题首先我创建n个对象(假设n:=3)fori:=0ton-1dobeginWithTGauge.Create(Form1)dobeginParent:=Form1;//thisisimportantLef... 查看详情
在运行时 C++ 中使用派生类
...C++中使用派生类【英文标题】:usingderivedclassinruntimec++【发布时间】:2015-04-2600:44:18【问题描述】:如果mybase类是派生类,这是在运行时检查。我需要在运行时使用myBase(如myBase.member1)从myDerived.member1调用成员变量。这里myBase是... 查看详情