Discussion:
[Libav-user] statically linking x264 and x265 into ffmpeg
Peter Steinbach
2016-09-06 08:14:00 UTC
Permalink
Hi to all,

for a project, I'd like to bundle ffmpeg statically. The project itself
is cross-platform, which is proving to be a challenge.

For this, I'd like to build ffmpeg statically and link in libx264 and
libx265 so that I only have to link my library in turn to ffmpeg and be
done with it. I started to experiment with this on Linux. In order to
achieve that, I compiled both libx264 and libx265 statically with
--enable-pic (my distro only ships static libs with -fPIE :( ).

I then build ffmpeg with the following flags:
$ ./configure --prefix=/tmp/master-x264-x265-minimal --enable-static
--enable-pic --disable-everything --disable-programs --enable-libx264
--enable-libx265 --enable-gpl

When running "make V=1" and inspecting the gcc calls, I can however not
see where both libx26* are linked into ffmpeg. I also inspected
libavcodec, but couldn't find any (undefined) symbols of h264 or h265. I
only saw
$ nm *.a | egrep -i "(264|hevc)"
U ff_h264_profiles
U ff_hevc_profiles
0000000000000340 D ff_h264_profiles
00000000000002e0 D ff_hevc_profiles
...

The pkgconfig files generated however contain direct references to
"-lx26?". Excuse me if I am overseeing something obvious. I tried this
with master from 10minutes ago and 3.0.2

So my question is, how can I link x264 and x265 into libavcodec so that
symbols/objects from these dependencies are imported into libav*
completely?
Best,
Peter
Carl Eugen Hoyos
2016-09-06 10:04:09 UTC
Permalink
Post by Peter Steinbach
$ ./configure --prefix=/tmp/master-x264-x265-minimal --enable-static
--enable-pic --disable-everything --disable-programs --enable-libx264
--enable-libx265 --enable-gpl
When running "make V=1" and inspecting the gcc calls, I can
however not see where both libx26* are linked into ffmpeg
That is because your configure line requests not to link ffmpeg,
it requests not to link any binary, so no libraries can ever be
linked.

Carl Eugen
Carl Eugen Hoyos
2016-09-06 10:00:19 UTC
Permalink
Post by Peter Steinbach
$ ./configure --prefix=/tmp/master-x264-x265-minimal --enable-static
--enable-pic --disable-everything --disable-programs --enable-libx264
--enable-libx265 --enable-gpl
--enable-static has no effect and does not imply static linking.
Are you sure that you have no dynamic libraries for x264 or
x265 anywhere in the path: Most linkers will prefer them
over static libraries. An alternative is using "/path/to/lib.a" on
the linking line instead of "-L/path/to -llib".
You may want to use "ldd" to test for dynamic libraries.

Do you know what "--disable-everything" does?
It is a debug option, you should never use it for anything
that you distribute, use --disable-all instead (if you need
it), it implies --disable-programs.

Just curious: Does --enable-pic really have an effect?
Which platform is this?

Carl Eugen
Peter Steinbach
2016-09-06 10:55:42 UTC
Permalink
Post by Carl Eugen Hoyos
Post by Peter Steinbach
$ ./configure --prefix=/tmp/master-x264-x265-minimal --enable-static
--enable-pic --disable-everything --disable-programs --enable-libx264
--enable-libx265 --enable-gpl
Hi Carl Eugen,
Post by Carl Eugen Hoyos
--enable-static has no effect and does not imply static linking.
wow, I wasn't aware of that. I guess I misunderstood the docs then.
Post by Carl Eugen Hoyos
Are you sure that you have no dynamic libraries for x264 or
x265 anywhere in the path: Most linkers will prefer them
over static libraries. An alternative is using "/path/to/lib.a" on
the linking line instead of "-L/path/to -llib".
You may want to use "ldd" to test for dynamic libraries.
Alright, I'll look into doing that. So you mean that I should add
```
--extra-libs="-L/path/to/static/libx264a -lx264"
```
right? I'll give that a shot.
Post by Carl Eugen Hoyos
Do you know what "--disable-everything" does?
nope. I though it does what it means ;)
Post by Carl Eugen Hoyos
It is a debug option, you should never use it for anything
that you distribute, use --disable-all instead (if you need
it), it implies --disable-programs.
ok, thanks a bunch for the pointer. I'll use that flag instead then.
Post by Carl Eugen Hoyos
Just curious: Does --enable-pic really have an effect?
AFAIK, yes. PIC is propagated to the compiler calls, PIC is then
generated and I can bundle the library as I wish to.
Post by Carl Eugen Hoyos
Which platform is this?
I am working on fc23 right now. the static libs coming with fedora all
have -fPIE enabled (if I understood the docs correctly), which doesn't
help me at all.

