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/…

相關文章
相關標籤/搜索