srt: [BUG] Linux: static linking apps fails
Background I’m building libsrt on Ubuntu 16.04. I’m building in a Docker build process, since it gives me a clean and easily reproducible build environment - but this should be irrelevant to this bug report. I’ve been building FFmpeg in this way without libsrt for years - adding libsrt has been this weekend’s challenge. I’m building for linux x86_64 and also cross compiling for win_x86_64 and osx_x86_64 - which My final goal is to build a static FFmpeg for all three platforms including libsrt.
Describe the bug I’ve built OpenSSL 1.0.2 as static from git branch OpenSSL_1_0_2-stable.
I wand to build libsrt as static, but after make has built libsrt.a it builds some applications, and those do not link correctly (they need -ldl appending to the link command).
cmake \
-G \"Unix Makefiles\" \
-DCMAKE_INSTALL_PREFIX=${prefix} \
-DENABLE_C_DEPS=ON \
-DENABLE_SHARED=OFF \
-DENABLE_STATIC=ON
make VERBOSE=1
[ 91%] Linking CXX executable srt-live-transmit
/usr/bin/cmake -E cmake_link_script CMakeFiles/srt-live-transmit.dir/link.txt --verbose=1
/usr/bin/g++ --static -static -I/opt/ffbuild/include -DENABLE_LOGGING=1 -Wall -Wextra -O3 -DNDEBUG -L/opt/ffbuild/lib -static CMakeFiles/srt-live-transmit.dir/apps/srt-live-transmit.cpp.o CMakeFiles/srtsupport_virtual.dir/apps/apputil.cpp.o CMakeFiles/srtsupport_virtual.dir/apps/logsupport.cpp.o CMakeFiles/srtsupport_virtual.dir/apps/socketoptions.cpp.o CMakeFiles/srtsupport_virtual.dir/apps/transmitmedia.cpp.o CMakeFiles/srtsupport_virtual.dir/apps/uriparser.cpp.o CMakeFiles/srtsupport_virtual.dir/apps/verbose.cpp.o -o srt-live-transmit -rdynamic libsrt.a -ldl -Wl,-Bstatic -lssl -lcrypto -Wl,-Bdynamic -lpthread
/opt/ffbuild/lib/libcrypto.a(dso_dlfcn.o): In function `dlfcn_globallookup':
dso_dlfcn.c:(.text+0x11): undefined reference to `dlopen'
dso_dlfcn.c:(.text+0x24): undefined reference to `dlsym'
dso_dlfcn.c:(.text+0x2f): undefined reference to `dlclose'
/opt/ffbuild/lib/libcrypto.a(dso_dlfcn.o): In function `dlfcn_bind_func':
dso_dlfcn.c:(.text+0x334): undefined reference to `dlsym'
dso_dlfcn.c:(.text+0x3db): undefined reference to `dlerror'
/opt/ffbuild/lib/libcrypto.a(dso_dlfcn.o): In function `dlfcn_bind_var':
dso_dlfcn.c:(.text+0x454): undefined reference to `dlsym'
dso_dlfcn.c:(.text+0x4fb): undefined reference to `dlerror'
/opt/ffbuild/lib/libcrypto.a(dso_dlfcn.o): In function `dlfcn_load':
dso_dlfcn.c:(.text+0x569): undefined reference to `dlopen'
dso_dlfcn.c:(.text+0x5cb): undefined reference to `dlclose'
dso_dlfcn.c:(.text+0x603): undefined reference to `dlerror'
/opt/ffbuild/lib/libcrypto.a(dso_dlfcn.o): In function `dlfcn_pathbyaddr':
dso_dlfcn.c:(.text+0x69f): undefined reference to `dladdr'
dso_dlfcn.c:(.text+0x709): undefined reference to `dlerror'
/opt/ffbuild/lib/libcrypto.a(dso_dlfcn.o): In function `dlfcn_unload':
dso_dlfcn.c:(.text+0x762): undefined reference to `dlclose'
collect2: error: ld returned 1 exit status
make[2]: *** [srt-live-transmit] Error 1
CMakeFiles/srt-live-transmit.dir/build.make:109: recipe for target 'srt-live-transmit' failed
make[2]: Leaving directory '/opt/ffbuild/src/srt/build'
CMakeFiles/Makefile2:105: recipe for target 'CMakeFiles/srt-live-transmit.dir/all' failed
make[1]: Leaving directory '/opt/ffbuild/src/srt/build'
Makefile:127: recipe for target 'all' failed
make[1]: *** [CMakeFiles/srt-live-transmit.dir/all] Error 2
make: *** [all] Error 2
Workaround Since I only want libsrt.a I can work around by installing the required component (libsrt.a, srt.pc and various .h files) - but it’s a bit ugly.
make VERBOSE=1 srt_static \
&& mkdir -p ${prefix}/include/srt/win \
&& install -m 644 -c libsrt.a ${prefix}/lib/libsrt.a \
&& install -m 644 -c srt.pc ${prefix}/lib/pkgconfig/srt.pc \
&& install -m 644 -c version.h ${prefix}/include/srt/version.h \
&& install -m 644 -c ../srtcore/srt.h ${prefix}/include/srt/srt.h \
&& install -m 644 -c ../srtcore/platform_sys.h ${prefix}/include/srt/platform_sys.h \
&& install -m 644 -c ../srtcore/srt4udt.h ${prefix}/include/srt/srt4udt.h \
&& install -m 644 -c ../srtcore/logging_api.h ${prefix}/include/srt/logging_api.h
(plus some other .h files if I’m cross-compiling for Windows)
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 26 (1 by maintainers)
Ok, I think I got it. I manually changed the libcrypto.pc from above, as:
Libs: -L${libdir} -lcrypto -lz -ldl
thus showing the private libs as public libs, and it worked!
This is NOT the right way to do this, but I think it clearly shows the config/cmake process is not picking up the static (i.e. private) internal libs when it is finding OpenSSL. Coming through FFMPEG configure, it is clear they pass
--static
and append the Libs.Private when necessary.I’m way way over my head now. Thanks for listening 😃
Unfortunately, this issue doesn’t solved. I encountered it again when I try to link static openssl library.
After go through this issue, https://github.com/Haivision/srt/issues/1172#issuecomment-680326684 already gives perfect summary. However, it doesn’t help without modify
libcrypto.pc
which is not supposed to do. https://github.com/Haivision/srt/issues/1172#issuecomment-683852463 also summaries the problem even though it’s mostly talked aboutzlib
, notopenssl
itself.So I’d like to talk a bit more to explain and try to help solve this issue.
Reproduction
It can be reproduced on my
debian11(gcc (Debian 10.2.1-6) 10.2.1 20210110)
as well asUbuntu 20.04.4 LTS(gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0)
.Analysis
https://github.com/Haivision/srt/issues/1172#issuecomment-680326684 already tells us that it caused by missed
-ldl
when linking. But doesnlibcrypto.pc
really miss the-ldl
? Let’s take a look.We can see that the
-ldl
is inLibs.private
section instead ofLibs
. According to manual of pkg-config,manual of pkg-config also tells us another option for static linking:
OK, it seems that we need to use
pkg-config --static <xxx>
instead ofpkg-config <xxx>
for static linking. If we try it on command line, it looks like this:Got it! Now another problem is that srt uses
cmake
build system, how can we add--static
incmake
configurations? Actually https://github.com/Haivision/srt/issues/1172#issuecomment-683836490 has already metioned it, cmake FindPkgConfig tells us thatHere’s a simply change to verify it:
And run the build again
Now it works correctly!
Conclusion
PR to solve this issue: https://github.com/Haivision/srt/pull/2369 It has been tested on my ffmpeg-build integration.
Hope it can help! Thanks!
Let me reopen this issue to consider in the future then. It will still require some research to see if SRT’s CMake can/should detect extra dependencies of OpenSSL or any other statically built library.
Summary
When OpenSSL is built statically, building SRT apps fails, as there is an additional dependency
zlib
that has to be linked. Specifyingzlib
in-DWITH_EXTRALIBS
does not help due to the wrong order (zlib
is included before OpenSSL?).Steps to reproduce
Not clear. Try to link statically built OpenSSL? Or follow ffmpeg-build-script.