我有以下文件夹结构
--Makefile
--source/
--boot.s
--kernel.c
--linker.ld
--build/
我使用以下Makefile编译我的源代码
###############################################################################
#
# A makefile script for generation of raspberry pi kernel images.
#
###############################################################################
# The toolchain to use. arm-none-eabi works, but there does exist
CC = arm-none-eabi-gcc
LD = arm-none-eabi-gcc
# The intermediate directory for compiled object files.
BUILD = build/
# The directory in which source files are stored.
SOURCE = source/
CFLAGS = -march=armv8-a+crc \
-mcpu=cortex-a53 \
-mtune=cortex-a53 \
-mfpu=crypto-neon-fp-armv8 \
-mfloat-abi=hard \
-ftree-vectorize \
-funsafe-math-optimizations \
-O2 -pipe -ffreestanding
LDFLAGS = -T $(SOURCE)linker.ld -ffreestanding -O2 -nostdlib
# The name of the output file to generate.
TARGET = kernel.img
.PHONY: all clean run
# Rule to make everything.
all: $(TARGET)
# Rule to remake everything. Does not include clean.
rebuild: clean all
#Rule to invoke qemu
run:
qemu-system-arm -m 256 -M raspi2 -serial stdio -kernel $(BUILD)kernel.elf
$(TARGET): kernel.elf
arm-none-eabi-objcopy $(BUILD)kernel.elf -O binary $(BUILD)kernel.img
kernel.elf: boot.o kernel.o
$(LD) $(LDFLAGS) -o $(BUILD)kernel.elf $(BUILD)boot.o $(BUILD)kernel.o
boot.o: $(SOURCE)boot.s
$(CC) $(CFLAGS) -c $(SOURCE)boot.s -o $(BUILD)boot.o
kernel.o: $(SOURCE)boot.s
$(CC) $(CFLAGS) -c $(SOURCE)kernel.c -o $(BUILD)kernel.o
# Rule to clean files.
clean :
-rm -f $(BUILD)*
-rm -f *.o
-rm -f *.elf
-rm -f *.img
如何编写基于模式的规则?我尝试了很多堆栈溢出答案,但无法使其工作。
首先我使用通配符列出了我的源代码,但无法编写正确的目标,因为源列表有[source / boot.s source / kernel.c],它会自动在源文件夹中创建目标文件。
我在保持资源和构建目录方面遇到了困难。任何帮助表示赞赏。
----------根据@MadScientist的完整解决方案-----------
###############################################################################
#
# A makefile script for generation of raspberry pi kernel images.
#
###############################################################################
# The toolchain to use. arm-none-eabi works, but there does exist
CC = arm-none-eabi-gcc
LD = arm-none-eabi-gcc
# The intermediate directory for compiled object files.
BUILD = build/
# The directory in which source files are stored.
SOURCE = source/
CFLAGS = -march=armv8-a+crc \
-mcpu=cortex-a53 \
-mtune=cortex-a53 \
-mfpu=crypto-neon-fp-armv8 \
-mfloat-abi=hard \
-ftree-vectorize \
-funsafe-math-optimizations \
-O2 -pipe -ffreestanding
LDFLAGS = -T $(SOURCE)linker.ld -ffreestanding -O2 -nostdlib
SOURCES := $(wildcard $(SOURCE)*.s) $(wildcard $(SOURCE)*.c)
OBJECTS := $(patsubst $(SOURCE)%,$(BUILD)%.o,$(basename $(SOURCES)))
# The name of the output file to generate.
TARGET = kernel.img
.PHONY: all clean run
# Rule to make everything.
all: $(BUILD)$(TARGET)
# Rule to remake everything. Does not include clean.
rebuild: clean all
#Rule to invoke qemu
run:
qemu-system-arm -m 256 -M raspi2 -serial stdio -kernel $(BUILD)kernel.elf
$(BUILD)%.o : $(SOURCE)%.s
$(CC) $(CFLAGS) -c $< -o $@
$(BUILD)%.o : $(SOURCE)%.c
$(CC) $(CFLAGS) -c $< -o $@
$(BUILD)$(TARGET): $(BUILD)kernel.elf
arm-none-eabi-objcopy $< -O binary $@
$(BUILD)kernel.elf: $(OBJECTS)
$(LD) $(LDFLAGS) -o $@ $^
# Rule to clean files.
clean :
-rm -f $(BUILD)*
-rm -f *.o
-rm -f *.elf
-rm -f *.img
答案 0 :(得分:1)
这是错误的:
boot.o: $(SOURCE)boot.s
$(CC) $(CFLAGS) -c $(SOURCE)boot.s -o $(BUILD)boot.o
您告诉make您的配方将构建一个名为boot.o
的文件,但它不会:它创建一个名为$(BUILD)boot.o
的文件,这是完全不同的。与您构建kernel.img
和kernel.elf
的规则相同。
如果要编写模式规则,%
只能匹配相同的部分。由于SOURCE
和BUILD
不相同,因此它们与%
部分不匹配。所以你必须写下这个:
$(BUILD)%.o : $(SOURCE)%.s
$(CC) $(CFLAGS) -c $< -o $@
由于你正在构建$(BUILD)xxx.o
,你必须将它作为先决条件,所以你必须写:
$(BUILD)$(TARGET): $(BUILD)kernel.elf
arm-none-eabi-objcopy $< -O binary $@
$(BUILD)kernel.elf: $(BUILD)boot.o $(BUILD)kernel.o
$(LD) $(LDFLAGS) -o $@ $^
ETA
如果你想通过通配符获取源文件,你必须替换目录,而不仅仅是后缀,如下所示:
SOURCES := $(wildcard $(SOURCE)*.s)
OBJECTS := $(patsubst $(SOURCE)%.s,$(BUILD)%.o,$(SOURCES))
如果你同时拥有汇编和C源文件(你的示例makefile中没有显示任何C源文件),你可以使用它:
SOURCES := $(wildcard $(SOURCE)*.s) $(wildcard $(SOURCE)*.c)
OBJECTS := $(patsubst $(SOURCE)%,$(BUILD)%.o,$(basename $(SOURCES)))