来源:开源中国 时间:2023-01-28 09:34:05
Xmake是一个基于 Lua 的轻量级跨平台构建工具。
【资料图】
它非常的轻量,没有任何依赖,因为它内置了 Lua 运行时。
它使用 xmake.lua 维护项目构建,相比 makefile/CMakeLists.txt,配置语法更加简洁直观,对新手非常友好,短时间内就能快速入门,能够让用户把更多的精力集中在实际的项目开发上。
我们能够使用它像 Make/Ninja 那样可以直接编译项目,也可以像 CMake/Meson 那样生成工程文件,另外它还有内置的包管理系统来帮助用户解决 C/C++ 依赖库的集成使用问题。
目前,Xmake 主要用于 C/C++ 项目的构建,但是同时也支持其他 native 语言的构建,可以实现跟 C/C++ 进行混合编译,同时编译速度也是非常的快,可以跟 Ninja 持平。
Xmake = Build backend + Project Generator + Package Manager + [Remote|Distributed] Build + Cache
尽管不是很准确,但我们还是可以把 Xmake 按下面的方式来理解:
Xmake ≈ Make/Ninja + CMake/Meson + Vcpkg/Conan + distcc + ccache/sccache
项目源码 官方文档 入门课程 通过add_requires("iverilog")
配置,我们能够自动拉取 iverilog 工具链包,然后使用set_toolchains("@iverilog")
自动绑定工具链来编译工程。
add_requires("iverilog")target("hello")add_rules("iverilog.binary")set_toolchains("@iverilog")add_files("src/*.v")
设置抽象配置
add_requires("iverilog")target("hello")add_rules("iverilog.binary")set_toolchains("@iverilog")add_files("src/*.v")add_defines("TEST")add_includedirs("inc")set_languages("v1800-2009")
我们可以通过set_languages("v1800-2009")
来设置切换 Verilog 的语言标准。
目前支持的一些取值和映射关系如下:
["v1364-1995"]="-g1995"["v1364-2001"]="-g2001"["v1364-2005"]="-g2005"["v1800-2005"]="-g2005-sv"["v1800-2009"]="-g2009"["v1800-2012"]="-g2012"
设置自定义 flags
add_requires("iverilog")target("hello")add_rules("iverilog.binary")set_toolchains("@iverilog")add_files("src/*.v")add_values("iverilogs.flags","-DTEST")
构建工程
$ xmakechecking for iverilog ... iverilogchecking for vvp ... vvp[ 50%]: linking.iverilog hello.vvp[100%]: build ok!
运行程序
$ xmake runhello world!LXT2 info: dumpfile hello.vcd opened for output.src/main.v:6: $finish called at 0 (1s)
更多完整例子:iVerilog Examples
通过add_requires("verilator")
配置,我们能够自动拉取 verilator 工具链包,然后使用set_toolchains("@verilator")
自动绑定到工具链来编译工程。
add_requires("verilator")target("hello")add_rules("verilator.binary")set_toolchains("@verilator")add_files("src/*.v")add_files("src/*.cpp")
verilator 工程,我们需要一个额外的sim_main.cpp
文件参与编译,作为程序的入口代码。
#include "hello.h"#include "verilated.h"int main(int argc, char** argv) { VerilatedContext* contextp = new VerilatedContext; contextp->commandArgs(argc, argv); hello* top = new hello{contextp}; while (!contextp->gotFinish()) { top->eval(); } delete top; delete contextp; return 0;}
设置抽象配置
add_requires("verilator")target("hello")add_rules("verilator.binary")set_toolchains("@verilator")add_files("src/*.v")add_defines("TEST")add_includedirs("inc")set_languages("v1800-2009")
我们可以通过set_languages("v1800-2009")
来设置切换 Verilog 的语言标准。
目前支持的一些取值和映射关系如下:
-- Verilog["v1364-1995"]="+1364-1995ext+v",["v1364-2001"]="+1364-2001ext+v",["v1364-2005"]="+1364-2005ext+v",-- SystemVerilog["v1800-2005"]="+1800-2005ext+v",["v1800-2009"]="+1800-2009ext+v",["v1800-2012"]="+1800-2012ext+v",["v1800-2017"]="+1800-2017ext+v",
设置自定义 flags
add_requires("verilator")target("hello")add_rules("verilator.binary")set_toolchains("@verilator")add_files("src/*.v")add_files("src/*.cpp")add_values("verilator.flags","--trace","--timing")
构建工程
$ xmake[ 0%]: compiling.verilog src/main.v[ 15%]: cache compiling.release /Users/ruki/.xmake/packages/v/verilator/2023.1.10/cd2268409c1d44799288c7759b3cbd56/share/verilator/include/verilated.cpp[ 15%]: cache compiling.release build/.gens/hello/macosx/x86_64/release/rules/verilator/hello___024root__Slow.cpp[ 15%]: cache compiling.release build/.gens/hello/macosx/x86_64/release/rules/verilator/hello___024root__DepSet_h9053a130__0__Slow.cpp[ 15%]: cache compiling.release build/.gens/hello/macosx/x86_64/release/rules/verilator/hello.cpp[ 15%]: cache compiling.release /Users/ruki/.xmake/packages/v/verilator/2023.1.10/cd2268409c1d44799288c7759b3cbd56/share/verilator/include/verilated_threads.cpp[ 15%]: cache compiling.release build/.gens/hello/macosx/x86_64/release/rules/verilator/hello__Syms.cpp[ 15%]: cache compiling.release build/.gens/hello/macosx/x86_64/release/rules/verilator/hello___024root__DepSet_h07139e86__0.cpp[ 15%]: cache compiling.release src/sim_main.cpp[ 15%]: cache compiling.release build/.gens/hello/macosx/x86_64/release/rules/verilator/hello___024root__DepSet_h9053a130__0.cpp[ 84%]: linking.release hello[100%]: build ok!
运行程序
$ xmake runruki-2:hello ruki$ xmake runhello world!- src/main.v:4: Verilog $finish
更多完整例子:Verilator
非常感谢Arthapz在新版本中继续帮忙改进了 xmake 对 C++ Modules 的支持。
现在,我们可以将 C++ Modules 做成包进行分发,然后在其他项目中进行快速集成和复用。
它是基于p2473r1中对模块分发的设计草案做的一个原型实现。
我们先使用 xmake.lua 维护模块的构建,并通过指定{install=true}
,来告诉 xmake 哪些模块文件需要安装对外分发。
add_rules("mode.release","mode.debug")set_languages("c++20")target("foo")set_kind("static")add_files("*.cpp")add_files("*.mpp",{install =true})
然后,我们把它做成包,可以提交到xmake-repo仓库,当然也可以直接做成本地包,或者私有仓库包。
这里,为了方便测试验证,我们仅仅通过set_sourcedir
将它做成本地包。
package("foo")set_sourcedir(path.join(os.scriptdir(),"src"))on_install(function(package)import("package.tools.xmake").install(package,{})end)
然后,我们通过add_requires("foo")
的包集成接口,对 C++ Modules 包进行快速集成使用。
由于 foo 的模块包,我们放在私有仓库中定义,所以我们通过add_repositories("my-repo my-repo")
引入自己的包仓库。
如果,包已经提交到 xmake-repo 官方仓库,就不需要额外配置它。
add_rules("mode.release","mode.debug")set_languages("c++20")add_repositories("my-repo my-repo")add_requires("foo","bar")target("packages")set_kind("binary")add_files("src/*.cpp")add_packages("foo","bar")set_policy("build.c++.modules",true)
集成好包后,我们就可以执行xmake
命令,一键下载、编译、集成 C++ Modules 包来使用。
$ xmakechecking for platform ... linuxchecking for architecture ... x86_64note: install or modify (m)these packages (pass -y to skip confirm)?in my-repo: -> foo latest -> bar latestplease input: y (y/n/m)=> install bar latest .. ok => install foo latest .. ok[0%]: generating.module.deps src/main.cpp[0%]: generating.module.deps /mnt/xmake/tests/projects/c++/modules/packages/build/.packages/b/bar/latest/4e0143c97b65425b855ad5fd03038b6a/modules/bar/bar.mpp[0%]: generating.module.deps /mnt/xmake/tests/projects/c++/modules/packages/build/.packages/f/foo/latest/4e0143c97b65425b855ad5fd03038b6a/modules/foo/foo.mpp[14%]: compiling.module.release bar[14%]: compiling.module.release foo[57%]: compiling.release src/main.cpp[71%]: linking.release packages[100%]: build ok!
注:每个包安装后,会在包路径下,存储维护模块的 meta-info 文件,这是p2473r1.pdf
中约定的一种格式规范,也许它不是最终的标准,但这并不影响我们现在去使用模块的分发。
$ cat ./build/.packages/f/foo/latest/4e0143c97b65425b855ad5fd03038b6a/modules/foo/foo.mpp.meta-info{"_VENDOR_extension":{"xmake":{"name":"foo","file":"foo.mpp"}},"definitions":{},"include_paths":{}}
完整的例子工程见:C++ Modules 包分发例子工程
Arthapz也帮忙改进了对 C++23 Std Modules 的支持。
目前三个编译器对它的支持进展:
最新 Visual Studio 17.5 preview 已经支持,并且非标准的 ifc std modules 将被废弃。
对于标准的 C++23 std modules,我们是这么引入的。
import std;
而对于 ifc std modules,我们需要这么写:
import std.core;
它不是 C++23 标准,仅仅 msvc 提供,对其他编译器并不兼容,以后新版本 msvc 中也会逐步废弃。 因此新版本 Xmake 将仅仅 C++23 std modules,不再支持废弃的 ifc std modules。
目前最新的 clang 似乎也还没完全支持 C++23 std modules,当前还是 draft patch 状态,#D135507。
但是,Xmake 也对它进行了支持,如果大家想要尝鲜,可以自行合入这个 patch,然后使用 xmake 来测试。
另外,低版本的 clang 也有对非标准的 std modules 做了实验性支持。
我们还是可以在低版本 clang 中尝试性使用 xmake 来构建 std modules,尽管它可能还只是个玩具(会遇到很多问题)。
相关讨论见:#3255
目前还不支持。
之前,我们仅仅支持 xmake 命令的不全,新版本中,我们还支持了xrepo install
命令的不全, 可以自动搜索xmake-repo仓库的包,来不全我们的安装命令。
非常感谢 @glcraft 的贡献。
$ xrepo install libplibpaper libpfm libpng libpqxx libpthread-stubslibpcap libplist libpq libpsl
OAuthApp v2.1.19 更新 | 前端发布工具 全球速递
MX Linux 21.3 发布,基于 Debian 的 Linux 发行版-天天快播