]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
meson: for internal linkage, link to both libzstd and a static copy of it 3122/head
authorEli Schwartz <eschwartz@archlinux.org>
Thu, 28 Apr 2022 22:22:55 +0000 (18:22 -0400)
committerEli Schwartz <eschwartz@archlinux.org>
Fri, 29 Apr 2022 01:57:02 +0000 (21:57 -0400)
Partial, Meson-only implementation of #2976 for non-MSVC builds.

Due to the prevalence of private symbol reuse, linking to a shared
library is simply utterly unreliable, but we still want to defer to the
shared library for installable applications. By linking to both, we can
share symbols where possible, and statically link where needed.

This means we no longer need to manually track every file that needs to
be extracted and reused.

The flip side is that MSVC completely does not support this, so for MSVC
builds we just link to a full static copy even where
-Ddefault_library=shared.

As a side benefit, by using library inclusion rather than including
extra explicit object files, the zstd program shrinks in size slightly
(~4kb).

build/meson/lib/meson.build
build/meson/programs/meson.build
build/meson/tests/meson.build

index 2f4126374dc02d001000c11dc6eb0bc50604bc00..467007491f59166e0c42bbe82d45eedecfdca123 100644 (file)
@@ -126,6 +126,35 @@ libzstd = library('zstd',
 libzstd_dep = declare_dependency(link_with: libzstd,
   include_directories: libzstd_includes)
 
+# we link to both:
+# - the shared library (for public symbols)
+# - the static library (for private symbols)
+#
+# this is needed because internally private symbols are used all the time, and
+# -fvisibility=hidden means those cannot be found
+if get_option('default_library') == 'static'
+  libzstd_static = libzstd
+  libzstd_internal_dep = libzstd_dep
+else
+  if get_option('default_library') == 'shared'
+    libzstd_static = static_library('zstd_objlib',
+      objects: libzstd.extract_all_objects(recursive: true),
+      build_by_default: false)
+  else
+    libzstd_static = libzstd.get_static_lib()
+  endif
+
+  if cc_id == compiler_msvc
+    # msvc does not actually support linking to both, but errors out with:
+    #   error LNK2005: ZSTD_<foo> already defined in zstd.lib(zstd-1.dll)
+    libzstd_internal_dep = declare_dependency(link_with: libzstd_static)
+  else
+    libzstd_internal_dep = declare_dependency(link_with: libzstd,
+      # the static library must be linked after the shared one
+      dependencies: declare_dependency(link_with: libzstd_static))
+  endif
+endif
+
 pkgconfig.generate(libzstd,
   name: 'libzstd',
   filebase: 'libzstd',
index 55ebf166cadc217e489b356b123fcff6cf359486..8df3a5dcbdd7941a2fae3108e7e7ac0a46088842 100644 (file)
@@ -21,10 +21,10 @@ zstd_programs_sources = [join_paths(zstd_rootdir, 'programs/zstdcli.c'),
   join_paths(zstd_rootdir, 'programs/dibio.c'),
   join_paths(zstd_rootdir, 'programs/zstdcli_trace.c')]
 
-zstd_deps = [ libzstd_dep ]
+zstd_deps = [ libzstd_internal_dep ]
 zstd_c_args = libzstd_debug_cflags
 
-zstd_frugal_deps = [ libzstd_dep ]
+zstd_frugal_deps = [ libzstd_internal_dep ]
 zstd_frugal_c_args = [ '-DZSTD_NOBENCH', '-DZSTD_NODICT', '-DZSTD_NOTRACE' ]
 
 if use_multi_thread
@@ -70,12 +70,6 @@ zstd = executable('zstd',
   zstd_programs_sources,
   c_args: zstd_c_args,
   dependencies: zstd_deps,
-  # needed due to use of private symbol + -fvisibility=hidden
-  objects: libzstd.extract_objects(
-    join_paths(zstd_rootdir, 'lib/common/xxhash.c'),
-    join_paths(zstd_rootdir, 'lib/common/pool.c'),
-    join_paths(zstd_rootdir, 'lib/common/zstd_common.c'),
-    join_paths(zstd_rootdir, 'lib/common/error_private.c')),
   export_dynamic: export_dynamic_on_windows, # Since Meson 0.45.0
   install: true)
 
@@ -90,11 +84,6 @@ zstd_frugal_sources = [join_paths(zstd_rootdir, 'programs/zstdcli.c'),
 executable('zstd-frugal',
   zstd_frugal_sources,
   dependencies: zstd_frugal_deps,
-  # needed due to use of private symbol + -fvisibility=hidden
-  objects: libzstd.extract_objects(
-    join_paths(zstd_rootdir, 'lib/common/pool.c'),
-    join_paths(zstd_rootdir, 'lib/common/zstd_common.c'),
-    join_paths(zstd_rootdir, 'lib/common/error_private.c')),
   c_args: zstd_frugal_c_args,
   install: true)
 
index cf876a395a476718b82238916acbc5b7bb526fe9..22f43209ad7bd573643af7d552005dfc401ab7b1 100644 (file)
@@ -38,7 +38,7 @@ testcommon_sources = [join_paths(zstd_rootdir, 'programs/datagen.c'),
 testcommon = static_library('testcommon',
   testcommon_sources,
   # needed due to use of private symbol + -fvisibility=hidden
-  objects: libzstd.extract_all_objects(recursive: false))
+  link_with: libzstd_static)
 
 testcommon_dep = declare_dependency(link_with: testcommon,
   dependencies: libzstd_deps,