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

C 设置Makefile中的变量未按预期工作的规则,c,makefile,C,Makefile,我正在编写一个makefile,它可以根据使用的规则编译不同的项目。为此,我需要设置某些变量来设置路径并生成正确的输出文件 这是当前不起作用的部分: bubblesort: OUTPROG = bubblesort bubblesort: APP_PATH = $(SRCS)/bubblesort bubblesort: OBJS = ../programs/bubblesort/bubblesort.o bubblesort: $(COMMON_OBJS) $(OBJS)

我正在编写一个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 $@
bubblesort:OUTPROG=bubblesort
bubblesort:APP_PATH=$(SRCS)/bubblesort
bubblesort:OBJS=../programs/bubblesort/bubblesort.o
bubblesort:$(通用对象)$(对象)
@回声“”
@回声“”
$(LD)$(通用对象)$(对象)$(LDFLAGS)
@回声“”
$(OC)$(OCFLAGS)$(目标)$(BINOUT)
@回声“”
$(R2V)$(R2V参数)
#这是通过编译将任何c代码转换为目标文件的规则。
%.o:%.c
@回声“”
$(CC)$(CFLAGS_应用程序)$<-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) 
OBJS=../programs/bubblesort/bubblesort.o
bubblesort:OUTPROG=bubblesort
bubblesort:APP_PATH=$(SRCS)/bubblesort
bubblesort:$(通用对象)$(对象)
@回声“”
@回声“”
$(LD)$(通用对象)$(对象)$(LDFLAGS)
@回声“”
$(OC)$(OCFLAGS)$(目标)$(BINOUT)
@回声“”
$(R2V)$(R2V参数)
我的问题是为什么?如果您有任何意见,我将不胜感激

编辑:

另外,如何使前提条件依赖于调用的规则

编辑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
bubblesort:OUTPROG=bubblesort
bubblesort:APP_PATH=$(SRCS)/bubblesort
bubblesort:$(公共对象)…/programs/bubblesort/bubblesort.o创建
创建:$^
@回声“”
@回声“”
$(LD)$^$(LDFLAGS)
@回声“”
$(OC)$(OCFLAGS)$(目标)$(BINOUT)
@回声“”
$(R2V)$(R2V参数)
@回声“”
$(OD)$(ODFLAGS)$(TARGET)>$(APP\u PATH)/$(OUTPROG)\u DUMP.txt

这是一个可变扩展时间的问题。(见附件。)

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

特定于目标的变量行
bubblesort:OBJS=../programs/bubblesort/bubblesort.o
在运行
bubblesort
目标之前不会“执行”(实际执行赋值)

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


它工作并使用内置的
$^
自动变量来实现其预期目的。

在编写宏(如OBJS)时,请使用“:=” 因此,宏创建将只执行一次 而不是在每次调用宏时重复

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

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

# 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 $@ =========
#调用“make”时,使用“target=bubblesort”
#因此,相同的makefile可用于多个目标:
应用程序路径:=$(SRC\u路径)/$(目标)/
SRCS:=$(通配符$(应用程序路径)*.c)
OBJS:=../programs/$(target)/$(basename:$(SRCS):.c=.o)
$(目标):$(普通对象)$(对象)
# 
#=======链接${target}==============
$(LD)$(LDFLAGS)$(COMMON_OBJS)$(OBJS)-o$(目标)
#"
$(OC)$(OCFLAGS)$(目标)$(BINOUT)
#"
$(R2V)$(R2V参数)
#=======已完成${target}=============
#这是通过编译将任何c代码转换为目标文件的规则。
%.o:%.c
#=======将$<编译为$@=========
$(CC)$(CCFLAGS\u APP)-c$<-o$@
#=======结束$<到$@=========
但是,发布的规则没有考虑到:

  • 源代码#包含依赖项
  • 需要为每个.c文件生成依赖项列表
  • 需要扩展相应的依赖项列表 在“%o.%c”行上
  • 依赖项列表需要通过路径引用 以“-Ipath”参数的形式在“${CC}”行上
  • 如果未生成/使用依赖项列表,则 头文件中的更改将无法强制执行 重新编译/重新链接等

  • 谢谢,我已经编辑了这个问题,询问如何修改我的makefile,使前提条件取决于调用的规则。它确实取决于它。如果您在此处手动列出了任何
    .o
    文件,则该文件规则中的
    $(OBJS)
    值将是特定于
    的泡泡排序值。你只是不能用你想要的方式在一个先决条件下使用它。我不确定我是否理解。所以我会努力更好地表达自己。现在的情况如果我想要两个不同的规则(比如一个用于bubblesort,一个用于quicksort),我需要用与chagin OBJS用于类似OBJS_quicksort(包含用于快速排序的.o文件列表)的方法完全相同的方法来编写配方。但是其他的一切都是一样的,我正在尝试复制和粘贴这么多代码。有什么方法可以避免这种情况吗?不要使用特定于目标的变量使用单个变量。因此,
    COMMON_OBJS
    QUICKSORT_OBJS
    ,以及
    BUBBLESORT_OBJS
    。或者根本不使用它们,直接把它们写在必备行上(因为你可以而且应该在你的食谱行中使用
    $^
    和另一行)。谢谢,但我仍然不明白替代方法。我已经阅读了您显示给我的页面,但是我不明白使用$^会有什么帮助。也许是一个例子?这里的一些要点非常有用,但是格式使我们很难理解这个答案。同样在这个特定的例子中,
    :=
    并没有真正获得任何东西。这也不允许同时构建两者。而且
    -Dtarget=bubblesort
    不正确,可能是
    make target=bubblesort
    @EtanReisner,请指出阅读帖子的难点,以便我将来可以改进此类帖子顺便说一句:规则中以“#”开头的行将正确地表示为
    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)
    
    # 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 $@ =========