【问题标题】:How to Compile all C file into Object and place it in subdirectories如何将所有 C 文件编译成 Object 并将其放在子目录中
【发布时间】:2023-03-09 20:40:02
【问题描述】:

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

我有三个目录:

  1. usr - main.c 所在的位置
  2. sources1 - init_var1.c 和 init_var2.c 所在的位置
  3. include - 头文件所在的位置
  4. obj - 此目录应包含由 1 和 2 下列出的目录中的 C 源文件生成的目标文件。

我写了这个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»

但是,我需要

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_var2.c -o ../obj/init_var2.o
make[1]: out from directory «/home/alexey/exercise/ex_makefile/source»

请帮忙,怎么办?

【问题讨论】:

  • 您应该在发布输出之前将本地化设置为默认值(例如export LANG=C LC_ALL=C ....)。并非这里的每个人都能阅读俄语错误消息。
  • @dkasak 不一样,我不会编译差异 .c 文件但我编译身份。
  • 是的,我现在注意到了,抱歉。
  • 我错过了所需输出与实际输出的差异。
  • $(OBJECTS): $(SOURCES) 规则可疑。

标签: c linux makefile


【解决方案1】:

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

$(OBJECTS): $(SOURCES)

扩展到类似的东西

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

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

由于automatic variable $&lt; 表示第一个 先决条件的名称,每个目标文件a.ob.oc.o 等都是使用源文件@987654332 创建的@。


你想要的是 pattern rule:

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

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

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

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

【讨论】:

  • 是的,除了您提供的模式规则不适合 OP 从位于不同目录中的源构建目标的要求。
猜你喜欢
  • 2013-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-16
  • 2011-02-11
  • 1970-01-01
  • 2018-02-02
  • 1970-01-01
相关资源
最近更新 更多