当前位置: 首页 > 工具软件 > XMake > 使用案例 >

xmake更新1

蒲昊苍
2023-12-01

v2.3.1

1,无缝交叉编译.
2,用xmake project -k ninja生成ninja构建配置.
添加socket,pipe模块,改进process模块.重构进程调度器,并行调度构建.重构协程模块,准备远程分布式编译.
生成后,用$ ninja构建.
xmake.lua,可调用其他构建工具来完成编译.
只管xmake就行,对接xmake config的配置环境,复用xmake的平台探测和sdk环境检测,简化平台配置
目前支持autotools xcodebuild cmake make msbuild scons meson bazel ndkbuild ninja.
可对接xmake clean, xmake --rebuild和xmake config命令.

$ xmake clean 
$ xmake clean --all
//可清理第3方
$ xmake --rebuild
//强制构建

可试构建

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

快速交叉编译

$ xmake f -p android --trybuild=autotools [--ndk=xxx] 
$ xmake
//
$ xmake f -p iphoneos --trybuild=autotools 
$ xmake
//
$ xmake f -p mingw --trybuild=autotools [--mingw=xxx] 
$ xmake
//
$ xmake f -p cross --trybuild=autotools --sdk=/xxxx 
$ xmake
//交叉编译工具链.

ANDROID_NDK_HOME环境变量.
--tryconfigs=传递用户配置.

$ xmake f --trybuild=autotools --tryconfigs="--enable-shared=no" 
//禁用动态编译
$ xmake

xmake config --cflags=可透传,--cflags,--includedirs--ldflags同样如此

$ xmake f --trybuild=[autotools|cmake|meson|ninja|bazel|make|msbuild|xcodebuild] 
//用其他工具编译.
$ xmake
//
$ xmake f -p android --trybuild=ndkbuild [--ndk=] 
$ xmake
//

命令风格:

$ xmake -j8 -rvD
//替代
$ xmake -j 8 -r -v -D

C++编译C.

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

v2.3.2

加速构建.多目标同时构建.并行链接无依赖目标,细粒化调度.

v2.3.4

解耦平台与工具链,

$ xmake f -p windows --toolchain=clang
//不仅仅是
xmake f -p windows
//原来的默认用msvc

内置了常用工具链,避免交叉编译工具链复杂配置过程,只需传递工具链名到--toolchain=xxx即可.

$ xmake f -p cross --toolchain=llvm --sdk="C:\Program Files\LLVM" 
$ xmake
//用llvm

内置工具链,只需要设置--toolchain=--sdk=.
显示支持的工具链

$ xmake show -l toolchains

同步切换工具链:

$ xmake f --toolchain=clang 
$ xmake

一个切换,一堆工具都切换了.

$ xmake f --toolchain=gcc 
$ xmake
//切换回来.

自定义工具链

toolchain("myclang")
    set_kind("standalone")
    set_toolset("cc", "clang")
    set_toolset("cxx", "clang", "clang++")
    set_toolset("ld", "clang++", "clang")
    set_toolset("sh", "clang++", "clang")
    set_toolset("ar", "ar")
    set_toolset("ex", "ar")
    set_toolset("strip", "strip")
    set_toolset("mm", "clang")
    set_toolset("mxx", "clang", "clang++")
    set_toolset("as", "clang")

    -- ...

xmake f --sdk=xx探测工具.
还可针对,特定项目切换工具链.

target("test")
    set_kind("binary")
    add_files("src/*.c")
    set_toolchains("clang", "yasm")
//完整切换.

设置主题:

$ xmake g --theme=ninja

构建策略

set_policy("check.auto_ignore_flags", false)
target("test") 
    set_policy("check.auto_ignore_flags", false)
//局部目标也可以

列举当前策略配置:

$ xmake l core.project.policy.policies

默认,检测所有add_cxflags, add_ldflags标志,但有时不需要.
set_policy目标/项目直接禁用默认自动检测行为.

set_policy("check.auto_ignore_flags", false) 
target("test") 
    add_ldflags("-static")

check.auto_map_flags自动映射,可能用户需要原始配置.
set_policy("check.auto_map_flags", false)来取消映射.

set_policy("build.across_targets_in_parallel", false)
//禁用并行构建

新增编译模式

add_rules("mode.releasedbg")
//==
if is_mode("releasedbg") then 
    set_symbols("debug") 
    set_optimize("fastest") 
    set_strip("all")
end

