【问题标题】:makefile target specific variables as prerequisitesmakefile 将特定变量作为先决条件
【发布时间】:2012-06-05 04:16:36
【问题描述】:

相关:Target-specific Variables as Prerequisites in a Makefile

我正在尝试制作一个 Makefile,它使用特定于目标的变量来指定目标文件和最终可执行文件的输出目录。这个想法是维护两个独立的二进制版本,一个“发布”版本和一个带有额外调试信息的“调试”版本。

我的问题是“make”每次都会进行干净的构建,即使我没有更改任何内容。我很确定这是因为'make'在'debug'或'release'目标的先决条件中的变量声明之前评估目标'corewars'的先决条件。

Makefile 如下所示。

CXX=g++
LD=g++
LDFLAGS=
CXXFLAGS=-Iinclude -Wall -Wextra
OBJECTS=main.o Machine.o Core.o ProcessQueue.o Instruction.o
OUTPUT_DIR:=Test/

.PHONY: default
.PHONY: all
.PHONY: release
default: release
all: release
release: OUTPUT_DIR:=Release/
release: corewars

.PHONY: debug
debug: CXXFLAGS+=-DDEBUG -g
debug: OUTPUT_DIR:=Debug/
debug: corewars

corewars: $(OUTPUT_DIR) $(addprefix $(OUTPUT_DIR),$(OBJECTS))
    $(LD) -o $(addprefix $(OUTPUT_DIR),corewars) $(addprefix $(OUTPUT_DIR),$(OBJECTS))

Release:
    mkdir -p $@
Debug:
    mkdir -p $@

%.o: %.cpp include/%.h
    $(CXX) -c $(CXXFLAGS) $< -o $(OUTPUT_DIR)$@


.PHONY: clean
clean:
    $(RM) -r Release
    $(RM) -r Debug

【问题讨论】:

    标签: makefile gnu-make


    【解决方案1】:

    首先,一个非虚假食谱must create a target, $@, not $(OUTPUT_DIR)$@。还可以考虑将目录依赖项转换为order-only 先决条件。

    为了在先决条件列表中获得正确的$(OUTPUT_DIR) 值,您必须使用secondary expansion,否则,在主扩展期间,将使用全局定义OUTPUT_DIR:=Test/ 而不是目标-具体的。

    不幸的是,我想不出一种理智的方法来使用目标特定变量使其工作,而不求助于二次扩展和 vpath 魔法。我个人宁愿先设置环境(找出OUTPUT_DIR的值等),然后用正确的值重新执行Make。

    ifndef OUTPUT_DIR
    
    .PHONY: default all release debug
    
    default all: release
    
    release: export OUTPUT_DIR := Release/
    debug:   export OUTPUT_DIR := Debug/
    debug:   export EXTRA_CXXFLAGS := -DDEBUG -g
    
    release debug:
        @$(MAKE)
    
    else
    
    # ...
    CXXFLAGS := -Iinclude -Wall -Wextra $(EXTRA_CXXFLAGS)
    
    PROGRAM := $(OUTPUT_DIR)corewars
    OBJECTS := $(addprefix $(OUTPUT_DIR), \
        main.o Machine.o Core.o ProcessQueue.o Instruction.o)
    
    # Default target.
    $(PROGRAM): $(OBJECTS) | $(OUTPUT_DIR)
        $(LD) -o $@ $<
    
    $(OUTPUT_DIR)%.o: %.cpp | $(OUTPUT_DIR)
        $(CXX) -c $(CXXFLAGS) $< -o $@
    
    $(OUTPUT_DIR):
        mkdir -p $@
    
    endif # OUTPUT_DIR
    

    这两个部分可以拆分为单独的 makefile,根(启动器)一个,以及做实际工作的一个,以使整个事情更易于管理。

    【讨论】:

    • 这是对我的构建系统的出色清理,谢谢。我发现有必要将 | $(OUTPUT_DIR) 添加到规则的先决条件列表中以生成 .o 文件,并且我添加了一个“干净”目标,但除此之外,它可以按引用的方式工作。非常感谢。
    • @Chris,哦,是的,你说得对,我忘记了(已修复)。不客气! ;-)
    • 感谢您的提醒!我现在就解决这个问题。
    【解决方案2】:

    目标特定变量仅在目标配方及其递归先决条件的上下文中可用。也就是说,目标特定变量不能用作目标或先决条件

    一种解决方法是生成文件there

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-23
      • 2014-05-05
      • 2013-04-22
      • 1970-01-01
      • 2011-06-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多