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

精通xmake

郑俊弼
2023-12-01

01
下载发布版
xmake update来自动更新.
02创建和编译工程
xmake create创建各语言的空工程.
默认为C++,生成

add_rules("mode.debug", "mode.release") 
//可选,两种构建模式
target("test") 
//子工程模块
    set_kind("binary") 
//exe
    add_files("src/*.cpp")

默认用发布模式,切换模式:

$ xmake f -m debug
$ xmake
//f表明是配置.

xmake --help有更多简写.
xmake create --help,有各种类型工程.如c++(默认),-l设置语言.有go/rust/dlang/....
-t来指定模板类型.
如,基于C的静态库

xmake create -l c -t static test

基于qt:

xmake create -l c++ -t qt.quickapp test
...

重点在c/c++语言.

运行目标

$ xmake run

add_runenvs来设置目标环境变量.

target("test")
    set_kind("binary")
    add_files("src/*.c")
    add_runenvs("PATH", "/tmp/bin", "xxx/bin")
    add_runenvs("LD_LIBRARY_PATH", "/tmp/lib", "xxx/lib")
//支持多个值.

on_run自动运行脚本,
xmake run -d调试程序.

常用设置

target("demo", {kind = "binary", files = "src/*.c"})

一行编译src下面所有c文件.生成demo.上面为精简写法.更推荐这样:

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

set_kind(),设置binary,static,shared,为静态/动态/二进制.
加宏(add_defines())等价于-DXXX.
is_plat()判断平台.
多个目标,是单独的.
全局设置,放在最外面.

-- 全局设置
add_defines("TEST")
//加宏
if is_arch("arm64", "armv7") then
    add_defines("ARM")
end

可用target_end()强制结束target子域,切回全局域.
add_cflags(仅c), add_cxflags(c/c++), add_cxxflags(c++)来设置编译选项.由用户判断编译平台.如

add_cflags("-g", "-O2", "-DDEBUG")
if is_plat("windows") then
    add_cflags("/MT")
end

gcc定义为标准,不兼容时,自动转换,无匹配值时,忽略.
禁用标志.

add_cflags("-g", "-O2", {force = true})
//强制,为强制传入参数.

xmake -v查看编译细节.

添加库目录

target("test")
    set_kind("binary")
    add_includedirs("/usr/local/include")
    add_links("pthread")
    add_linkdirs("/usr/local/lib")
//头目录,库名,库目录.

add_syslinks()为系统链接库.add_links()为非系统.

target("test") 
    set_kind("binary") 
    add_links("A", "B") 
    add_syslinks("pthread")

转成了-lA -lB -lpthread这样.系统放最后.
设置语言标准:set_languages("c99", "c++11").

内置优化

编译优化配置:none,fast,faster,fastest,smallest,aggressive

set_optimize("fastest")

xmake内部映射了.所以很方便并跨平台.
不同编译模式,要加判断:

if is_mode("debug") then
    set_symbols("debug")
    set_optimize("none")
end
if is_mode("release") then
    set_symbols("hidden")
    set_strip("all")
    if is_plat("iphoneos", "android") then
        set_optimize("smallest")
    else
        set_optimize("fastest")
    end
end

太麻烦,因而用内置规则来简化设置.

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

可定制:

add_rules("mode.release", "mode.debug") 
if is_mode("release") then 
    set_optimize("fastest") 
end

切换到调试模式:

xmake f -m debug; xmake

加源文件

add_files()

加各类源文件:C/Cpp/d/.....obj, .a/.lib也可以,如.

add_files("src/test_*.c") 
add_files("src/xxx/**.cpp") 
add_files("src/asm/*.S", "src/objc/**/hello.m")

*单级,**多级目录.还可过滤.

add_files("src/**.c|impl/*.c")
//不包括impl目录下面.
add_files("src/*.cpp|test.cpp|hello.cpp|xx_*.cpp")
//后面都是排除

更细控制

target("test")
    add_defines("TEST1")
    add_files("src/*.c")
    add_files("test/*.c", "test2/test2.c", {defines = "TEST2", languages = "c99", includedirs = ".", cflags = "-O0"})

add_files最后参数,传入配置,来控制指定文件编译选项.

target("test") 
    -- ... 
    add_files("src/test/*.md", {rule = "markdown"})
//对指定文件添加规则.

强制:

add_files("src/*.c", {force = {cxflags = "-DTEST", mflags = "-framework xxx"}})

同样来删文件:

target("test") 
    add_files("src/*.c") 
    del_files("src/test.c")
//与|效果一样.

这样:

target("test") 
    add_files("src/**.c") 
    del_files("src/test*.c") 
    del_files("src/subdir/*.c|xxx.c") 
//xxx.c,双重否定下,表示保留.
    if is_plat("iphoneos") then 
        add_files("xxx.m") 
    end

安卓平台
ndk目录:

