您将不得不运行编译器两次,但您可以-std=c++98通过仅指定语法检查来节省编译时间并避免生成不需要的目标文件。您可以通过传递 option 来做到这一点-fsyntax-only。
您还需要修改您的make以跳过 C++98 的链接,因为将没有任何链接。
执行此操作的最有效方法可能是make在以下几行中使用 a :
.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
Run Code Online (Sandbox Code Playgroud)
在这里,%.ii: %.cpp规则首先将 预处理.cpp到.ii,然后将已经预处理过的源传递给 C++98 语法检查传递,这不会产生新文件。
空%.o: %.cpp规则覆盖了否则会导致.cpp编译为的隐式规则.o,并替换%.o: %.ii
为编译.ii. g++ 识别.ii为表示已经预处理过的 C++ 源代码,因此它不会再次预处理源代码。
代码只预处理一次,目标代码只生成一次。
联动和往常一样。如果 C++98 语法检查通过,amake将如下所示:
$ 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
Run Code Online (Sandbox Code Playgroud)
您会注意到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