如何编写基于通用规则的makefile
我有以下文件夹结构如何编写基于通用规则的makefile
--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
如何编写基于模式的规则?我尝试了许多堆栈溢出的答案,但无法使其工作。
首先我把我的源使用通配符,但不能写适当的目标为源列表有[来源/ boot.s源/ 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 [email protected]
$(BUILD)%.o : $(SOURCE)%.c
$(CC) $(CFLAGS) -c $< -o [email protected]
$(BUILD)$(TARGET): $(BUILD)kernel.elf
arm-none-eabi-objcopy $< -O binary [email protected]
$(BUILD)kernel.elf: $(OBJECTS)
$(LD) $(LDFLAGS) -o [email protected] $^
# Rule to clean files.
clean :
-rm -f $(BUILD)*
-rm -f *.o
-rm -f *.elf
-rm -f *.img
这是错误的:
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 [email protected]
既然你正在构建$(BUILD)xxx.o
你必须使用为前提一样,所以你必须写:
$(BUILD)$(TARGET): $(BUILD)kernel.elf
arm-none-eabi-objcopy $< -O binary [email protected]
$(BUILD)kernel.elf: $(BUILD)boot.o $(BUILD)kernel.o
$(LD) $(LDFLAGS) -o [email protected] $^
ETA
如果你想获得通过通配符您可以将源文件,但你需要替换的目录,以及不只是后缀,像这样:
SOURCES := $(wildcard $(SOURCE)*.s)
OBJECTS := $(patsubst $(SOURCE)%.s,$(BUILD)%.o,$(SOURCES))
如果你有汇编和C源文件(你没有显示在你的例子生成文件的任何C源文件),你可以使用这个:
SOURCES := $(wildcard $(SOURCE)*.s) $(wildcard $(SOURCE)*.c)
OBJECTS := $(patsubst $(SOURCE)%,$(BUILD)%.o,$(basename $(SOURCES)))
我将它包含在我的Makefile中。但必须添加一些东西。 'SOURCES = $(通配符$(SOURCE)*。S)$(通配符$(SOURCE)*。C) OBJECTS = $(滤波器%的.o,\ \t $(patsubst $(SOURCE)%。 S,$(BUILD)%。O,$(SOURCES))\ \t $(patsubst $(SOURCE)%C,$(BUILD)%。$(SOURCES))) $(BUILD)kernel.elf:$(OBJECTS) $(LD)$(LDFLAGS)-o $ @ $ ^' – zero
正如您所看到的,您不能将格式化的内容添加到注释中在SO。您必须编辑您的问题,而不是将其设置为可读格式。我更新了我的答案。 – MadScientist
你说“我试过很多[东西],但无法使其工作“。当提问时,显示你所尝试的内容,显示你运行的命令,显示你得到的结果(剪切粘贴,而不是释义),并解释为什么你的输出不是你想要的。 – MadScientist
我是新来堆栈溢出。我将编辑我的问题并添加更多详细信息。 – zero