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 -ldlthus 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
--staticand 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.pcwhich 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, notopensslitself.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
-ldlwhen linking. But doesnlibcrypto.pcreally miss the-ldl? Let’s take a look.We can see that the
-ldlis inLibs.privatesection 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
cmakebuild system, how can we add--staticincmakeconfigurations? 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
zlibthat has to be linked. Specifyingzlibin-DWITH_EXTRALIBSdoes not help due to the wrong order (zlibis included before OpenSSL?).Steps to reproduce
Not clear. Try to link statically built OpenSSL? Or follow ffmpeg-build-script.