Plugins and libyams_onnx_resource were linked with default visibility, so
their dynamic symbol tables exported everything they contained, including
statically linked third-party code. The S3 plugin exported 11,147
symbols (OpenSSL, libcurl, zlib, spdlog, nlohmann_json); the ONNX
resource library exported 895 (850 of them spdlog). Every loader uses
RTLD_LOCAL, so this was not a live interposition bug, but the export
table is the ABI and anything that binds RTLD_GLOBAL (or a future host)
could resolve into a plugin's private copies.
Plugins:
- plugins/exports/yams_plugin.map (ELF version script, global
yams_plugin_*, local *) and yams_plugin.exp (ld64
-exported_symbols_list) are applied to every plugin (s3, onnx, glint,
zyp) with gnu_symbol_visibility: 'hidden' and --exclude-libs,ALL.
- The S3 legacy factory (yams_plugin_create/destroy_object_storage) is
marked YAMS_PLUGIN_API so it stays exported under hidden visibility.
libyams_onnx_resource:
- Builds with hidden visibility; YAMS_ONNX_RESOURCE_API now expands to
visibility("default") on GCC/Clang, so only OnnxConcurrencyRegistry is
exported.
- It no longer links spdlog. Its messages reached the host log only
because the executable's spdlog interposed the library's copy; with the
copy hidden, the registry would have logged through a private default
logger to stdout. The registry now takes a host log sink
(OnnxConcurrencyRegistry::setLogSink); TuningManager and
AbiModelProviderAdapter install a spdlog forwarder from the header-only
onnx_registry_spdlog_sink.h. Without a sink, messages are dropped.
Tests (red first on grim, Debug):
- tests/plugins/plugin_export_surface_catch2_test.cpp dlopens the built
S3 and zyp plugins and asserts the entry points resolve while libcurl,
OpenSSL, zlib and zyp internals do not: 2/2 cases failed (11 of 31
assertions) before, pass after.
- resource_governance_test gains a case for the log sink routing (did
not compile before; passes after). `meson test --suite plugins`: 5/5.
Measured on grim (release, stripped staged payload):
file bytes before after exports before after
libyams_object_storage_s3.so 7,854,064 6,240,112 11,147 10
yams_zyp.so 80,112 63,728 103 8
libyams_onnx_resource.so 477,472 30,840 895 20
bin/yams-cli 33,712,056 33,859,512 80 39
bin/yams-daemon 28,389,784 28,537,304 98 39
The executables now carry their own spdlog code paths instead of
exporting them for the resource library to interpose (+0.4%), and export
41 fewer symbols each. check_install_surface turns GREEN; budgets are
reset to the measured payload plus ~20%.
Signed-off-by: trvon <me@trevon.dev>
222 lines
7.1 KiB
Meson
222 lines
7.1 KiB
Meson
#zyp - Zig YAMS PDF Extractor
|
|
#High - performance PDF text extraction using zpdf(https: // github.com/Lulzx/zpdf)
|
|
|
|
if not get_option ('plugin-zyp')
|
|
subdir_done()
|
|
endif
|
|
|
|
if host_machine.system() == 'darwin' and get_option('b_coverage')
|
|
warning('Skipping zyp plugin in macOS coverage builds: Clang gcov runtime cannot link with the zyp bundle/benchmark.')
|
|
subdir_done()
|
|
endif
|
|
|
|
#Find Zig compiler(requires 0.15.x; zpdf is not Zig 0.16 - compatible yet)
|
|
zig = find_program('zig', required: false)
|
|
if not zig.found()
|
|
warning('Zig compiler not found, skipping zyp plugin. Install Zig 0.15.x to enable.')
|
|
subdir_done()
|
|
endif
|
|
|
|
zig_version_result = run_command(zig, 'version', check: false)
|
|
if zig_version_result.returncode() != 0
|
|
warning('Unable to determine Zig version, skipping zyp plugin.')
|
|
subdir_done()
|
|
endif
|
|
|
|
zig_version = zig_version_result.stdout().strip()
|
|
if not zig_version.version_compare('>=0.15.0')
|
|
warning('Zig @0@ is unsupported by zyp; zpdf requires Zig 0.15+. Skipping zyp plugin.'.format(zig_version))
|
|
subdir_done()
|
|
endif
|
|
|
|
#Platform - specific library name and rpath
|
|
if host_machine.system() == 'darwin'
|
|
zpdf_lib_name = 'libzpdf.dylib'
|
|
#@loader_path is used for shared libraries / modules to find libs in same directory
|
|
zyp_install_rpath = '@loader_path'
|
|
zyp_link_args = ['-fno-sanitize=thread']
|
|
elif host_machine.system() == 'windows'
|
|
zpdf_lib_name = 'zpdf.dll'
|
|
zpdf_import_lib_name = 'zpdf.lib'
|
|
zyp_install_rpath = '' # Windows doesn't use rpath
|
|
#Link against dynamic CRT libraries; avoid static CRT conflict
|
|
zyp_link_args = [
|
|
'/NODEFAULTLIB:libcmt',
|
|
'/NODEFAULTLIB:libcmtd',
|
|
'msvcrt.lib',
|
|
'vcruntime.lib',
|
|
'ucrt.lib',
|
|
]
|
|
else
|
|
zpdf_lib_name = 'libzpdf.so'
|
|
#$ORIGIN refers to directory containing the loading module
|
|
zyp_install_rpath = '$ORIGIN'
|
|
zyp_link_args = ['-fno-sanitize=thread']
|
|
endif
|
|
|
|
#Build zpdf shared library via Zig and copy to build directory
|
|
#Zig outputs DLLs to zpdf / zig - out / bin / on Windows, shared libs to zig - out / lib / on Unix
|
|
zpdf_src_dir = meson.current_source_dir() / 'zpdf'
|
|
if host_machine.system() == 'windows'
|
|
#Windows : DLL goes to bin /, import lib goes to lib /
|
|
zpdf_lib_src = zpdf_src_dir / 'zig-out' / 'bin' / zpdf_lib_name
|
|
zpdf_import_lib_src = zpdf_src_dir / 'zig-out' / 'lib' / zpdf_import_lib_name
|
|
else
|
|
zpdf_lib_src = zpdf_src_dir / 'zig-out' / 'lib' / zpdf_lib_name
|
|
endif
|
|
zpdf_build_dir = meson.current_build_dir()
|
|
fs = import('fs')
|
|
if not fs.exists(zpdf_src_dir / 'build.zig')
|
|
warning('zpdf source not found (missing build.zig), skipping zyp plugin build.')
|
|
subdir_done()
|
|
endif
|
|
|
|
#Platform - specific build command
|
|
if host_machine.system() == 'windows'
|
|
#Windows : Use PowerShell for build
|
|
#Build zpdf and copy both DLL and import lib to build directory
|
|
zpdf_lib = custom_target('zpdf_shared',
|
|
command: [
|
|
'powershell', '-NoProfile', '-Command',
|
|
'Push-Location "@0@"; & "@1@" build -Doptimize=ReleaseFast; Copy-Item "@2@" "@3@\\@4@"; Copy-Item "@5@" "@3@\\@6@"; Pop-Location'.format(
|
|
zpdf_src_dir,
|
|
zig.full_path(),
|
|
zpdf_lib_src,
|
|
zpdf_build_dir,
|
|
zpdf_lib_name,
|
|
zpdf_import_lib_src,
|
|
zpdf_import_lib_name
|
|
)
|
|
],
|
|
output: [zpdf_lib_name, zpdf_import_lib_name],
|
|
build_by_default: true,
|
|
console: true,
|
|
)
|
|
#Extract just the import library for linking
|
|
zpdf_import_lib = zpdf_lib[1]
|
|
elif host_machine.system() == 'darwin'
|
|
zpdf_build_command = (
|
|
'cd "@0@" && "@1@" build -Doptimize=ReleaseFast -Dtarget=@2@-macos.${MACOSX_DEPLOYMENT_TARGET:-26.0} && cp "@3@" "@4@/@5@"'
|
|
).format(
|
|
zpdf_src_dir,
|
|
zig.full_path(),
|
|
host_machine.cpu_family(),
|
|
zpdf_lib_src,
|
|
zpdf_build_dir,
|
|
zpdf_lib_name
|
|
)
|
|
zpdf_lib = custom_target('zpdf_shared',
|
|
command: [
|
|
'sh', '-c', zpdf_build_command
|
|
],
|
|
output: [zpdf_lib_name],
|
|
build_by_default: true,
|
|
console: true,
|
|
)
|
|
else
|
|
#Unix(Linux / macOS) : Use shell
|
|
zpdf_lib = custom_target('zpdf_shared',
|
|
command: [
|
|
'sh', '-c',
|
|
'cd "@0@" && "@1@" build -Doptimize=ReleaseFast && cp "@2@" "@3@/@4@"'.format(
|
|
zpdf_src_dir,
|
|
zig.full_path(),
|
|
zpdf_lib_src,
|
|
zpdf_build_dir,
|
|
zpdf_lib_name
|
|
)
|
|
],
|
|
output: [zpdf_lib_name],
|
|
build_by_default: true,
|
|
console: true,
|
|
)
|
|
endif
|
|
|
|
#Create a dependency object that includes the exact custom-target output. Meson recognizes
|
|
#the shared/import-library suffix and passes this artifact to the linker while preserving its
|
|
#generated-file edge. Avoid a separate -L/-l lookup: Meson resolves that to an absolute input
|
|
#without a generating rule, which breaks a clean rebuild after the artifact is removed.
|
|
if host_machine.system() == 'windows'
|
|
#On Windows, link against the import library only (not the DLL).
|
|
zpdf_dep = declare_dependency(sources: [zpdf_import_lib])
|
|
else
|
|
zpdf_dep = declare_dependency(sources: [zpdf_lib])
|
|
endif
|
|
|
|
#Compiler - specific flags for this plugin.
|
|
zyp_cpp_args = []
|
|
if meson.get_compiler('cpp').get_id() != 'msvc'
|
|
zyp_cpp_args = ['-std=c++20', '-fno-sanitize=thread']
|
|
endif
|
|
|
|
#Plugin sources
|
|
zyp_sources = files(
|
|
'zyp_plugin.cpp',
|
|
'zpdf_wrapper.cpp',
|
|
'pdf_metadata.cpp',
|
|
)
|
|
|
|
#Build the plugin(minimal dependencies - no spdlog to avoid TSan conflicts)
|
|
zyp_plugin = shared_module('yams_zyp',
|
|
zyp_sources,
|
|
include_directories: [
|
|
include_directories('../../include'),
|
|
include_directories('.'),
|
|
],
|
|
dependencies: [zpdf_dep],
|
|
cpp_args: zyp_cpp_args,
|
|
link_args: zyp_link_args + plugin_export_link_args,
|
|
link_depends: plugin_export_link_depends,
|
|
gnu_symbol_visibility: 'hidden',
|
|
#build_rpath ensures the plugin can find libzpdf during build / test
|
|
build_rpath: zpdf_build_dir,
|
|
#install_rpath ensures the plugin can find libzpdf after installation
|
|
install_rpath: zyp_install_rpath,
|
|
build_by_default: true,
|
|
install: true,
|
|
install_dir: plugins_dir,
|
|
name_prefix: '',
|
|
)
|
|
|
|
#Install zpdf library alongside the plugin
|
|
#Use platform - specific install script
|
|
if host_machine.system() == 'windows'
|
|
meson.add_install_script('powershell', '-NoProfile', '-Command',
|
|
'$dest = if ($env:DESTDIR) { Join-Path $env:DESTDIR "@1@" } else { "@1@" }; New-Item -ItemType Directory -Force -Path $dest | Out-Null; Copy-Item -Path "@0@" -Destination $dest'.format(
|
|
zpdf_build_dir / zpdf_lib_name,
|
|
get_option('prefix') / plugins_dir
|
|
),
|
|
install_tag: 'runtime',
|
|
)
|
|
else
|
|
meson.add_install_script('sh', '-c',
|
|
'mkdir -p "$DESTDIR@1@" && cp "@0@" "$DESTDIR@1@/"'.format(
|
|
zpdf_build_dir / zpdf_lib_name,
|
|
get_option('prefix') / plugins_dir
|
|
),
|
|
install_tag: 'runtime',
|
|
)
|
|
endif
|
|
|
|
#-- -- zyp extraction benchmark -- --
|
|
#Measures sequential vs parallel PDF extraction throughput.
|
|
#Usage : zyp_extraction_bench < pdf_path>[repeat_count]
|
|
zyp_extraction_bench_sources = files(
|
|
'../../tests/benchmarks/zyp_extraction_bench.cpp',
|
|
'zpdf_wrapper.cpp',
|
|
)
|
|
|
|
zyp_extraction_bench = executable('zyp_extraction_bench',
|
|
zyp_extraction_bench_sources,
|
|
include_directories: [
|
|
include_directories('../../include'),
|
|
include_directories('../..'),
|
|
include_directories('.'),
|
|
],
|
|
dependencies: [zpdf_dep],
|
|
cpp_args: zyp_cpp_args,
|
|
build_rpath: zpdf_build_dir,
|
|
build_by_default: false,
|
|
install: false,
|
|
override_options: ['b_sanitize=none'],
|
|
)
|