在Makefile中处理链接的正确方法?

时间:2012-02-28 00:55:03

标签: c linux dependencies makefile

我目前正在开发一个项目,其中有大约20个c源文件和大约8个二进制目标。我们发现Makefile维护相当困难并且容易出错。主要问题是记录哪些二进制文件依赖于哪些目标文件,因为自动头部依赖性解析似乎相当简单(但我们还没有实现它)。

这是我们的makefile当前设置方式的一个示例。两个节目foo和bar。 Foo需要使用从timestamp.c导出的函数,bar需要使用从pretty_print.c导出的函数,而pretty_print.c又使用时间戳函数生成带时间戳的字符串。

foo bar:
     $(CC) -o $@ $^ $(CFLAGS) $(LIBS)

foo: foo.o timestamp.o
foo.o: timestamp.h   

bar: bar.o pretty_print.o timestamp.o
bar.o: pretty_print.h 

pretty_print.o: pretty_print.h timestamp.h

timestamp.o: timestamp.h

有没有更好的方法(除了自动生成foo.o和bar.o行)?我觉得必须有一个更好的方法,那就是写一个bar取决于timestamp.o,当它不包括timestamp.h时。这实际上是大多数错误的根源。直到链接器找不到符号“create_timestamp”,我们才意识到pretty_print依赖于来自时间戳的函数。也许这只是它的工作方式?

3 个答案:

答案 0 :(得分:0)

链接仍然是构建过程中相对传统的一部分。添加另一个源文件是一个不常见且相对较重的(创建新的源和头文件,添加到源代码控制,添加版权样板)任务,所以没有太大的压力来自动化添加一个对象的相对简单的子任务提交几个链接食谱。

所以实际上我会以更直接的方式写这个:

FOO_OBJS = foo.o timestamp.o
foo: $(FOO_OBJS)
    $(CC) $(LDFLAGS) -o $@ $(FOO_OBJS) $(LIBS)

BAR_OBJS = bar.o pretty_print.o timestamp.o
bar: $(BAR_OBJS)
    $(CC) $(LDFLAGS) -o $@ $(BAR_OBJS) $(LIBS)

如果您真的想避免担心哪些二进制目标需要哪些杂项目标文件,您可以将目标文件划分为与每个二进制目标对应的规范目标文件(foo.obar.o等)和其他杂项,并将后者放入其他链接库:

foo: foo.o libmisc.a
    $(CC) $(LDFLAGS) -o $@ foo.o libmisc.a $(LIBS)

bar: bar.o libmisc.a
    $(CC) $(LDFLAGS) -o $@ bar.o libmisc.a $(LIBS)

MISC_OBJS = pretty_print.o timestamp.o
libmisc.a: $(MISC_OBJS)
    -rm -f $@
    $(AR) rc $@ $(MISC_OBJS)
    -$(RANLIB) $@

然后链接每个二进制目标(foobar)将只提取它所需的各种目标文件。

答案 1 :(得分:0)

我自己从未尝试过,但为了列出链接依赖关系,您可以使用nm进行一些简单的文本后处理。

答案 2 :(得分:-1)

在这样的makefile中自动生成所需行的脚本已经存在。

参见“makedepend”或“mkdepend” - 这就是人们在实践中通常如何做到这一点。很常见的是,它们随附了大多数Unix版本。