[英]Creating several precompiled header files using GNU make
I use gcc (running as g++
) and GNU make. 我使用gcc(作为g++
运行)和GNU make。 I use gcc to precompile a header file precompiled.h
, creating precompiled.h.gch
; 我使用gcc预编译头文件precompiled.h
,创建precompiled.h.gch
; the following line in a Makefile does it: Makefile中的以下行可以做到这一点:
# MYCCFLAGS is a list of command-line parameters, e.g. -g -O2 -DNDEBUG
precompiled.h.gch: precompiled.h
g++ $(MYCCFLAGS) -c $< -o $@
All was well until i had to run g++
with different command-line parameters. 一切都很好,直到我不得不使用不同的命令行参数运行g++
为止。 In this case, even though precompiled.h.gch
exists, it cannot be used, and the compilation will be much slower. 在这种情况下,即使存在precompiled.h.gch
,也无法使用它,并且编译速度会慢得多。 In the gcc documentation i have read that to handle this situation, i have to make a directory called precompiled.h.gch
and put the precompiled header files there, one file for each set of g++
command-line parameters. 在gcc文档中,我读到了要处理这种情况的信息,我必须创建一个名为precompiled.h.gch
的目录,并将预编译的头文件放在此处,每个g++
命令行参数集都有一个文件。
So now i wonder how i should change my Makefile to tell g++
to create the gch-files this way. 所以现在我想知道如何更改我的Makefile来告诉g++
以这种方式创建gch文件。 Maybe i can run g++
just to test whether it can use any existing file in the precompiled.h.gch
directory, and if not, generate a new precompiled header with a unique file name. 也许我可以运行g++
只是为了测试它是否可以使用precompiled.h.gch
目录中的任何现有文件,如果不能,则生成具有唯一文件名的新的预编译头文件。
Does gcc have support for doing such a test? gcc是否支持进行此类测试?
Maybe i can implement what i want in another way? 也许我可以用另一种方式实现我想要的?
It seems weird to answer my own question; 回答我自己的问题似乎很奇怪。 anyway, here goes. 无论如何,这里去。
To detect whether a suitable precompiled header file exists, i add a deliberate error to my header file: 为了检测是否存在合适的预编译头文件,我在头文件中添加了一个故意的错误:
// precompiled.h
#include <iostream>
#include <vector>
...
#error Precompiled header file not found
This works because if gcc finds a precompiled header, it will not read the .h
file, and will not encounter the error. 之所以可行,是因为如果gcc找到了预编译的标头,它将不会读取.h
文件,也不会遇到该错误。
To "compile" such a file, i remove the error first, placing the result in a temporary file: 为了“编译”这样的文件,我首先消除了错误,将结果放在一个临时文件中:
grep -v '#error' precompiled.h > precompiled.h.h
g++ -c -x c++ $(MYCCFLAGS) precompiled.h.h -o MORE_HACKERY
Here MORE_HACKERY is not just a plain file name, but contains some code to make a file with unique name ( mktemp
). 在这里,MORE_HACKERY不仅是纯文件名,还包含一些代码来创建具有唯一名称( mktemp
)的文件。 It was omitted for clarity. 为了清楚起见,将其省略。
There is a simpler way than introducing an #error in precompiled.h: never create this file at all. 有一种比在precompiled.h中引入#error更为简单的方法:根本不要创建此文件。 Neither G++ nor Visual C++ (at least up to 2005) expect the "real" file to be there, if a precompiled version is around (and if they get the necessary compilation flags). 如果预编译的版本已经存在(并且获得了必要的编译标志),那么G ++和Visual C ++(至少在2005年之前)都不会期望“真实”文件存在。
Let's say the list of #includes that we want to precompile is called "to_be_precompiled.cpp". 假设我们要预编译的#include列表称为“ to_be_precompiled.cpp”。 The filename extension doesn't matter much, but I don't like to call this a .h file, since it has to be used in a way different from genuine header files, and it's easier in Visual C++ if this is a .cpp. 文件扩展名没什么大不了,但是我不喜欢将此文件称为.h文件,因为它的使用方式必须不同于真正的头文件,而且如果它是.cpp,则在Visual C ++中更容易使用。 。 Then pick a different name to refer to it throughout the code, let's say "precompiled_stuff". 然后在整个代码中选择一个不同的名称来引用它,比如说“ precompiled_stuff”。 Again, II don't like to call this a .h file, because it's not a file at all, it's a name to refer to precompiled data. 同样,II不喜欢将此文件称为.h文件,因为它根本不是文件,它是指预编译数据的名称。
Then in all other source files, the statement #include "precompiled_stuff"
is not a genuine include, but simply loads precompiled data. 然后,在所有其他源文件中,语句#include "precompiled_stuff"
不是真正的包含,而是仅加载预编译的数据。 It's up to you to prepare the precompiled data. 由您来准备预编译的数据。
#include "to_be_precompiled.cpp"
. “ precompiled_stuff”是“ to_be_precompiled.cpp”的副本,硬链接或符号链接,或者是包含#include "to_be_precompiled.cpp"
的小文件。 In other words, you take the viewpoint that every compiler supports precompilation, but it's just a dumb copy for some compilers. 换句话说,您认为每个编译器都支持预编译,但是对于某些编译器而言,它只是一个哑本。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.