最小大小

add_rules("mode.minsizerel")
//==
if is_mode("minsizerel") then 
    set_symbols("hidden") 
    set_optimize("smallest")
    set_strip("all") 
end

显示:

$ xmake show
//显示自身信息
$ xmake show -l toolchains
//显示工具链
$ xmake show --target=tbox
//显示目标配置
$ xmake show -l modes
//内置编译模式列表
$ xmake show -l rules
//内置编译规则列表
$ xmake show --help
//显示显示帮助

xmake f --menu来可视化配置.

target("buildvm")
    set_kind("binary")
    add_files("src/*.c")
    set_toolchains("xcode", {plat = os.host(), arch = os.arch()})
//特定目标工具链

target("luajit")
    set_kind("static")
    add_deps("buildvm")
    add_files("src/*.c")
//其他主机.

针对不同平台,自动选用当前平台可用主机工具链.

target("buildvm")
    set_kind("binary")
    add_files("src/*.c")
    set_plat(os.host())
    set_host(os.arch())
//自动设置,而非手动.
//直接设置特定`target`到主机平台,可内部自动选择`host`工具链了

target("luajit")
    set_kind("static")
    add_deps("buildvm")
    add_files("src/*.c")

下载

$ xmake g --pkg_searchdirs="/download/packages"
//设置下载搜索目录.
$ xmake require --info zlib 
-> searchdirs: /download/packages 
-> searchnames: zlib-1.2.11.tar.gz
//搜索包名.

默认,msvc/GL最小目标.

xmake show -l envs
//显示内置环境变量
add_files("src/*.c", {rules = {"xx", override = true}})
//重写内建规则.

内置tinyc编译器,有winapi,可开始写c程序.

xmake f --toolchain=[tinyc|emscripten] xmake
//避免安装VS

trybuild迅速编译autotools/cmake维护项目.
可快速对接android/ios/mingw等交叉编译环境.

xmake f -p cross --sdk=/xxx

更多通用交叉工具链.
检测到autotools,自动调用./configure; make来编译.
cmake,则调用cmake生成makefile/build.ninja来编译.
xmake -r重新编译,xmake clean统一清理,xmake -v细节.
xmake对接cmake交叉编译

xmake f -p android --trybuild=cmake --ndk=/xxx 
xmake
//安卓
xmake f -p iphoneos --trybuild=cmake 
xmake
//ios
xmake f -p mingw --trybuild=cmake --mingw=/sdk/xxx 
xmake

--trybuild=cmake,启用cmake的尝试编译模式,用-p android/iphoneos/mingw切换到平台,对接对应工具,来实现交叉编译.
用户不必关心不同工具链的配置.还可用

xmake f -p iphoneos -a arm64 --trybuild=cmake

快速切换架构.
最好尽量用xmake.lua.xmake会更完美支持交叉编译.

xmake f -p iphoneos 
xmake
//或
xmake f -p android --ndk=/xxx
xmake

直接编译的.

对远程包支持交叉编译

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

直接,用

xmake f -p iphoneos 
xmake

切换平台.

xmake g --network=private

私有网络,不从官方包下载.

xmake require --export

递归导出第3方依赖.

v2.3.8

支持icc工具链.

$ xmake f --toolchain=icc 
$ xmake

升级luajit.

$ xmake f --toolchain=ifort 
$ xmake

intelFortran.

xmake f -p wasm

支持emcc工具链.

$ xmake create -t qt.quickapp_static quickapp
//静态链接
add_rules("mode.debug", "mode.release")
includes("qt_add_static_plugins.lua")
//配置必须插件.

target("demo")
    add_rules("qt.quickapp_static")
//启用编译规则.
    add_headerfiles("src/*.h")
    add_files("src/*.cpp")
    add_files("src/qml.qrc")
    add_frameworks("QtQuickControls2", "QtQuickTemplates2")
    qt_add_static_plugins("QtQuick2Plugin", {linkdirs = "qml/QtQuick.2", links = "qtquick2plugin"})
    qt_add_static_plugins("QtQuick2WindowPlugin", {linkdirs = "qml/QtQuick/Window.2", links = "windowplugin"})
    qt_add_static_plugins("QtQuickControls2Plugin", {linkdirs = "qml/QtQuick/Controls.2", links = "qtquickcontrols2plugin"})
    qt_add_static_plugins("QtQuickTemplates2Plugin", {linkdirs = "qml/QtQuick/Templates.2", links = "qtquicktemplates2plugin"})
