使用xmake檢測編譯器特性支援

2021-09-16 18:45:48 字數 2972 閱讀 9101

如果我們要寫跨平台的c/c++**,很多時候需要處理由於不同編譯器對c/c++各個標準支援力度不同導致的相容性問題,一般通常的解決辦法是:自己在**中通過巨集去判斷各個編譯器的版本、內建巨集、標準庫巨集、__has_feature等來檢測處理。

自己如果在**中按上述的方式檢測,會很繁瑣,尤其是像c++這種存在大量語法特性,如果一一檢測過來,工作量是非常大的。

通過構建工具預先檢測編譯特性

另外比較省事的方式,就是依賴構建工具提前做好檢測,然後把檢測結果作為巨集新增到編譯中去,這樣**只需要判斷對應的特性巨集是否存在,就可以進行處理了。

在cmake中就有類似的檢測機制,非常強大,因此xmake也對其進行了支援,提供更加靈活強大的編譯器特性預先檢測支援:

target("test")

on_load(function (target)

import("core.tool.compiler")

if compiler.has_features("cxx_constexpr") then

target:add("defines", "has_cxx_constexpr=1")

endend)

通過core.tool.compiler模組的compiler.has_features介面,在xmake.lua中預先判斷當前編譯期支援的語言特性,實現條件編譯。

上述**,在載入target的時候,判斷當前編譯器是否支援c++的常量表示式語法特性,如果支援則新增巨集定義:has_cxx_constexpr=1

我們也可以在判斷時候,追加一些引數控制編譯選項,例如上述特性需要c++11支援,我們可以啟用它:

if compiler.has_features(, ) then

-- ok

end

通過上面的**可以看到,此介面是可以同時檢測多個特性的,返回值為實際支援的特性列表。

如果之前對這個target已經設定了c++11,那麼我們也可以傳入target物件,繼承target的所有設定,甚至指定一些其他擴充套件編譯配置:

if compiler.has_features("cxx_constexpr", ) then

-- ok

end

批量編譯器特性檢測

c++的語言特性非常多,這個時候我們可以通過指令碼實現快速的批量檢測:

target("test")

on_load(function (target)

import("core.tool.compiler")

for feature, _ in pairs(compiler.features("cxx", )) do -- 傳入target在檢測特性時繼承target的所有編譯配置

target:add("defines", "has_feature_" .. feature)

endend)

上述**,會在載入target的時候,把當前編譯器對c++的所有支援特性,都新增到target的巨集定義中進行編譯,例如:-dhas_feature_cxx_constexpr

我們只需要在**中,通過判斷對應的特性巨集是否存在就行了:

#ifdef has_feature_cxx_constexpr

// todo

#endif

目前支援的所有c/c++編譯器特性列表,見:compiler.features

更加底層的檢測介面

如果我們要指定獲取具體哪個編譯器的特性支援,則需要更加底層的介面支援了,例如:

import("lib.detect.has_features")

local features = has_features("clang", "cxx_constexpr")

local features = has_features("clang", , , program = "xcrun -sdk macosx clang"})

local features = has_features("clang", , )

lib.detect.has_features屬於探測模組的介面,可以指定需要檢測的工具名,例如這裡通過傳入clang,只對clang編譯器進行檢測。

當然此介面,還可以檢測其他非編譯器的工具特性,更加的通用。

通過自定義c/c++**片段來檢測特性

對於一些複雜的編譯器特性,連compiler.has_features都無法檢測到的時候,可以通過自定義**片段嘗試編譯來檢測它。

import("lib.detect.check_cxsnippets")

local ok = check_cxsnippets("constexpr int f(int x) constexpr int x = f(5); static_assert(x == 15);", )

上述**通過自定義乙個constexpr的測試**,去檢測c++11的constexpr支援。

此介面是detect.has_cfuncs, detect.has_cincludes和detect.has_ctypes等介面的通用版本,也更加底層。

因此我們可以用它來檢測:types, functions, includes 還有 links,或者是組合起來一起檢測。

第乙個引數為**片段列表,一般用於一些自定義特性的檢測,如果為空,則可以僅僅檢測可選引數中條件,例如:

local ok = check_cxsnippets(", "void test2() {}"}, , includes = "stdio.h", funcs = })
上面那個呼叫,會去同時檢測types, includes和funcs是否都滿足,如果通過返回true。

原文出處:

Java編譯器與雙鎖檢測

jre5 public class lazysingleton2 return m instance getinstance class 在上面的下劃線處會出現問題。無法保證編譯器為物件分配記憶體之後,是直接將物件的引用賦值給m instance 還是將物件初始化之後才將引用賦值給 m instan...

如何檢測編譯器的大小端

大端模式 所謂的大端模式,是指資料的高位,儲存在記憶體的低位址中,而資料的低位,儲存在記憶體的高位址中,這樣的儲存模式有點兒類似於把資料當作字串順序處理 位址由小向大增加,而資料從高位往低位放 小端模式 所謂的小端模式,是指資料的高位儲存在記憶體的高位址中,而數 據的低位儲存在記憶體的低位址中,這種...

GCC編譯器的使用

看下面的例子 test.c include main char str i like linux i advices you jion in the linux world printf s n str exit 0 使用gcc編譯 輸入gcc c test.c得到目標檔案test.o。c命令表示對...