级联库依赖项

时间:2013-01-09 20:44:01

标签: python c cuda shared-libraries undefined-symbol

由于这里解释的原因太长,我需要在“C”中创建一个可在Python中调用的共享库(称为libA)。这个共享库需要调用另一个自定义共享库(我们将其命名为libCuda)。此外,libA还调用许多其他外部共享库,如MySQL等。

在包含libCuda之前,Python中调用的所有C函数都运行良好,MySQL子调用工作正常,等等。但是,一旦libCuda被添加到libA,Python就会抱怨:

caughtError c process - [directory]/libA.so: undefined symbol: cudaFunction1
正如您可能已经猜到的那样,libCuda是使用nvcc编译的nVidia Cuda代码并且设置为C-linkable(即在函数prototyes中导出“C”)我已经使用独立测试测试了此共享库(libCuda)替补(用C编写),一切都按预期工作。这是用于编译Cuda库的指令:

nvcc -arch=sm_30 -shared -o libCuda.so *.cu -Xcompiler -fPIC

如果我使用:

$ ldd libA

我没有看到任何表明libA需要加载libCuda(或MySQL)的信息

用于编译libA的命令如下(libCuda位于本地目录中):

gcc *.c -c -L. -lCuda -lmysqlclient [many other shared libraries] -fPIC
gcc -shared -Wl,-soname,libA.so -lCuda -lmysqlclient [many other shared libraries] -o libA.so *.o

我尝试将两个库文件放在/ usr / lib中并显式导出LD_LIBRARY_PATH。没运气。任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:0)

链接libA.so时,应将您使用的共享库指定为依赖项(-L$somedirectory -lCuda)。然后,ldd ./libA.so可以看到依赖项,但LD_LIBRARY_PATH会有所帮助。

共享库中允许使用未定义的符号,因此您可以在构建库时提供足够的依赖项。如果libmysqlclient没有发生同样的事情,可能是因为libmysqlclient由于某些其他依赖项而被加载(或者在{/ 1>}和之前动态加载RTLD_GLOBAL libA.so 1}})。然后它可能不是你想要的,即使问题不是立即可见。

P.S。

  1. 您可能想要阅读 sonames 上的内容(从man ld开始?),以确定您是否真的想要链接libCuda.so(而不是libCuda.so.N我希望如此。
  2. 快速而肮脏的解决方法(如果你还在这个地方陪我:),试试LD_PRELOAD=/full/path/to/libCuda.so your-program

答案 1 :(得分:0)

好的,所以没有获胜,但我能够改变规则。

Using this as a reference,我首先用nvcc编译CUDA代码,从而创建了几个对象(* .o)文件。然后,在创建库libA时,这些目标文件被添加到由gcc链接的目标文件列表中。此外,以下链接器参数被添加到gcc命令“-L / usr / local / cuda / lib64 -lcudart”(我正在使用x64机器)。

非常重要的是要指出必须在需要它的目标文件之后放置任何库依赖项。如果你不gcc会抱怨未定义的引用。一个好的经验法则是将所有库放在gcc行的末尾。有关详细信息,请参阅下文。

简而言之,这是有效的:

CUDA:

nvcc -arch=sm_30 -c *.cu -Xcompiler -fPIC

C:

gcc *.c -c -fPIC -L/usr/local/cuda/lib64 -lcudart -lmysqlclient [many other shared libraries]
gcc -shared -Wl,-soname,libA.so -o libA.so *.o [cuda_obj_file_dir]/*.o -L/usr/local/cuda/lib64 -lcudart -lmysqlclient [many other shared libraries]

非常感谢Anton Kovalenko的建议。不幸的是,我无法解决我的最终目标,但也许这将成为别人的中间人,因为它现在正在为我做。