【问题标题】:multiple targets build in makefile在makefile中构建多个目标
【发布时间】:2013-02-12 18:03:20
【问题描述】:

知道为什么这样的东西在 makefile 中不起作用吗?

all : $(GOAL_DB) $(GOAL)

%.d: %.cpp      
    $(CC) $(CPPFLAGS_DB) $<  > $@
%.o : %.cpp
    $(CC) $(FLAGS_DB) $< -o $@

$(GOAL_DB) : $(OFILES)
        $(CC) $(LFLAGS_DB) -o $@ $^ $(LIBS_DB)
    strip $(GOAL_DB)
    rm -f *.o *.d

%.d: %.cpp     
    $(CC) $(CPPFLAGS) $<  > $@
%.o : %.cpp
    $(CC) $(FLAGS) $< -o $@
$(GOAL) : $(OFILES)
        $(CC) $(LFLAGS) -o $@ $^ $(LIBS)
    strip $(GOAL)
    rm -f *.o *.d

我只是尝试使用 make all 和 GNU make 构建两个不同的目标。

第一个目标构建良好,但它没有为另一个目标创建新的对象文件。

【问题讨论】:

    标签: makefile


    【解决方案1】:

    makefile 不像按顺序执行的标准程序。您似乎已经假设出现在新目标之前的新规则将适用于该目标。不是这种情况。在开始应用规则之前,makefile 会针对变量、目标、依赖项等进行全面评估。

    Make 将仅将这些 $(OFILES) 与其中一个 %.d: 目标进行匹配,这可能是它找到的第一个目标模式。

    您没有为另一个目标获取新对象的原因是为了使它看起来像您正在构建同一组文件两次,从而跳过第二次构建,因为它已经完成。

    解决方案是使用“目标特定变量”:

    all : $(GOAL_DB) $(GOAL)
    
    $(GOAL): BUILD_FLAGS=$(FLAGS)
    $(GOAL): BUILD_CPPFLAGS=$(CPPFLAGS)
    $(GOAL): BUILD_OUTDIR=./outdir
    $(GOAL): $(OFILES)
    
    $(GOAL_DB): BUILD_FLAGS=$(FLAGS_DB)
    $(GOAL_DB): BUILD_CPPFLAGS=$(CPPFLAGS_DB)
    $(GOAL_DB): BUILD_OUTDIR=./outdir_db
    $(GOAL_DB): $(OFILES)
    
    %.d: %.cpp      
        mkdir -p $(BUILD_OUTDIR)
        $(CC) $(BUILD_CPPFLAGS) $<  > $(BUILD_OUTDIR)/$@
    
    %.o : %.cpp
        mkdir -p $(BUILD_OUTDIR)
        $(CC) $(BUILD_FLAGS) $< -o $(BUILD_OUTDIR)/$@
    

    【讨论】:

    • 谢谢!是的,我假设一个绝对不会发生的顺序执行。您的解决方案更有意义,但它不会在 make all 时创建两个目标。
    • 它仍然没有为另一个创建目标文件。我试图构建相同的文件集,但它使用不同的库,你认为这可能是一个问题吗?
    • 对了。输出文件仍然相同。可能应该将生成文件设置为输出到单独的目录。
    • 添加了输出目录变量。