From dd6df9270290e8a33302a228f4c9554d00d453e6 Mon Sep 17 00:00:00 2001 From: "L. E. Segovia" Date: Wed, 16 Aug 2023 22:20:06 -0300 Subject: [PATCH] gstreamer-full: Work around Win32 PE missing symbols from static libraries MSVC's /WHOLEARCHIVE and GCC/Clang's -Wl,--whole-archive options are often sold as allowing the developer to reexport symbols coming from static dependencies. However, this is not the complete picture. While it is true in both ELF and MachO, which merge the symbol tables into one [1], in PE this is not the case when the end binary is a DLL. For this case, projects like FFmpeg extract the symbol table from the static version and then construct a module definition file to mark them as exported [2]. The approach in this platform is to, for the Windows and Cygwin cases, reexport the libraries that are intended to be link_whole'd for downstream consumption. Alternatively, the libraries in exposed_libs need to be dumpbin'd individually and then a .def has to be constructed for the whole [3]. [1]: https://stackoverflow.com/a/61544818 [2]: https://github.com/FFmpeg/FFmpeg/blob/3057ce797f6e1348b978f5ffe9e2afd2224544f0/configure#L5726 [3]: https://gitlab.freedesktop.org/gstreamer/meson-ports/ffmpeg/-/commit/ec0137734c1be29ce905b298b0bcc5608ea85b4a Part-of: --- meson.build | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 48624cc081..4863ee54ee 100644 --- a/meson.build +++ b/meson.build @@ -400,6 +400,10 @@ if building_full # glib and gobject are part of our public API. If we are using glib from the # system then our pkg-config file must require it. If we built it as # subproject then we need to link_whole it. + # Note that link_whole dependencies aren't exposed transitively in + # Windows/Cygwin, because symbols from static libraries must + # be manually marked as exported through a module definition file. + # See e.g. https://github.com/FFmpeg/FFmpeg/blob/3057ce797f6e1348b978f5ffe9e2afd2224544f0/configure#L5726 glib_deps = [] glib_dep = dependency('glib-2.0') gobject_dep = dependency('gobject-2.0') @@ -450,7 +454,14 @@ if building_full gst_full_c_flags += ['-DGST_STATIC_COMPILATION'] endif - gst_full_dep = declare_dependency(link_with: gstfull, + gst_full_libs = [gstfull] + + # See above re: symbol exports in Win32 + if ['windows', 'cygwin'].contains(host_machine.system()) + gst_full_libs += exposed_libs + endif + + gst_full_dep = declare_dependency(link_with: gst_full_libs, compile_args: gst_full_c_flags, dependencies : incdir_deps + glib_deps, include_directories: include_directories('.')