【问题标题】:Make file warning, overriding commands for target制作文件警告,覆盖目标命令
【发布时间】:2012-08-14 18:36:22
【问题描述】:

作为 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 $@

当我make 我得到调试版本,当我make release 我得到发布版本。

但我也收到警告:

Makefile:35: warning: overriding commands for target `src/Timer.o'
Makefile:29: warning: ignoring old commands for target `src/Timer.o'
Makefile:35: warning: overriding commands for target `test/TimerTest.o'
Makefile:29: warning: ignoring old commands for target `test/TimerTest.o'

这两个问题:

  1. 忽略警告的任何方式
  2. 我做对了吗?需要进行哪些更改?

【问题讨论】:

    标签: makefile warnings


    【解决方案1】:

    像 OP (James Leonard) 一样,我想禁止或避免有关覆盖 Makefile 目标的警告。但是,我的情况和目标不同。

    我希望 Makefileinclude base.mk,并且我希望 Makefile 能够覆盖来自 base.mk 的目标,而不会出现任何警告消息。我正在使用 GNU Make。

    GNU Make 文档描述了这样做的一种方法:

    如下创建Makefile

    foo:
            echo 'bar' > foo
    
    %: force
            @$(MAKE) -f base.mk $@
    force: ;
    

    来源:https://www.gnu.org/software/make/manual/html_node/Overriding-Makefiles.html

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

    很高兴,我找到了一个更好的解决方案,如下所述:

    如下创建base.mk

    foo-default:
            echo  'foo-default'
    
    bar-default:
            echo  'bar-default'
    
    %:  %-default
            @  true
    

    如下创建Makefile

    include  base.mk
    
    foo:
            echo  'foo  Makefile'
    

    示例输出:

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

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

    【讨论】:

    【解决方案2】:

    执行此操作的最常见方法之一是将发布对象和调试对象放在不同的子目录中。这样您就不会重新定义对象的规则,因为它们将具有不同的名称。像这样的:

    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)
    

    【讨论】:

    • 你知道如何在自动生成 Makefile 的 netbeans 中做到这一点吗?
    • 如果您有多个二进制文件的相同代码,请创建一个库
    【解决方案3】:

    为避免多次包含同一个文件,您可以使用 C 风格的标头“指令”:

    ifeq ($(_MY_MAKEFILE_),)
    _MY_MAKEFILE_ := defined
    
    ...
    
    endif
    
    • ifeq 这里只是说“值是空的”
    • ifndef 可以做类似的事情,但我首先得到了这个工作
    • “定义”的值就是任何非空白的值

    【讨论】:

      【解决方案4】:

      我遵守了自己的制作并注释掉了打印这些警告的部分。奇迹般有效。在第 2114 行附近制作 v4.2,read.c

      【讨论】:

      • 您建议注释掉代码并没有为答案做出贡献。
      猜你喜欢
      • 1970-01-01
      • 2011-06-10
      • 2020-03-01
      • 2019-12-22
      • 2013-08-31
      • 1970-01-01
      • 2011-01-04
      • 1970-01-01
      • 2021-03-04
      相关资源
      最近更新 更多