2017-11-25 226 views
0

我有以下文件夹结构如何编写基于通用规则的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 
+0

你说“我试过很多[东西],但无法使其工作“。当提问时,显示你所尝试的内容,显示你运行的命令,显示你得到的结果(剪切粘贴,而不是释义),并解释为什么你的输出不是你想要的。 – MadScientist

+0

我是新来堆栈溢出。我将编辑我的问题并添加更多详细信息。 – zero

回答

1

这是错误的:

boot.o: $(SOURCE)boot.s 
     $(CC) $(CFLAGS) -c $(SOURCE)boot.s -o $(BUILD)boot.o 

您正在告诉make您的食谱将生成一个名为boot.o的文件,但它不会:它会创建一个名为$(BUILD)boot.o的文件,它完全不同。与您的规则相同以建立kernel.imgkernel.elf

如果你想写一个模式规则,%只能匹配相同的部分。由于SOURCEBUILD不相同,它们将不匹配%部分。所以,你必须这样写:

$(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))) 
+0

我将它包含在我的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

+0

正如您所看到的,您不能将格式化的内容添加到注释中在SO。您必须编辑您的问题,而不是将其设置为可读格式。我更新了我的答案。 – MadScientist