V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
waruqi
V2EX  ›  程序员

xmake v2.3.1 发布, 无缝对接其他构建系统,有玩 c/c++的可以进来看看。

  •  2
     
  •   waruqi ·
    waruqi · 2020-02-24 09:48:37 +08:00 · 2096 次点击
    这是一个创建于 1719 天前的主题,其中的信息可能已经有所发展或是发生改变。

    xmake 是一个基于 Lua 的轻量级现代化 C/C++跨平台构建系统,理念是:简单,高效,跨平台。

    最近对 xmake 内部做了不少的重构来改进,并且新增了不少实用的新特性,欢迎来体验。

    一些新特性:

    1. 一键编译其他构建系统维护的项目,实现无缝对接,并且支持交叉编译(比如 autotools 的快速交叉编译,见下文详述)
    2. 新增xmake project -k ninja工程生成插件,支持对 build.ninja 构建系统文件的生成

    一些改进点:

    1. 改进命令行参数输入,支持*nix style 的参数输入,感谢@OpportunityLiu的贡献
    2. 改进 tab 命令补全,增加对参数 values 的命令补全支持
    3. 优化 get.sh 安装和 xmake update 更新脚本,添加国内镜像源,加速下载和安装更新
    4. gcc/clang 编译错误输出支持原生色彩高亮支持
    5. 新增 msys/cygwin 平台,并且 xmake 源码也支持 msys/mingw 平台编译

    一些看不见的改进点:

    1. 添加 socket, pipe 模块,改进 process 模块
    2. 重构整个进程调度器,更好的调度并行构建
    3. 重构改进整个 coroutine 协程模块,支持对 socket/pipe/process 三者的同时调度支持(为后续远程编译和分布式编译做准备)

    还有一些零散的 bug 修复,见下文更新内容。

    新特性介绍

    生成 build.ninja 构建文件

    xmake 现已支持对 ninja 构建文件的生成,让用户可以使用 ninja 来快速构建 xmake 维护的项目。不得不承认,目前就构建速度来讲,ninja 确实比 xmake 快不少,后续版本我会尝试优化下 xmake 的构建速度。

    $ xmake project -k ninja
    

    然后调用 ninja 来构建:

    $ ninja
    

    或者直接使用 xmake 命令来调用 ninja 构建,见下文。

    尝试使用其他构建系统构建

    xmake v2.3.1 以上版本直接对接了其他第三方构建系统,即使其他项目中没有使用 xmake.lua 来维护,xmake 也可以直接调用其他构建工具来完成编译。

    那用户直接调用使用第三方构建工具来编译不就行了,为啥还要用 xmake 去调用呢?主要有以下好处:

    1. 完全的行为一致,简化编译流程,不管用了哪个其他构建系统,都只需要执行 xmake 这个命令就可以编译,用户不再需要去研究其他工具的不同的编译流程
    2. 完全对接xmake config的配置环境,复用 xmake 的平台探测和 sdk 环境检测,简化平台配置
    3. 对接交叉编译环境,即使是用 autotools 维护的项目,也能通过 xmake 快速实现交叉编译

    目前已支持的构建系统:

    • autotools (已完全对接 xmake 的交叉编译环境)
    • xcodebuild
    • cmake
    • make
    • msbuild
    • scons
    • meson
    • bazel
    • ndkbuild
    • ninja

    自动探测构建系统并编译

    例如,对于一个使用 cmake 维护的项目,直接在项目根目录执行 xmake,就会自动触发探测机制,检测到 CMakeLists.txt ,然后提示用户是否需要使用 cmake 来继续完成编译。

    $ xmake 
    note: CMakeLists.txt found, try building it (pass -y or --confirm=y/n/d to skip confirm)?
    please input: y (y/n)
    -- Symbol prefix:
    -- Configuring done
    -- Generating done
    -- Build files have been written to: /Users/ruki/Downloads/libpng-1.6.35/build
    [  7%] Built target png-fix-itxt
    [ 21%] Built target genfiles
    [ 81%] Built target png
    [ 83%] Built target png_static
    ...
    output to /Users/ruki/Downloads/libpng-1.6.35/build/artifacts
    build ok!
    

    无缝对接 xmake 命令

    目前支持xmake clean, xmake --rebuildxmake config等常用命令与第三方系统的无缝对接。

    我们可以直接清理 cmake 维护项目的编译输出文件

    $ xmake clean
    $ xmake clean --all
    

    如果带上--all执行清理,会清除 autotools/cmake 生成的所有文件,不仅仅只清理对象文件。

    默认xmake对接的是增量构建行为,不过我们也可以强制快速重建:

    $ xmake --rebuild
    

    手动切换指定构建系统

    如果一个项目下有多个构建系统同时在维护,比如 libpng 项目,自带 autotools/cmake/makefile 等构建系统维护,xmake 默认优先探测使用了 autotools,如果想要强制切换其他构建系统,可以执行:

    $ xmake f --trybuild=[autotools|cmake|make|msbuild| ..]
    $ xmake
    

    另外,配置了--trybuild=参数手动指定了默认的构建系统,后续的 build 过程就不会额外提示用户选择了。

    实现快速交叉编译

    众所周知,autotools 维护的项目虽然很多都支持交叉编译,但是交叉编译的配置过程很复杂,不同的工具链处理方式还有很多的差异,中途会踩到很多的坑。

    即使跑通了一个工具链的交叉编译,如果切到另外一个工具链环境,可能又要折腾好久,而如果使用 xmake,通常只需要两条简单的命令即可:

    !> 目前就 autotools 对接支持了 xmake 的交叉编译,后期还会对 cmake 等其他构建系统加上支持。

    交叉编译 android 平台
    $ xmake f -p android --trybuild=autotools [--ndk=xxx]
    $ xmake
    

    !> 其中,--ndk 参数配置是可选的,如果用户设置了 ANDROID_NDK_HOME 环境变量,或者 ndk 放置在~/Library/Android/sdk/ndk-bundle,xmake 都能自动检测到。

    是不是很简单?如果你觉得这没啥,那么可以对比下直接操作./configure去配置交叉编译,可以看下这篇文档对比下:将 NDK 与其他编译系统配合使用

    说白了,你大概得这样,还不一定一次就能搞定:

    $ export TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/$HOST_TAG
    $ export AR=$TOOLCHAIN/bin/aarch64-linux-android-ar
    $ export AS=$TOOLCHAIN/bin/aarch64-linux-android-as
    $ export CC=$TOOLCHAIN/bin/aarch64-linux-android21-clang
    $ export CXX=$TOOLCHAIN/bin/aarch64-linux-android21-clang++
    $ export LD=$TOOLCHAIN/bin/aarch64-linux-android-ld
    $ export RANLIB=$TOOLCHAIN/bin/aarch64-linux-android-ranlib
    $ export STRIP=$TOOLCHAIN/bin/aarch64-linux-android-strip
    $ ./configure --host aarch64-linux-android
    $ make
    
    交叉编译 iphoneos 平台
    $ xmake f -p iphoneos --trybuild=autotools
    $ xmake
    
    交叉编译 mingw 平台
    $ xmake f -p mingw --trybuild=autotools [--mingw=xxx]
    $ xmake
    
    使用其他交叉编译工具链
    $ xmake f -p cross --trybuild=autotools --sdk=/xxxx
    $ xmake
    

    关于更多交叉编译的配置细节,请参考文档:交叉编译,除了多了一个--trybuild=参数,其他交叉编译配置参数都是完全通用的。

    传递用户配置参数

    我们可以通过--tryconfigs=来传递用户额外的配置参数到对应的第三方构建系统,比如:autotools 会传递给./configure,cmake 会传递给cmake命令。

    $ xmake f --trybuild=autotools --tryconfigs="--enable-shared=no"
    $ xmake
    

    比如上述命令,传递--enable-shared=no./configure,来禁用动态库编译。

    另外,对于--cflags, --includedirs--ldflags等参数,不需要通过--tryconfigs,通过xmake config --cflags=等内置参数就可透传过去。

    编译其他构建系统过程示例

    通用编译方式

    大多数情况下,每个构建系统对接后的编译方式都是一致的,除了--trybuild=配置参数除外。

    $ xmake f --trybuild=[autotools|cmake|meson|ninja|bazel|make|msbuild|xcodebuild]
    $ xmake
    

    !> 我们还需要确保--trybuild 指定的构建工具已经安装能够正常使用。

    构建 Android jni 程序

    如果当前项目下存在jni/Android.mk,那么 xmake 可以直接调用 ndk-build 来构建 jni 库。

    $ xmake f -p android --trybuild=ndkbuild [--ndk=]
    $ xmake
    

    *nix style 命令参数输入

    目前的输入规范参考自:https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html

    也非常感谢@OpportunityLiu的贡献,现在的输入方式,可以支持采用如下写法:

    $ xmake -j8 -rvD
    

    之前只能这么写:

    $ xmake -j 8 -r -v -D
    

    tab 命令自动补全

    之前的版本,只能对参数名进行补全,现在可以对参数值进行补全和值列表提示,比如敲如下命令后:

    $ xmake f --plat=and
    

    按 tab 键就可以补全 platform 参数,变成

    $ xmake f --plat=android
    

    强制将 c 代码作为 c++编译

    xmake 新增一个配置参数,可以指定源文件的类型,强制作为对应的源文件来编译,比如将 c 代码作为 c++来编译。

    target("test")
        set_kind("binary")
        add_files("src/*.c", {sourcekind = "cxx"})
    

    更新内容

    新特性

    • #675: 支持通过设置强制将*.c作为 c++代码编译, add_files("*.c", {sourcekind = "cxx"})
    • #681: 支持在 msys/cygwin 上编译 xmake,以及添加 msys/cygwin 编译平台
    • 添加 socket/pipe 模块,并且支持在协程中同时调度 process/socket/pipe
    • #192: 尝试构建带有第三方构建系统的项目,还支持 autotools 项目的交叉编译
    • 启用 gcc/clang 的编译错误色彩高亮输出
    • #588: 改进工程生成插件xmake project -k ninja,增加对 build.ninja 生成支持

    改进

    • #665: 支持 *nix style 的参数输入,感谢@OpportunityLiu的贡献
    • #673: 改进 tab 命令补全,增加对参数 values 的补全支持
    • #680: 优化 get.sh 安装脚本,添加国内镜像源,加速下载
    • 改进 process 调度器
    • #651: 改进 os/io 模块系统操作错误提示

    Bugs 修复

    • 修复增量编译检测依赖文件的一些问题
    • 修复 log 输出导致 xmake-vscode 插件解析编译错误信息失败问题
    • #684: 修复 windows 下 android ndk 的一些 linker 错误
    9 条回复    2020-02-24 12:50:15 +08:00
    mmqc
        1
    mmqc  
       2020-02-24 10:28:09 +08:00
    支持一下
    zhuangzhuang1988
        2
    zhuangzhuang1988  
       2020-02-24 10:45:47 +08:00
    学不动了.
    Alexhohom
        3
    Alexhohom  
       2020-02-24 11:09:20 +08:00
    mark,看起来很美好
    waruqi
        4
    waruqi  
    OP
       2020-02-24 11:37:20 +08:00
    @zhuangzhuang1988 哈哈 入门很简单 你可以先体验下
    vitovan
        5
    vitovan  
       2020-02-24 11:51:21 +08:00
    看楼主整洁的发帖风格,就觉得这个工具挺靠谱
    j137tt736CExzlfM
        6
    j137tt736CExzlfM  
       2020-02-24 12:02:38 +08:00
    支持一下,不错!
    ylx
        7
    ylx  
       2020-02-24 12:03:56 +08:00 via iPhone
    可以用来编译内核吗
    waruqi
        8
    waruqi  
    OP
       2020-02-24 12:13:43 +08:00
    @ylx 理论上肯定可以编译,前提是有 xmake.lua 维护描述项目构建,如果你移植过去了 就可以编译,而现有内核的构建系统,只能使用 xmake 去调用 make 来 wrap 编译,就如上文说的,不过内核编译配置的东西比较多,如果没有 xmake.lua ,那么还是直接用现有系统直接 make 编译吧。
    waruqi
        9
    waruqi  
    OP
       2020-02-24 12:50:15 +08:00
    @lazzyboy 谢谢
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2682 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 01:46 · PVG 09:46 · LAX 17:46 · JFK 20:46
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.