很抱歉重复,但我找不到解决方案。 以下是我希望Makefile完成的命令序列。
gcc-elf-gcc -S -combine loadStoreByte.c string.c lib_uart.c bubble_uart.c -o bubble_uart.s
gcc-elf-as -o startup.o startup.s;
gcc-elf-as -o handler.o handler.s;
gcc-elf-as -o bubble_uart.o bubble_uart.s;
gcc-elf-ld -o bubble_uart -T browtb.x bubble_uart.o startup.o handler.o;
也就是说,我想将所有C文件编译成单个S文件,然后将所有s文件汇编成相应的目标文件,并将所有目标文件链接成一个可执行文件。
我尝试了以下makefile。单个目标工作正常,但无法使用“make all”同时运行所有目标。 请指导如何修复它。
CC = brownie32-elf-gcc
AS = brownie32-elf-as
LK = brownie32-elf-ld
SFILE = $(wildcard *.s)
OFILE = $(patsubst %.s,%,$(SFILE))
CFILE = $(wildcard *.c)
OBJ = $(wildcard *.o)
APP = bubble_uart
all: compile assemble link
link: $(OBJ)
$(LK) -o $(APP) -T browtb.x $^
assemble: $(OFILE)
%: %.s compile
$(AS) -o $@.o $<
compile: $(CFILE)
$(CC) -S -combine $^ -o $(APP).s
clean:
rm -f $(OBJ) $(APP) $(APP).s *.o
由于
答案 0 :(得分:2)
你的makefile不是用&#34;最佳实践&#34;因此,你很容易犯错误。我将在此处重新编写您的makefile,并提供最佳实践,以解决您的所有问题。请借助GNU Make手册进行研究。
最大的问题是你有&#34;程序/动作&#34;,例如&#34;汇编&#34;作为目标。这使得makefile成为一种&#34;程序&#34;程序。 GNU Make并不是一种过程语言,而是一种声明性语言。 &#34;目标&#34;不应该是行动,而是实际的文件,或者&#34;假的&#34;文件,应该是实际文件的集合。
在makefile中使用wildcard
是一个坏主意 - 最好明确列出你的文件,如我所示。
请咨询我的回答 makefile enforce library dependency ordering 讨论良好做法,包括虚假和真实目标。
MAKEFILE := $(lastword $(MAKEFILE_LIST))
CFILES := \
loadStoreByte.c \
string.c \
lib_uart.c \
bubble_uart.c
SFILE_OUTPUT := bubble_uart.s
SFILES := $(SFILE_OUTPUT) \
startup.s \
handler.s
OFILES := $(SFILES:s=o)
APP := bubble_uart
.PHONY: all
all: $(APP)
$(APP): browtb.x $(OFILES) $(MAKEFILE)
gcc-elf-ld -o $@ -T $< $(OFILES)
$(OFILES): %o : %s $(MAKEFILE)
gcc-elf-as -o $@ $<
$(SFILE_OUTPUT): $(CFILES) $(MAKEFILE)
gcc-elf-gcc -S -combine $(CFILES) -o $@
答案 1 :(得分:0)
It is usually best if the target of a rule is the name of the file the rule produces.
所以compile
规则:
compile: $(CFILE)
$(CC) -S -combine $^ -o $(APP).s
应该是这样的:
$(APP).s: $(CFILE)
$(CC) -S -combine $^ -o $@
同样是对象规则:
%: %.s compile
$(AS) -o $@.o $<
应该是这样的:
%.o: %.s
$(AS) -o $@ $<
(没有理由依赖compile
或$(APP).s
,因为bubble_uart.s
与大多数目标文件无关。)
然后,目标文件列表应包含bubble_uart.o
:
SFILES = $(sort $(wildcard *.s) $(APP).s)
OFILES = $(patsubst %.s,%.o,$(SFILES))
(sort
将删除重复项。)请注意,这是构建可执行文件所需的目标文件列表,不恰好存在于的对象文件列表构建过程的开始。
最后,可执行文件:
$(APP): $(OFILES)
$(LK) -o $@ -T browtb.x $^