编译包含许多目录的文件列表

时间:2012-09-27 18:38:30

标签: c makefile gnu-make

我今天一直在讨论这个问题。

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

以下是文件的假设布局:

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

我有一个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

我非常肯定问题是我使用$(SRC)    $(OBJS):$(SRC) 但是,我只是不知道该怎么做。

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

2 个答案:

答案 0 :(得分:1)

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

$(OBJDIR)/%.o : %.c
    @echo Compiling : $<
    $(C) -c $(CFLAGS) -o $@ $<

答案 1 :(得分:1)

你对$(OBJS)规则是正确的问题是正确的。

查看变量:(SRC)src/thing1/thing1.c src/thing2/thing2.c src/thing3/thing3.c$(OBJS)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”,因此{{1扩展为“ src / thing1 / thing1.c ”。显然,在这种情况下你想要的是“ src / thing2 / thing2.c ”,这就是前提条件字段应该是什么。您需要的是pattern rulestatic pattern rule。诀窍在于你不提前知道路径,并且Make不能很好地处理模式,所以我们必须灵巧:

$<