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]:
3057ce797f/configure (L5726)
[3]:
ec0137734c

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5194>
This commit is contained in:
L. E. Segovia 2023-08-16 22:20:06 -03:00 committed by GStreamer Marge Bot
parent 18a3dfa4a1
commit dd6df92702

View file

@ -400,6 +400,10 @@ if building_full
# glib and gobject are part of our public API. If we are using glib from the # 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 # system then our pkg-config file must require it. If we built it as
# subproject then we need to link_whole it. # 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_deps = []
glib_dep = dependency('glib-2.0') glib_dep = dependency('glib-2.0')
gobject_dep = dependency('gobject-2.0') gobject_dep = dependency('gobject-2.0')
@ -450,7 +454,14 @@ if building_full
gst_full_c_flags += ['-DGST_STATIC_COMPILATION'] gst_full_c_flags += ['-DGST_STATIC_COMPILATION']
endif 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, compile_args: gst_full_c_flags,
dependencies : incdir_deps + glib_deps, dependencies : incdir_deps + glib_deps,
include_directories: include_directories('.') include_directories: include_directories('.')