Makefile 在FreeBSD下的错误目录中启动

Makefile 在FreeBSD下的错误目录中启动,makefile,freebsd,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,它可以转换成另一个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时,它是在./obj下执行的,这意味着它正在寻找./obj/src/to cd

除了我不知道它为什么这样做之外,我确信在FreeBSD下调用gmake而不是make会解决这个问题,但事实并非如此,我松了一口气,因为我不相信BSD make和GNU make在核心运营方面有这么大的区别


奇怪的是,删除obj可以让一切都完美地工作。因此,在存在obj目录的情况下,首先将CD制作成./obj;否则,它将按照您的预期执行。

回答我自己的问题

从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.
关键在于

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

相比之下,没有提及任何类型的OBJDIR自动确定,只是在设置了OBJDIR后才会使用它

解决方案是通过伪目标重写OBJDIR变量。OBJDIR:

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


然而,我不明白为什么gmake会有同样的行为。对我来说,这几乎像是一个bug。

会使-C src的行为符合预期吗?@FelixPalmen不,它的行为完全相同。您可以在这里查看我的代码,我正在维护一个名为bbcp的废弃工具:
.OBJDIR: ./

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