Makefile找不到对象的规则

Makefile找不到对象的规则,makefile,Makefile,我的源代码分布在不在同一根目录下的多个目录中。我不想讨论为什么会出现这种情况,目前我只想编译它。我已经编写了一个Makefile来编译代码,但它告诉我它找不到创建object.o文件的规则。Makefile的代码如下所示。我做错了什么 TARGET=main ROOT_DIR:=. BUILD_DIR:=$(ROOT_DIR)/build OBJ_DIR:=$(BUILD_DIR)/obj TARGET_DIR:=$(BUILD_DIR)/bin OBJ:= src/main.o \

我的源代码分布在不在同一根目录下的多个目录中。我不想讨论为什么会出现这种情况,目前我只想编译它。我已经编写了一个Makefile来编译代码,但它告诉我它找不到创建object.o文件的规则。Makefile的代码如下所示。我做错了什么

TARGET=main

ROOT_DIR:=.
BUILD_DIR:=$(ROOT_DIR)/build
OBJ_DIR:=$(BUILD_DIR)/obj
TARGET_DIR:=$(BUILD_DIR)/bin

OBJ:= src/main.o \
    ../src/system.o \
    ../../LTC2947/src/LTC2947.o \
    ../../spi/src/my_spi.o

INC_DIR:=src ../src/ ../../LTC2947/src ../../spi/src/

CFLAGS := -O2 -g -Wall -Wextra -Werror -std=gnu99 -DDEBUG -L$(LIB_DIR)

#====================================================
TARGET_BIN:=$(TARGET_DIR)/$(TARGET)
_INC_DIR:=$(foreach _dir,$(INC_DIR), -I$(_dir))

# absolute paths for object files
_OBJ:=$(foreach _path, $(OBJ), $(abspath $(_path))) 
# prepend $(OBJ_DIR) to the oejct full paths
_OBJ2:=$(patsubst %,$(OBJ_DIR)/%,$(_OBJ))
# Remove double slashes
_OBJ:=$(shell echo $(_OBJ2) | sed 's,//,/,g')
OBJ_DIRS:=$(dir $(_OBJ))

BUILD_DIRS:= $(OBJ_DIRS) $(TARGET_DIR)

_CFLAGS := $(CFLAGS) $(_INC_DIR)

all: create-build-dirs $(TARGET_BIN)

$(TARGET_BIN): $(_OBJ)
    $(CC) -o $@ $^ $(_CFLAGS) $(LIBS)

%.o: %.c
    $(CC) $(_CFLAGS) -c $< -o $@

.PHONY: clean
clean:
    rm -rf $(BUILD_DIR)
    find . -type f \( -name *~ -o -name core \) -exec rm -f {} \;

create-build-dirs:
    mkdir -p $(BUILD_DIRS)
编辑

这就是生成的错误


没有规则使target/home/user/projects/myproject/spi/src/my_spi.o

请提供您看到的剪切和粘贴的确切错误消息,而不是抽象描述

这里有很多问题,但从根本上来说,这条规则:

%.o: %.c
        $(CC) $(_CFLAGS) -c $< -o $@
告诉make如何从文件路径.c构建文件路径.o。这两个文件中的PATH值必须是完全相同的字符串。在您的环境中,如果您提供了错误消息,则更清楚的是,您正在$OBJ_DIR中为不存在的源文件创建对象文件,因此这些路径不可能完全相同。这意味着您要求make构建一个目标$OBJ_DIR/foo/bar.o,make将尝试查找一个文件$OBJ_DIR/foo/bar.c,如果找不到,则此规则不匹配

其他一些注意事项:

您不需要将foreach与abspath一起使用;它有多个名字。你可以说$abspath$OBJ。 不需要sed shell命令将//替换为/;您只需使用$subst/,/,$\u OBJ2即可 由于创建输出目录的方式,您将无法在此处可靠地使用并行构建;它们可以与要使用它们的编译行并行创建。
我在编辑中提供了错误消息。我想我理解你对PATH.o的看法。当文件位于不同的目录中时,我不知道如何从.c创建.o。如果没有太复杂的Makefile,我该如何处理它呢?这个错误消息意味着你的Makefile有问题,因为据我所知,你希望你的对象文件出现在obj目录中,但错误消息没有列出。我不明白为什么要在OBJ变量中列出对象文件,而不是源文件,然后尝试将它们以OBJ_DIR作为前缀。也许,如果您试图在文本中清楚地写下您想要实现的目标,我们就会明白为什么您的makefile没有做到这一点。比如,我的源文件在这里,我希望我的目标文件和示例在那里。一个太复杂的makefile是一个主观的东西。如果不确切了解源文件的位置以及目标文件的放置位置,我们无法确定。但是,make找到对象和源文件之间关系的唯一方法是通过规则,您必须定义它们。如果您有许多不同的源目录,并且希望将输出放在与源目录无关的不同目录中,那么您必须为每个目录编写不同的规则。您希望我的_spi.o去哪里?