Makefile自动编译,汇编和链接目录中的许多文件

时间:2017-09-30 21:06:15

标签: shell gcc makefile

很抱歉重复,但我找不到解决方案。 以下是我希望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

由于

2 个答案:

答案 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 $^