首页 > 其他分享 >Xmake v2.7.8 发布,改进包虚拟环境和构建速度

Xmake v2.7.8 发布,改进包虚拟环境和构建速度

时间:2023-04-19 22:03:36浏览次数:45  
标签:Xmake end target -- v2.7 编译 add 虚拟环境 检测

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

新特性介绍

快速切换临时虚拟环境

Xmake 很早就支持了包的虚拟环境管理,可以通过配置文件的方式,实现不同包环境之间的切换。

我们可以通过在当前目录下,添加 xmake.lua 文件,定制化一些包配置,然后进入特定的包虚拟环境。

add_requires("zlib 1.2.11")
add_requires("python 3.x", "luajit")
$ xrepo env shell
> python --version
> luajit --version

也可以通过导入自定义环境配置文件,来切换环境:

$ xrepo env --add /tmp/base.lua
$ xrepo env -b base shell

而在新版本中,我们进一步做了改进,让 Xrepo 能够直接在命令行临时指定需要绑定的环境包列表,实现快速切换,无需任何配置。

并且支持同时指定多个包环境。

例如,我们想进入一个带有 python 3.0, luajit 和 cmake 的环境,只需要执行:

$ xrepo env -b "python 3.x,luajit,cmake" shell
[python,luajit,cmake] $ python --version
Python 3.10.6
[python,luajit,cmake] $ cmake --version
cmake version 3.25.3

Xmake 会自动安装相关依赖,然后开启一个新的 shell 环境,新环境终端左边也有 prompt 提示。

如果我们想退出当前环境,仅仅需要执行

[python,luajit,cmake] $ xrepo env quit
$

改进代码特性检测

has_cfuncs/check_cxxsnippets 等系列检测接口,在 option 中已经有提供,并且有对应的辅助 API 来帮助检测。

相关文档可以参考:辅助检测接口。

但是目前 option 提供的检测接口仅仅针对全局平台工具链,无法根据每个特定的 target 配置在针对性做一些检测。

因为 target 本身可能还会附带依赖包,不同的工具链,编译宏等差异性,检测结果也会有一些差异。

因此,如果用户想要更加灵活细粒度的检测每个 target 目标的编译特性,可以通过新版本提供的 target 目标实例接口。

  • target:has_cfuncs
  • target:has_cxxfuncs
  • target:has_ctypes
  • target:has_cxxtypes
  • target:has_cincludes
  • target:has_cxxincludes
  • target:has_cflags
  • target:has_cxxflags
  • target:has_features
  • target:check_csnippets
  • target:check_cxxsnippets

这里,仅仅针对其中一些比较常用的接口,稍微展开介绍下使用方式。

target:has_cfuncs

  • 检测目标编译配置能否获取给定的 C 函数

这应该在 on_config 中使用,比如可以用它来判断当前目标能否获取到 zlib 依赖包的一些函数接口,然后自动定义 HAVE_INFLATE

add_requires("zlib")
target("test")
    set_kind("binary")
    add_files("src/*.c")
    add_packages("zlib")
    on_config(function (target)
        if target:has_cfuncs("inflate", {includes = "zlib.h"}) then
            target:add("defines", "HAVE_INFLATE")
        end
    end)

尽管 option 也提供了类似的检测功能,但 option 的检测使用的是全局的平台工具链,它无法附带上 target 相关的一些编译配置,
也无法根据 target 设置不同编译工具链来适配检测,并且无法检测包里面的一些接口。

如果我们仅仅是想粗粒度的检测函数接口,并且 target 没有额外设置不同的工具链,那么 option 提供的检测功能已经足够使用了。

如果想要更细粒度控制检测,可以使用 target 实例接口提供的检测特性。

target:has_cxxfuncs

  • 检测目标编译配置能否获取给定的 C++ 函数

用法跟 target:has_cfuncs 类似,只是这里主要用于检测 C++ 的函数。

不过,在检测函数的同时,我们还可以额外配置 std languages,来辅助检测。

target:has_cxxfuncs("foo", {includes = "foo.h", configs = {languages = "cxx17"}})

target:has_ctypes

  • 检测目标编译配置能否获取给定的 C 类型

这应该在 on_config 中使用,如下所示:

add_requires("zlib")
target("test")
    set_kind("binary")
    add_files("src/*.c")
    add_packages("zlib")
    on_config(function (target)
        if target:has_ctypes("z_stream", {includes = "zlib.h"}) then
            target:add("defines", "HAVE_ZSTEAM_T")
        end
    end)

target:has_cflags

  • 检测目标编译配置能否获取给定的 C 编译 flags
target("test")
    set_kind("binary")
    add_files("src/*.cpp")
    on_config(function (target)
        if target:has_cxxflags("-fPIC") then
            target:add("defines", "HAS_PIC")
        end
    end)

