【发布时间】:2014-10-21 22:28:33
【问题描述】:
我已经搜索并尝试了一些示例来使用非递归 makefile 完成一个简单的项目。过去,我使用简单的单目录代码库,但现在我正在为多个工程师构建一个环境:-)
+--app
| +-- obj/
| +-- Makefile
| +-- first.c
| +-- second.c
|
+--lib1
| +-- obj/
| +-- Makefile
| +-- foo.c
| +-- bar.c
|
+--lib2
| +-- obj/
| +-- Makefile
| +-- sample.c
没什么特别的——只有两个目录(可能稍后第三个),库代码和多个应用程序都在“app”目录中。我想将 .o 和 .d 文件保存在单独的 obj/ 目录中以保持清洁。
- 我希望能够在每个子目录(如 lib1 和 lib2)中进行“制作”以验证库。它们将分别生成 libabc.a 和 libxyz.a。
- 我编写了一些简单的 Makefile,但我的规则不起作用,我试图理解 GNU make 手册但迷路了。
lib1/Makefile:
lib_src = foo.c bar.c
lib_obj = $(patsubst %.c,obj/%.o,$(lib_src))
libabc.a: $(lib_obj)
@echo [Archive... $(@F)]
@$(AR) -cr libabc.a $^
obj/%.c : %.c
$(CC) $(CFLAGS) -c -o $@ $<
应用程序/Makefile:
ALL_APP = first second
% : %.c libabc.a libxyz.a
$(CC) $(CLFAGS) $^ -o $@
include ../lib1/Makefile
include ../lib2/Makefile
现在,我无法在每个 Makefile 中定义相同的目标(显然)。就像我无法在 lib1/Makefile 和 app/Makefile 中定义一个干净,因为 lib1 包含在那里。虽然我希望我可以单独在 lib1 中进行 make clean,但这是有道理的。
现在,当我在“app”中制作时,没有规则可以制作 obj/foo.o。我猜是因为路径都是假的。 "obj/" 指的是 lib1/obj/ 但随着 Makefile 的包含,这一切都丢失了。
我做错了什么,我可以像上面那样使用非常简单的 Makefile 来构建我的项目。大多数在线示例都相当复杂,因为它们试图实现更多(我相信)。
提前致谢(对于已经讨论过多次的话题,我们深表歉意)。如果可以避免的话,我宁愿现在不学习 automake 和 cmake。我希望我的项目足够简单,不需要使用这些强大的工具。
最好的问候,
【问题讨论】:
-
我不认为在您的应用程序生成文件中包含库生成文件是正确的解决方案。这是我要做的:为每个目录编写一个功能齐全的独立 makefile。然后为您的应用程序编写一个简单的构建脚本,为您的每个库调用 make,最后为您的应用程序调用 make。您还可以让构建脚本将构建的库复制到您的应用目录中。
-
@BrandonYates 这或多或少是递归的,但又删除了一步,因为你甚至不让 make 进行递归构建。
-
谢谢布兰登。我认为调用 make 不是一个好主意,而包含 Makefile 是一种更好的方法。彼得米勒写了一篇论文解释了原因。独立调用每个 Makefile 更难管理依赖关系。
-
顺便说一句:这篇论文被称为Recursive Make Considered Harmful。
-
构建这种非递归的makefile系统(具有包含独立makefile的能力)并非易事。我已经完成了自己的实现,我花了几年的时间来完善它。你可以在这里找到它github.com/igagis/prorab/blob/master/wiki/…
标签: c makefile gnu-make non-recursive