我编写了一个Python C模块(仅ffmpeg.c
,它取决于一些FFmpeg库和其他库),我想知道如何链接。
我正在编译:
cc -std=c99 -c ../ffmpeg.c -I /usr/include/python2.7 -g
我正在尝试立即与:
联系 ld -shared -o ../ffmpeg.so -L/usr/local/lib -lpython2.7 -lavutil -lavformat -lavcodec -lswresample -lportaudio -lchromaprint ffmpeg.o -lc
没有错误。但是,当我在Python中尝试import ffmpeg
时,我得到:
ImportError: ./ffmpeg.so: undefined symbol: avio_alloc_context
也许这已经是正确的了。我使用ffmpeg.so
检查了结果ldd
,部分链接到错误的FFmpeg。这很奇怪,因为-L/usr/local/lib
应该优先于默认值。也许是因为我的自定义安装FFmpeg(在/usr/local/lib
中)由于某种原因只安装了静态*.a
库,*.so
文件优先于*.a
个文件。
答案 0 :(得分:0)
您应该将您链接的库放在 .o
文件之后;即:
ld -shared -o ../ffmpeg.so ffmpeg.o -L/usr/local/lib -lpython2.7 -lavutil -lavformat -lavcodec -lswresample -lportaudio -lchromaprint -lc
链接器是愚蠢的,并且不会在静态库中链接它认为不需要的静态库,直到出现依赖关系,即在avio_alloc_context
中使用ffmpeg.o
,并且因为它不是在使用库后列出,然后链接器将不会根据需要考虑库中的代码,因此它不会被链接 - 这是使用.a
文件链接失败的最大原因。
您还可以在链接的所有文件周围使用--start-group
和--end-group
- 这允许您链接具有交叉依赖关系的静态库,这些依赖关系似乎无法通过其他方式解决:
ld -shared -o ../ffmpeg.so -L/usr/local/lib -lpython2.7 --start-group -lavutil -lavformat -lavcodec -lswresample -lportaudio -lchromaprint ffmpeg.o --end-group -lc
使用.a
文件比.so
文件有点棘手,但这两个项目通常可以解决链接时遇到的任何问题。