在 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 $@ =========
但是,发布的规则没有考虑到:
- 源代码#include dependencies
- 需要为每个 .c 文件生成依赖列表
- 需要扩展适当的依赖列表
在“%o.%c”行
- 需要通过路径引用依赖列表
在“${CC}”行上以“-Ipath”参数的形式
- 如果依赖列表不是 generated/used,那么
头文件中的更改将无法强制执行
一个re-compile/re-link,等等
我正在编写一个 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 $@ =========
但是,发布的规则没有考虑到:
- 源代码#include dependencies
- 需要为每个 .c 文件生成依赖列表
- 需要扩展适当的依赖列表 在“%o.%c”行
- 需要通过路径引用依赖列表 在“${CC}”行上以“-Ipath”参数的形式
- 如果依赖列表不是 generated/used,那么 头文件中的更改将无法强制执行 一个re-compile/re-link,等等