【问题标题】:How do I read source files from a directory and create object files into another folder in a makefile?如何从目录中读取源文件并将目标文件创建到 makefile 中的另一个文件夹中?
【发布时间】:2020-07-11 02:09:05
【问题描述】:

我有以下源文件:

% ls 
data_lexicon.c  data_lexicon.h  lex.l           makefile

还有下面的makefile:

% cat makefile
CC              = cc
CFLAGS          = -Wall -std=c89
LDFLAGS         = -ll
OBJFILES        = lex.o data_lexicon.o
TARGET          = lexical_analyzer_1

all:            $(TARGET) lex.c

lex.c:          lex.l data_lexicon.h
                lex -olex.c lex.l

$(TARGET):      $(OBJFILES)
                $(CC) $(CFLAGS) -o $(TARGET) $(OBJFILES) $(LDFLAGS)

clean:
                rm -f $(OBJFILES) lex.c $(TARGET)

如果我这样做make all,我会得到:

% ls 
data_lexicon.c          data_lexicon.o          lex.l
lexical_analyzer_1      data_lexicon.h          lex.c
lex.o                   makefile

到目前为止一切顺利。

但是,我想将源文件(data_lexicon.c、data_lexicon.h、lex.l)移动到文件夹src 并生成中间文件(data_lexicon.o lex.c、lex.o)到obj 文件夹。

我创建了两个文件夹,但我不明白应该如何配置 makefile 文件。

我使用的是 FreeBSD make,所以解决方案越便携越好。

【问题讨论】:

  • 您将术语“目录”和“文件夹”混合在一起。在 BSD/Unix/Linux 上,它们是目录,而不是 Windows 用户术语文件夹,这不是一回事。
  • 只是说:如果您将自己限制为可移植/标准制作,那么 John Bollinger 在下面的回答是完全正确的:创建隐式规则(POSIX 后缀规则)的唯一可移植方法无法描述以下情况目标位于与控制先决条件不同的目录中。您必须为每个目标编写明确的规则。当然,make 的各种实现都有办法避免这种情况,但是你不再可移植了。

标签: makefile freebsd c89


【解决方案1】:

但是,我想移动源文件(data_lexicon.c, data_lexicon.h, lex.l) 到一个文件夹 src 并生成中间 文件(data_lexicon.o lex.c、lex.o)到一个 obj 文件夹中。

人们总是坚持为自己做额外的工作,这让我感到惊讶。您当然可以按照您的描述进行操作,但这需要为目标文件编写明确的规则。

不过,首先,您需要了解make 本身并不真正了解目录。 (无论如何,传统的 make 不知道。GNU make 和其他人可能对它们知之甚少。)也就是说,它对解析文件的不同目录没有任何意义名字。相反,每个目标名称都针对make 的工作目录进行解析。如果你想引用子目录中的某些东西,那么你必须这样说。首先:

OBJFILES        = obj/lex.o obj/data_lexicon.o

规则中的目标名称和先决条件名称类似:

obj/lex.c:      src/lex.l src/data_lexicon.h
                lex -o$@ src/lex.l

这也是支持make 的自动变量的原因之一,例如上面规则中的$@ 表示正在构建的目标的名称。

您的 makefile 目前依赖于make 的内置规则,用于从相应的 C 源文件构建目标文件,但“对应”意味着目标和先决条件名称​​相同,包括任何路径组件, 除了后缀 (.c vs .o)。您将不再拥有data_lexicon.o 的对应关系,因此您需要为其构建它编写一个明确的规则。这部分留作练习。

【讨论】:

  • 感谢您的回答。关于这样做的目标,是在一个文件夹中拥有清晰、组织良好和分离的源代码(并且不会产生额外的工作)。
  • @M.E.,我敢肯定你没有在一天早上醒来时想“我想知道我今天能做些什么来为自己做更多的工作?”但事实仍然存在,这是我开场白的重点,这是坚持将输出构建到专用于该目的的单独目录的主要结果之一。在我看来,这些好处并不能证明成本是合理的。如果您仅编写 clean 目标还不够,那么我建议您考虑使用 make 的 VPATH 功能来提供源外构建。
  • 我实际上想到了一个 clean 目标,在您回答后会擦除中间内容,所以是的,这就足够了
猜你喜欢
  • 2011-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-01
相关资源
最近更新 更多