[FFmpeg-devel] [PATCH] restoring binary compatibility with ffmpeg 0.5
Mon Jun 7 07:52:11 CEST 2010
On Mo, Jun 07, 2010 at 01:44:30 (CEST), Michael Niedermayer wrote:
>> > we can duplicate the symbols and code in lavf under #if
>> I suspect that might cause a conflict during linking since the same
>> symbol would be provided by two libraries. If it doesn't fail, the
>> version chosen is unpredictable. We'd end up with apps linked against
>> a mix of sym at LIBAVFORMAT_XX and sym at LIBAVCODEC_XX which is obviously
>> not good.
> marking one as weak symbol might work.
> weak symbols are part of the ELF spec ... doesnt mean gnu tools support
> them of course ;)
I've (of course) tried that as well, but it doesn't work in this
case. The problem here is that you must not create symbol collisions in
the same compilation unit. Removing the symbols from libavcodec, even
conditionally, is not an option that we have. Using weak symbols, like
#if HAVE_SYMBOL_VERSIONING && LIBAVFORMAT_VERSION_MAJOR < 53
/* compatibility trampolines for packet functions */
#define av_weak_alias(x) __attribute__ (( weak, alias ("x") ))
void av_init_packet(AVPacket *pkt) av_weak_alias(av_init_packet);
void av_init_packet(AVPacket *pkt)
av_log(NULL, AV_LOG_WARNING, "diverting av_*_packet function calls to libavcodec. Recompile to improve performance\n");
// and so on
causes this compiler error:
.../ffmpeg/libavformat/utils.c:326: error: redefinition of 'av_init_packet'
.../ffmpeg/libavformat/utils.c:325: note: previous definition of 'av_init_packet' was here
the point here is that defining multiple versions of the same symbol
(this is what we effectively need here) is generally not allowed in C.
It was also not part of the original sun symbol versioning
implementation, but a gnu extension that allows programmers to make
changes to the API and still retain binary compatibility. And even with
that extension, you still need to declare which version of the symbol is
to be used as default. compare:
>> readelf -s -V /tmp/ffmpeg/lib/libavformat.so.52 | grep av_init_packet
121: 00000000 0 FUNC GLOBAL DEFAULT UND av_init_packet at LIBAVCODEC_52 (4)
470: 000a81b0 49 FUNC GLOBAL DEFAULT 13 av_init_packet at LIBAVFORMAT_52
516: 000a81b0 49 FUNC GLOBAL DEFAULT 13 ff_av_init_packet@@LIBAVFORMAT_52
>> readelf -s -V /tmp/ffmpeg/lib/libavcodec.so.52 | grep av_init_packet
1274: 000c0ca0 88 FUNC GLOBAL DEFAULT 13 av_init_packet@@LIBAVCODEC_52
NB: 'av_init_packet@@LIBAVCODEC_52' vs. 'av_init_packet at LIBAVFORMAT_52'.
In this case, the symbol with '@@' is the default version. The gnu
implementation furthermore requires that there must be exactly one
default version for a symbol. If this is not done, linked applications
might prefer the symbol from libavformat over libavcodec, and we really
really do not want this.
AFAIUI, these are our options now:
- my proposed "half fix" (mans strongly objects to this)
- bump major of libavformat
Ruled out options:
- move symbols back to libavformat (would reintroduce lavc->lavf dependency)
- using weak symbols (doesn't support duplicate symbols)
Any options that I've missed?
Reinhard Tartler, KeyID 945348A4
More information about the ffmpeg-devel