//编译
$ xmake f -p wasm [--qt=~/Qt]
$ xmake

设置平台,指定qt根目录.打开,即可运行.
set_fpmodels()设置浮点编译模式,级别有fast, strict, except, precise.

set_fpmodels("fast")
set_fpmodels("strict")
set_fpmodels("fast", "except")
set_fpmodels("precise") -- defaul

启用openmp

add_requires("libomp", {optional = true})
//加依赖
target("loop")
    set_kind("binary")
    add_files("src/*.cpp")
    add_rules("c++.openmp")
//加规则.
//或add_rules("c.openmp")
    add_packages("libomp")

如果c/C++混合编译,则要加两个规则.

set_languages("c17")
//置语言

不同架构

$ xmake f -p mingw -a arm64 
$ xmake

快速集成,linux, macOS, windows, mingw, bsd, msys, iphoneos, android八大平台.
跨平台集成C/C++远程依赖库

add_requires("tbox >1.6.1", "libuv master", "vcpkg::ffmpeg", "brew::pcre2/libpcre2-8")
add_requires("conan::openssl/1.1.1g", {alias = "openssl", optional = true, debug = true})
target("test")
    set_kind("binary")
    add_files("src/*.c")
    add_packages("tbox", "libuv", "vcpkg::ffmpeg", "brew::pcre2/libpcre2-8", "openssl")

集成了vcpkg::,brew::conan::等空间,
加了Zig空工程模板

xrepo

$ xrepo install zlib tbox
//安装包.
$ 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 install pacman:libpng 
$ xrepo install dub:log
//第三方包
$ xrepo fetch pcre2
//查找包信息
$ xrepo fetch --ldflags openssl
$ xrepo fetch --cflags openssl
//
$ xrepo export -o /tmp/output zlib
//导出安装包(库/头文件)
$ xrepo import -i /xxx/packagedir zlib
//导入
$ xrepo search vcpkg::pcre
//搜索第3方包
$ xrepo env --show luajit
//查看包环境
$ xrepo env luajit
//加载包环境并运行
$ xrepo env -b "luajit 2.x" luajit 
$ xrepo env -p iphoneos -b "zlib,libpng,luajit 2.x" cmake ..
$ xrepo info zlib
//查看包信息
$ xrepo remove --all
$ xrepo remove --all zlib pcr*
//卸载

包支持交叉编译

add_requires("zlib", "openssl") 
target("test") 
    set_kind("binary")
    add_files("src/*.c")
    add_packages("zlib", "openssl")
//依赖包.
$ xmake f -p cross --sdk=/tmp/arm-linux-musleabi-cross
//切换平台.

自动拉取,然后用arm-linux-musleabi-cross编译安装,自动集成.

$ xrepo search -p cross zli*

模糊查询.set_license设置目标的许可.
支持pacman集成,

add_requires("libcurl 7.73.0", {verify = false})
//取消验证sha256

增强交叉编译

toolchain("my_toolchain")
    set_kind("standalone")
//独立
    set_sdkdir("/tmp/arm-linux-musleabi-cross")
//sdk目录
toolchain_end()

target("hello")
    set_kind("binary")
    add_files("apps/hello/*.c")

就可手动--toolchain=my_toolchain来切换到此工具链.

toolchain("my_toolchain")
    set_kind("standalone")
    set_sdkdir("/tmp/arm-linux-musleabi-cross")
toolchain_end()

target("hello")
    set_kind("binary")
    add_files("apps/hello/*.c")
    set_toolchains("my_toolchain")
//绑定工具链.

嵌入式开发来讲尤其有用,因为嵌入式平台的交叉编译工具链非常多,经常需要切换来完成不同平台的编译.

includes("toolchains/*.lua")
//工具链们
target("hello")
    set_kind("binary")
    add_files("apps/hello/*.c")
    if is_plat("myplat1") then
        set_toolchains("my_toolchain1")
//根据不同平台,设置工具链.
    elseif is_plat("myplat2") then
        set_toolchains("my_toolchain2")
    end

快速切换

xmake f -p myplat1
xmake

更复杂的,用set_toolset,set_crossset_bindir

