环境:
这是我正在查看的构建的一个非常简化的示例:
all: ${list of shared objects to build}
@do whatever
lib1.so: ${1s objects}
lib2.so: ${2s objects}
lib3.so: ${3s objects}
#...
%.so:
$(call CHECK_DEPENDENCIES_EXIST)
@${LD} ${LDFLAGS} ${^} -o ${@}
%.o : %.c
@do stuff
%.o : %.cc
@do stuff
define CHECK_DEPENDENCIES_EXIST =
$(if $(realpath ${^}),,$(warning No dependencies specified for ${@})false)
endef
简短& sweet:$(realpath x y z)
(如果它们存在则返回x / y / z;返回一个不包含符号链接的绝对路径)在某些情况下从列表中删除文件,我认为它与NFS有关。无法预测哪个目标会失败。有时目标会在最后10次成功时失败。如果我从宏中取出@false
,那么构建会继续而不会出错 - 也就是说,链接器不会抱怨所谓的丢失文件。
我会饶恕你提出的解释;这足以说明,宏有助于调试。
答案 0 :(得分:2)
原来gmake中存在一个错误。来自GNU Make 3.82源代码function.c
,在2026行或左右:
while ((path = find_next_token (&p, &len)) != 0 ) {
/* ... */
if (
#ifdef HAVE_REALPATH
realpath (in, out)
#else
abspath (in, out) && stat (out, &st) == 0
#endif
)
{
/* ... */
}
}
}
/* ... */
偶尔,对realpath
的各种调用都会被中断(EINTR
);此代码中没有任何内容检查errno
,因此它只是默默地失败。
所以,并不是文件不存在,而是$(realpath ...)
被信号中断(可能是gmake
的子实例,表示其完成或类似的事情)和此功能并非旨在从这类事件中恢复。
解决问题:
while ((path = find_next_token (&p, &len)) != 0 ) {
...变成:
while ( errno == EINTR || (path = find_next_token (&p, &len)) != 0 ) {
||
将快捷方式&防止它进入下一个令牌。