这是我的项目结构。
| - src
| - boot
| - table.s
| - boot.s
| - machine
| - revb
| - memmap
| - vars.s
| - os
| - utils
| - ...lots here
我正在按文件夹对功能进行分组,并且有一个专用文件夹,用于存储机器特定的代码,链接脚本等。
make遇到的问题是我似乎无法使Pattern匹配正常工作。
下面将运行并构建.o文件。
#This gets repetative as every file needs to have a recipe by itself.
$(TARGET_DIR)/hash.o : $(SRC_DIR)/utils/hash.s machine
@echo "compiling $<"
$(CC) $(CFLAGS) $< -o $@
@echo "assembly dump $@"
$(DUMP) -D $@ > $@.list
以下内容无效。它不会运行任何命令。
#if this works that would be perfect every folder/file will be a recipe!
$(TARGET_DIR)/%.o : $(SRC_DIR)/%.s machine
@echo "compiling $<"
$(CC) $(CFLAGS) $< -o $@
@echo "assembly dump $@"
$(DUMP) -D $@ > $@.list
一无所有,由于某种原因,似乎没有文件符合该格式。
我也尝试过这个。
# if this works, it would be a bit annoying as this is per feature recipe/target.
$(TARGET_DIR)/%.o : $(SRC_DIR)/boot/%.s machine
@echo "compiling $<"
$(CC) $(CFLAGS) $< -o $@
@echo "assembly dump $@"
$(DUMP) -D $@ > $@.list
修改 完整的makefile供参考
CFLAGS = -march=rv32i -mabi=ilp32
CC = riscv32-unknown-linux-gnu-as
LINKER = riscv32-unknown-linux-gnu-ld
DUMP = riscv32-unknown-linux-gnu-objdump
COPY = riscv32-unknown-linux-gnu-objcopy
SRC_DIR = src
TARGET_DIR = target
MACHINE_FILES_DIR = machine
TARGET_MACHINE = revb
# vizoros : $(TARGET_DIR)/%.o
# $(LINKER) $(TARGET_DIR)/boot.o $(TARGET_DIR)/table.o $(TARGET_DIR)/os.o $(TARGET_DIR)/hash.o -T $(TARGET_DIR)/memmap -o $(TARGET_DIR)/$@.elf
# $(DUMP) -D $(TARGET_DIR)/$@.elf > $(TARGET_DIR)/$@.list
$(TARGET_DIR)/%.o : $(SRC_DIR)/boot/%.s machine
@echo "compiling $<"
$(CC) $(CFLAGS) $< -o $@
@echo "assembly dump $@"
$(DUMP) -D $@ > $@.list
machine: folders
cp -r $(SRC_DIR)/$(MACHINE_FILES_DIR)/$(TARGET_MACHINE)/. $(TARGET_DIR)
folders:
mkdir -p $(TARGET_DIR)
.phony: clean
clean:
rm -rf $(TARGET_DIR)
答案 0 :(得分:1)
与其他问题一样,您期望make拥有太多的幻想功能。 Make是一个非常简单的工具。它不会在目录中四处寻找可以生成的文件。它只会完全按照您的要求进行构建。它不会根据启发式方法推断匹配的文件:它将仅匹配精确的字符串。
Make总是向后向后起作用:它从您要求它构建的最终目标开始,并找到可以构建该目标的规则。然后,它查看了最终目标的每个先决条件,并找到了可以构建每个目标的规则。然后,查看每个前提条件中的任何前提条件,等等。一旦构建(或找到目标的)所有前提条件的源文件,它将构建该目标,然后回溯直到最终构建最终目标你要的。
在上面的makefile中,您已注释了要构建的“最终目标”(vizoros
),因此make当然不会构建它。
我将为您提供一个可以解决您问题的makefile ...如果您想了解它的作用,请查阅GNU make手册。注意我实际上并没有尝试过,我只是在这里写的。还要注意,我省略了整个machine
的内容,因为我不知道它应该做什么,而您却没有真正定义它。
CFLAGS = -march=rv32i -mabi=ilp32
CC = riscv32-unknown-linux-gnu-as
LINKER = riscv32-unknown-linux-gnu-ld
DUMP = riscv32-unknown-linux-gnu-objdump
COPY = riscv32-unknown-linux-gnu-objcopy
SRC_DIR = src
TARGET_DIR = target
MACHINE_FILES_DIR = machine
TARGET_MACHINE = revb
# Find all .s files under SRC_DIR
SRCS := $(shell find $(SRC_DIR) -name \*.s)
# Use VPATH with a list of directories to be searched for
VPATH := $(sort $(dir $(SRCS)))
# Convert all .s files into .o files directly under TARGET_DIR
# First strip off the directory, then convert
OBJS := $(patsubst %.s,$(TARGET_DIR)/%.o,$(notdir $(SRCS)))
# Define the final target and provide all the object files as prerequisites
$(TARGET_DIR)/vizoros.elf : $(OBJS)
mkdir -p $(@D)
$(LINKER) $^ -T $(TARGET_DIR)/memmap -o $@
$(DUMP) -D $@ > $(@:.elf=.list)
# Define a pattern rule to build an object file in TARGET_DIR
# The source file will be searched for via VPATH
$(TARGET_DIR)/%.o : %.s
mkdir -p $(@D)
@echo "compiling $<"
$(CC) $(CFLAGS) -c $< -o $@
@echo "assembly dump $@"
$(DUMP) -D $@ > $@.list
# It must be .PHONY, not .phony: make, like all POSIX tools, is
# case-sensitive
.PHONY: clean
clean:
rm -rf $(TARGET_DIR)
参考文献:
=
vs :=
variables shell
function dir
and notdir
functions sort
and patsubst
functions VPATH
还要注意,您的编译命令有错误;您缺少-c
选项,该选项告诉编译器生成一个目标文件,而不是最终的可执行文件。