您需要运行编译器两次,但您可以通过指定仅进行语法检查来节省编译时间并避免生成不需要的目标文件,从而在
-std=c++98
过程中节省编译时间。您可以通过传递选项
-fsyntax-only
来实现这一点。
您还需要修改
make
,以跳过C++98的链接,因为没有需要链接的内容。
您可以使用以下方式最有效地完成此操作:
make
如下所示:
.phony: all clean
SRCS = foo.cpp
FLAT_SRCS = $(patsubst %.cpp,%.ii,$(SRCS))
OBJS = $(patsubst %.ii,%.o,$(FLAT_SRCS))
%.ii: %.cpp
g++ -std=c++98 $(CPPFLAGS) -E $< > $@ && g++ -std=c++98 -fsyntax-only $@
%.o: %.cpp
%.o: %.ii
g++ -c -o $@ $(CPPFLAGS) $(CXXFLAGS) $<
all: foo
foo: $(OBJS)
g++ -o $@ $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LDLIBS)
clean:
rm -f $(OBJS) $(FLAT_SRCS) foo
在这里,%.ii:%.cpp
规则首先只是将.cpp
预处理为.ii
,然后将已经预处理过的源代码传递给C++98语法检查器,
这不会产生新文件。
空的%.o:%.cpp
规则覆盖了否则会导致.cpp
编译为.o
的隐式规则,并被%.o:%.ii
规则替换以编译.ii
。
g++将.ii
识别为表示已经预处理的C++源代码,因此它不会再次对源代码进行预处理。
代码只预处理一次,并且生成目标代码也只有一次。
链接与往常一样。只要C++98语法检查通过,make
看起来像:
$ make
g++ -std=c++98 -E foo.cpp > foo.ii && g++ -std=c++98 -fsyntax-only foo.ii
g++ -c -o foo.o foo.ii
g++ -o foo foo.o
rm foo.ii
您会注意到,
make
自动删除预处理的
.ii
,这没问题:它只是
.cpp
和
.o
之间的一个通道。
尽管如此,我同意 @Matt McNabb 的观点,即您没有任何收获!既然您的代码确实是 C++98,那么编译器在被告知必须是 C++98 时不会比不指定更好地进行优化。当 GCC 到达其业务的优化阶段时,它不再关心源代码的类型。
您可能认为,将 -std=c++98
给 g++ 4.x 等编译器使用,会导致整个编译器像 g++ 2.x 一样运行。并非如此。它仍然是 g++ 4.x,具有 g++ 4.x 的优化技术等,只是按照 C++98 的语言定义操作。
如果您的代码出于某种原因必须作为 C++98 在发布编译器之前的某个较旧的编译器上通过,那么在这种情况下,您需要在 makefile 中区分编译器。但显然这不是这种情况。您可以像常规编译一样使用 -std=C++98
进行编译。