c++ - 创建静态包含 ffmpeg 的共享库

标签 c++ ffmpeg shared-libraries static-libraries

我很难尝试创建一个将 ffmpeg 库“内置”为静态库的共享库。

考虑以下目录模式:

include/
  my own .h files
  ext/
    ffmpeg .h files
lib/
  libav*.a archive files (softlinks to the actual .a files)
  libValkka.so (my shared library)
test/
  mytest.cpp
bin/
  (binaries appear here)

我已经走了很长一段路(参见 Including objects to a shared library from a C++ archive (.a))并且库编译正常:(为简洁起见省略了 [STUFF])

/usr/bin/c++ -fPIC -std=c++14 -pthread -Iinclude/ext -I/usr/include/libdrm -g -shared -Wl,-soname,libValkka.so -o lib/libValkka.so CMakeFiles/Valkka.dir/src/avthread.cpp.o CMakeFiles/Valkka.dir/src/opengl.cpp.o CMakeFiles/Valkka.dir/src/openglthread.cpp.o [STUFF] CMakeFiles/Valkka.dir/src/filters.cpp.o -lX11 -lGLEW -lGLU -lGL -Wl,--allow-multiple-definition -Wl,-Bsymbolic -Wl,--whole-archive -Wreorder lib/libavdevice.a lib/libavfilter.a lib/libavformat.a lib/libavcodec.a lib/libavutil.a lib/libswscale.a lib/libswresample.a -Wl,--no-whole-archive

但是,在创建可执行文件时 - 他们的源代码不使用任何 ffmpeg api(只是我自己的 api) - 使用:

c++ -std=c++14 -pthread -Iinclude -Iinclude/ext -Llib test/mytest.cpp -lValkka -g -o bin/mytest

我收到一堆关于缺少 ffmpeg 依赖项的错误。并不是所有东西都丢失了,只是一些奇怪的东西:

lib/libValkka.so: undefined reference to `pa_stream_get_index'
lib/libValkka.so: undefined reference to `deflateInit_'
lib/libValkka.so: undefined reference to `pa_stream_get_state'
lib/libValkka.so: undefined reference to `lzma_stream_decoder'
lib/libValkka.so: undefined reference to `BZ2_bzDecompress'
lib/libValkka.so: undefined reference to `vaInitialize'
lib/libValkka.so: undefined reference to `pa_stream_unref'
lib/libValkka.so: undefined reference to `deflateInit2_'
lib/libValkka.so: undefined reference to `snd_pcm_close'
...
lib/libValkka.so: undefined reference to `vaGetDisplayDRM'
lib/libValkka.so: undefined reference to `vaMaxNumEntrypoints'
lib/libValkka.so: undefined reference to `uncompress'
lib/libValkka.so: undefined reference to `pa_stream_drop'
lib/libValkka.so: undefined reference to `pa_context_connect'
lib/libValkka.so: undefined reference to `FT_Get_Kerning'
lib/libValkka.so: undefined reference to `ass_free_track'
lib/libValkka.so: undefined reference to `pa_operation_unref'
lib/libValkka.so: undefined reference to `FT_Stroker_Done'
lib/libValkka.so: undefined reference to `vaTerminate'
lib/libValkka.so: undefined reference to `ass_new_track'
lib/libValkka.so: undefined reference to `jack_client_close'
...
lib/libValkka.so: undefined reference to `xcb_xfixes_query_version'
lib/libValkka.so: undefined reference to `xcb_shape_rectangles'
lib/libValkka.so: undefined reference to `pa_mainloop_free'
lib/libValkka.so: undefined reference to `snd_device_name_hint'
lib/libValkka.so: undefined reference to `vaCreateImage'
lib/libValkka.so: undefined reference to `vaBeginPicture'
lib/libValkka.so: undefined reference to `DtsSetColorSpace'
lib/libValkka.so: undefined reference to `vaDestroyConfig'
lib/libValkka.so: undefined reference to `pa_stream_writable_size'
lib/libValkka.so: undefined reference to `snd_pcm_hw_params_get_buffer_size_max'
lib/libValkka.so: undefined reference to `ass_read_file'

这非常令人沮丧,尤其是当我看到这些名称包含在共享库中时......!

nm lib/libValkka.so | grep "vaBeginPicture"

给予

U vaBeginPicture

等我认为这可能是关于存档 .a 文件的依赖顺序的问题,并且还尝试了:

..... -Wl,--allow-multiple-definition -Wl,-Bsymbolic -Wl,--start-group -Wl,--whole-archive -Wreorder lib/libavdevice.a lib/libavfilter.a lib/libavformat.a lib/libavcodec.a lib/libavutil.a lib/libswscale.a lib/libswresample.a -Wl,--no-whole-archive -Wl,--end-group

但问题依然存在。

我已经成功地创建了一个共享库,它“烘焙”那些 .a 文件,也就是说,它只动态地依赖于 ffmpeg 库,并且没有这样的问题。

我很困惑..我是不是误解了一些基本的东西,忘记了一些烦人的链接选项,或者两者兼而有之?帮助表示赞赏!

最佳答案

您需要将共享库与 ffmpeg 所需的第 3 方/系统库链接:libbz2、libva、libxcb、libass、freetype2 等。实际列表应该位于 ffmpeg 分发/构建工件(automake 的 .pc 文件)中的某处

ignore-all 不是一个好主意;您的应用程序可能运行正常,但这些 Unresolved 项目仍然存在;一旦碰到其中任何一个,它就会崩溃。我的猜测是它们中的大多数永远不会被击中,因为它们是用于您可能甚至不会使用的 libavdevice 的,但这仍然是一个坏主意。另外,检查您是否真的需要那个 libavdevice 库 - 如果您去掉那个库,您可能会大大减少所需库的列表。

关于c++ - 创建静态包含 ffmpeg 的共享库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46630386/

相关文章:

c++ - 为什么构造函数不调用?

c++ - 如何通过 C++ API 为 tflite 提供多维输入

输入多路复用的 C++ 设计模式?

dll - 如果我仍然需要 .dll 和 .pri 文件,那么使用 .winmd 库有什么意义?

c++ - 如何将应用程序链接到依赖于另一个库的库?

c++ - 运行代码时无法输入值

javascript - 如何在 Nativescript 中实现 Java 方法?

ffmpeg - 当输出通过网络驱动器时,为什么 FFMPEG 的 -movflags faststart 参数会生成空文件?

php - 知道 youtube 使用的是什么视频编码技术吗?

c++ - 在 OS X 上链接期间包装符号