簡體   English   中英

如何使用 Clang++ 生成和使用預編譯頭文件?

[英]How do I generate and use precompiled headers with Clang++?

官方文檔說明了如何通過-cc1接口使用預編譯的頭文件,例如生成它們:

$ clang -cc1 test.h -emit-pch -o test.h.pch

並使用它們:

$ clang -cc1 -include-pch test.h.pch test.c -o test.s

問題是-cc1接口太低級,無法由 CLI 的開發人員使用。 事實上,常規高級接口最終調用低級-cc1接口,方法是為其提供正確操作所需的大量參數,例如適合編譯時系統的包含路徑。 沒有這些參數, -cc1接口就沒有工作的希望:

$ clang++ -cc1 /usr/include/x86_64-linux-gnu/c++/7/bits/stdc++.h -emit-pch -o std.pch
/usr/include/x86_64-linux-gnu/c++/7/bits/stdc++.h:33:10: fatal error: 'cassert' file not found
#include <cassert>
         ^~~~~~~~~
         1 error generated.

有沒有辦法使用高級界面中的預編譯頭文件,以便開發人員可以在日常工作中方便地利用此功能?

我認為您的問題的根源是您的文件名是test.h並且 clang 認為您正在編譯 C 代碼,而不是 C++ 代碼。 因此,當您包含<cassert>時,clang 不知道它應該查看 C++ 包含路徑。 嘗試命名您的文件test.hpp 您只需使用 .hpp 將您想要的文件命名為.hpp頭文件。 您可以使用.h擴展名保留所有頭文件。

無論如何,我可能會將此與 gcc/g++ 混淆,但每當我在 Mac 上編譯我的代碼時,Clang 都會遵循相同的行為。 這就是我使用預編譯頭文件的方式。 繼續閱讀...

如果您有要預編譯的 C++ 頭文件,只需將其編譯為任何其他 .cpp 文件即可。 請注意,我使用.hpp作為文件擴展名,因此編譯器將其作為 C++ 頭文件拾取。

clang -c precomp.hpp

這將產生precomp.hpp.gch

現在要使用任何其他普通 C++ 文件的預編譯,只需包含普通的.hpp文件:

// main.cpp
#include "precomp.hpp"

void func1() {...}
void main() {...}

編譯器將自動使用相應的 .gch 文件,如果它存在於原始 .hpp 文件的位置。

我不知道為什么clang文檔沒有解釋這一點,但確實正如@selbie 推測的那樣,可以在不使用-cc1的情況下使用 Clang 預編譯頭文件(PCH)。

要生成 PCH 文件:

$ clang -c -o big-header.hh.pch big-header.hh <other options>

這是正常的編譯命令,除了輸入文件具有.hh (C++ 標頭)擴展名。 clang將認識到這意味着生成 PCH。 或者,如果您不想使用該擴展名(或另一個,如.H.hpp ,這無疑是 C++),則在頭文件名之前傳遞-xc++-header

您可以說big-header.hh.pch不是目標代碼(盡管-c在命令行上),因為file會說它是“數據”(至少我的版本是這樣)而不是目標代碼。 為了更加確定,運行strings big-header.hh.pch | head strings big-header.hh.pch | head 第一行應該是“CPCH”(意思是“Clang PCH”)。

要使用 PCH 文件:

$ clang -c -include-pch big-header.hh.pch <other compile options>

添加-include-pch big-header.hh.pch是與gcc不同的關鍵步驟。 Clang不會僅僅因為它們的名稱而自動拾取 PCH 文件。

以上是在 Linux 上使用 Clang+LLVM-14.0.0 測試的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM