[英]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.