2014-07-18 16 views
4

例如,gcc 4.7具有新功能 - 虛擬。在configure.ac中,如何測試當前gcc是否支持某個功能?
gnulibc中有file,但對我沒有多大意義。如何在configure.ac中檢查特定的gcc功能

+0

也許這個問題應該是一般化的。你不能假定編譯器是gcc,所以你應該問如何檢查編譯器是否支持某個特定的功能,而不是gcc是否支持某個特定的功能。 –

回答

0

查看http://code.google.com/p/opendoom/source/browse/trunk/VisualC8/autotools/ac_c_compile_flags.m4對於這種類型的示例測試 - 它試圖編譯一個具有給定編譯器標誌的普通程序,並將其添加到CFLAGS(如果它有效)。

+0

謝謝,line3中$ 1的含義是什麼? – nzomkxia

+0

這是AC_C_COMPILE_FLAGS宏的第一個參數(在宏展開時被替換)。 –

+0

這種方法正是我所警告的:如果一個編譯器接受了'Wnarrowing'選項,並且提示信息'忽略未知選項 - 虛擬化'(是的,這樣的編譯器存在),'不應該添加' - 虛擬化' 。你的方法確實會導致它被添加。 – hvd

1

這背後的邏輯也許應該是:

創建一個正確的文件應該收到警告-Wnarrowing。驗證它是否正確編譯。這是一個健康檢查。

然後用-Wnarrowing編譯同一個文件,並驗證它是否仍然正確編譯。這可以確保您檢測到不支持-Wnarrowing的編譯器作爲選項,並且不會嘗試將僞選項傳遞給它們。

最後,編譯與-Werror=narrowing相同的文件,並驗證它現在不能正確編譯。如果它現在失敗了,你可以確信編譯器確實支持-Wnarrowing。最後一個檢查對檢測確實接受-Wnarrowing/-Werror=narrowing的編譯器很有用,但會發出警告「忽略未知選項-Wnarrowing」。在這種情況下,你不應該通過-Wnarrowing

另外,您可能還需要編譯的文件應該得到與-Wnarrowing警告與-Werror=narrowing,如果你找到一個編譯器在哪裏-Wnarrowing是無用的,-Werror=narrowing是一個嚴重的錯誤。儘管如此,我無法想象編譯器在哪裏需要。

將此轉換爲配置檢查應該是微不足道的。

+0

這是脆弱的,需要3次編譯,並且我無法區分步驟1和步驟2之間的區別。 –

+0

@BrettHale在配置檢查過程中多次編譯沒有任何問題。他們是非常短的程序,應該編譯得非常快。至於步驟1和步驟2之間的區別,假設當'-Wnarrowing'傳遞時編譯器發出錯誤,但是當'-Wnarrowing'沒有傳遞時也會發出錯誤。在那種情況下,錯誤完全沒有提及是否支持「Warnarrowing」。如果測試程序無意中依賴於特定於實現的功能,並且將測試調整爲防禦性編碼,則可能會發生這種情況。 – hvd

+0

這對於clang來說是失敗的,因爲'-Wnarrowing'是默認的,並且是一個錯誤。 –

1

gcc和clang都支持-W[no-]narrowing-W[no-]error=narrowing選項。

隨着-std=c++11,GCC發出默認爲警告和鐺默認發出錯誤。即使你只提到gcc,我想你可以將功能檢查擴展到像clang這樣的編譯器,試圖提供相同的選項和擴展。這可能也包括Intel的icc。

我們假設您選擇了帶有AC_PROG_CXX的C++編譯器,並確保了it's using the C++11 standard

ac_save_CXXFLAGS="$CXXFLAGS" 
CXXFLAGS="$CXXFLAGS -Werror -Wno-error=narrowing" 
AC_LANG_PUSH([C++]) 

AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], 
    [[int i {1.0}; (void) i;]])], 
    [ac_cxx_warn_narrowing=1], [ac_cxx_warn_narrowing=0]) 

AS_IF([test $ac_cxx_warn_narrowing -ne 0], 
    [AC_MSG_RESULT(['$CXX' supports -Wnarrowing])]) 

AC_LANG_POP([C++]) 
CXXFLAGS="$ac_save_CXXFLAGS" 

編譯纔會成功,如果:1)編譯器支持-Wnarrowing相關的選項,這意味着它支持-Werror,和:2)識別C++ 11初始化語法。

通常,configure.ac傳遞給configure的腳本和標誌應該避免-Werror,因爲它打破了太多的內部測​​試。在這種情況下,我們確保除縮小之外沒有其他警告,這就是爲什麼需要(void) i;以防止未使用變量的警告。

+0

'-Werror'在這個配置測試中是錯誤的,因爲你說它在配置測試中通常是錯誤的:這個測試程序可能會產生一個警告(包括用戶添加額外的警告選項在CXXFLAGS中),你沒有考慮過,也無法解釋。我似乎記得一些編譯器對無用語句'(void)i;'發出警告,用戶的警告選項可能會在初始化過程中警告C++ 98兼容性問題,用戶的警告選項可能會警告「主要」聲明的特定形式。 – hvd

+0

@hvd - 我很想知道任何額外的標誌選項添加到海灣合作委員會(或鐺),會給這個測試程序不正確的結果。在任何情況下,配置腳本是否必須處理病態編譯器標誌組合?一些標誌不會超過'AC_PROG_CC'和早期測試。 –

+0

不是一般的,但我確實認爲警告標誌應該總是安全的添加,至少因爲新警告會一直添加到較新版本的編譯器中,所以檢查已經需要預測所有可能的警告。一般情況下(不是針對你的具體例子,因爲你碰巧選擇了一個C++檢查),作爲一個病理例子,對於未原型函數有警告,並且原型函數有警告,所以無論AC_LANG_PROGRAM如何定義main ',至少有一個選項會導致警告。如果我找到一個更具體的這個,我會告訴你。 – hvd