在FreeBSD下的错误目录下启动 [英] Make starts in wrong directory under FreeBSD
问题描述
我有一个非常简单的Makefile,可以将它打包为另一个Makefile:
I have a very simple Makefile that just shells out to another Makefile:
all:
cd src && make all
我的目录结构(Makefile
在顶级目录中):
My directory structure (the Makefile
is in the top-level directory):
[I] mqudsi@php ~/bbcp> tree -d
.
├── bin
│ └── FreeBSD
├── obj
│ └── FreeBSD
├── src
└── utils
这在Linux上可以正常工作,但是在FreeBSD下,它会给出有关找不到src
的错误.
This works just fine under Linux, but under FreeBSD, it gives an error about src
not being found.
要进行调试,我将Makefile命令更新为pwd; cd src && make all
,当我在顶级目录中运行make
时,我发现以某种方式,它正在./obj
下执行,表示它正在寻找./obj/src/
至cd
进入.
To debug, I updated the Makefile command to pwd; cd src && make all
and I discovered that somehow when I run make
in the top-level directory, it is being executed under ./obj
instead, meaning it's looking for ./obj/src/
to cd
into.
除了我不知道为什么要这么做的事实外,我想肯定可以在FreeBSD下调用gmake
而不是make
来解决这个问题,但是事实并非如此(我我松了口气,因为我不敢相信BSD品牌和GNU品牌之间在核心操作方面会有巨大的差异.
Aside from the fact that I have no clue why it's doing that, I presumed for sure that calling gmake
instead of make
under FreeBSD would take care of it, but that wasn't the case (and I'm relieved, because I can't believe there is that huge of a difference between BSD make and GNU make in terms of core operation).
奇怪的是,删除obj
可使一切正常运行.因此,在存在obj
目录的情况下,make
cds首先进入./obj
.否则它将按照您的期望执行.
The odd thing is, deleting obj
makes everything work perfectly. So in the presence of an obj
directory, make
cds into ./obj
first; otherwise it executes as you'd expect it to.
推荐答案
在这里回答我自己的问题.
Answering my own question here.
从FreeBSD make
手册页:
From the FreeBSD make
man page:
.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.
关键部分是
在所有情况下,make都会将chdir(2)到指定目录(如果存在),并在执行任何目标之前将
.OBJDIR'
PWD'设置为该目录.
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手册页没有这样的内容引用OBJDIR
的任何种类的自动确定,只有在设置了它后才使用.
By contrast, the GNU make manual page makes no such reference to any sort of automatic determination of OBJDIR
, only that it will be used if it is set.
解决方案是通过伪目标.OBJDIR
覆盖OBJDIR
变量:
The solution was to override the OBJDIR
variable via the pseudotarget .OBJDIR
:
.OBJDIR: ./
all:
cd src && make
clean:
cd src && make clean
另一种解决方案是在cd
目标前面加上${CURDIR}
,在chdir
到OBJDIR
之后不会对其进行修改.
An alternative solution is to prefix the cd
targets with ${CURDIR}
, which isn't modified after the chdir
into OBJDIR
.
我不明白为什么gmake
表现出相同的方式.对我来说,这简直像是个虫子.
I don't get why gmake
behaved the same way, however. That feels almost like a bug to me.
这篇关于在FreeBSD下的错误目录下启动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!