xmake f -p android --ndk=~/downloads/android-ndk-r19c $ xmake
//传入

-p android切换到安卓.可编译安卓本地.支持binary,static,shared
xmake f/config仅针对当前项目.
设置全局用:

$ xmake g --ndk=~/xxx/android-ndk-r19c
//ANDROID_NDK_HOME=
$ xmake f -p android --ndk=xxx --ndk_sdkver=16
//api版本
$ xmake f -p android --ndk=xxx -a arm64-v8a
//改架构

架构有:armv7-a,arm64-v8a,armv5te,mips,mips64,i386,x86_64
is_plat("android")来判断安卓.

target("test") 
    set_kind("shared") 
    add_files("src/*.c") 
    if is_plat("android") then 
        add_defines("ANDROID") 
        add_syslinks("log") 
    end

开发qt

$ xmake f --qt=/home/xxx/qtsdk
//手动配置
$ xmake g --qt=/home/xxx/qtsdk
//搞成全局
$ xmake create -t qt.quickapp test
//qt快速

生成

target("test")
    add_rules("qt.quickapp")
//用此内建规则,加上`链接/标志/包含目录`等
    add_headerfiles("src/*.h")
    add_files("src/*.cpp") 
    add_files("src/qml.qrc")
//
$ xmake run
//运行

qt.quickapp中维护*.qrc规则.

$ xmake create -t qt.widgetapp test
//创建项目.生成
target("qt_widgetapp")
    add_rules("qt.widgetapp")
    add_files("src/*.cpp") 
    add_files("src/mainwindow.ui")
    add_files("src/mainwindow.h")  
 -- 添加带有`Q_OBJECT`的`meta`头文件
//静态版本
$ xmake create -t qt.widgetapp_static test
--变成 add_rules("qt.widgetapp_static")

还有:

-qt.console:c++
-qt.quickapp:c++
-qt.quickapp_static:c++
-qt.shared:c++
-qt.static:c++
-qt.widgetapp:c++
-qt.widgetapp_static:c++

还要设置--android_sdk位置.

$ xmake install
//安装qtapk至设备

-m/--mode=来切换模式.加载目标时,判断

xmake f --mode=xxx

设置,用is_mode()来判断.debug则禁用优化启用符号,而release启用优化,禁用符号.
还可定制:

if is_mode("release") then
    set_symbols("debug")
end
//或额外增加编译标志:
if is_mode("release") then
    add_cflags("-fomit-frame-pointer")
end

用户配置优先.也可用户全自定义:

-- 如果当前编译模式是debug
if is_mode("debug") then

    -- 添加DEBUG编译宏
    add_defines("DEBUG")

    -- 启用调试符号
    set_symbols("debug")

    -- 禁用优化
    set_optimize("none")
end

-- 如果是release或者profile模式
if is_mode("release", "profile") then
    -- 如果是release模式
    if is_mode("release") then
        -- 隐藏符号
        set_symbols("hidden")
        -- strip所有符号
        set_strip("all")
        -- 忽略帧指针
        add_cxflags("-fomit-frame-pointer")
        add_mxflags("-fomit-frame-pointer")

    -- 如果是profile模式
    else
        -- 启用调试符号
        set_symbols("debug")
    end

    -- 添加扩展指令集
    add_vectorexts("sse2", "sse3", "ssse3", "mmx")
end

内部:

add_rules("mode.debug")
//==
if is_mode("debug") then
    set_symbols("debug")
    set_optimize("none")
end
//而
add_rules("mode.release")
//==
if is_mode("release") then
    set_symbols("hidden")
    set_optimize("fastest")
    set_strip("all")
end
//用于检查内存
add_rules("mode.check")
//==
if is_mode("check") then
    set_symbols("debug")
    set_optimize("none")
    add_cxflags("-fsanitize=address", "-ftrapv")
    add_mxflags("-fsanitize=address", "-ftrapv")
    add_ldflags("-fsanitize=address")
end
//
add_rules("mode.profile")
//==
//用于分析性能
if is_mode("profile") then
    set_symbols("debug")
    add_cxflags("-pg")
    add_ldflags("-pg")
end
//分析覆盖
add_rules("mode.coverage")
//===
if is_mode("coverage") then
    add_cxflags("--coverage")
    add_mxflags("--coverage")
    add_ldflags("--coverage")
end

$(mode)为变量,根据不同模式启用:

target("test")
    set_kind("binary")
    add_files("src/*.c")
    add_links("xxx_$(mode)")
//加链接库
target("test")
    set_kind("binary")
    add_files("src/*.c")
    add_linkdirs("lib/$(mode)")
//搜索路径
    add_links("xxx")

get_config("mode")得到模式的值.
自定义,也有效:

on_load(function (target)
    if is_mode("release") then
        print(get_config("mode"), "$(mode)")
    end
end)
 类似资料: