Make 在 FreeBSD 下启动错误的目录
Make starts in wrong directory under FreeBSD
我有一个非常简单的 Makefile,它只是 shell 到另一个 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/
到 cd
到
除了我不知道它为什么这样做之外,我确信在 FreeBSD 下调用 gmake
而不是 make
会处理它,但事实并非如此这种情况(我松了一口气,因为我无法相信 BSD make 和 GNU make 在核心操作方面存在如此巨大的差异)。
奇怪的是,删除 obj
后一切正常。因此,在存在 obj
目录的情况下,首先 make
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.
关键部分是
In all cases, make will chdir(2) to specified directory if it exists, and set .OBJDIR'
PWD' to that directory before executing any targets.
相比之下,GNU make manual page 没有对 OBJDIR
的任何类型的自动确定进行此类引用,只是在设置后才会使用它。
解决方案是通过伪目标 .OBJDIR
:
覆盖 OBJDIR
变量
.OBJDIR: ./
all:
cd src && make
clean:
cd src && make clean
另一种解决方案是在 cd
目标前加上 ${CURDIR}
前缀,在 chdir
到 OBJDIR
之后不修改。
不过,我不明白为什么 gmake
的行为方式相同。这对我来说几乎就像一个错误。
我有一个非常简单的 Makefile,它只是 shell 到另一个 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/
到 cd
到
除了我不知道它为什么这样做之外,我确信在 FreeBSD 下调用 gmake
而不是 make
会处理它,但事实并非如此这种情况(我松了一口气,因为我无法相信 BSD make 和 GNU make 在核心操作方面存在如此巨大的差异)。
奇怪的是,删除 obj
后一切正常。因此,在存在 obj
目录的情况下,首先 make
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.
关键部分是
In all cases, make will chdir(2) to specified directory if it exists, and set
.OBJDIR'
PWD' to that directory before executing any targets.
相比之下,GNU make manual page 没有对 OBJDIR
的任何类型的自动确定进行此类引用,只是在设置后才会使用它。
解决方案是通过伪目标 .OBJDIR
:
OBJDIR
变量
.OBJDIR: ./
all:
cd src && make
clean:
cd src && make clean
另一种解决方案是在 cd
目标前加上 ${CURDIR}
前缀,在 chdir
到 OBJDIR
之后不修改。
不过,我不明白为什么 gmake
的行为方式相同。这对我来说几乎就像一个错误。