如何将所有C文件编译为Object并将其放在子目录中

时间:2016-10-31 19:55:32

标签: c linux makefile

如何将所有C文件编译成目标文件并将它们放在子目录中?

我有三个目录:

  1. [image]text - 其中main.c位于
  2. usr - 其中init_var1.c和init_var2.c位于
  3. sources1 - 头文件所在的位置
  4. include - 此目录应包含由1和2下列出的目录中的C源文件制作的目标文件。
  5. 我写了这个obj

    Makefile

    但输出是

    CC=gcc
    
    O_DIR = ./../obj
    I_DIR = ./../include
    
    SOURCES := $(wildcard *.c)
    OBJECTS := $(SOURCES:.c=.o)
    
    OBJECTS := $(addprefix $(O_DIR)/,$(OBJECTS))
    
    all: $(OBJECTS)
    
    $(OBJECTS): $(SOURCES)
        $(CC) -c -I$(I_DIR) $< -o $@
    

    但是,我需要

    make[1]: enter directory «/home/alexey/exercise/ex_makefile/source»
    gcc -c -I./../include init_var1.c -o ../obj/init_var1.o
    gcc -c -I./../include init_var1.c -o ../obj/init_var2.o
    make[1]: out from directory «/home/alexey/exercise/ex_makefile/source»
    

    请帮忙,怎么办呢?

1 个答案:

答案 0 :(得分:2)

您将SOURCES设置为等于*.c的通配符扩展。这将扩展为所有.c文件的列表,因此,行

$(OBJECTS): $(SOURCES)

扩展为类似

a.o b.o c.o ... : a.c b.c c.c ...

请注意,这在语义上是错误的,因为每个目标文件都不应该依赖所有源文件。

由于automatic variable $<表示第一个先决条件的名称,因此每个目标文件a.ob.oc.o等等使用源文件a.c创建。

您想要的是pattern rule

  

您可以通过编写模式规则来定义隐式规则。模式规则看起来像普通规则,除了它的目标包含字符'%'(恰好是其中之一)。目标被认为是匹配文件名的模式; '%'可以匹配任何非空子字符串,而其他字符只匹配自己。

这将允许您使每个目标文件仅依赖于其相应的源文件(并且它还将$<扩展为正确的文件,因为第一个先决条件将是先决条件)。因此,您的规则应如下所示:

%.o : %.c
    $(CC) -c -I$(I_DIR) $< -o $(O_DIR)/$@

事实上,GNU make手册的examples page for pattern rules有一个与你的规则非常相似的例子。