如何使用目标和源的不同目录编写Makefile

时间:2013-08-08 01:48:25

标签: makefile

我正在写一个Makefile,我想分开构建和源目录。我最初的想法只是“哦,我可以编写我的规则,将源路径添加到文件名之前并完成它。”

问题是这个解决方案会超重复,看起来不太好。写一个Makefile的最佳方法是什么,它将目标存储在与保存我的源的目录不同的目录中。

1 个答案:

答案 0 :(得分:1)

程序非常支持将构建的目标存储在与持有源的目录不同的目录中。使用此功能的Makefile可能会更难写,因此我将在回答中查看最重要的技巧。

选择存储构建目标的目录

内置变量.OBJDIR包含构建目标的目录的名称。它是这样确定的(摘自man页面):

 .OBJDIR         A path to the directory where the targets are built.  Its
                 value is determined by trying to chdir(2) to the follow‐
                 ing directories in order and using the first match:

                 1.   ${MAKEOBJDIRPREFIX}${.CURDIR}

                      (Only if ‘MAKEOBJDIRPREFIX’ is set in the environ‐
                      ment or on the command line.)

                 2.   ${MAKEOBJDIR}

                 …

                 6.   ${.CURDIR}

程序makechdir(2)改为.OBJDIR并将PWD设置为该目录之前 执行任何目标。如果没有任何足够的准备.OBJDIR.CURDIR,那么我们需要创建所需的目录 - 或树结构 - 然后再运行make来构建我们的目标。

假设您选择依靠第一种机制来设置.OBJDIR,然后您可以组织构建系统,以便在运行make之前构建目标,

  • 将环境变量MAKEOBJDIRPREFIX设置为合适的值。
  • 特殊脚本(可能是make目标)准备${MAKEOBJDIRPREFIX}下的必要目录。

Makefiles安排

我们考虑一个简单的Makefile,并描述上一个设置工作所需的安排。

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之前,程序makechdir(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以更好地理解所涉及的技术。

bsdowl的便携式宏也支持bsdmake的此功能,您可以查看文件bps.objdir.mk示例。