xmake从入门到精通8:切换编译模式

xmake是一个基于Lua的轻量级现代化c/c++的项目构建工具,主要特色是:语法简单易上手,提供更加可读的项目维护,实现跨平台行为一致的构建体验。android

本文咱们会详细介绍下如何在项目构建过程当中切换debug/release等经常使用构建模式,以及自定义其余编译模式。c++

调试和发布模式

一般,若是咱们是经过xmake create命令建立的项目,会在xmake.lua里面自动添加一行编译规则的配置,以下:git

add_rules("mode.release", "mode.debug")
target("hello")
    set_kind("binary")
    add_files("src/*.c")
复制代码

经过add_rules接口,咱们默认添加了release和debug两个经常使用的内置规则,它们会在编译的时候附带上对应模式相关的一些编译flags,来开启优化用于发布或者调试编译。github

若是仅仅执行了xmake命令,没有额外的配置,那么默认就会是release编译,等价于:bash

$ xmake f -m release
$ xmake
[  0%]: ccache compiling.release src/main.cpp
[100%]: linking.release test
build ok!
复制代码

若是咱们要切换到debug编译模式,只须要:iphone

$ xmake f -m debug
$ xmake
[  0%]: ccache compiling.debug src/main.cpp
[100%]: linking.debug test
build ok!
复制代码

上面的-m/--mode=参数就是用来设置编译模式,会跟mode.releasemode.debug这两个规则作关联。工具

那么,他们是如何关联上的呢?咱们能够先来看下这两个规则的内部实现:性能

rule("mode.debug")
    after_load(function (target)
        if is_mode("debug") then
            if not target:get("symbols") then
                target:set("symbols", "debug")
            end
            if not target:get("optimize") then
                target:set("optimize", "none")
            end
        end
    end)

rule("mode.release")
    after_load(function (target)
        if is_mode("release") then
            if not target:get("symbols") and target:targetkind() ~= "shared" then
                target:set("symbols", "hidden")
            end
            if not target:get("optimize") then
                if is_plat("android", "iphoneos") then
                    target:set("optimize", "smallest")
                else
                    target:set("optimize", "fastest")
                end
            end
            if not target:get("strip") then
                target:set("strip", "all")
            end
        end
    end)
复制代码

能够看到,在target被加载阶段,xmake会去判断用户对xmake f --mode=xxx的参数配置,若是经过is_mode()接口获取到是debug模式,那么会禁用相关优化而且启用符号输出。 而若是是release模式,那么会开启编译优化而且strip掉全部调试符号。优化

定制化的模式配置

固然,内置的这两规则默认设置的这些编译配置,只能知足大部分场景的常规需求,若是用户想要在不一样的编译模式下定制化一些我的的编译配置,那么须要本身在xmake.lua作判断。ui

例如,咱们想在release下也启用调试符号,那么只须要:

if is_mode("release") then
    set_symbols("debug")
end
复制代码

或者额外增长一些编译flags:

if is_mode("release") then
    add_cflags("-fomit-frame-pointer")
end
复制代码

注:若是用户本身的配置和mode.release内置的配置冲突,会优先使用用户的设置。

固然,咱们也能够彻底不去经过add_rules("mode.debug", "mode.release")添加默认的配置规则,让用户彻底本身控制模式配置:

-- 若是当前编译模式是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
复制代码

其余内置模式规则

经过上文的例子,咱们看到除了debug/release模式,还加了个profile模式的配置判断,其实xmake也提供了对应的内置模式,还有哪些,咱们具体来看下:

mode.debug

为当前工程xmake.lua添加debug编译模式的配置规则,例如:

add_rules("mode.debug")
复制代码

至关于:

if is_mode("debug") then
    set_symbols("debug")
    set_optimize("none")
end
复制代码

咱们能够经过:xmake f -m debug来切换到此编译模式。

mode.release

为当前工程xmake.lua添加release编译模式的配置规则,例如:

add_rules("mode.release")
复制代码

至关于:

if is_mode("release") then
    set_symbols("hidden")
    set_optimize("fastest")
    set_strip("all")
end
复制代码

咱们能够经过:xmake f -m release来切换到此编译模式。

mode.check

为当前工程xmake.lua添加check编译模式的配置规则,通常用于内存检测,例如:

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
复制代码

咱们能够经过:xmake f -m check来切换到此编译模式。

mode.profile

为当前工程xmake.lua添加profile编译模式的配置规则,通常用于性能分析,例如:

add_rules("mode.profile")
复制代码

至关于:

if is_mode("profile") then
    set_symbols("debug")
    add_cxflags("-pg")
    add_ldflags("-pg")
end
复制代码

咱们能够经过:xmake f -m profile来切换到此编译模式。

mode.coverage

为当前工程xmake.lua添加coverage编译模式的配置规则,通常用于覆盖分析,例如:

add_rules("mode.coverage")
复制代码

至关于:

if is_mode("coverage") then
    add_cxflags("--coverage")
    add_mxflags("--coverage")
    add_ldflags("--coverage")
end
复制代码

咱们能够经过:xmake f -m coverage来切换到此编译模式。

注:生成的gcno文件通常都是个obj所在目录对应的哦,所以须要从build目录下去找。

扩展本身的编译模式

xmake的模式配置,并无固定值,用户能够随意传入和配置,只要xmake f -m/--mode=xxx传入的模式值和xmake.lua里面的is_mode("xxx")能对应上就行。

好比,咱们设置了一个本身独有的编译模式my_mode,能够直接在命令行配置切换;

$ xmake f -m my_mode
$ xmake
[  0%]: ccache compiling.my_mode src/main.cpp
[100%]: linking.my_mode test
build ok!
复制代码

而后xmake.lua里面对相应的值进行判断便可:

if is_mode("my_mode") then
    add_defines("ENABLE_MY_MODE")
end
复制代码

使用模式变量

咱们也能够直接在配置值中传递模式变量$(mode),好比根据不一样模式选择连接不一样的库:

target("test")
    set_kind("binary")
    add_files("src/*.c")
    add_links("xxx_$(mode)")
复制代码

上面的配置,若是是调试模式编译就会选择连接:libxxx_debug.a库,而release下就会连接libxxx_release.a,固然,咱们也能够设置到库搜索路径中,根据目录来选择对应的库。

target("test")
    set_kind("binary")
    add_files("src/*.c")
    add_linkdirs("lib/$(mode)")
    add_links("xxx")
复制代码

另外,咱们能够经过get_config("mode")直接获取到传入的模式配置值,而且这几种获取方式,在自定义脚本也是一样有效的哦,例如:

target("test")
    set_kind("binary")
    add_files("src/*.c")
    on_load(function (target)
        if is_mode("release") then
            print(get_config("mode"), "$(mode)")
        end
    end)
复制代码

原文:tboox.org/cn/2019/12/…

相关文章
相关标签/搜索