From 6548ec7440712eb531f4148ed0568cf90fa1e523 Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Thu, 28 Apr 2022 18:22:55 -0400 Subject: [PATCH] meson: for internal linkage, link to both libzstd and a static copy of it 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 | 29 +++++++++++++++++++++++++++++ build/meson/programs/meson.build | 15 ++------------- build/meson/tests/meson.build | 2 +- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/build/meson/lib/meson.build b/build/meson/lib/meson.build index 2f4126374..467007491 100644 --- a/build/meson/lib/meson.build +++ b/build/meson/lib/meson.build @@ -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_ 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', diff --git a/build/meson/programs/meson.build b/build/meson/programs/meson.build index 55ebf166c..8df3a5dcb 100644 --- a/build/meson/programs/meson.build +++ b/build/meson/programs/meson.build @@ -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) diff --git a/build/meson/tests/meson.build b/build/meson/tests/meson.build index cf876a395..22f43209a 100644 --- a/build/meson/tests/meson.build +++ b/build/meson/tests/meson.build @@ -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, -- 2.47.2