Linux 为什么bashrc中的变量声明会使CUDA变得混乱?

Linux 为什么bashrc中的变量声明会使CUDA变得混乱?,linux,bash,cuda,Linux,Bash,Cuda,我最近在64位Ubuntu12.04系统上安装了CUDA 5.0,方法是按照站点、站点和站点上的说明进行操作。(作为一个注释,Ubuntu 12.04不是英伟达网站上的CUDA 5支持的OS之一,但显然其他人已经安装了它并使其在系统上运行。)在正确安装驱动程序和包之后,我将尝试编译和运行 1) 包括的示例中的第一个程序(在~/NVIDIA_CUDA-5.0_samples/1_Utilities/deviceQuery/中的可执行设备查询),以及 2) 第一个支持GPU的程序——第03章中的si

我最近在64位Ubuntu12.04系统上安装了CUDA 5.0,方法是按照站点、站点和站点上的说明进行操作。(作为一个注释,Ubuntu 12.04不是英伟达网站上的CUDA 5支持的OS之一,但显然其他人已经安装了它并使其在系统上运行。)在正确安装驱动程序和包之后,我将尝试编译和运行

1) 包括的示例中的第一个程序(在~/NVIDIA_CUDA-5.0_samples/1_Utilities/deviceQuery/中的可执行设备查询),以及

2) 第一个支持GPU的程序——第03章中的simple_kernel.cu——包含在NVidia出版的CUDA示例书的源代码(可用)中

可执行文件1)我通过在相应目录中运行
make
获得;可执行文件2)我通过
nvcc simple_kernel.cu
获得。两者的结果都是这样的输出:

./deviceQuery: error while loading shared libraries: libcudart.so.5.0: cannot open shared object file: No such file or directory

为清楚起见,是的,我已将我的
路径
变量设置为包含
/usr/local/cuda-5.0/bin
,并将我的
LD\u LIBRARY\u路径
变量设置为同时包含
/usr/local/cuda-5.0/lib
/usr/local/cuda-5.0/lib64
,是的,有链接指向
/usr/local/cuda-5.0/lib/libcudart.so
指向
/usr/local/cuda-5.0/lib/libcudart.so.5.0
以及
/usr/local/cuda-5.0/lib/libcudart.so
指向
/usr/local/cuda-5.0/libcudart.so.5.0
。但这引出了我的问题

通过在~/.bashrc文件中添加行,我修改了路径和LD_LIBRARY_路径变量

export PATH=${PATH}:/usr/local/cuda-5.0/bin
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/cuda-5.0/lib:/usr/local/cuda-5.0/lib64

打开终端窗口并键入
echo$PATH
echo$LD_LIBRARY_PATH
将显示这两个变量都已正确设置,但我在运行上述CUDA可执行文件时遇到了问题

然后我在stackoverflow上找到了帖子,并尝试了sivapal ayyappan nadar提供的建议——通过修改
/etc/environment
设置
路径,通过修改
/etc/LD.so.conf.d/cuda50.conf
(我同时注释了~/.bashrc中的相应行)。现在,当我编译和运行我的CUDA示例时,它们工作了

那么,现在我的问题是:这里发生了什么?为什么在
/etc/LD.so.conf.d/cuda50.conf
中设置了LD_library_路径时libcudart库被正确链接,而在
~/.bashrc
中设置时却没有正确链接?一个做什么而另一个不做?或者,这不是我问题的真正根源吗


在回答时,请记住我提出这个问题的动机。我想1)了解Linux系统的复杂性,2)为其他可能遇到同样问题的人发布一个可能的解决方案,即使他们遵循了其他可用的优秀说明。非常感谢。

这是一个有趣的话题,我将试着解释一下。因此,在本例中,我安装了一个小型库来进行测试。我将继续将其配置为安装在非标准目录中:

./configure --prefix=/home/ubuntu/mystuff
$ sudo vim /etc/ld.so.conf.d/50-jansson.conf
- add /home/ubuntu/mystuff/lib to the file -
$ sudo ldconfig
现在,在执行
make install
后,会出现以下警告:

Libraries have been installed in:
   /home/ubuntu/mystuff/lib

If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:
   - add LIBDIR to the `LD_LIBRARY_PATH' environment variable
     during execution
   - add LIBDIR to the `LD_RUN_PATH' environment variable
     during linking
   - use the `-Wl,--rpath -Wl,LIBDIR' linker flag
   - have your system administrator add LIBDIR to `/etc/ld.so.conf'

See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
好的,我将继续尝试使用一个测试套件程序与之链接:

$ gcc test_dump.c -ljansson 
test_dump.c:8:21: fatal error: jansson.h: No such file or directory
为了让C知道它可以使用什么,它首先需要知道包含文件。幸运的是,这只需要在编译时发生。我们使用
-I
传入include目录,以便
gcc
知道在哪里可以找到include文件:

