根据条件重建特定对象

问题描述:

我在尝试修改具有通用/特定模式特定规则的大型项目的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 

能有人帮我如何我可以递归或以其他方式再次调用通用的编译规则。

帮助将不胜感激。提前致谢。

+0

难道你不想让对象文件成为链接规则的先决条件吗?在这种情况下,再次调用编译规则将不会执行任何操作,因为对象文件已经是最新的。 – Beta

+0

谢谢。我可以添加目标文件作为链接规则依赖项,或者我可以在再次调用编译规则之前删除生成的链接文件。你能帮我解决一下原来的问题:我怎样才能在链接规则中再次调用编译规则。 – Akamai

+0

我想你误解了Make是如何工作的。如果您有所需的目标文件列表,重新编译编译规则很容易,但我没有看到这样做。你能告诉我们为什么你要重建目标文件吗? – Beta

我同意贝塔,这听起来很疯狂。

但是,如果你只是想要这样做,这很简单。但是,这里的东西,你必须在配方中编写测试,作为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 
+0

谢谢..我还没有测试过,但我有一个小混乱。我们明确指定源文件,其中一个对象可以由多个.cpp文件组成。有没有办法在递归make之前知道该对象由哪些源文件组成,或者只是在调用链接规则之前处理此对象的父编译规则/ s。我问这个Makefile需要为不同的对象自己执行。 – Akamai

+0

我不太清楚我是否理解这个问题,但总的来说,没有内建的方法来确定造成某些其他规则的先决条件。如果这是你真正想要做的事情,你可以用'$(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 
+0

谢谢测试版。我没有测试过你的解决方案,但是我能够创建一个类似的Makefile,它遵循或多或少相同的方法,但我引入了一些更多的自定义规则,以便我可以基于该特定对象的新修订版递归调用这些特定规则。 – Akamai