根据条件重建特定对象
我在尝试修改具有通用/特定模式特定规则的大型项目的gnu makefile。根据条件重建特定对象
该生成文件正在编译和链接在单独的规则。我有一个特定的需求,如果某个条件在链接时传递,那么我想在再次链接之前再次调用编译规则。从生成文件样本问题如下,
$(obj_dir)/%.o: $(src_base)/%.cpp
@echo Compiling: $<
$(q)$(CXX) $(CXXFLAGS) $(REV) $(CXX_INCLUDE_PATH) -o [email protected] $<
$(link_files) :
@echo Linking [email protected]
$(q)$(CXX) $(LINKFLAGS) -o [email protected] %.o
ifeq (1,1)
#condition pass so I want to call generic above ompilation rule again
?????
else
$(warning Do Nothing)
endif
能有人帮我如何我可以递归或以其他方式再次调用通用的编译规则。
帮助将不胜感激。提前致谢。
我同意贝塔,这听起来很疯狂。
但是,如果你只是想要这样做,这很简单。但是,这里的东西,你必须在配方中编写测试,作为shell测试。你不能使用制作测试(ifeq
等)然后你可以调用一个递归make来建立文件,并使用-W
标志来强制它被重建。像(假设你要重建文件的东西是foo.cpp
:
$(obj_dir)/%.o: $(src_base)/%.cpp
@echo Compiling: $<
$(q)$(CXX) $(CXXFLAGS) $(REV) $(CXX_INCLUDE_PATH) -o [email protected] $<
$(link_files) :
@echo Linking [email protected]
$(q)$(CXX) $(LINKFLAGS) -o [email protected] %.o
if [ 1 -eq 1 ]; then \
$(MAKE) -W $(src_base)/foo.cpp $(obj_dir)/foo.o || exit 1; \
else; \
echo do nothing; \
fi
谢谢..我还没有测试过,但我有一个小混乱。我们明确指定源文件,其中一个对象可以由多个.cpp文件组成。有没有办法在递归make之前知道该对象由哪些源文件组成,或者只是在调用链接规则之前处理此对象的父编译规则/ s。我问这个Makefile需要为不同的对象自己执行。 – Akamai
我不太清楚我是否理解这个问题,但总的来说,没有内建的方法来确定造成某些其他规则的先决条件。如果这是你真正想要做的事情,你可以用'$(eval ...)'来做到这一点:在你的编译规则中,你会添加类似'$(eval $ @ _ SRC:= $ MadScientist
步骤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 [email protected] $<
$(link_files) : $(OBJECTS)
@echo Linking [email protected]
$(q)$(CXX) $(LINKFLAGS) -o [email protected] $^
要确保在继续之前,这个工作正常。特别是,确保您可以在命令行中通过为值为REV
,如下所示:
make REV=123
第2步:测试递归调用。一开始就是无条件的。
$(link_files) : $(OBJECTS)
@echo Linking [email protected]
$(q)$(CXX) $(LINKFLAGS) -o [email protected] $^
$(MAKE) REV=$(NEWREV) $(OBJECTS)
步骤3:测试条件。
$(link_files) : $(OBJECTS)
@echo Linking [email protected]
$(q)$(CXX) $(LINKFLAGS) -o [email protected] $^
$(MAKE) REV=$(NEWREV) $(OBJECTS)
if [ 1 -eq 2 ];\
then echo Do Something; \
else \
echo Do Nothing; \
fi
注意,这是在壳一个壳输出语句有条件的,不是让输出语句在使条件。 (Make语句倾向于在任何规则运行之前进行评估。)在if
前有一个TAB,但条件中其他行前的空格仅为空格。
第4步:把它放在一起。
$(link_files) : $(OBJECTS)
@echo Linking [email protected]
$(q)$(CXX) $(LINKFLAGS) -o [email protected] $^
$(MAKE) REV=$(NEWREV) $(OBJECTS)
if [ 1 -eq 2 ];\
then $(MAKE) REV=$(NEWREV) $(OBJECTS); \
else \
echo Do Nothing; \
fi
谢谢测试版。我没有测试过你的解决方案,但是我能够创建一个类似的Makefile,它遵循或多或少相同的方法,但我引入了一些更多的自定义规则,以便我可以基于该特定对象的新修订版递归调用这些特定规则。 – Akamai
难道你不想让对象文件成为链接规则的先决条件吗?在这种情况下,再次调用编译规则将不会执行任何操作,因为对象文件已经是最新的。 – Beta
谢谢。我可以添加目标文件作为链接规则依赖项,或者我可以在再次调用编译规则之前删除生成的链接文件。你能帮我解决一下原来的问题:我怎样才能在链接规则中再次调用编译规则。 – Akamai
我想你误解了Make是如何工作的。如果您有所需的目标文件列表,重新编译编译规则很容易,但我没有看到这样做。你能告诉我们为什么你要重建目标文件吗? – Beta