在 Makefile 中设置变量的规则未按预期工作

Rule to set a variable in Makefile not working as expected

我正在编写一个 makefile,它可以根据使用的规则编译不同的项目。为此,我需要设置某些变量来设置路径并生成正确的输出文件。

这是当前无效的部分:

bubblesort: OUTPROG = bubblesort
bubblesort: APP_PATH    = $(SRCS)/bubblesort
bubblesort: OBJS    = ../programs/bubblesort/bubblesort.o
bubblesort: $(COMMON_OBJS) $(OBJS)
    @ echo "<-------------------- Making Bubblesort -------------------->"
    @ echo "<-------------------- Linking files -------------------->"
    $(LD) $(COMMON_OBJS) $(OBJS) $(LDFLAGS)
    @ echo "<-------------------- ELF to Binary File -------------------->"
    $(OC) $(OCFLAGS) $(TARGET) $(BINOUT)
    @ echo "<-------------------- Binary to Verilog Conversion -------------------->"
    $(R2V) $(R2VPARAMS) 


# This is the rule to transform any c code to object file via compilation.
%.o : %.c
    @ echo "<-------------------- Compiling C Source Files -------------------->"
    $(CC) $(CFLAGS_APP) $< -o $@

发生的事情是从未调用生成 .o 的 c 源代码的编译(%.o: %.c 规则)。然而这有效:

OBJS        = ../programs/bubblesort/bubblesort.o
bubblesort: OUTPROG = bubblesort
bubblesort: APP_PATH    = $(SRCS)/bubblesort
bubblesort: $(COMMON_OBJS) $(OBJS)
    @ echo "<-------------------- Making Bubblesort -------------------->"
    @ echo "<-------------------- Linking files -------------------->"
    $(LD) $(COMMON_OBJS) $(OBJS) $(LDFLAGS)
    @ echo "<-------------------- ELF to Binary File -------------------->"
    $(OC) $(OCFLAGS) $(TARGET) $(BINOUT)
    @ echo "<-------------------- Binary to Verilog Conversion -------------------->"
    $(R2V) $(R2VPARAMS) 

我的问题很简单,为什么?我将不胜感激。

编辑:

另外,如何使先决条件依赖于调用的规则?

编辑 2:

根据 Etan Raiser 的建议,我将代码修改为如下所示:

bubblesort: OUTPROG = bubblesort
bubblesort: APP_PATH    = $(SRCS)/bubblesort
bubblesort: $(COMMON_OBJS) ../programs/bubblesort/bubblesort.o creation

creation: $^
    @ echo "<-------------------- Making in general -------------------->"
    @ echo "<-------------------- Linking files -------------------->"
    $(LD) $^ $(LDFLAGS)
    @ echo "<-------------------- ELF to Binary File -------------------->"
    $(OC) $(OCFLAGS) $(TARGET) $(BINOUT)
    @ echo "<-------------------- Binary to Verilog Conversion -------------------->"
    $(R2V) $(R2VPARAMS) 
    @ echo "<-------------------- Creating Obj Dump -------------------->"
    $(OD) $(ODFLAGS) $(TARGET) > $(APP_PATH)/$(OUTPROG)_DUMP.txt

是变量展开时间的问题。 (参见 How make Reads a Makefile。)

目标行bubblesort: $(COMMON_OBJS) $(OBJS)立即展开

目标特定变量行 bubblesort: OBJS = ../programs/bubblesort/bubblesort.o 不是 "executed"(实际执行赋值),直到 bubblesort 目标被 运行.

而不是这个(不起作用):

bubblesort: OUTPROG = bubblesort
bubblesort: APP_PATH    = $(SRCS)/bubblesort
bubblesort: OBJS    = ../programs/bubblesort/bubblesort.o
bubblesort: $(COMMON_OBJS) $(OBJS)
    @ echo "<-------------------- Making Bubblesort -------------------->"
    @ echo "<-------------------- Linking files -------------------->"
    $(LD) $(COMMON_OBJS) $(OBJS) $(LDFLAGS)
    @ echo "<-------------------- ELF to Binary File -------------------->"
    $(OC) $(OCFLAGS) $(TARGET) $(BINOUT)
    @ echo "<-------------------- Binary to Verilog Conversion -------------------->"
    $(R2V) $(R2VPARAMS) 

并且需要 $(OBJ) 变量用于 $(LD) 调用。

您可以使用:

bubblesort: OUTPROG = bubblesort
bubblesort: APP_PATH    = $(SRCS)/bubblesort
bubblesort: $(COMMON_OBJS) ../programs/bubblesort/bubblesort.o
    @ echo "<-------------------- Making Bubblesort -------------------->"
    @ echo "<-------------------- Linking files -------------------->"
    $(LD) $^ $(LDFLAGS)
    @ echo "<-------------------- ELF to Binary File -------------------->"
    $(OC) $(OCFLAGS) $(TARGET) $(BINOUT)
    @ echo "<-------------------- Binary to Verilog Conversion -------------------->"
    $(R2V) $(R2VPARAMS)

它可以正常工作并使用内置 $^ 自动变量来达到预期目的。

写宏的时候,比如OBJS,用':=' 所以宏创建只会执行一次 而不是在每次调用宏时重复。

“:”之前的第一个词是目标名称。 “:”右侧的所有内容都是该目标的依赖项 我有点惊讶 make 没有失败 由于多个重复目标。

编写这些规则的更好方法是:

# when invoking 'make', use 'target=bubblesort'
# so the same makefile can be used for several targets:

APP_PATH    := $(SRC_PATH)/$(target)/
SRCS        := $(wildcard $(APP_PATH)*.c)
OBJS        := ../programs/$(target)/$(basename:$(SRCS):.c=.o)
$(target)   : $(COMMON_OBJS) $(OBJS)
    # 
    # ========= LINKING ${target} ==============
    $(LD) $(LDFLAGS) $(COMMON_OBJS) $(OBJS) -o $(target) 
    #<-------------------- ELF to Binary File -------------------->"
    $(OC) $(OCFLAGS) $(TARGET) $(BINOUT)
    #<-------------------- Binary to Verilog Conversion ---------->"
    $(R2V) $(R2VPARAMS) 
    # ========= finished ${target} =============


# This is the rule to transform any c code to object file via compilation.
%.o : %.c
    # ========= COMPILING $< TO $@ =========
    $(CC) $(CCFLAGS_APP) -c $< -o $@  
    # ========= END $< TO $@ =========

但是,发布的规则没有考虑到:

  1. 源代码#include dependencies
  2. 需要为每个 .c 文件生成依赖列表
  3. 需要扩展适当的依赖列表 在“%o.%c”行
  4. 需要通过路径引用依赖列表 在“${CC}”行上以“-Ipath”参数的形式
  5. 如果依赖列表不是 generated/used,那么 头文件中的更改将无法强制执行 一个re-compile/re-link,等等