2010-12-19 52 views
8

我使用gcc(作爲g++運行)和GNU make。 我使用gcc預編譯頭文件precompiled.h,創建precompiled.h.gch;在一個Makefile以下行做的:使用GNU創建幾個預編譯頭文件make

# MYCCFLAGS is a list of command-line parameters, e.g. -g -O2 -DNDEBUG 
precompiled.h.gch: precompiled.h 
    g++ $(MYCCFLAGS) -c $< -o [email protected] 

一切都很好,直到我不得不使用不同的命令行參數運行g++。 在這種情況下,即使存在precompiled.h.gch,也無法使用,編譯速度會更慢。 在我已閱讀的gcc文檔中,爲了處理這種情況,我必須創建一個名爲precompiled.h.gch的目錄,並將 預編譯頭文件放在那裏, 每個g++命令行參數集合包含一個文件。

所以現在我想知道我應該如何改變我的Makefile來告訴g++以這種方式創建 gch-files。 也許我可以運行g++只是爲了測試它是否可以使用precompiled.h.gch目錄中的任何現有文件 , ,如果沒有,則使用唯一文件名生成新的預編譯頭。

gcc是否支持做這樣的測試?

也許我可以用另一種方式實現我想要的嗎?

+0

'-Winvalid-pch'會給你一個警告。與'-Werror'一起使用時,如果gcc發現無效的.gch,它將停止編譯。 – bobbogo 2011-01-12 19:10:48

+0

@bobbogo謝謝,這正是我需要的!它會爲我節省一些麻煩。 – anatolyg 2011-01-16 12:25:39

回答

5

回答我自己的問題似乎很奇怪,無論如何,在這裏。

檢測到合適的預編譯的頭文件是否存在,我添加了一個故意的錯誤我的頭文件:

// precompiled.h 
#include <iostream> 
#include <vector> 
... 
#error Precompiled header file not found 

這樣做是因爲,如果GCC發現預編譯的頭,也不會讀.h文件,不會遇到錯誤。

「編譯」這樣的文件,我首先刪除錯誤,把結果放置在臨時文件:

grep -v '#error' precompiled.h > precompiled.h.h 
g++ -c -x c++ $(MYCCFLAGS) precompiled.h.h -o MORE_HACKERY 

這裏MORE_HACKERY不只是一個簡單的文件名,但包含了一些代碼來使具有唯一名稱的文件(mktemp)。爲了清楚起見,省略了它。

0

有一種比在precompiled.h中引入#error簡單的方法:根本不會創建這個文件。如果預編譯版本(如果他們獲得了必要的編譯標誌),那麼G ++和Visual C++(至少到2005年)都不會期望「真實」文件存在。

假設我們要預編譯的#include的列表被稱爲「to_be_precompiled.cpp」。文件擴展名並不重要,但我不喜歡將其稱爲.h文件,因爲它必須以與真正的頭文件不同的方式使用,並且在Visual C++中更容易,如果這是.cpp 。然後在整個代碼中選擇一個不同的名稱來引用它,比如說「precompiled_stuff」。再說一遍,我不喜歡把這個叫做.h文件,因爲它根本不是文件,它是一個引用預編譯數據的名字。

然後在所有其他源文件中,語句#include "precompiled_stuff"不是真正的包含,而只是加載預編譯的數據。準備預編譯數據由您決定。

  • 對於G ++,你需要構建規則從源文件的名字不要緊,編譯器(但將是「to_be_precompiled.cpp」在這裏)創建「precompiled_stuff.gch」。
  • 在Visual C++中,字符串「precompiled_stuff」等於/ Yu標誌的值,並且加載的預編譯數據來自一個名稱不相關的.pch文件,也是您從一個不相關的源文件創建的(同樣是「to_be_precompiled。 cpp「)。
  • 只有在編譯器沒有預編譯頭支持的情況下編譯時,構建規則需要生成一個名爲「precompiled_stuff」的實際文件,最好在遠離真實源文件的編譯目錄中。 「precompiled_stuff」可以是「to_be_precompiled.cpp」的副本,也可以是硬鏈接或符號鏈接,也可以是包含#include "to_be_precompiled.cpp"的小文件。

換句話說,你認爲每個編譯器都支持預編譯,但對於某些編譯器來說,它只是一個愚蠢的副本。

+0

請注意,在Visual Studio中,與C++編譯器相反,[Intellisense確實需要預編譯頭文件(至少在2015年)](http://stackoverflow.com/questions/31943634/visual-studio-2015-intellisense -errors - 丁溶液編譯) – Stein 2015-09-16 15:35:38