我有一个非常简单的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
;否则它会像你期望的那样执行。
答案 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
的表现方式相同。这对我来说几乎就像一个小虫。