toolchain("my_toolchain")
    set_kind("standalone")
    set_sdkdir("/tmp/arm-linux-musleabi-cross")
    on_load(function (toolchain)
        -- 对架构,加工具链.
        if toolchain:is_arch("arm") then
            toolchain:add("cxflags", "-march=armv7-a", "-msoft-float", {force = true})
            toolchain:add("ldflags", "-march=armv7-a", "-msoft-float", {force = true})
        end
        toolchain:add("ldflags", "--static", {force = true})
        toolchain:add("syslinks", "gcc", "c")
    end)

add_sysincludedirs系统头包含目录,依赖包,默认用-isystem.

v2.5.1

支持zig.
xmake f --menu图形化配置.
add_requireconfs配置子包及子依赖.

add_requires("zlib") 
add_requireconfs("zlib", {configs = {shared = true}})
//==
add_requires("zlib", {configs = {shared = true}})

多个要求时,可简化配置

add_requireconfs("*", {configs = {shared = true}})
//统一配置,
add_requires("zlib")
add_requires("pcre")
add_requires("libpng")
add_requires("libwebp")
//前面都是动态,下面为静态
add_requires("libcurl", {configs = {shared = false}})

多个配置.

add_requires("zlib 1.2.11") 
add_requireconfs("zlib", {override = true, version = "1.2.10"})
//覆盖前面的配置

add_requireconfs用来改写特定包的配置.

add_requires("libpng", {configs = {shared = true}})

libpng,用动态库,而内部zlib为静态库,要改zlib动态,则:

add_requires("libpng", {configs = {shared = true}}) 
add_requireconfs("libpng.zlib", {configs = {shared = true}})
//该项内部也是动态.
add_requires("libpng")
add_requireconfs("libpng.zlib", {version = "1.2.10"})
//还可改版本.

递归依赖:

add_requires("libwebp") 
add_requireconfs("libwebp.**|cmake", {configs = {cxflags = "-DTEST"}})

对子项目,全改配置.用|来排除,如果只*,则只是单级子项目改.
set_group来分组目标.

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

target("test1")
    set_kind("binary")
    add_files("src/*.cpp")
    set_group("group1")

target("test2")
    set_kind("binary")
    add_files("src/*.cpp")
    set_group("group1")

target("test3")
    set_kind("binary")
    add_files("src/*.cpp")
    set_group("group1/group2")
//在1组的下面的2组.

target("test4")
    set_kind("binary")
    add_files("src/*.cpp")
    set_group("group3/group4")
//在3组下面的4组.

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

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

自动更新vs工程

xmake project -k vsxmake
//麻烦了.

可用

plugin.vsxmake.autoupdate

来自动更新.

add_rules("plugin.vsxmake.autoupdate")
//文件改变,

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

winos.registry_keys/registry_values/registry_query...取注册表.

$ xmake create -l zig console
//zig空工程
target("console")
    set_kind("binary")
    add_files("src/*.zig", "src/*.c")
//混合编程

安装QT

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

target("demo")
    add_rules("qt.quickapp")
    add_headerfiles("src/*.h")
    add_files("src/*.cpp")
    add_files("src/qml.qrc")
//
$ xmake 
$ xmake install -o d:\installdir
//
$ xmake f -p android --ndk=/xxx/android-ndk-r20b --sdk=/xxx 
$ xmake
//部署打包

xmake f --vs_runtime=MTset_runtimes("MT")设置目标和.

v2.5.2

自动拉取交叉工具链和集成依赖包

clang编译

add_requires("llvm 10.x", {alias = "llvm-10"})
target("test")
    set_kind("binary")
    add_files("src/*.c")
    set_toolchains("llvm@llvm-10")

llvm@llvm-10格式为工具链名@包名(别名).

add_requires("muslcc")
//交叉编译工具链
target("test")
    set_kind("binary")
    add_files("src/*.c")
    set_toolchains("@muslcc")

或用xmake f -a arm64切换架构.

add_requires("muslcc")
add_requires("zlib", "libogg", {system = false})

set_toolchains("@muslcc")

target("test")
    set_kind("binary")
    add_files("src/*.c")
    add_packages("zlib", "libogg")

依赖,切换为@muslcc工具链,可用set_plat/set_arch来固定平台.

add_requires("muslcc")
add_requires("zlib", "libogg", {system = false})

set_plat("cross")
set_arch("arm64")
//这里.
set_toolchains("@muslcc")

target("test")
    set_kind("binary")
    add_files("src/*.c")
    add_packages("zlib", "libogg")

集成zig

add_rules("mode.debug", "mode.release")
add_requires("zig 0.7.x")

