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

Xmake 和 C/C++ 包管理

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

    Xmake 是一个基于 Lua 的轻量级跨平台构建工具,关于 Xmake 与构建系统的介绍,我们已经在之前的文章中做了详细的介绍:C/C++ 构建系统,我用 xmake

    如果大家已经对 Xmake 已经有了大概的了解,就会知道,它不仅仅是一个构建工具,还内置了对 C/C++ 包管理的支持,我们也可以把 Xmake 理解为:

    Xmake = Build backend + Project Generator + Package Manager
    

    经过几年的持续迭代,Xmake 对 C/C++ 包管理的支持不断完善,也新增了不少实用的包管理特性,因此,在本文中,我们对其做一些总结,希望对大家有所帮助。

    构建系统与包管理

    C++ 的生态比较繁杂,这其中也有一定历史原因,不管如何,官方没有提供原生的包管理支持,对我们开发者来说,使用第三方 C++ 依赖库多少存在很多不便。

    其实,现在已经有很多强大的 C/C++ 包管理器,最知名,用的最多的有:vcpkg, conan, conda 等等,它们虽然很强大,但是有一个共同的问题:构建工具对它们没有提供原生的支持。

    由于 CMake 对它们没有提供内置支持,想在 CMake 中使用它们集成依赖包非常繁琐,并且集成和使用的方式都不一致。

    在 CMake 中使用 Conan

    在 CMake 中使用 conan 集成 C/C++ 包,我们需要提供额外的 CMake Wrapper 脚本,以类似插件的方式注入进自己的工程中去。

    cmake_minimum_required(VERSION 3.5)
    project(FormatOutput CXX)
    
    list(APPEND CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR})
    list(APPEND CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR})
    
    add_definitions("-std=c++11")
    
    if(NOT EXISTS "${CMAKE_BINARY_DIR}/conan.cmake")
      message(STATUS "Downloading conan.cmake from https://github.com/conan-io/cmake-conan")
      file(DOWNLOAD "https://raw.githubusercontent.com/conan-io/cmake-conan/v0.16.1/conan.cmake"
                    "${CMAKE_BINARY_DIR}/conan.cmake"
                    EXPECTED_HASH SHA256=396e16d0f5eabdc6a14afddbcfff62a54a7ee75c6da23f32f7a31bc85db23484
                    TLS_VERIFY ON)
    endif()
    
    include(${CMAKE_BINARY_DIR}/conan.cmake)
    
    conan_cmake_configure(REQUIRES fmt/6.1.2
                          GENERATORS cmake_find_package)
    
    conan_cmake_autodetect(settings)
    
    conan_cmake_install(PATH_OR_REFERENCE .
                        BUILD missing
                        REMOTE conancenter
                        SETTINGS ${settings})
    
    find_package(fmt)
    
    add_executable(main main.cpp)
    target_link_libraries(main fmt::fmt)
    

    为了集成一个包,需要额外配置很多的脚本。

    在 CMake 中使用 Vcpkg

    在 CMake 中使用 vcpkg 集成包,我们也需要额外注入一个工具链脚本文件。

    cmake -B [build directory] -S . -DCMAKE_TOOLCHAIN_FILE=[path to vcpkg]/scripts/buildsystems/vcpkg.cmake
    cmake --build [build directory]
    

    另外,还有一个问题,就是我们还需要额外自己调用 vcpkg install [packages] 命令,去安装包。

    这其中每一个环节,对于用户来讲都需要额外的探索过程,没法做到真正的一键编译。

    想象下,用户下载了一个集成了 vcpkg 包的 cmake 项目,想要编译通过,除了项目配置,还需要做哪些额外的事情:

    1. 安装 vcpkg
    2. 执行 vcpkg install xxx 安装里面需要的包
    3. 执行 cmake 传递 vcpkg.cmake 脚本给 cmake ,进行工程配置

    在 CMake 中使用 FetchContent

    提供了 FetchContent 模式来管理依赖,但似乎是源码拉取,而且必须依赖也是基于 CMake 维护构建的,另外,我们需要对每个依赖项,配置 url, 版本等各种包信息。

    cmake_minimum_required(VERSION 3.14)
    project(fetchContent_example CXX)
    
    include(FetchContent)
    
    FetchContent_Declare(
            DocTest
            GIT_REPOSITORY "https://github.com/onqtam/doctest"
            GIT_TAG "932a2ca50666138256dae56fbb16db3b1cae133a"
    )
    FetchContent_Declare(
            Range-v3
            GIT_REPOSITORY "https://github.com/ericniebler/range-v3"
            GIT_TAG "4d6a463bca51bc316f9b565edd94e82388206093"
    )
    
    FetchContent_MakeAvailable(DocTest Range-v3)
    
    add_executable(${PROJECT_NAME} src/main.cpp)
    target_link_libraries(${PROJECT_NAME} doctest range-v3)
    

    在 Meson 中使用依赖包

    Meson 很强大,并且也提供了自带的包管理支持,但是想要在 Meson 中使用其他包管理器,例如 vcpkg/conan 等等同样很繁琐,并没有提供原生支持。

    在 Xmake 中使用依赖包

    Xmake 不仅提供了内置的 xmake-repo 内置的包管理仓库,可以直接集成使用里面的包,还支持以相同的集成方式,去快速集成 vcpkg/conan 等第三方的依赖包。

    集成一个内置依赖包只需要几行配置:

    add_requires("zlib 1.2.11")
    target("test")
        add_files("src/*.c")
        add_packages("zlib")
    

    集成一个 vcpkg 包,仅仅只需要加上对应的包管理器命名空间,集成方式完全相同:

    add_requires("vcpkg::zlib 1.2.11")
    target("test")
        add_files("src/*.c")
        add_packages("vcpkg::zlib")
    

    集成一个 conan 包,或者 conda, homebrew, pacman, apt, clib 等第三方包,也只需要改成 conan::zlib 就行了,用户可以随意切换包源。

    另外,Xmake 会自动帮你调用 vcpkg/conan install 安装命令去安装依赖包,然后集成它们,不需要用户做任何其他事情,仅仅只需要执行 xmake 一键编译。

    C/C++ 包太少?

    觉得 Xmake 内置的包仓库里面的包太少么?完全没关系,理论上,你可以通过 Xmake 使用整个 C/C++ 生态 90% 的常用依赖包,就是因为 Xmake 可以快速从各种其他包管理器中集成包来使用。

    目前 Xmake 支持的包源有以下这些:

    • Official package repository xmake-repo (tbox >1.6.1)
    • Official package manager Xrepo
    • User-built repositories
    • Conan (conan::openssl/1.1.1g)
    • Conda (conda::libpng 1.3.67)
    • Vcpkg (vcpkg:ffmpeg)
    • Homebrew/Linuxbrew (brew::pcre2/libpcre2-8)
    • Pacman on archlinux/msys2 (pacman::libcurl)
    • Apt on ubuntu/debian (apt::zlib1g-dev)
    • Clib (clib::clibs/[email protected])
    • Dub (dub::log 0.4.3)
    • Portage on Gentoo/Linux (portage::libhandy)
    • Nimble for nimlang (nimble::zip >1.3)
    • Cargo for rust (cargo::base64 0.13.0)

    基本上,这些仓库基本已经覆盖了 C/C++ 用户日常所需的所有包。

    作者从写这篇文章开始,统计了下 vcpkg/conan/xmake-repo 仓库的包数量:

    • vcpkg: 1859
    • conan: 1218
    • xmake-repo: 651

    可以看到,目前 Xmake 内置仓库的包数量,已经快要接近 vcpkg/conan 了,也不少了,我们也在不断的收录新的包进来。

    但是这完全没有关系,因为我们可以使用任意包仓库中的包。

    如果在 CMake 中使用 vcpkg ,我们只能使用 1859 个包。 如果在 CMake 中使用 conan ,我们只能使用 1218 个包。

    而如果在 Xmake 中使用包,我们可以使用 651 (xmake-repo) + vcpkg/conan (1k+) + more (conda, homebrew, pacman, apt, clib ...) 中的包。

    甚至,C/C++ 包不够,其他语言的包也可以拿过来用,例如:Xmake 也支持从 dub/cargo 等 Dlang/Rust 的包管理器中拉取包,给 C/C++ 项目使用。

    Xmake 内置包管理集成

    除了接入第三方包管理,我们也更推荐优先使用集成 xmake-repo 内置仓库中提供的包,Xmake 会提供更多特性支持。

    因此,如果用户需要的包还没被收录,可以先尝试提交到 xmake-repo 进来。

    接下来,我们系统介绍下,集成内置包的一些特性。

    语义版本设置

    Xmake 的依赖包管理是完全支持语义版本选择的,例如:"~1.6.1",对于语义版本的具体描述见:https://semver.org/

    比如下面一些语义版本写法:

    add_requires("tbox 1.6.*", "pcre 1.3.x", "libpng ^1.18")
    add_requires("libpng ~1.16", "zlib 1.1.2 || >=1.2.11 <1.3.0")
    

    当然,如果我们对当前的依赖包的版本没有特殊要求,那么可以直接这么写:

    add_requires("tbox", "libpng", "zlib")
    

    这会使用已知的最新版本包,或者是 master 分支的源码编译的包,如果当前包有 git repo 地址,我们也能指定特定分支版本:

    add_requires("tbox master")
    add_requires("tbox dev")
    

    Xmake 的语义版本支持,在几年前就已经很好的支持,而 vcpkg 也仅仅在最近一年才通过清单模式勉强支持它。

    即使现在,vcpkg 对版本语义的支持也很受限,只能支持 >=1.0, 1.0 等几种版本模式,想要选择任意版本的包,比如 >=1.0 <1.5 等复杂版本条件的包,vcpkg 还是无法支持。

    可选包设置

    如果指定的依赖包当前平台不支持,或者编译安装失败了,那么 Xmake 会编译报错,这对于有些必须要依赖某些包才能工作的项目,这是合理的。 但是如果有些包是可选的依赖,即使没有也可以正常编译使用的话,可以设置为可选包:

    add_requires("tbox", {optional = true})
    

    使用系统库

    默认的设置,Xmake 会去优先检测系统库是否存在(如果没设置版本要求),如果用户完全不想使用系统库以及第三方包管理提供的库,那么可以设置:

    add_requires("tbox", {system = false})
    

    而如果配置成:

    add_requires("tbox", {system = true})
    

    就是仅仅查找使用系统库,不会去远程下载安装它,这类似于 CMake 的 find_package ,但是集成方式更加简单一致。

    使用调试版本的包

    如果我们想同时源码调试依赖包,那么可以设置为使用 debug 版本的包(当然前提是这个包支持 debug 编译):

    add_requires("tbox", {debug = true})
    

    启用包的可选特性

    我们也可以安装带有指定特性的包,比如安装开启了 zlib 和 libx265 的 ffmpeg 包。

    add_requires("ffmpeg", {configs = {zlib = true, libx265 = true}})
    

    传递额外的编译选项

    我们也可以传递额外的编译选项给包:

    add_requires("spdlog", {configs = {cxflags = "-Dxxx"}})
    

    独立的包管理命令 Xrepo

    Xrepo 是一个基于 Xmake 的跨平台 C/C++ 包管理器。

    它是一个独立于 Xmake 的命令程序,用于辅助用户去管理依赖包,类似 vcpkg/conan ,但相比它们,有额外多了一些实用的特性,我们会简单介绍一些。

    多仓库管理

    除了可以直接从官方仓库:xmake-repo 检索安装包之外, 我们还可以添加任意多个自建的仓库,甚至可以完全隔离外网,仅仅在公司内部网络维护私有包的安装集成。

    只需要通过下面的命令,添加上自己的仓库地址:

    $ xrepo add-repo myrepo https://github.com/mygroup/myrepo
    

    基本使用

    $ xrepo install zlib tbox
    

    安装指定版本包

    完整支持 Semantic Versioning (语义版本)。

    $ xrepo install "zlib 1.2.x"
    $ xrepo install "zlib >=1.2.0"
    

    安装指定平台包

    $ xrepo install -p iphoneos -a arm64 zlib
    $ xrepo install -p android [--ndk=/xxx] zlib
    $ xrepo install -p mingw [--mingw=/xxx] zlib
    $ xrepo install -p cross --sdk=/xxx/arm-linux-musleabi-cross zlib
    

    安装调试版本包

    $ xrepo install -m debug zlib
    

    安装动态库版本包

    $ xrepo install -k shared zlib
    

    安装指定配置包

    $ xrepo install -f "vs_runtime=MD" zlib
    $ xrepo install -f "regex=true,thread=true" boost
    

    安装第三方包管理器的包

    $ xrepo install brew::zlib
    $ xrepo install vcpkg::zlib
    $ xrepo install conan::zlib/1.2.11
    

    查看包的库使用信息

    $ xrepo fetch pcre2
    {
      {
        linkdirs = {
          "/usr/local/Cellar/pcre2/10.33/lib"
        },
        links = {
          "pcre2-8"
        },
        defines = {
          "PCRE2_CODE_UNIT_WIDTH=8"
        },
        includedirs = "/usr/local/Cellar/pcre2/10.33/include"
      }
    }
    
    $ xrepo fetch --ldflags openssl
    -L/Users/ruki/.xmake/packages/o/openssl/1.1.1/d639b7d6e3244216b403b39df5101abf/lib -lcrypto -lssl
    
    $ xrepo fetch --cflags openssl
    -I/Users/ruki/.xmake/packages/o/openssl/1.1.1/d639b7d6e3244216b403b39df5101abf/include
    
    $ xrepo fetch -p [iphoneos|android] --cflags "zlib 1.2.x"
    -I/Users/ruki/.xmake/packages/z/zlib/1.2.11/df72d410e7e14391b1a4375d868a240c/include
    
    $ xrepo fetch --cflags --ldflags conan::zlib/1.2.11
    -I/Users/ruki/.conan/data/zlib/1.2.11/_/_/package/f74366f76f700cc6e991285892ad7a23c30e6d47/include -L/Users/ruki/.conan/data/zlib/1.2.11/_/_/package/f74366f76f700cc6e991285892ad7a23c30e6d47/lib -lz
    

    导入导出安装后的包

    xrepo 可以快速导出已经安装后的包,包括对应的库文件,头文件等等。

    $ xrepo export -o /tmp/output zlib
    

    也可以在其他机器上导入之前导出的安装包,实现包的迁移。

    $ xrepo import -i /xxx/packagedir zlib
    

    搜索支持的包

    $ xrepo search zlib "pcr*"
        zlib:
          -> zlib: A Massively Spiffy Yet Delicately Unobtrusive Compression Library (in xmake-repo)
        pcr*:
          -> pcre2: A Perl Compatible Regular Expressions Library (in xmake-repo)
          -> pcre: A Perl Compatible Regular Expressions Library (in xmake-repo)
    

    另外,现在还可以从 vcpkg, conan, conda 以及 apt 等第三方包管理器中搜索它们的包,只需要加上对应的包命名空间就行,例如:

    $ xrepo search vcpkg::pcre
    The package names:
        vcpkg::pcre:
          -> vcpkg::pcre-8.44#8: Perl Compatible Regular Expressions
          -> vcpkg::pcre2-10.35#2: PCRE2 is a re-working of the original Perl Compatible Regular Expressions library
    
    $ xrepo search conan::openssl
    The package names:
        conan::openssl:
          -> conan::openssl/1.1.1g:
          -> conan::openssl/1.1.1h:
    

    包虚拟环境管理

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

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

    在 Xmake 中集成第三方构建系统

    在 Xmake 中集成 Cmake 项目

    Xmake 并不打算分裂 C/C++ 生态,它能很好和兼容复用现有 cmake/autoconf/meson 维护的项目,比如可以将一些其他使用 CMake 维护的代码库,直接本地集成进来,参与混合编译。

    也就是说,Xmake 不会强制用户将所有的项目重新 port 到 xmake.lua ,现有的 CMake 项目,一样可以快速集成到 Xmake 项目中去。

    例如,我们有如下项目结构:

    ├── foo
    │   ├── CMakeLists.txt
    │   └── src
    │       ├── foo.c
    │       └── foo.h
    ├── src
    │   └── main.c
    ├── test.lua
    └── xmake.lua
    

    foo 目录下是一个使用 CMake 维护的静态库,而根目录下使用了 Xmake 来维护,我们可以在 xmake.lua 中通过定义 package("foo") 包来描述如何构建 foo 代码库。

    add_rules("mode.debug", "mode.release")
    
    package("foo")
        add_deps("cmake")
        set_sourcedir(path.join(os.scriptdir(), "foo"))
        on_install(function (package)
            local configs = {}
            table.insert(configs, "-DCMAKE_BUILD_TYPE=" .. (package:debug() and "Debug" or "Release"))
            table.insert(configs, "-DBUILD_SHARED_LIBS=" .. (package:config("shared") and "ON" or "OFF"))
            import("package.tools.cmake").install(package, configs)
        end)
        on_test(function (package)
            assert(package:has_cfuncs("add", {includes = "foo.h"}))
        end)
    package_end()
    
    add_requires("foo")
    
    target("demo")
        set_kind("binary")
        add_files("src/main.c")
        add_packages("foo")
    

    其中,我们通过 set_sourcedir() 来设置 foo 包的代码目录位置,然后通过 import 导入 package.tools.cmake 辅助模块来调用 cmake 构建代码,xmake 会自动获取生成的 libfoo.a 和对应的头文件。

    !> 如果仅仅本地源码集成,我们不需要额外设置 add_urlsadd_versions

    关于包的配置描述,详情见:包描述说明

    定义完包后,我们就可以通过 add_requires("foo")add_packages("foo") 来集成使用它了,就跟集成远程包一样的使用方式。

    另外,on_test 是可选的,如果想要严格检测包的编译安装是否成功,可以在里面做一些测试。

    完整例子见:Library with CMakeLists

    在 Xmake 中集成 Meson 项目

    Xmake 支持集成更多其他构建系统维护的第三方源码库,比如 Meson ,仅仅只需要导入使用 package.tools.meson 辅助构建模块调用 meson 来构建它们。

    例如,我们从 xmake-repo 仓库中挑选一个使用 meson 构建的包作为例子:

    package("harfbuzz")
        set_sourcedir(path.join(os.scriptdir(), "3rd/harfbuzz"))
        add_deps("meson")
        on_install(function (package)
            local configs = {"-Dtests=disabled", "-Ddocs=disabled", "-Dbenchmark=disabled", "-Dcairo=disabled", "-Dfontconfig=disabled", "-Dglib=disabled", "-Dgobject=disabled"}
            table.insert(configs, "-Ddefault_library=" .. (package:config("shared") and "shared" or "static"))
            import("package.tools.meson").install(package, configs)
        end)
    

    在 Xmake 中集成 Autoconf 项目

    我们也可以使用 package.tools.autoconf 来本地集成带有 autoconf 维护的第三方代码库。

    package("libev")
        set_sourcedir(path.join(os.scriptdir(), "3rd/libev"))
        on_install(function (package)
            import("package.tools.autoconf").install(package)
        end)
    

    package.tools.autoconfpackage.tools.cmake 模块都是可以支持 mingw/cross/iphoneos/android 等交叉编译平台和工具链的,xmake 会自动传递对应的工具链进去,用户不需要做任何其他事情。

    在 Xmake 中集成 Gn 项目

    我们也可以使用 package.tools.gn 来本地集成带有 GN 维护的第三方代码库。

    package("skia")
        set_sourcedir(path.join(os.scriptdir(), "3rd/skia"))
        add_deps("gn", "ninja")
        on_install(function (package)
            import("package.tools.gn").install(package)
        end)
    

    这里有完整的脚本例子:Skia with GN

    在 Xmake 中查找使用 CMake/C++ 包

    现在 CMake 已经是事实上的标准,所以 CMake 提供的 find_package 已经可以查找大量的系统库和模块,我们也可以完全复用 CMake 的这部分生态来扩充 xmake 对包的集成。

    只需要像集成 vcpkg/conan 包那样,将包命名空间改成 cmake:: 就可以了。

    add_requires("cmake::ZLIB", {alias = "zlib", system = true})
    target("test")
        set_kind("binary")
        add_files("src/*.c")
        add_packages("zlib")
    

    我们指定 system = true 告诉 xmake 强制从系统中调用 cmake 查找包,如果找不到,不再走安装逻辑,因为 cmake 没有提供类似 vcpkg/conan 等包管理器的安装功能,只提供了包查找特性。

    指定版本

    add_requires("cmake::OpenCV 4.1.1", {system = true})
    

    指定组件

    add_requires("cmake::Boost", {system = true, configs = {components = {"regex", "system"}})}
    

    预设开关

    add_requires("cmake::Boost", {system = true, configs = {components = {"regex", "system"},
                                                 presets = {Boost_USE_STATIC_LIB = true}}})
    

    相当于内部调用 find_package 查找包之前,在 CMakeLists.txt 中预定义一些配置,控制 find_package 的查找策略和状态。

    set(Boost_USE_STATIC_LIB ON) -- will be used in FindBoost.cmake
    find_package(Boost REQUIRED COMPONENTS regex system)
    

    设置环境变量

    add_requires("cmake::OpenCV", {system = true, configs = {envs = {CMAKE_PREFIX_PATH = "xxx"}}})
    

    指定自定义 FindFoo.cmake 模块脚本目录

    mydir/cmake_modules/FindFoo.cmake

    add_requires("cmake::Foo", {system = true, configs = {moduledirs = "mydir/cmake_modules"}})
    

    在 Cmake 中集成 Xrepo 依赖包

    除了可以在 Xmake 中集成 CMake 项目,我们也可以在 CMake 中直接集成 Xmake/Xrepo 提供的包,只需要使用 xrepo-cmake 提供的 CMake Wrapper 。

    例如:

    cmake_minimum_required(VERSION 3.13.0)
    project(foo)
    
    # Download xrepo.cmake if not exists in build directory.
    if(NOT EXISTS "${CMAKE_BINARY_DIR}/xrepo.cmake")
        message(STATUS "Downloading xrepo.cmake from https://github.com/xmake-io/xrepo-cmake/")
        # mirror https://cdn.jsdelivr.net/gh/xmake-io/[email protected]/xrepo.cmake
        file(DOWNLOAD "https://raw.githubusercontent.com/xmake-io/xrepo-cmake/main/xrepo.cmake"
                      "${CMAKE_BINARY_DIR}/xrepo.cmake"
                      TLS_VERIFY ON)
    endif()
    
    # Include xrepo.cmake so we can use xrepo_package function.
    include(${CMAKE_BINARY_DIR}/xrepo.cmake)
    
    xrepo_package("zlib")
    
    add_executable(example-bin "")
    target_sources(example-bin PRIVATE
        src/main.cpp
    )
    xrepo_target_packages(example-bin zlib)
    

    添加带有配置的包

    我们,也可以跟在 Xmake 中一样,定制包的可选特性。

    xrepo_package("gflags 2.2.2" CONFIGS "shared=true,mt=true")
    
    add_executable(example-bin "")
    target_sources(example-bin PRIVATE
        src/main.cpp
    )
    xrepo_target_packages(example-bin gflags)
    

    使用来自第三个存储库的包

    除了从 Xmake 官方维护的存储库安装软件包之外,我们也可以直接在 CMake 中使用它来安装来自第三方仓库的包,只需将仓库名称添加为命名空间即可。

    例如:vcpkg::zlib, conan::pcre2

    xrepo_package("conan::gflags/2.2.2")
    xrepo_package("conda::gflags 2.2.2")
    xrepo_package("vcpkg::gflags")
    xrepo_package("brew::gflags")
    

    通过这种方式,我们将在 CMake 中集成使用 vcpkg/conan 包的方式进行了统一,并且额外提供了自动包安装特性,以及对 homebrew/conda 等其他包仓库的支持。

    15 条回复    2022-03-13 22:17:59 +08:00
    ccppgo
        1
    ccppgo  
       150 天前
    支持
    neilp
        2
    neilp  
       150 天前
    必须支持.
    loadxtp
        3
    loadxtp  
       150 天前
    支持,比 cmake 写起来舒服多了。
    natsji
        4
    natsji  
       150 天前 via Android
    一直在用 xmake 顶一下
    ashong
        5
    ashong  
       150 天前
    很好, 就是社区太小。 官方应该多弄些实例补充文档的不足
    stimw
        7
    stimw  
       150 天前
    b 站和 b 乎都看到过,github 也 star 了,但一直没动力去用
    redsun368573607
        8
    redsun368573607  
       150 天前
    支持
    DinoStray
        9
    DinoStray  
       150 天前
    支持 Clion 的么
    szzhiyang
        10
    szzhiyang  
       150 天前
    道阻且长。
    Origami404
        11
    Origami404  
       150 天前 via Android
    支持! xmake 对我写的小型开发项目来说非常好用,期待生态起来的一天
    nightwitch
        12
    nightwitch  
       150 天前
    已 sponser
    waruqi
        13
    waruqi  
    OP
       150 天前
    @DinoStray 有插件 支持 idea/clion https://github.com/xmake-io/xmake-idea

    也有相关 clion 下的插件使用视频 https://www.bilibili.com/video/BV1Xb4y147z5/
    waruqi
        14
    waruqi  
    OP
       150 天前
    sadhen
        15
    sadhen  
       150 天前
    赞,我这边用 Qt ,后面评估一下,考虑把我的 C++开源项目从 CMake 迁移到 Xmake
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1497 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 17:32 · PVG 01:32 · LAX 10:32 · JFK 13:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.