在FreeBSD下的错误目录下启动

时间:2017-08-14 13:13:14

标签: makefile freebsd

我有一个非常简单的Makefile,只是弹出另一个Makefile:

all:
    cd src && make all

我的目录结构(Makefile位于顶级目录中):

[I] mqudsi@php ~/bbcp> tree -d
.
├── bin
│   └── FreeBSD
├── obj
│   └── FreeBSD
├── src
└── utils

这在Linux下运行得很好,但是在FreeBSD下,它会出现src找不到的错误。

要进行调试,我将Makefile命令更新为pwd; cd src && make all,当我在顶级目录中运行make时,我发现以某种方式,它正在{ {1}}而是意味着它正在寻找./obj./obj/src/

除了我不知道为什么会这样做之外,我确信在FreeBSD下调用cd而不是gmake会照顾它,但事实并非如此(而且我松了一口气,因为我无法相信BSD make和GNU make在核心操作方面存在巨大差异。)

奇怪的是,删除make会使一切运作完美。因此,在obj目录存在的情况下,首先obj cds进入make;否则它会像你期望的那样执行。

1 个答案:

答案 0 :(得分:1)

在这里回答我自己的问题。

来自FreeBSD make手册页:

.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}

              (Only if `MAKEOBJDIR' is set in the environment or
              on the command line.)

             3.   ${.CURDIR}/obj.${MACHINE}

             4.   ${.CURDIR}/obj

             5.   /usr/obj/${.CURDIR}

             6.   ${.CURDIR}

             Variable expansion is performed on the value before it's
             used, so expressions such as
               ${.CURDIR:S,^/usr/src,/var/obj,}
             may be used.  This is especially useful with
             `MAKEOBJDIR'.

             `.OBJDIR' may be modified in the makefile via the special
             target `.OBJDIR'.  In all cases, make will chdir(2) to
             the specified directory if it exists, and set `.OBJDIR'
             and `PWD' to that directory before executing any targets.

关键部分是

  

在所有情况下,如果存在,则将chdir(2)指定到指定目录,并在执行任何目标之前将.OBJDIR' PWD'设置为该目录。

相比之下,GNU make manual page没有对OBJDIR的任何类型的自动确定进行此类引用,只是在设置它时将使用它。

解决方案是通过伪目标OBJDIR覆盖.OBJDIR变量:

.OBJDIR: ./

all:
    cd src && make
clean:
    cd src && make clean

另一种解决方案是在cd目标前加${CURDIR}作为前缀,chdir之后不会修改OBJDIR

然而,我不明白为什么gmake的表现方式相同。这对我来说几乎就像一个小虫。