我的源代码不是集中的。我想将所有对象放入单个目录SwitchToFiber
中。
这是我到目前为止所拥有的
SwitchToFiber
这对我来说并不完全有效,因为它会创建makefile所在的一些文件和目录。我真正想要的是所有./build/obj
文件都位于ROOT=.
BUILDDIR=$(ROOT)/build
BINDIR=$(BUILDDIR)/bin
OBJDIR=$(BUILDDIR)/obj
CC=$(XCOMPILE)gcc
BIN=my-reader
CFLAGS+=\
-Wall \
-Wextra \
-Werror \
-pedantic \
-std=gnu11 \
$(INCLUDE)
SRCDIRS+=\
$(ROOT)/src \
$(ROOT)/../../folder0/folder01/src \
$(ROOT)/../../folder0/folder02/src \
$(ROOT)/../../folder1/folder03/folder04/i2c/src \
$(ROOT)/../../folder1/folder03/folder04/spi/src \
$(ROOT)/../../folder1/folder03/folder04/system/src \
$(ROOT)/../../folder2/folder03/folder04/chip-1-api/src \
$(ROOT)/../../folder2/folder03/folder04/chip-2-api/src
DEPDIRS+=\
$(SRCDIRS)
SRC+=$(shell find $(SRCDIRS) -type f -name "*\.c")
DEP+=$(shell find $(DEPDIRS) -type f -name "*\.h")
OBJ=$(patsubst %.c, $(OBJDIR)/%.o, $(SRC))
INCLUDE=$(foreach d, $(DEP),-I $(dir $d))
test:
echo $(SRC)
all: CFLAGS+=-O3
all: _all
debug: CFLAGS+=-ggdb
debug: CPPFLAGS+=-DDEBUG
debug: _all
_all: $(BINDIR) $(BINDIR)/$(BIN)
$(BINDIR)/$(BIN): $(OBJ) | $(BINDIR)
$(CC) $(CPPFLAGS) $(CFLAGS) $^ -o $@
$(BINDIR):
mkdir -p $@
$(OBJDIR)/%.o: %.c $(DEP)
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
.PHONY: clean
clean:
rm -rf $(BUILDDIR)
中。我花了几天的时间试图弄清楚是否有一种通用的方法,但似乎没有。据我了解,为了将所有文件放入.o
目录,我需要为每个文件创建一个特定的目标,这违背了使用通用Makefile的目的。有人知道我要做什么吗?我见过人们生成./build/obj
(其中有自定义目标)文件,然后将它们包含在makefile中。不幸的是我不知道该怎么做。感谢您的帮助。
答案 0 :(得分:1)
这很简单,using VPATH。首先,您必须确保OBJS
变量包含要构建的变量。当前,您有以下内容:
OBJ=$(patsubst %.c, $(OBJDIR)/%.o, $(SRC))
这是错误的,因为SRC
包含./../../folder0/folder02/src/foobar.c
之类的路径,这意味着在patsubst
之后,您将获得./build/obj/./../../folder0/folder02/src/foobar.o
之类的路径,这显然不是您想要的。改用它:
OBJ = $(patsubst %.c, $(OBJDIR)/%.o, $(notdir $(SRC)))
对于每个源文件somepath/foobar.c
,无论 somepath 的值如何,它都会给您./build/obj/foobar.o
,这就是您想要的。
然后,保留从.c文件构建此.o的规则。最后,使用VPATH告诉make如果本地目录中不存在源文件,请在哪里查找:
VPATH = $(SRCDIRS)
这就是您要做的一切。
我应该指出,您的INCLUDES
有点破损:您将为-I
添加大量重复目录。代替这个:
INCLUDE=$(foreach d, $(DEP),-I $(dir $d))
您应该使用:
INCLUDE = $(addprefix -I,$(sort $(dir $(DEP)))
sort
函数也将变得唯一,并且您不需要foreach
,因为make中的大多数函数都需要多个单词并对其全部进行操作。
最后一点,您应该使用:=
而不是=
,它会效率更高。每次扩展这些变量时,您在此处编写的方式将重新运行find
等操作。在{{1}之前的echo find 1>&2;
函数调用中插入shell
},并查看其运行了多少次...
哦,那是最后的笔记:现在设置此文件的方式将在任何头文件发生更改时重新构建每个单个源文件(您已将find
添加为$(DEPS)
的先决条件目标)。也许这就是您想要的,但这很不寻常。