V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Sponsored by
LinkedIn
不坐班的神仙工作 · 去任何你想去的地方远程,赚一线城市的工资
2000 个不用出门 Social 的全球远程工作,帮助 V2EX 的小伙伴开启全新的工作方式。
Promoted by LinkedIn
waruqi
V2EX  ›  程序员

Xmake: 现在可以支持远程编译了,有玩 C/C++ 的同学可以试试

  •  
  •   waruqi ·
    waruqi · 155 天前 · 1494 次点击
    这是一个创建于 155 天前的主题,其中的信息可能已经有所发展或是发生改变。

    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
    

    前言

    尽管 VSCode 等现代化的编辑器都内置支持远程编译,但是不是所有编辑器都支持,通过 Xmake 内置的远程编译特性,我们可以再全端任意编辑器(甚至在 vim/emacs 上),IDE (包括 vs )上快速地编辑代码,然后进行远程编译和运行。

    例如,我们可以像本地编译一样,实现在 macOS 、linux 上编译 Windows 程序,并远程运行,也可以在 Windows 上远程编译调试 linux/macOS 程序。

    目前支持初步支持,还有很多细节体验有待改进,欢迎大家试用 Xmake 新版本。

    新特性介绍

    远程编译支持

    新版本提供了远程编译支持,我们可以通过它可以远程服务器上编译代码,远程运行和调试。

    服务器可以部署在 Linux/MacOS/Windows 上,实现跨平台编译,例如:在 Linux 上编译运行 Windows 程序,在 Windows 上编译运行 macOS/Linux 程序。

    相比 ssh 远程登入编译,它更加的稳定,使用更加流畅,不会因为网络不稳定导致 ssh 终端输入卡顿,也可以实现本地快速编辑代码文件。

    甚至我们可以在 vs/sublime/vscode/idea 等编辑器和 IDE 中无缝实现远程编译,而不需要依赖 IDE 本身对远程编译的支持力度。

    开启服务

    $ xmake service
    <remote_build_server>: listening 0.0.0.0:90091 ..
    

    我们也可以开启服务的同时,回显详细日志信息。

    $ xmake service -vD
    <remote_build_server>: listening 0.0.0.0:90091 ..
    

    以 Daemon 模式开启服务

    $ xmake service --start
    $ xmake service --restart
    $ xmake service --stop
    

    配置服务端

    我们首先,运行 xmake service 命令,它会自动生成一个默认的 service.conf 配置文件,存储到 ~/.xmake/service.conf

    然后,我们编辑它,修复服务器的监听端口(可选)。

    {
        logfile = "/Users/ruki/.xmake/service/logs.txt",
        remote_build = {
            server = {
                listen = "0.0.0.0:90091"
            }
        }
    }
    

    配置客户端

    我们还是编辑这个文件 ~/.xmake/service.conf,配置客户端需要连接的服务器地址。

    {
        logfile = "/Users/ruki/.xmake/service/logs.txt",
        remote_build = {
            client = {
                connect = "192.168.56.101:90091",
            }
        }
    }
    

    导入给定的配置文件

    我们也可以通过下面的命令,导入指定的配置文件。

    $ xmake service --config=/tmp/service.conf
    

    连接远程的服务器

    接下来,我们只需要进入需要远程编译的工程根目录,执行 xmake service --connect 命令,进行连接。

    $ xmake create test
    $ cd test
    $ xmake service --connect 
    <remote_build_client>: connect 192.168.56.110:90091 ..
    <remote_build_client>: connected!
    <remote_build_client>: sync files in 192.168.56.110:90091 ..
    Scanning files ..
    Comparing 3 files ..
        [+]: src/main.cpp
        [+]: .gitignore
        [+]: xmake.lua
    3 files has been changed!
    Archiving files ..
    Uploading files with 1372 bytes ..
    <remote_build_client>: sync files ok!
    

    远程构建工程

    连接成功后,我们就可以像正常本地编译一样,进行远程编译。

    $ xmake
    <remote_build_client>: run xmake in 192.168.56.110:90091 ..
    checking for platform ... macosx
    checking for architecture ... x86_64
    checking for Xcode directory ... /Applications/Xcode.app
    checking for Codesign Identity of Xcode ... Apple Development: [email protected] (T3NA4MRVPU)
    checking for SDK version of Xcode for macosx (x86_64) ... 11.3
    checking for Minimal target version of Xcode for macosx (x86_64) ... 11.4
    [ 25%]: ccache compiling.release src/main.cpp
    [ 50%]: linking.release test
    [100%]: build ok!
    <remote_build_client>: run command ok!
    

    远程运行目标程序

    我们也可以像本地运行调试那样,远程运行调试编译的目标程序。

    $ xmake run
    <remote_build_client>: run xmake run in 192.168.56.110:90091 ..
    hello world!
    <remote_build_client>: run command ok!
    

    远程重建工程

    $ xmake -rv
    <remote_build_client>: run xmake -rv in 192.168.56.110:90091 ..
    [ 25%]: ccache compiling.release src/main.cpp
    /usr/local/bin/ccache /usr/bin/xcrun -sdk macosx clang -c -Qunused-arguments -arch x86_64 -mmacosx-version-min=11.4 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk -fvisibility=hidden -fvisibility-inlines-hidden -O3 -DNDEBUG -o build/.objs/test/macosx/x86_64/release/src/main.cpp.o src/main.cpp
    [ 50%]: linking.release test
    "/usr/bin/xcrun -sdk macosx clang++" -o build/macosx/x86_64/release/test build/.objs/test/macosx/x86_64/release/src/main.cpp.o -arch x86_64 -mmacosx-version-min=11.4 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk -stdlib=libc++ -Wl,-x -lz
    [100%]: build ok!
    <remote_build_client>: run command ok!
    

    远程配置编译参数

    $ xmake f --xxx --yy
    

    手动同步工程文件

    连接的时候,会自动同步一次代码,后期代码改动,可以执行此命令来手动同步改动的文件。

    $ xmake service --sync
    <remote_build_client>: sync files in 192.168.56.110:90091 ..
    Scanning files ..
    Comparing 3 files ..
        [+]: src/main.cpp
        [+]: .gitignore
        [+]: xmake.lua
    3 files has been changed!
    Archiving files ..
    Uploading files with 1372 bytes ..
    <remote_build_client>: sync files ok!
    

    断开远程连接

    针对当前工程,断开连接,这仅仅影响当前工程,其他项目还是可以同时连接和编译。

    $ xmake service --disconnect
    <remote_build_client>: disconnect 192.168.56.110:90091 ..
    <remote_build_client>: disconnected!
    

    查看服务器日志

    $ xmake service --logs
    

    清理远程服务缓存和构建文件

    我们也可以手动清理远程的任何缓存和构建生成的文件。

    $ cd projectdir
    $ xmake service --clean
    

    改进 Cargo 包依赖

    在之前的版本中,我们已经可以通过 add_requires("cargo::base64") 去单独集成每个 cargo 包,用于编译 rust 项目,以及与 C/C++ 的混合编译,例如:

    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")
    

    但是上面的方式会有一个问题:

    如果依赖很多,并且有几个依赖都共同依赖了相同的子依赖,那么会出现重定义问题,因此如果我们使用完整的 Cargo.toml 去管理依赖就不会存在这个问题。

    例如:

    add_rules("mode.release", "mode.debug")
    add_requires("cargo::test", {configs = {cargo_toml = path.join(os.projectdir(), "Cargo.toml")}})
    
    target("test")
        set_kind("binary")
        add_files("src/main.rs")
        add_packages("cargo::test")
    

    然后,我们就可以在 Cargo.toml 中集成所有需要的依赖,让 Rust 自己去分析依赖关系,避免重复的子依赖冲突。

    完整例子见:cargo_deps_with_toml

    当然,如果用户的依赖比较单一,那么之前的集成方式还是完全可用。

    为什么使用 Xmake 编译 Rust?

    这个时候,肯定会有人问,既然都用了 Cargo.toml 和 Cargo 了,为什么还要在 xmake.lua 中去配置呢,直接 Cargo 编译不就好了么。

    如果我们是在用 Xmake 开发 C/C++ 项目,但是需要引入一些 Rust 子模块给 C/C++ 项目使用,那么就可以借助这种方式,快速方便地在 C/C++ 中调用 Rust 库和代码。

    更多关于 C/C++ 中调用 Rust 代码库的说明,见:使用 cxxbridge 在 C/C++ 中调用 Rust

    支持源文件分组

    新版本,我们提供了一个新接口 add_filegroups,用于对 vs/vsxmake/cmakelists generator 生成的工程文件进行源文件分组展示。

    如果不设置分组展示,Xmake 也会默认按照树状模式展示,但是有些极端情况下,目录层级显示不是很好,例如:

    target("test")
        set_kind("binary")
        add_files("../../../../src/**.cpp")
    

    目前主要支持两种展示模式:

    • plain: 平坦模式
    • tree: 树形展示,这也是默认模式

    另外,它也支持对 add_headerfiles 添加的文件进行分组。

    设置分组并指定根目录

    target("test")
        set_kind("binary")
        add_files("../../../../src/**.cpp")
        add_filegroups("group1/group2", {rootdir = "../../../../"})
    

    设置分组并指定文件匹配模式

    target("test")
        set_kind("binary")
        add_files("../../../../src/**.cpp")
        add_filegroups("group1/group2", {rootdir = "../../../../", files = {"src/**.cpp"}})
    

    作为平坦模式展示

    这种模式下,所有源文件忽略嵌套的目录层级,在分组下同一层级展示。

    target("test")
        set_kind("binary")
        add_files("../../../../src/**.cpp")
        add_filegroups("group1/group2", {rootdir = "../../../../", mode = "plain"})
    

    包版本选择支持 Git Commit

    Xmake 的包依赖管理接口 add_requires 支持版本语义选择,分支选择,例如:

    add_requires("tbox 1.6.1")
    add_requires("tbox >=1.6.1")
    add_requires("tbox master")
    

    但是,之前的版本,我们还不支持从 Git Commit 中选择版本,而现在我们也支持上了。

    add_requires("tbox e807230557aac69e4d583c75626e3a7ebdb922f8")
    

    只要,这个包的配置中带有 Git url ,就能从 Commit 中选择版本。

    更好地支持 iOS 模拟器编译

    如果要编译 iOS 平台目标程序,之前可以使用如下配置,仅仅通过切换 arch ,就能分别编译真机,模拟器版本程序。

    $ xmake f -p iphoneos [-a armv7|armv7s|arm64|i386|x86_64]
    $ xmake
    

    但是由于 M1 设备上模拟器也支持 arm64 架构,因此之前单纯从 arch 去区分是否为模拟器,已无法满足需求。 因此,在新版本中,我们新增了一个参数配置去区分是否为模拟器目标。

    $ xmake f -p iphoneos --appledev=simulator
    $ xmake f -p watchos --appledev=simulator
    $ xmake f -p appletvos --appledev=simulator
    

    而如果没有指定 --appledev= 参数,默认就是编译真机程序,当然,之前的模式也是完全兼容的。

    更新内容

    新特性

    • #2138: 支持模板包
    • #2185: 添加 --appledev=simulator 去改进 Apple 模拟器目标编译支持
    • #2227: 改进 cargo 包,支持指定 Cargo.toml 文件
    • 改进 add_requires 支持 git command 作为版本
    • #622: 支持远程编译
    • #2282: 添加 add_filegroups 接口为 vs/vsxmake/cmake generator 增加文件组支持

    改进

    • #2137: 改进 path 模块
    • macOS 下,减少 50% 的 Xmake 二进制文件大小
    • 改进 tools/autoconf,cmake 去更好地支持工具链切换
    • #2221: 改进注册表 api 去支持 unicode
    • #2225: 增加对 protobuf 的依赖分析和构建支持
    • #2265: 排序 CMakeLists.txt
    • 改进 os.files 的文件遍历速度

    Bugs 修复

    • #2233: 修复 c++ modules 依赖
    7 条回复    2022-04-28 21:02:05 +08:00
    codefever
        1
    codefever  
       155 天前
    挺好的,可以搭配代码仓库 codefever 一起用,生产力直接大跃进了嗷
    waruqi
        2
    waruqi  
    OP
       155 天前
    另外,Xmake 社区参加了今年的开源之夏活动,欢迎在校学生参与我们的项目: https://summer-ospp.ac.cn/#/org/orgdetail/090748c6-6504-4d2d-9a11-f9f3e1876f7b/
    airqj
        3
    airqj  
       155 天前
    现在不写 c 了 还是支持一下
    waruqi
        4
    waruqi  
    OP
       155 天前
    @airqj 不光可以编译 c/c++,还可以编译 rust/dlang/swift/zig/vala/go/objc/pascal/fortran 等其他语言的
    SJ2050cn
        5
    SJ2050cn  
       155 天前
    有空了学习一下,使用 cmake 找依赖太烦了。
    airqj
        6
    airqj  
       154 天前
    @waruqi 感谢 有空试一下
    pursuer
        7
    pursuer  
       152 天前
    简单用过您维护的 tbox ,发现 API 的命名有些清奇,通常释放资源多是 close,delete,free,dispose ,该项目用的是 exit ,还有 tb_poller_spak 这个 API ,也没查到 spak 是什么意思,通常结束 wait 用的大多是 wake notify 之类的。所以在初次使用的时候没看 demo,只凭代码补全有的 API 一顿好找(捂脸)
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2608 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 44ms · UTC 15:30 · PVG 23:30 · LAX 08:30 · JFK 11:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.