0

我今天一直在努力解决这个问题。

我在许多目录中有许多 c 文件。它们都需要编译并链接到库。

这是文件的假设布局:

main_dir/
  thing1/
    thing1.c
  thing2/
    thing2.c
  thing3/
    thing3.c
MakeFile

我有一个生成文件,可以“找到”这些文件并生成必要的对象,但是,始终使用同一个 c 文件作为输入。

这就是 Makefile 的样子(每个文件的内容都是一个使用 puts() 的函数):

C=gcc
CFLAGS=-Wall -g
OBJDIR=obj
SRC=$(shell find src/ -type f -name "*.c")
SRC_DIRS=$(shell find src/ -type f -name "*.c" -exec dirname {} \; | uniq)
OBJS=$(SRC:%.c=${OBJDIR}/%.o)    

$(OBJS) : $(SRC)
    @echo Compiling : $<
    $(C) -c $(CFLAGS) -o $@ $<

clean:
    rm -fv $(OBJS) thingy.a

folders:
    $(call build_dirs)

all: folders $(OBJS)
    ar -r -o thingy.a $(OBJS)

define build_dirs
    for dir in $(SRC_DIRS); do \
        mkdir -pv $(OBJDIR)/$$dir; \
    done
endef

制作的输出:

for dir in src/thing1 src/thing2 src/thing3; do mkdir -pv obj/$dir; done
Compiling : src/thing1/thing1.c
gcc -c -Wall -g -o obj/src/thing1/thing1.o src/thing1/thing1.c
Compiling : src/thing1/thing1.c
gcc -c -Wall -g -o obj/src/thing2/thing2.o src/thing1/thing1.c
Compiling : src/thing1/thing1.c
gcc -c -Wall -g -o obj/src/thing3/thing3.o src/thing1/thing1.c
ar -r -o thingy.a obj/src/thing1/thing1.o obj/src/thing2/thing2.o obj/src/thing3/thing3.o
ar: creating thingy.a

我很确定问题是我在 $(OBJS) 中使用了 $(SRC) : $(SRC) 但是,我只是不知道该怎么做。

任何有MakeFu的人可以提供帮助吗?

4

2 回答 2

1

您的 $(OBJS) 似乎设置正确,因此以下应该有效(而不是 $(OBJ) : $(SRC) 目标):

$(OBJDIR)/%.o : %.c
    @echo Compiling : $<
    $(C) -c $(CFLAGS) -o $@ $<
于 2012-09-27T19:11:45.603 回答
1

你说得对,$(OBJS)规则就是问题所在。

查看变量:(SRC)issrc/thing1/thing1.c src/thing2/thing2.c src/thing3/thing3.c$(OBJS)is obj/src/thing1/thing1.o obj/src/thing2/thing2.o obj/src/thing3/thing3.o。(你确定你想要一个src目录obj/吗?)现在假设你想obj/src/thing2/thing2.o使用这个规则来构建:

$(OBJS) : $(SRC)
    @echo Compiling : $<
    $(C) -c $(CFLAGS) -o $@ $<

先决条件字段 ( $(SRC)) 扩展为“ src/thing1/thing1.c src/thing2/thing2.c src/thing3/thing3.c”,因此$<扩展为“ src/thing1/thing1.c ”。显然,在这种情况下您想要的是“ src/thing2/thing2.c ”,所以这就是先决条件字段应该是什么。您需要的是类似模式规则静态模式规则的东西。诀窍是你不提前知道路径,而且 Make 不能很好地处理模式,所以我们必须灵巧:

$(OBJS) : $(OBJDIR)/%.o : %.c
    @echo Compiling : $<
    $(C) -c $(CFLAGS) -o $@ $<
于 2012-09-27T23:53:03.780 回答