I'll keep you posted,
P
Peter Steinbach
2016-09-06 12:18:33 UTC
Permalink
Alright, so this
```
./configure --prefix=/tmp/ffmpeg --disable-programs --enable-pic
--enable-static --enable-libx264 --enable-libx265 --enable-gpl
--extra-ldflags="/home/steinbac/software/x264/master-static/lib/libx264.a
/home/steinbac/software/x265/master-static/lib/libx265.a"
```

generates the static libraries I wanted and it contains x264/x265 symboles.

I checked libavcodec with nm, and I see stuff like this:
$ nm libavcodec.a|grep ff_hevc_transform_add16_10_sse2
0000000000002810 T ff_hevc_transform_add16_10_sse2
U ff_hevc_transform_add16_10_sse2

Which I found a bit weird as the function call is declared as undefined
and as found in the .text section. I'll check downstream now, if my
project can such that up without having to link against libx264/libx265
as well.

Let me do some more checks, before I sign this thread off. ;)
Thanks for the help so far.

Best,
Peter
Carl Eugen Hoyos
2016-09-06 18:29:06 UTC
Permalink
Post by Peter Steinbach
./configure --prefix=/tmp/ffmpeg --disable-programs --enable-pic
--enable-static --enable-libx264 --enable-libx265 --enable-gpl
--extra-ldflags="/home/steinbac/software/x264/master-static/lib/libx264.a
/home/steinbac/software/x265/master-static/lib/libx265.a"
As said, --enable-static has no effect, I suggest you remove
it to avoid misunderstandings.

[...]
Post by Peter Steinbach
$ nm libavcodec.a|grep ff_hevc_transform_add16_10_sse2
0000000000002810 T ff_hevc_transform_add16_10_sse2
U ff_hevc_transform_add16_10_sse2
These are symbols from FFmpeg's decoder (note the "ff_"),
they are unrelated to x265.
(You can test by recompiling without x265.)

Carl Eugen
Peter Steinbach
2016-09-16 12:31:22 UTC
Permalink
Post by Carl Eugen Hoyos
Post by Peter Steinbach
./configure --prefix=/tmp/ffmpeg --disable-programs --enable-pic
--enable-static --enable-libx264 --enable-libx265 --enable-gpl
--extra-ldflags="/home/steinbac/software/x264/master-static/lib/libx264.a
/home/steinbac/software/x265/master-static/lib/libx265.a"
As said, --enable-static has no effect, I suggest you remove
it to avoid misunderstandings.
[...]
Post by Peter Steinbach
$ nm libavcodec.a|grep ff_hevc_transform_add16_10_sse2
0000000000002810 T ff_hevc_transform_add16_10_sse2
U ff_hevc_transform_add16_10_sse2
These are symbols from FFmpeg's decoder (note the "ff_"),
they are unrelated to x265.
(You can test by recompiling without x265.)
Just to confirm the following does the static linking that I aspired to:
./configure --prefix=${HOME}/software/ffmpeg/3.0.2-x264-hevc-static
--disable-shared --enable-pic --enable-libx264 --enable-libx265
--enable-gpl
--extra-ldflags="${HOME}/software/x264/master-static/lib/libx264.a
${HOME}/software/x265/master-static/lib/libx265.a" ... more flags ...

