2017-11-25 222 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