...世界上最受推崇且設計精良的 C++ 函式庫專案之一。
— Herb Sutter 與 Andrei Alexandrescu,《C++ Coding Standards》
有時您需要根據編譯器支援的功能來控制是否建置建置目標。例如,假設您有一個測試檔案「test_constexpr_128.cpp」,它需要三個關鍵功能才能建置:
constexpr
關鍵字。__int128
資料類型。顯然,我們知道如果編譯器不支援這些功能,那麼即使嘗試建置測試程式也毫無意義。主要優點是:
回到我們的範例,測試案例可能在其 Jamfile 中透過「run」規則執行:
run test_constexpr_128.cpp ;
現在,我們需要根據必要的功能使此目標成為條件式。我們可以透過在 Jamfile 開頭導入必要的規則來做到這一點:
import path-to-config-lib/checks/config : requires ;
假設測試案例位於通常的目錄中:
libs/yourlib/test
那麼導入規則實際上將是:
import ../../config/checks/config : requires ;
然後在目標的需求區段中新增一個「requires」規則呼叫:
run test_constexpr_128.cpp : : : #requirements: [ requires cxx11_constexpr cxx11_user_defined_literals int128 ] ;
請注意,可以向 requires 規則新增多個參數,而且這些參數始終與 Boost.Config 巨集名稱相同,但採用小寫形式,並移除 boost_no_ 或 boost_has_ 前綴。您也可以使用任何 C++ 標準功能巨集名稱,並移除前導底線(詳見下文)。
建置上述範例時,您會在建置過程的開始看到設定結果,例如,C++11 模式下的 GCC 會顯示:
- Boost.Config Feature Check: int128 : yes - Boost.Config Feature Check: cxx11_constexpr : yes - Boost.Config Feature Check: cxx11_user_defined_literals : yes
如果您希望根據 C++ 標準功能巨集進行條件式建置,您也可以指定這些巨集,只需從名稱中移除前導底線即可。例如:
[ requires cpp_constexpr ]
需要 C++11 風格的常數運算式。如果您要指定特定標準的巨集,則可以在名稱後面加上底線,然後加上標準的年份(兩位數),例如:
[ requires cpp_constexpr_17 ]
適用於 C++17 的 constexpr。如果您沒有指定標準,則會取得引入該巨集的第一個版本。此外,每個巨集版本更新都只有特定標準的規則,因此:
[ requires cpp_if_constexpr_17 ]
可以,因為該巨集是在 C++17 中引入的,並且與未版本化的名稱相同,但是:
[ requires cpp_if_constexpr_20 ]
將導致建置錯誤,因為 __cpp_if_constexpr
沒有 C++20 版本更新。
這個方便的功能就是這樣了。如果您在任何時候不確定可以傳遞給「requires」規則的功能測試名稱,請在 libs/config/checks/Jamfiles.v2 中搜尋感興趣的 Boost.Config 巨集,功能檢查的名稱就會在它後面。
最後,此功能是圍繞 Boost.Build 內建規則check-target-builds 建構的,該規則可用於執行更通用的編譯時期功能測試。這個函式庫中的檢查作為方便的簡寫提供,無需您自行編寫測試案例。