我正在编译Linux并试图了解共享和静态库的复杂性,可以做什么以及不应该做什么。
使用ffmpeg的例子,我将x264作为包含的依赖项。
根据SO上的很多帖子,似乎x264的静态版本是最好的。然后根据需要动态地将它们加载到几个不同版本的ffmpeg中。
编译两个二进制文件时,正确的配置语法是什么。
方案一x264 --enable-static --disable-shared
ffmpeg --disable-static --enable-shared --enable-libx264
或反过来
x264 --disable-static --enable-shared
ffmpeg --enable-static --disable-shared --enable-libx264
方案二,假设理论依赖瀑布,我们必须包括(prog-x到x264)然后x264动态加载到ffmpeg
progx--enable-static --disable-shared
x264 --enable-static --disable-shared
ffmpeg --disable-static --enable-shared --enable-libx264
答案 0 :(得分:3)
更新:我忘记了-fPIC,这是将共享库与静态库链接起来的一个非常重要的方面,这已经得到纠正。
根据SO上的很多帖子,似乎x264的静态版本是最好的。然后根据需要动态地将它们加载到几个不同版本的ffmpeg中。
如果您的意思是用动态"正在链接静态libx264"根据需要"在运行时,这是静态库的定义,这是不可能的。如果在启用PIC选项的情况下编译了libx264,则可以在编译时将共享ffmpeg库与静态libx264链接,这将导致x264代码存在于共享ffmpeg库中。在这种情况下,您的ffmpeg共享库将不依赖于libx264,因此ffmpeg的这个特定版本将在系统上运行并提供不具备它的x264功能。略微修改的方案一个选项一:
x264$ ./configure --enable-static --enable-pic
ffmpeg$ ./configure --enable-shared --enable-libx264
将在一个条件下为您执行此操作: 没有旧的libx264.so *在旧版本和你的测试的链接器库搜索路径中挥之不去,否则它会愉快地使用它们。如果只存在libx264.a文件,它将使用该文件。据我所知,没有其他用户友好的方式来告诉标准配置脚本将静态版本用于某个特定库,而不是另一个库。共享库的构建将始终链接到共享库(如果可用),但如果它们不可用,则回退到静态.a库。如果项目作者明确配置autoconf以通过配置标志向用户公开该选项,则会出现异常。
选项二,
x264$ ./configure --disable-static --enable-shared
ffmpeg$ ./configure --enable-static --disable-shared --enable-libx264
不起作用。原因是您无法将静态库与共享库链接起来。
有了这些知识,情景二也难以理解。您将把progx功能集成到x264库中,然后将其集成到ffmpeg中。 FFmpeg不会依赖前两个库中的任何一个,因为它们是静态链接的。但是,就像libx264一样,您的progx库需要使用-fPIC选项进行编译。 libx264附带的configure脚本可以轻松启用PIC。来自其他库的其他配置脚本可能不会为您提供此选项,但我相信您可以使用CFLAGS和LDFLAGS环境变量来配置和手动添加-fPIC。所以这对你有用:
progx$ ./configure --enable-static --enable-pic
或者,如果" progx"有一个经典的样式配置脚本:
progx$ CFLAGS=-fPIC LDFLAGS=-fPIC ./configure --enable-static --disable-shared
最后:
x264$ ./configure --enable-static --enable-pic
ffmpeg$ ./configure --enable-shared --enable-libx264
" PIC"意味着"位置独立代码"。共享库需要是PIC,因为它们可以在一个过程中链接。在标准程序代码中,任何位置的地址空间都是如此,其中所有偏移在编译时都是已知的。因此,您想要链接到共享库的任何静态库也需要是PIC。
作为最后一点,命令" ldd libsomelibrary.so"将产生libsomelibrary.so依赖的其他共享库。此命令也适用于动态可执行文件。 以ffmpeg为例,如果你链接到共享的libx264库,你会看到对libx264的依赖,如果你链接到它的静态版本,你将看不到这种依赖。