Thanks Carl Eugen,
Peter
Carl Eugen Hoyos
2016-09-16 12:34:45 UTC
Permalink
Post by Peter Steinbach
./configure --prefix=${HOME}/software/ffmpeg/3.0.2-x264-hevc-static
--disable-shared --enable-pic --enable-libx264 --enable-libx265 --enable-gpl
--extra-ldflags="${HOME}/software/x264/master-static/lib/libx264.a
${HOME}/software/x265/master-static/lib/libx265.a" ... more flags ...
--disable-shared has no effect, --enable-pic generally either has no
effect, or an undesirable effect.

I am not completely convinced that your extra ld flags would fix the
issue for everybody.

Carl Eugen
Peter Steinbach
2016-09-16 12:37:08 UTC
Permalink
Post by Carl Eugen Hoyos
--disable-shared has no effect, --enable-pic generally either has no
effect, or an undesirable effect.
I am not completely convinced that your extra ld flags would fix the
issue for everybody.
mmmh, from what you are saying I might sarcastically (the AE/UE meaning)
ask, what configure flags actually do have an effect? ;)

Anyhow, the flags I posted produce static libraries only that contain
PIC. And that was what I was after.

Best,
Peter
Carl Eugen Hoyos
2016-09-16 12:42:58 UTC
Permalink
Post by Peter Steinbach
Post by Carl Eugen Hoyos
--disable-shared has no effect, --enable-pic generally either has no
effect, or an undesirable effect.
I am not completely convinced that your extra ld flags would fix the
issue for everybody.
mmmh, from what you are saying I might sarcastically (the AE/UE meaning)
I have no idea what AE/UE means.
Post by Peter Steinbach
ask, what configure flags actually do have an effect? ;)
The ldflags you provided helped on your system (and I don't mean the
path) and for your use-case, I am not convinced they will help everybody
(with similar needs).
(--disable-shared is the default, so using it in your configure line makes
no difference)
Post by Peter Steinbach
Anyhow, the flags I posted produce static libraries only that contain PIC.
And that was what I was after.
If --enable-pic really made a difference, you should ask yourself again
(carefully) if that's really what you want.
(Note that enable-pic is the default on x86-64 and cannot be turned off
afair, it hurts on x86-32 and cannot do what people want because
FFmpeg binaries are not position independent on x86-32, no matter
the pic option.)

Carl Eugen
Peter Steinbach
2016-09-16 12:45:44 UTC
Permalink
Post by Carl Eugen Hoyos
Post by Peter Steinbach
mmmh, from what you are saying I might sarcastically (the AE/UE meaning)
ups, a typo on my side, I meant AE/BE ... American English/British English.
Post by Carl Eugen Hoyos
The ldflags you provided helped on your system (and I don't mean the
path) and for your use-case, I am not convinced they will help everybody
(with similar needs).
(--disable-shared is the default, so using it in your configure line makes
no difference)
Interesting. Thanks for the heads-up.
Post by Carl Eugen Hoyos
Post by Peter Steinbach
Anyhow, the flags I posted produce static libraries only that contain PIC.
And that was what I was after.
If --enable-pic really made a difference, you should ask yourself again
(carefully) if that's really what you want.
(Note that enable-pic is the default on x86-64 and cannot be turned off
afair, it hurts on x86-32 and cannot do what people want because
FFmpeg binaries are not position independent on x86-32, no matter
the pic option.)
Wow, that is really good to know for my use case.
Thanks -
P
Carl Eugen Hoyos
2016-09-16 12:55:53 UTC
Permalink
Post by Carl Eugen Hoyos
(Note that enable-pic is the default on x86-64 and cannot be turned off
Sorry:
Shared libraries on x86-64 need pic, for static libraries, you can choose
(and contrary to x86-32, it should work as intended).

Carl Eugen

Loading...