zoukankan      html  css  js  c++  java
  • xmake从入门到精通8:切换编译模式

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

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

    调试和发布模式

    通常,如果我们是通过xmake create命令创建的项目,会在xmake.lua里面自动添加一行编译规则的配置,如下:

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

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

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

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

    如果我们要切换到debug编译模式,只需要:

    $ 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做判断。

    例如,我们想在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)
    

    原文:https://tboox.org/cn/2019/12/05/quickstart-8-switch-build-mode/xmake

  • 相关阅读:
    hdu6229 Wandering Robots 2017沈阳区域赛M题 思维加map
    hdu6223 Infinite Fraction Path 2017沈阳区域赛G题 bfs加剪枝(好题)
    hdu6438 Buy and Resell 买卖物品 ccpc网络赛 贪心
    hdu6441 Find Integer 求勾股数 费马大定理
    bzoj 1176 Mokia
    luogu 3415 祭坛
    bzoj 1010 玩具装箱
    bzoj 3312 No Change
    luogu 3383【模板】线性筛素数
    bzoj 1067 降雨量
  • 原文地址:https://www.cnblogs.com/tboox/p/11994383.html
Copyright © 2011-2022 走看看