我正在尝试修改具有泛型/模式特定规则的大型项目的gnu makefile。
makefile正在单独的规则中进行编译和链接。我有一个特定的需要,如果某个条件在链接时传递,那么我想再次链接之前再次调用编译规则。 makefile的示例问题如下,
$(obj_dir)/%.o: $(src_base)/%.cpp
@echo Compiling: $<
$(q)$(CXX) $(CXXFLAGS) $(REV) $(CXX_INCLUDE_PATH) -o $@ $<
$(link_files) :
@echo Linking $@
$(q)$(CXX) $(LINKFLAGS) -o $@ %.o
ifeq (1,1)
#condition pass so I want to call generic above ompilation rule again
?????
else
$(warning Do Nothing)
endif
有人可以帮我详细说明如何以递归或其他方式再次调用通用编译规则。
将非常感谢帮助。提前致谢。
答案 0 :(得分:2)
第1步:让基本的makefile正常工作。也许你已经有了这个,但这是一个大纲:
OBJECTS := $(obj_dir)/foo.o $(obj_dir)/bar.o $(obj_dir)/baz.o
# You MUST have a list like this somewhere, constructed somehow.
$(obj_dir)/%.o: $(src_base)/%.cpp
@echo Compiling: $<
$(q)$(CXX) $(CXXFLAGS) $(REV) $(CXX_INCLUDE_PATH) -o $@ $<
$(link_files) : $(OBJECTS)
@echo Linking $@
$(q)$(CXX) $(LINKFLAGS) -o $@ $^
在继续操作之前,请确保此操作正常。特别是,请确保您可以在命令行中为REV
传递值,如下所示:
make REV=123
第2步:测试递归调用。首先让它无条件。
$(link_files) : $(OBJECTS)
@echo Linking $@
$(q)$(CXX) $(LINKFLAGS) -o $@ $^
$(MAKE) REV=$(NEWREV) $(OBJECTS)
第3步:测试条件。
$(link_files) : $(OBJECTS)
@echo Linking $@
$(q)$(CXX) $(LINKFLAGS) -o $@ $^
$(MAKE) REV=$(NEWREV) $(OBJECTS)
if [ 1 -eq 2 ];\
then echo Do Something; \
else \
echo Do Nothing; \
fi
请注意,这是 shell 条件中的 shell 输出语句,而不是 Make中的 Make 输出语句有条件的。 (生成语句往往会在任何规则运行之前进行评估。)if
前面有一个TAB,但条件中其他行前面的空格只是空格。
第4步:将它放在一起。
$(link_files) : $(OBJECTS)
@echo Linking $@
$(q)$(CXX) $(LINKFLAGS) -o $@ $^
$(MAKE) REV=$(NEWREV) $(OBJECTS)
if [ 1 -eq 2 ];\
then $(MAKE) REV=$(NEWREV) $(OBJECTS); \
else \
echo Do Nothing; \
fi
答案 1 :(得分:0)
我同意Beta,这听起来很疯狂。
但是如果你只想这样做,那就很简单了。不过,这就是你必须在测试中将测试编写为 shell 测试。您不能使用 make 测试(ifeq
等)然后您可以调用递归make来构建文件,并使用-W
标志强制它重建。类似的东西(假设您要重建的文件是foo.cpp
:
$(obj_dir)/%.o: $(src_base)/%.cpp
@echo Compiling: $<
$(q)$(CXX) $(CXXFLAGS) $(REV) $(CXX_INCLUDE_PATH) -o $@ $<
$(link_files) :
@echo Linking $@
$(q)$(CXX) $(LINKFLAGS) -o $@ %.o
if [ 1 -eq 1 ]; then \
$(MAKE) -W $(src_base)/foo.cpp $(obj_dir)/foo.o || exit 1; \
else; \
echo do nothing; \
fi