Makefile 基于条件重建特定对象

Makefile 基于条件重建特定对象,makefile,gnu-make,Makefile,Gnu Make,我正试图修改具有通用/模式特定规则的大型项目的gnu makefile makefile在单独的规则中编译和链接。我有一个特殊的需求,如果某个条件在链接时通过,那么我想在再次链接之前再次调用编译规则。makefile中的示例问题如下所示 $(obj_dir)/%.o: $(src_base)/%.cpp @echo Compiling: $< $(q)$(CXX) $(CXXFLAGS) $(REV) $(CXX_INCLUDE_PATH) -o $@ $<

我正试图修改具有通用/模式特定规则的大型项目的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
$(obj\u dir)/%.o:$(src\u base)/%.cpp
@echo编译:$<
$(q)$(CXX)$(cxflags)$(REV)$(CXX\u INCLUDE\u PATH)-o$@$<
$(链接文件):
@回音链接$@
$(q)$(CXX)$(LINKFLAGS)-o$@%.o
ifeq(1,1)
#条件通过,所以我想再次调用上面的泛型编译规则
?????
其他的
$(警告不做任何事情)
恩迪夫
有人能帮我重新调用泛型编译规则吗


非常感谢您的帮助。提前谢谢

我同意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
$(obj\u dir)/%.o:$(src\u base)/%.cpp
@echo编译:$<
$(q)$(CXX)$(cxflags)$(REV)$(CXX\u INCLUDE\u PATH)-o$@$<
$(链接文件):
@回音链接$@
$(q)$(CXX)$(LINKFLAGS)-o$@%.o
如果[1-等式1];则\
$(MAKE)-W$(src_base)/foo.cpp$(obj_dir)/foo.o||退出1\
否则\
我什么也不做\
fi

第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 $@ $^
步骤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 output语句。(Make语句往往在任何规则运行之前进行求值。)if的
前面有一个选项卡,但条件中其他行前面的空格只是空格

第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

您不希望对象文件成为链接规则的先决条件吗?在这种情况下,再次调用编译规则将不会起任何作用,因为对象文件已是最新的。谢谢。我可以将对象文件添加为链接规则依赖项,也可以在再次调用编译规则之前删除生成的链接文件。您能帮助我解决此问题吗关于如何在链接规则中再次调用调用编译规则的原始问题。我认为您误解了Make的工作原理。如果您有所需对象文件的列表,则很容易重新调用编译规则,但我认为这样做没有任何意义。您能告诉我们为什么要重建对象文件吗?是的,我在ma方面没有做很多工作kefile,所以我的问题或用例可能会很疯狂。我必须用保存在单独清单文件中的同一对象的历史md5sum之一检查链接对象的md5sum。如果两个md5sum不匹配,我想用$(REV)指示的新修订号重新编译变量。有更好的方法吗?那太可怕了。我发现几乎不可能想象一种场景,在这种场景中,将对象文件保持在版本控制下是一个好主意。我知道您可能无权更改此方案,但您必须意识到这有多糟糕(并且您可以编译相同的源代码两次,并获得两个不同的目标文件)。如果您仍然想要原始问题的答案,我将发布它并附带警告——但在这种情况下,请告诉我您是否有所需对象文件的列表。谢谢。我还没有测试它,但我有一点困惑。我们正在显式地指定源文件,其中一个对象可以由多个.cpp文件组成。是这是一种在进行递归make之前知道该对象由哪些源文件组成的方法,或者在调用链接规则之前调用该对象的父编译规则。我问这个问题是因为Makefile需要为不同的对象单独执行。我不太确定我是否理解这个问题,但一般来说l没有内置的方法来确定是什么先决条件导致了其他规则的生成。如果您真的想这样做的话,您可以非常巧妙地使用
$(eval…
),在编译规则中添加类似
$(eval$@_SRC:=$感谢Beta。我还没有测试你的解决方案,但我能够创建一个类似的Makefile,它或多或少遵循相同的方法,但我引入了一些更多的自定义规则,以便我可以根据我对特定对象的新修订递归调用这些特定规则。
$(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