target:has_cincludes

  • 检测目标编译配置能否获取给定的 C 头文件

这应该在 on_config 中使用,比如可以用它来判断当前目标能否获取到 zlib 依赖包的 zlib.h 头文件,然后自动定义 HAVE_INFLATE

add_requires("zlib")
target("test")
    set_kind("binary")
    add_files("src/*.c")
    add_packages("zlib")
    on_config(function (target)
        if target:has_cincludes("zlib.h") then
            target:add("defines", "HAVE_ZLIB_H")
        end
    end)

target:check_cxxsnippets

  • 检测是否可以编译和链接给定的 C++ 代码片段

这应该在 on_config 中使用,如下所示:

add_requires("libtins")
target("test")
    set_kind("binary")
    add_files("src/*.cpp")
    add_packages("libtins")
    on_config(function (target)
        local has_snippet = target:check_cxxsnippets({test = [[
            #include <string>
            using namespace Tins;
            void test() {
                std::string name = NetworkInterface::default_interface().name();
                printf("%s\n", name.c_str());
            }
        ]]}, {configs = {languages = "c++11"}, includes = {"tins/tins.h"}}))
        if has_snippet then
            target:add("defines", "HAS_XXX")
        end
    end)

默认仅仅检测编译链接是否通过,如果想要尝试运行时检测,可以再设置 tryrun = true

target("test")
    set_kind("binary")
    add_files("src/*.cpp")
    on_config(function (target)
        local has_int_4 = target:check_cxxsnippets({test = [[
            return (sizeof(int) == 4)? 0 : -1;
        ]]}, {configs = {languages = "c++11"}, tryrun = true}))
        if has_int_4 then
            target:add("defines", "HAS_INT4")
        end
    end)

我们也可以继续通过设置 output = true 来捕获检测的运行输出,并且加上自定义的 main 入口,实现完整的测试代码,而不仅仅是代码片段。

target("test")
    set_kind("binary")
    add_files("src/*.cpp")
    on_config(function (target)
        local int_size = target:check_cxxsnippets({test = [[
            #include <stdio.h>
            int main(int argc, char** argv) {
                printf("%d", sizeof(int)); return 0;
                return 0;
            }
        ]]}, {configs = {languages = "c++11"}, tryrun = true, output = true}))
    end)

target:has_features

  • 检测是否指定的 C/C++ 编译特性

它相比使用 check_cxxsnippets 来检测,会更加快一些,因为它仅仅执行一次预处理就能检测所有的编译器特性,而不是每次都去调用编译器尝试编译。

target("test")
    set_kind("binary")
    add_files("src/*.cpp")
    on_config(function (target)
        if target:has_features("c_static_assert") then
            target:add("defines", "HAS_STATIC_ASSERT")
        end
        if target:has_features("cxx_constexpr") then
            target:add("defines", "HAS_CXX_CONSTEXPR")
        end
    end)

优化编译性能

Xmake 的 build cache 加速类似 ccache,采用预处理器计算 hash 后缓存编译对象文件来实现加速,它在 linux/mac 上提速效果非常明显。

而由于 msvc 的预处理器很慢,也可能是起进程相比 linux/mac 下更重,导致开启 build cache 后,windows 上使用 msvc 的整体编译效率反而慢了非常多。

尝试使用第三方的 ccache 来测试对比,也是一样的问题,因此我暂时针对 msvc 默认禁用了 build cache,使得整体构建速度恢复到正常水平。

clang-tidy 自动修复

上个版本,我们新增了对 clang-tidy 支持,可以通过 xmake check clang.tidy 来检测代码。
而在这个版本中,我们继续对它做了改进,新增了 --fix 参数,可以让 clang-tidy 去自动修复检测出来的问题代码。

$ xmake check clang.tidy --fix
$ xmake check clang.tidy --fix_errors
$ xmake check clang.tidy --fix_notes

Swig/Java 模块构建支持

另外,其他用户也帮忙贡献了 Swig/Java 模块的构建支持。

add_rules("mode.release", "mode.debug")

target("example")
    set_kind('shared')
    -- set moduletype to java
    add_rules("swig.c", {moduletype = "java"})
    -- use swigflags to provider package name and output path of java files
    add_files("src/example.i", {swigflags = {
        "-package",
        "com.example",
        "-outdir",
        "build/java/com/example/"
    }})
    add_files("src/example.c")
    before_build(function()
        -- ensure output path exists before running swig
        os.mkdir("build/java/com/example/")
    end)


更新内容

新特性

  • #3518: 分析编译和链接性能
  • #3522: 为 target 添加 has_cflags, has_xxx 等辅助接口
  • #3537: 为 clang.tidy 检测器添加 --fix 自动修复

