Makefile 生成文件警告,覆盖目标的命令

Makefile 生成文件警告,覆盖目标的命令,makefile,warnings,Makefile,Warnings,作为makefile的一部分,我希望生成目标的调试版本或发布版本 从功能上讲,一切正常,但是,我在运行make时收到警告 12 SRC := $(shell echo src/*.cpp) 13 SRC += $(shell echo $(TEST_ROOT)/*.cpp) 14 15 D_OBJECTS = $(SRC:.cpp=.o) # same objects will need to be built differently 16 R_OBJECTS = $(S

作为makefile的一部分,我希望生成目标的调试版本或发布版本

从功能上讲,一切正常,但是,我在运行make时收到警告

 12 SRC := $(shell echo src/*.cpp)
 13 SRC += $(shell echo $(TEST_ROOT)/*.cpp)
 14 
 15 D_OBJECTS = $(SRC:.cpp=.o)       # same objects will need to be built differently
 16 R_OBJECTS = $(SRC:.cpp=.o)       # same objects will need to be built differently

 22 all: $(TARGET)
 23 
 25 $(TARGET): $(D_OBJECTS)
 26   $(CC) $(D_OBJECTS) -o $(TARGET)
 27 
 28 $(D_OBJECTS) : %.o: %.cpp                     # ----- run with debug flags 
 29   $(CC) $(COMMON_FLAGS) $(DEBUG_FLAGS) -c $< -o $@
 30 
 31 release: $(R_OBJECTS)
 32   $(CC) $(R_OBJECTS) -o $(TARGET)
 33 
 34 $(R_OBJECTS) : %.o: %.cpp                     # ----- run with release flags
 35   $(CC) $(COMMON_FLAGS) $(RELEASE_FLAGS) -c $< -o $@
有两个问题:

  • 有没有办法忽略这些警告
  • 我做得对吗?需要做哪些改变

  • 最常用的方法之一是将发布对象和调试对象放在单独的子目录中。这样就不会重新定义对象的规则,因为它们将有不同的名称。大概是这样的:

    D_OBJECTS=$(SRC:%.cpp=debug/%.o)
    R_OBJECTS=$(SRC:%.cpp=release/%.o)
    
    RTARGET = a.out
    DTARGET = a.out.debug
    
    all : dirs $(RTARGET)
    
    debug : dirs $(DTARGET)
    
    dirs :
        @mkdir -p debug release
    
    debug/%.o : %.c
        $(CC) $(DEBUG_CFLAGS) -o $@ -c $<
    
    release/%.o : %.c
        $(CC) $(RELEASE_CFLAGS) -o $@ -c $<
    
    $(DTARGET) : $(D_OBJECTS)
        $(CC) $(DEBUG_CFLAGS) -o $@ $(D_OBJECTS)
    
    $(RTARGET) : $(R_OBJECTS)
        $(CC) $(RELEASE_CFLAGS) -o $@ $(R_OBJECTS)
    
    D_OBJECTS=$(SRC:%.cpp=debug/%.o)
    R_OBJECTS=$(SRC:%.cpp=release/%.o)
    RTARGET=a.out
    DTARGET=a.out.debug
    全部:目录$(RTARGET)
    调试:dirs$(数据目标)
    目录:
    @mkdir-p调试版本
    调试/%.o:%.c
    $(CC)$(DEBUG_CFLAGS)-o$@-c$<
    发行量/%.o:%.c
    $(CC)$(发布时间)-o$@-c$<
    $(数据目标):$(数据对象)
    $(CC)$(DEBUG_CFLAGS)-o$@$(D_对象)
    $(RTARGET):$(R\u对象)
    $(CC)$(RELEASE\u CFLAGS)-o$@$(R\u对象)
    
    与OP(James Leonard)一样,我希望抑制或避免关于覆盖
    Makefile
    目标的警告。然而,我的情况和目标是不同的

    我希望
    Makefile
    包含base.mk,我希望
    Makefile
    能够覆盖
    base.mk
    中的目标,而不显示任何警告消息。我正在使用GNU Make

    GNU Make文档描述了一种方法:

    创建
    Makefile
    ,如下所示:

    foo:
            echo 'bar' > foo
    
    %: force
            @$(MAKE) -f base.mk $@
    force: ;
    
    foo-default:
            echo  'foo-default'
    
    bar-default:
            echo  'bar-default'
    
    %:  %-default
            @  true
    
    include  base.mk
    
    foo:
            echo  'foo  Makefile'
    
    资料来源:

    上述方法有一个(潜在的严重)缺点,即它将调用
    $(MAKE)
    的单独实例,这意味着(部分或全部?)变量可能(将?)不会在MAKE的父调用和子调用之间共享

    幸运的是,我找到了一个更好的解决方案,如下所述:

    创建
    base.mk
    ,如下所示:

    foo:
            echo 'bar' > foo
    
    %: force
            @$(MAKE) -f base.mk $@
    force: ;
    
    foo-default:
            echo  'foo-default'
    
    bar-default:
            echo  'bar-default'
    
    %:  %-default
            @  true
    
    include  base.mk
    
    foo:
            echo  'foo  Makefile'
    
    创建
    Makefile
    ,如下所示:

    foo:
            echo 'bar' > foo
    
    %: force
            @$(MAKE) -f base.mk $@
    force: ;
    
    foo-default:
            echo  'foo-default'
    
    bar-default:
            echo  'bar-default'
    
    %:  %-default
            @  true
    
    include  base.mk
    
    foo:
            echo  'foo  Makefile'
    
    示例输出:

    $ make foo
    echo  'foo  Makefile'
    foo  Makefile
    
    $ make bar
    echo  'bar-default'
    bar-default
    

    请注意,您需要能够在
    base.mk
    中控制目标的名称,以便可以将它们命名为
    -default
    。换句话说,您不能使用这种方法来扩展任意的基本makefile。但是,如果您同时控制
    base.mk
    Makefile
    ,这种方法将允许您创建一个
    base.mk
    ,然后对其进行许多自定义。

    我编写了自己的make并注释掉了打印这些警告的部分。工作起来很有魅力。将第2114行周围的v4.2改为.c。为避免多次包含同一文件,可以使用c样式的头“指令”:

    ifeq ($(_MY_MAKEFILE_),)
    _MY_MAKEFILE_ := defined
    
    ...
    
    endif
    
    • ifeq
      这里只是说“值是否为空”
    • 如果使用
      ifndef
      也可以做类似的事情,但我先让它工作了
    • 值“defined”就是不是空的任何东西

    您知道如何在自动生成Makefile的netbeans中实现这一点吗?或者,如果您对多个二进制文件有相同的代码,请创建一个库作为答案。非常适合我的箱子,我爱这个!现在在这里使用它:谢谢你的回答。我试着用这种方法处理变量,比如。但没有运气。(有效,但有警告)(gmake 4.2.1)。我可以使用-default扩展所有命令,但我希望它保持干燥。如果有人能解决这个问题,请在这里添加评论…@benok-你试过GNU make的
    foreach
    功能吗@mpb,谢谢你的评论。我想在不久的某个时候查看并尝试使用
    foreach
    。您建议注释掉代码并不是为了回答问题。