Make中的通配符模式匹配

问题描述 投票:1回答:1

这是我的项目结构。

| - 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 $@ > [email protected]

以下内容无效。它不运行任何命令。

#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 $@ > [email protected]

完全没有运行,由于某种原因,似乎没有文件符合该模式。

我也尝试过这个。

# 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 $@ > [email protected]

编辑完整的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)/[email protected]
#   $(DUMP) -D $(TARGET_DIR)/[email protected] > $(TARGET_DIR)/[email protected]


$(TARGET_DIR)/%.o : $(SRC_DIR)/boot/%.s machine
    @echo "compiling $<"
    $(CC) $(CFLAGS) $< -o $@
    @echo "assembly dump $@"
    $(DUMP) -D $@ > [email protected]

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)
makefile riscv
1个回答
1
投票

与其他问题一样,您期望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 $@ > [email protected]

# It must be .PHONY, not .phony: make, like all POSIX tools, is
# case-sensitive

.PHONY: clean
clean:
        rm -rf $(TARGET_DIR)

参考:

还请注意,您的编译命令中有错误;您缺少sort and patsubst functions选项,该选项告诉编译器生成一个目标文件,而不是最终的可执行文件。

© www.soinside.com 2019 - 2024. All rights reserved.