$ gcc test_dump.c -I/home/ubuntu/mystuff/include -ljansson
/usr/bin/ld: cannot find -ljansson
好的,现在回到链接问题。因此,让我们在链接时尝试
LD\u LIBRARY\u PATH

$ LD_LIBRARY_PATH="/home/ubuntu/mystuff/lib" gcc test_dump.c -I/home/ubuntu/mystuff/include -ljansson
/usr/bin/ld: cannot find -ljansson
这是行不通的,这背后的原因是gcc正在不同的目录中查找,如运行以下命令所示:

gcc -print-search-dirs
要告诉gcc使用我们想要的目录,请使用
-L

$ gcc test_dump.c -I/home/ubuntu/mystuff/include -L/home/ubuntu/mystuff/lib -ljansson
$
$ LD_LIBRARY_PATH="/home/ubuntu/mystuff/lib" ./a.out
$
现在,我们可以使用一个名为
ldd
的程序来查看它所链接的内容:

$ ldd a.out 
        linux-vdso.so.1 =>  (0x00007fc4c872d000)
        libjansson.so.4 => not found
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc4c8366000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fc4c872e000)
您会注意到,它为我们想要的库显示“未找到”。现在尝试解决这个问题:

$ LD_RUN_PATH="/home/ubuntu/mystuff/lib" gcc test_dump.c -I/home/ubuntu/mystuff/include -L/home/ubuntu/mystuff/lib -ljansson
这是一种方法,使用
LD\u RUN\u PATH
。它不只是链接到库,而是链接到库的完整路径。再次运行
ldd
显示:

$ ldd a.out 
        linux-vdso.so.1 =>  (0x00007fff481d7000)
        libjansson.so.4 => /home/ubuntu/mystuff/lib/libjansson.so.4 (0x00007fe86b0dd000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe86ad18000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fe86b2eb000)
现在,当我们在不涉及
LD\u RUN\u PATH
的情况下尝试此操作时,我们得到以下结果:

$ ./a.out 
./a.out: error while loading shared libraries: libjansson.so.4: cannot open shared object file: No such file or directory
要解决此问题,请使用
LD\u LIBRARY\u PATH

$ gcc test_dump.c -I/home/ubuntu/mystuff/include -L/home/ubuntu/mystuff/lib -ljansson
$
$ LD_LIBRARY_PATH="/home/ubuntu/mystuff/lib" ./a.out
$
然而,这是一个有点黑客和皱眉。大卫·巴尔有一个朋友。现在出现的是一个动态库加载器,
ld.so/ld linux.so
,它“加载程序所需的共享库,准备程序运行,然后运行它”。如果您查看
ld.so
手册页,它会指出:

   The necessary shared libraries needed by the program are searched for in the following order

   o      Using the environment variable LD_LIBRARY_PATH (LD_AOUT_LIBRARY_PATH for a.out programs).  Except if the executable is a setuid/setgid binary, in which case it is ignored.

   o      From the cache file /etc/ld.so.cache which contains a compiled list of candidate libraries previously found in the augmented library path. Libraries installed in hardware capabilities
          directories (see below) are prefered to other libraries.

   o      In the default path /lib, and then /usr/lib.
您希望路径位于
/etc/ld.so.cache
中。此缓存由
ldconfig
使用
/etc/ld.so.conf
生成。如果您在Ubuntu上查看该文件:

include /etc/ld.so.conf.d/*.conf
就这么说的。默认情况下,
/etc/ld.so.conf.d
目录中是glib、gcc和
/usr/local/lib的目录,因为它在默认路径之外。要将我们想要的目录添加到缓存中,只需在该目录中添加一个文件:

./configure --prefix=/home/ubuntu/mystuff
$ sudo vim /etc/ld.so.conf.d/50-jansson.conf
- add /home/ubuntu/mystuff/lib to the file -
$ sudo ldconfig
这将为加载程序重新生成
/etc/ld.so.cache
文件。您可以通过让
ldconfig
打印缓存的目录来确认已拾取目录:

$ ldconfig -p | grep "mystuff"
        libjansson.so.4 (libc6,x86-64) => /home/ubuntu/mystuff/lib/libjansson.so.4
        libjansson.so (libc6,x86-64) => /home/ubuntu/mystuff/lib/libjansson.so
现在,如果我们尝试再次运行
ldd

$ ldd a.out 
        linux-vdso.so.1 =>  (0x00007fff1e510000)
        libjansson.so.4 => /home/ubuntu/mystuff/lib/libjansson.so.4 (0x00007f529da67000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f529d6a8000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f529dc7b000)
最后运行程序:

$ ./a.out
$

一切都好!这是一个关于当你链接时后端发生了什么的研究。有关更多详细信息,我建议查看
manld.so
manldconfig
。如果您需要任何澄清,请随时询问

很好,我刚刚学会了“flummox”这个词:)不知道,不过,对不起,你的问题是关于什么的。@Michael:tha