如何使用目标和源的不同目录编写Makefile
我正在写一个如何使用目标和源的不同目录编写Makefile,makefile,bsdmake,freebsd,netbsd,openbsd,bdsmake,ocaml,Makefile,Bsdmake,Freebsd,Netbsd,Openbsd,Bdsmake,Ocaml,我正在写一个Makefile,我想把构建目录和源目录分开。我最初的想法是“哦,我可以在文件名的源路径前面写我的规则,然后处理它。” 问题是,这个解决方案将是超级重复的,看起来不是很好。为自己编写一个Makefile的最佳方法是什么?该文件将目标存储在与保存源代码的目录不同的目录中。该程序非常支持将构建目标存储在与保存源代码的目录不同的目录中。使用此功能编写Makefile可能有点困难,因此我将在回答中回顾最重要的技术 选择用于存储生成目标的目录 内置变量.OBJDIR包含构建目标的目录的名称。它
Makefile
,我想把构建目录和源目录分开。我最初的想法是“哦,我可以在文件名的源路径前面写我的规则,然后处理它。”
问题是,这个解决方案将是超级重复的,看起来不是很好。为自己编写一个Makefile
的最佳方法是什么?该文件将目标存储在与保存源代码的目录不同的目录中。该程序非常支持将构建目标存储在与保存源代码的目录不同的目录中。使用此功能编写Makefile
可能有点困难,因此我将在回答中回顾最重要的技术
选择用于存储生成目标的目录
内置变量.OBJDIR
包含构建目标的目录的名称。它是这样确定的(摘自man
页面):
程序make
将chdir(2)
设置为.OBJDIR
,并在之前将PWD
设置为该目录
执行任何目标。在没有任何充分准备的情况下,.OBJDIR
是.CURDIR
,因此我们需要在运行make
构建目标之前创建所需的目录或树结构
假设,您选择依赖第一种机制来设置.OBJDIR
,然后可以组织构建系统,以便在运行make
构建目标之前
- 将环境变量
设置为合适的值MAKEOBJDIRPREFIX
- 特殊脚本(可能是
目标)准备make
下的必要目录${MAKEOBJDIRPREFIX}
我们考虑了一个简单的<代码> Auffic文件,并描述了前一个设置所需的工作安排。
program : a.o b.o c.o
cc a.o b.o c.o -o program
a.o b.o c.o : defs.h
a.o : a.c
cc -c a.c
b.o : b.c
cc -c b.c
c.o : c.c
cc -c c.c
manual.html: manual.css
manual.html: a.c b.c c.c defs.h
manualtool -c manual.css -o manual.html a.c b.c c.c defs.h
在构建a.o
之前,程序make
将chdir(2)
转换为${.OBJDIR}
并从该目录运行编译器cc
。由于源a.c
位于另一个目录中,编译器cc
将找不到它,编译将失败。此问题通过使用make
定义的局部变量来解决,因此前面的Makefile
转换为:
program : a.o b.o c.o
cc ${.ALLSRC} -o program
a.o b.o c.o : defs.h
a.o : a.c
cc -c ${.ALLSRC:M*.c}
b.o : b.c
cc -c ${.ALLSRC:M*.c}
c.o : c.c
cc -c ${.ALLSRC:M*.c}
manual.html: manual.css
manual.html: a.c b.c c.c defs.h
manualtool -c ${.ALLSRC:M*.css} -o manual.html ${.ALLSRC:N*.css}
请注意,在上一个配方中,如何使用globbing模式在命令行的各个位置适当地选择源代码片段
例子
构建系统(可能是和)使用此功能,以便能够同时构建各种体系结构的操作系统。(这也使清洁变得更容易!)您可以研究这些makefile,以更好地了解所涉及的技术
我的便携式宏也支持此功能的
bsdmake
,您可以查看文件bps.objdir.mk
和示例。使用变量和vpath
。它起作用了吗?你能举个有代表性的例子吗?我们可以向您展示如何整理makefile,但如果我们必须猜测您正在尝试做什么,则更难。您可以使用foreach将目录路径附加到相应的文件名集合。。。。这很愚蠢,但很简单,而且很管用fine@Beta看,问题是我还没有写我的makefile,因为我想正确地开始。我的目录结构最好是/src/
/build/
和/tests/
在哪里运行Make?我假定您希望将源代码和头放在/src/
中,并在/build/
中生成对象和可执行文件。那/tests/
呢?我并不特别关心我在哪里打电话。我正在编写一个库,因此build
将是实际的库,tests
将类似于单元测试,而不是库。我真的只想遵循典型的惯例
program : a.o b.o c.o
cc ${.ALLSRC} -o program
a.o b.o c.o : defs.h
a.o : a.c
cc -c ${.ALLSRC:M*.c}
b.o : b.c
cc -c ${.ALLSRC:M*.c}
c.o : c.c
cc -c ${.ALLSRC:M*.c}
manual.html: manual.css
manual.html: a.c b.c c.c defs.h
manualtool -c ${.ALLSRC:M*.css} -o manual.html ${.ALLSRC:N*.css}