預編譯標頭
解析系統函式庫的標頭檔出乎意料地耗費資源。典型的原始碼檔案少於一千行程式碼。相比之下,大型函式庫的標頭檔可能有數萬行。這在 C++ 中尤其麻煩,因為標頭檔函式庫很常見,而且它們可能包含極其複雜的程式碼。這使得它們編譯速度很慢。
預編譯標頭是緩解此問題的工具。基本上它們所做的是解析標頭,然後將編譯器的內部狀態序列化到磁碟。預編譯標頭的缺點是它們很難設定。Meson 原生支援預編譯標頭,但使用它們需要一些工作。
預編譯標頭檔相對簡單。它是一個標頭檔,其中包含要預編譯的系統標頭的 #include
指令。這是一個 C++ 範例。
#include<vector>
#include<string>
#include<map>
在 Meson 中,預編譯標頭檔始終是每個目標的。也就是說,給定的預編譯標頭在編譯目標中的每個檔案時都會使用。由於底層編譯器的限制,此標頭檔不得與任何原始碼檔案位於同一子目錄中。強烈建議您在目標目錄中建立一個名為 pch
的子目錄,並將標頭檔(且僅限標頭檔)放在其中。
切換預編譯標頭的使用
如果您希望在不使用預編譯標頭的情況下編譯您的專案,您可以在組態時透過將 -Db_pch=false
引數傳遞給 Meson,或稍後使用 meson configure
來更改 pch 選項的值。您也可以在已設定的建置目錄中使用 GUI 工具切換 pch 的使用。您不必對原始碼進行任何更改。通常這樣做是為了測試您的專案在沒有 pch 的情況下是否能乾淨地編譯(即檢查其 #include 是否按順序排列)並解決編譯器錯誤。
將預編譯標頭與 GCC 及其衍生版本一起使用
一旦您有一個要預編譯的檔案,您可以使用 pch 關鍵字引數來為給定的目標啟用 pch 的使用。舉例來說,假設您想要使用預編譯標頭建置一個小型 C 二進位檔。假設二進位檔的原始碼檔案使用系統標頭 stdio.h
和 string.h
。然後,您使用此內容建立一個標頭檔 pch/myexe_pch.h
#include <stdio.h>
#include <string.h>
並將其新增至 Meson
executable('myexe', sources : sourcelist, c_pch : 'pch/myexe_pch.h')
就這樣。您應該注意,您的原始碼檔案不得包含檔案 myexe_pch.h
,並且您不得將 pch 子目錄新增至您的搜尋路徑。不需要修改原始程式檔案。Meson 將使編譯器使用編譯器選項包含 pch。如果您想要停用 pch(例如,因為編譯器錯誤),則可以在建置系統端完全完成,而無需更改原始碼。
您可以在任何建置目標上使用預編譯標頭。如果您的目標有多種語言,您可以像這樣指定多個 pch 檔案。
executable('multilang', sources : srclist,
c_pch : 'pch/c_pch.h', cpp_pch : 'pch/cpp_pch.h')
將預編譯標頭與 MSVC 一起使用
自 Meson 0.50.0 版以來,MSVC 的預編譯標頭與 GCC 的工作方式相同。Meson 會自動為您建立相符的 pch 實作檔案。
在 0.50.0 版之前,除了標頭檔之外,Meson 還需要一個對應的原始碼檔案。如果您的標頭名為 foo_pch.h
,則對應的原始碼檔案通常名為 foo_pch.cpp
,並且與標頭位於相同的 pch
子目錄中。其內容如下
#if !defined(_MSC_VER)
#error "This file is only for use with MSVC."
#endif
#include "foo_pch.h"
若要啟用 pch,只需在目標定義中列出兩個檔案
executable('myexe', sources : srclist,
cpp_pch : ['pch/foo_pch.h', 'pch/foo_pch.cpp'])
此形式適用於 GCC 和 msvc,因為 Meson 知道 GCC 不需要 .cpp
檔案,因此只是忽略它。
應該注意的是,由於 MSVC 編譯器的實作細節,無法保證在同一目標中對多種語言使用預編譯標頭。
搜尋結果為