改进

  • #3433: 改进 QT 在 msys2/mingw64 和 wasm 上的构建支持
  • #3419: 支持 fish shell 环境
  • #3455: Dlang 增量编译支持
  • #3498: 改进绑定包虚拟环境
  • #3504: 添加 swig java 支持
  • #3508: 改进 trybuild/cmake 去支持工具链切换
  • 为 msvc 禁用 build cache 加速,因为 msvc 的预处理器太慢,反而极大影响构建性能。

Bugs 修复

  • #3436: 修复自动补全和 menuconf
  • #3463: 修复 c++modules 缓存问题
  • #3545: 修复 armcc 的头文件依赖解析



标签:Xmake,end,target,--,v2.7,编译,add,虚拟环境,检测
From: https://blog.51cto.com/tboox/6207490

相关文章

  • Python虚拟环境下使用Pyinstaller打包
    PyInstaller ,他是一款帮助我们把整个项目完整打包的工具。目前已经兼容Py3.7,以及MacApp和WindowsExe由于在进行Pyinstaller打包时,会一同将Pyinstaller所在环境里所有的package一起打进去,这就导致了非常多曾经下载过的,但是在这个项目中没用到的package,也会成为程序的一部分,......
  • Python之虚拟环境venv实战详解
     安装配置虚拟环境virtualenv官方给出的建议是最好在一开始就创建虚拟环境。在不同环境下,我们使用不同命令,即可创建出一个名为venv的虚拟环境最简的方式是使用python指令之间创建#windowspython-mvenvvenv#linux/macospython3-mvenvvenvWindows重点讲解......
  • python虚拟环境
    Python虚拟环境是一种为Python项目创建隔离的开发环境的方式,能够在单个安装的Python实例中创建多个独立的开发环境。Python虚拟环境将安装到特定目录中,并能够在该目录下管理Python包和依赖项,不会与其他Python项目的开发环境冲突。虚拟环境可以使用`venv`模块来创建。以下是使用......
  • Python虚拟环境管理
    1、安装软件1.1、安装virtualenv、virtualenvwrapperpip3installvirtualenvpip3install--no-depsstevedorevirtualenvwrapper2、配置环境变量mkdir/data//venvecho'exportWORKON_HOME=/data/venv'>>.bashrcecho'exportVIRTUALENVWRAPPER_PYTHON=/......
  • 虚拟环境迁移问题排查
    背景某项目开发过程中python虚拟环境通过anacondaconda创建,然后将该虚拟环境直接复制到开发环境中,将整个项目打包成exe之后,出现了一个奇怪的问题:在win8,win10,win11上均没有问题,但在win7上运行过程中出现了缺包的问题。【WinError127】找不到指定的程序:pywin32_system32和nump......
  • conda虚拟环境
    Conda的虚拟环境是一种可以让您在同一台计算机上创建和管理多个相互独立的Python环境的工具。每个虚拟环境可以具有自己的Python解释器和包集合,这意味着您可以在不同的虚拟环境中安装和管理不同版本的Python包,而不会相互干扰。以下是使用Conda创建和管理虚拟环境的步骤:安装Conda......
  • Python-venv-创建和管理虚拟环境
    Python-venv-创建和管理虚拟环境https://docs.python.org/3/tutorial/venv.html概述Python应用程序通常会使用不在标准库内的软件包和模块。应用程序有时需要特定版本的库,因为应用程序可能需要修复特定的错误,或者可以使用库的过时版本的接口编写应用程序。这意味着一个Pytho......
  • Python 虚拟环境迁移到其他电脑
    Python虚拟环境迁移到其他电脑 一、背景介绍在Python项目开发过程中,根据不同的项目场景,需要切换不同的Python版本。因此,我们经常会对不同的项目,创建特定的Python虚拟环境,实现项目环境间的“物理隔离”。本地创建Python虚拟环境,开发测试完项目功能,需要部署到现场环......
  • jump server服务器安装anaconda和虚拟环境
      两次cd..然后suxingming(这个姓名就是自己的账号)然后输入cd~然后联网,输入bashlogin然后联网成功后,输入ls查看当前文件下有哪些文件   比如我要删除这个文件夹下的yes文件,输入pwd查看当前路径:/data00/mabaoguo(姓名)然后输入sudorm-rf/data00/maba......
  • Jenkins部署python-flask后端项目,持续集成(jinkins配置python虚拟环境)
    第一步:新建项目Jenkins->新建任务->起名字,构建一个自由风格的软件项目->保存第二步,添加git仓库第三步,构建,添加shell(Windows系统选择ExecuteWindowsbatchcommand)以windows为例感谢大佬的分享:https://www.cnblogs.com/andy0816/p/16617675.html......