12 linux symlink build-process makefile gnu-make
GNU/Make手册§5.7声明如下:
5.7递归使用make
递归使用make意味着使用make作为makefile中的命令.当您需要为构成更大系统的各种子系统创建单独的makefile时,此技术非常有用.例如,假设您有一个子目录subdir,它有自己的makefile,并且您希望包含目录的makefile在子目录上运行make.你可以这样写:
Run Code Online (Sandbox Code Playgroud)subsystem: cd subdir && $(MAKE) or, equivalently, this (see Summary of Options): subsystem: $(MAKE) -C subdir
所以,基本上它意味着它cd subdir && $(MAKE)是一样的$(MAKE) -C subdir.
然而,事实证明它并不是真正的等价物.使用-C选项时,目录路径(如果是符号链接)始终是取消引用的,因此无法获得"逻辑"(如在pwd -L)目录名称.请考虑以下示例.Makefile在/tmp/b目录中具有以下内容,这是/tmp/a/目录的符号链接:
foo:
    @echo PWDL=$(shell pwd -L)
    @echo PWDP=$(shell pwd -P)
    @echo CURDIR=$(CURDIR)
现在,让我们以make不同的方式调用:
$ pwd
/tmp
$ (cd b && make foo)
PWDL=/tmp/b
PWDP=/tmp/a
CURDIR=/tmp/a
$ make -C b foo
make: Entering directory `/tmp/a'
PWDL=/tmp/a
PWDP=/tmp/a
CURDIR=/tmp/a
make: Leaving directory `/tmp/a'
$ make --directory=b foo
make: Entering directory `/tmp/a'
PWDL=/tmp/a
PWDP=/tmp/a
CURDIR=/tmp/a
make: Leaving directory `/tmp/a'
$ 
如您所见,pwd -P并且$(CURDIR)始终显示取消引用的符号链接.但pwd -L只有在运行之前更改目录时才有效make,这证明-CGNU/Make的选项总是使它取消引用目录路径,这是没有充分理由的.我试图在文档中找到对此行为的任何解释但不能.cd在运行之前   没有更改目录make(或者非常糟糕的挂钩槽LD_PRELOAD),我都不能为这个问题找到解决方法.
问题是 - 之前有没有其他人遇到过这个问题,有解释或解决方法吗?谢谢!
更新:
试图找到它的底部,我已经下载了源代码,make并没有找到任何特殊的目录处理,只有调用chdir.所以我写了一个小程序来进行实验,这就是我发现的.
当您在/tmp/b符号链接目录()并尝试将目录更改为相同时,该操作无效,当前工作目录继续指向符号链接.
当您调用chdir ()并指定完整路径或相对路径时,它会在更改目录之前取消引用它.这是一个证明:
$ cat cd.cpp 
#include <stdio.h>
#include <unistd.h>
int main ()
{
    chdir ("/tmp/b/");
    printf ("Current dir: %s\n",
        get_current_dir_name ()); /* Forgive my memory leak. */
}
$ gcc -o test ./cd.cpp 
$ pwd
/tmp/b
$ ./test 
Current dir: /tmp/b
$ cd ../
$ ./b/test 
Current dir: /tmp/a
$ cd /
$ /tmp/b/test 
Current dir: /tmp/a
$ 
所以看起来要么是libcLinux还是Linux,我之前并不关心它.最重要的是,bash scd`的工作方式有所不同.
奇怪的是,Linux的chdir ()手册页没有再提,但在Borland的生成器上的说明(!原文如此)的文件,在这里.所以我想知道bash在这方面做了什么.
小智 8
在epippient的帮助下,我能够把这一点弄清楚.所以很少有事情发生:
chdir ()始终将其设置为真实目录.PWD根据惯例,有一个名为的变量代表当前工作目录.PWD变量而一些不调.PWD变量.它解释了gmake行为.何时gmake被调用sh,PWD在gmake执行进程之前更新.因此,PWD设置为"符号"路径和功能尊重它继续工作正常.否则,gmake调用chdir (),更改工作目录和设置PWD没有sh的技巧.因此,包括那些尊重的所有功能PWD开始返回"真实"路径.
总而言之,我会说取决于符号路径名称是一个坏主意,事情很容易崩溃.例如,因为getcwd ()系统调用不关心PWD.cd在运行之前调用make可以作为短期解决方案.