级联库依赖项

2024-10-01 07:42:51 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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

caughtError c process - [directory]/libA.so: undefined symbol: cudaFunction1

libCuda,正如你可能已经猜到的,是nVidia Cuda代码用nvcc编译并设置为可以C-linkable(即在函数协议中导出“C”)我用一个独立的测试台(用C编写)测试了这个共享库(libCuda),一切正常。以下是用于编译Cuda库的指令:

^{pr2}$

如果我使用:

$ 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_路径。运气不好。任何帮助将不胜感激!在


Tags: 函数librariessomysql原因命名manycuda
2条回答

当你链接李巴。所以,应将您使用的共享库指定为依赖项(-L$somedirectory -lCuda)。然后,依赖项会随着ldd ./libA.so而变得可见,然后LD_LIBRARY_PATH将有所帮助。在

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

p.S

  1. 你可能想读一些关于sonames的文章(从man ld开始?)来决定是否真的要链接到libCuda.so(而不是我喜欢的libCuda.so.N)。在
  2. 为了快速而肮脏的解决方法(如果你还和我一起在这个地方:),请尝试LD_PRELOAD=/full/path/to/libCuda.so your-program。在

好吧,我没赢,但我能改变规则。在

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

必须指出的是,必须将任何库依赖项放在需要它的对象文件之后。如果不这样做,gcc将抱怨未定义的引用。所有gcc库的规则都是很好的。详见下文。在

简而言之,以下是有效的方法:

库达:

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

C:

^{pr2}$

非常感谢安东·科瓦连科的建议。不幸的是,我没能解决我的最终目标,但也许这会成为其他人的中间人,就像现在对我一样。在

相关问题 更多 >