target("test")
    set_kind("binary")
    add_files("src/*.zig")
    set_toolchains("@zig")

zig cczig内置的c/c++编译器,不依赖gcc/clang/msvc,非常给力,还支持不同架构的交叉编译.

$ xmake f --toolchain=zig
$ xmake
//
$ xmake f -a arm64 --toolchain=zig
$ xmake
//不同架构
$ xmake f -p windows -a x64 --toolchain=zig 
$ xmake
//在macOS,都可编译`x64`程序

替代了mingw.

自动导出所有dll符号

target("foo")
    set_kind("shared")
    add_files("src/foo.c")
    add_rules("utils.symbols.export_all")
//加上导出符号的规则

target("test")
    set_kind("binary")
    add_deps("foo")
    add_files("src/main.c")

生成def,传给链接器.
转换mingw/.dll.amsvc/.lib.在C++/fortran混编时有用.

import("utils.platform.gnu2mslib")

gnu2mslib("xxx.lib", "xxx.dll.a")
gnu2mslib("xxx.lib", "xxx.def")
gnu2mslib("xxx.lib", "xxx.dll.a", {dllname = "xxx.dll", arch = "x64"})

def=>libdll=>def=>lib.
支持批处理.
on_buildcmd_file,on_buildcmd_files,因为工程文件不支持on_build_files脚本,

rule("foo")
    set_extensions(".xxx")
    on_buildcmd_file(function (target, batchcmds, sourcefile, opt)
        batchcmds:vrunv("gcc", {"-o", objectfile, "-c", sourcefile})
    end)

支持,批处理命令:

batchcmds:show("hello %s", "xmake")
batchcmds:vrunv("gcc", {"-o", objectfile, "-c", sourcefile}, {envs = {LD_LIBRARY_PATH="/xxx"}})
batchcmds:mkdir("/xxx") -- and cp, mv, rm, ln ..
batchcmds:compile(sourcefile_cx, objectfile, {configs = {includedirs = sourcefile_dir, languages = (sourcekind == "cxx" and "c++11")}})
batchcmds:link(objectfiles, targetfile, {configs = {linkdirs = ""}})

完整示例:

rule("lex")
    set_extensions(".l", ".ll")
    on_buildcmd_file(function (target, batchcmds, sourcefile_lex, opt)

        -- 导入
        import("lib.detect.find_tool")

        -- 取lex
        local lex = assert(find_tool("flex") or find_tool("lex"), "lex not found!")

        -- 要编译文件
        local extension = path.extension(sourcefile_lex)
        local sourcefile_cx = path.join(target:autogendir(), "rules", "lex_yacc", path.basename(sourcefile_lex) .. (extension == ".ll" and ".cpp" or ".c"))

        -- 加目标文件
        local objectfile = target:objectfile(sourcefile_cx)
        table.insert(target:objectfiles(), objectfile)

        -- 加命令
        batchcmds:show_progress(opt.progress, "${color.build.object}compiling.lex %s", sourcefile_lex)
        batchcmds:mkdir(path.directory(sourcefile_cx))
        batchcmds:vrunv(lex.program, {"-o", sourcefile_cx, sourcefile_lex})
        batchcmds:compile(sourcefile_cx, objectfile)

        -- 加依赖
        batchcmds:add_depfiles(sourcefile_lex)
        batchcmds:set_depmtime(os.mtime(objectfile))
        batchcmds:set_depcache(target:dependfile(objectfile))
    end)

新增add_extsourceson_fetch配置接口来更好查找系统库.

add_requires("libusb")
target("test")
    set_kind("binary")
    add_files("src/*.c")
    add_packages("libusb")
//仓库有,直接使用.

定制查找系统库

package("libusb")
    on_fetch("linux", function(package, opt)
//查找系统库的逻辑.
        if opt.system then
            return find_package("pkgconfig::libusb-1.0")
        end
    end)

支持清单文件

add_files("src/*.manifest")

add_packages,支持{public = true}导出给目标.

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

target("test")
    set_kind("shared")
    add_packages("pcre2", {public = true})
    add_files("src/test.cpp")

target("demo")
    add_deps("test")
//依赖
    set_kind("binary")
    add_files("src/main.cpp")  
//-- 可导出哪些配置?
//-- 默认私有,但是会导出links/linkdirs
add_packages("pcre2")

 -- 包括`includedirs,defines`等全部导出
add_packages("pcre2", {public = true})
 类似资料: