Reputation: 2463
I am compiling on linux and am trying to understand the complexities of shared and static libs, what can be done and what should not be done.
Using the example of ffmpeg, I have x264 as an included dependency.
Based on many posts here on SO, it seems a static build of x264 would be best. Then load these into several different version of ffmpeg dynamically as needed.
What is the correct configure syntax when compiling both binaries.
scenario one
x264 --enable-static --disable-shared
ffmpeg --disable-static --enable-shared --enable-libx264
or the other way round
x264 --disable-static --enable-shared
ffmpeg --enable-static --disable-shared --enable-libx264
scenario two, assume a theoretical dependency waterfall, where we must include (prog-x into x264) then x264 dynamically loaded into ffmpeg
progx--enable-static --disable-shared
x264 --enable-static --disable-shared
ffmpeg --disable-static --enable-shared --enable-libx264
Upvotes: 1
Views: 1592
Reputation: 105
UPDATE: I forgot about -fPIC which is a very important aspect when linking shared libraries against static libraries, this has been corrected.
Based on many posts here on SO, it seems a static build of x264 would be best. Then load these into several different version of ffmpeg dynamically as needed.
If what you mean to say with "dynamically" is linking against a static libx264 "as needed" at runtime, this is by the very definition of static libraries not possible. If you compiled libx264 with the PIC option enabled, you can link a shared ffmpeg library against a static libx264 at compile time, which will then result in the x264 code being present inside the shared ffmpeg library. In this case, your ffmpeg shared library will have no dependency upon libx264 so that this particular build of ffmpeg will work on systems and provide x264 functionality that don't have it. A slightly modified scenario one option one:
x264$ ./configure --enable-static --enable-pic
ffmpeg$ ./configure --enable-shared --enable-libx264
will do this for you under one condition: There is no old libx264.so* lingering in the linker's library search path from old builds and tests of yours, or else it will happily use them. If there is only a libx264.a file present, it will use that one. To my knowledge, there is no other userfriendly way to tell standard configure scripts to use the static version for one particular library, but not for another. Builds of shared libraries will always link against shared libraries if they are available, but fallback to static .a libraries if they're not. An exception would be if autoconf was explicitly configured by the author of the project to expose that option to the user via configure flags.
Option two,
x264$ ./configure --disable-static --enable-shared
ffmpeg$ ./configure --enable-static --disable-shared --enable-libx264
will not work. The reason is that you cannot link static libraries against shared ones.
With this knowledge, scenario two is not that difficult to grasp either. You will have the progx functionality integrated into the x264 library, which in turn will be integrated into the ffmpeg. FFmpeg will not have a dependency upon either of the former two libraries since they're linked in statically. However, just as libx264, your progx library needs to be compiled with the -fPIC option. The configure script shipped with libx264 makes it easy to enable PIC. Other configure scripts from other libraries may not give you this option, but I believe you can use the CFLAGS and LDFLAGS environment variables to configure and manually add -fPIC to both. So this should work for you:
progx$ ./configure --enable-static --enable-pic
or, if "progx" has a classical style configure script:
progx$ CFLAGS=-fPIC LDFLAGS=-fPIC ./configure --enable-static --disable-shared
and finally:
x264$ ./configure --enable-static --enable-pic
ffmpeg$ ./configure --enable-shared --enable-libx264
"PIC" means "position independent code". Shared libraries need to be PIC, because they can be linked in a process' address space at any position, unlike standard program code, where all offsets are known at compile time. Thus, any static library you want to link into a shared library needs to be PIC as well.
As a final note, the command "ldd libsomelibrary.so" will yield which other shared libraries libsomelibrary.so is depending on. This command works also for dynamic executables. Taking your ffmpeg example, you will see a dependency on libx264 if you linked against the shared libx264 library, or no such dependency if you linked against its static version.
Upvotes: 3