Not only Solaris doesn't ship static libraries, it's common practice for Linux distributions in general (security updates, size/space, etc.). See, for example 'test cases/frameworks/1 boost'. Enhancements: * Added flexibility: Introduced the SKIP_STATIC_ZLIB environment variable to optionally skip static linkage (similar to SKIP_STATIC_BOOST). * Expanded testing: Included testing for dynamic linkage, which was previously limited to static in verify_static.py (renamed to verify_zlib_linkage.py). * Improved test coverage: Ensured that each case is tested for its specific linkage type and the opposite case fails. * Addressed Cygwin issue: Ensured that the corresponding symbol is present on Cygwin. Renames, comments, etc.pull/13842/head
parent
fd309fff24
commit
c9157c9351
6 changed files with 88 additions and 66 deletions
@ -1,36 +1,34 @@ |
||||
# This test uses zlib to verify static and dynamic linkages. |
||||
# A C program is used to call a single zlib function (zlibVersion). |
||||
# The nm utility is then used to check for the existence of this symbol |
||||
# in the resulting binary. |
||||
|
||||
project('static dynamic', 'c') |
||||
|
||||
# Solaris does not ship static libraries |
||||
if host_machine.system() == 'sunos' |
||||
has_static = false |
||||
else |
||||
has_static = true |
||||
s = get_option('static') |
||||
|
||||
if s and host_machine.system() == 'sunos' |
||||
error('MESON_SKIP_TEST: static zlib linkage is not supported on SunOS by default') |
||||
endif |
||||
|
||||
cc = meson.get_compiler('c') |
||||
|
||||
z_default = cc.find_library('z') |
||||
if has_static |
||||
z_static = cc.find_library('z', static: true) |
||||
endif |
||||
z_dynamic = cc.find_library('z', static: false) |
||||
z = cc.find_library('z', static: s) |
||||
|
||||
exe_default = executable('main_default', 'main.c', dependencies: [z_default]) |
||||
if has_static |
||||
exe_static = executable('main_static', 'main.c', dependencies: [z_static]) |
||||
endif |
||||
exe_dynamic = executable('main_dynamic', 'main.c', dependencies: [z_dynamic]) |
||||
exe = executable('print_zlib_version', 'main.c', dependencies: [z]) |
||||
|
||||
test('test default', exe_default) |
||||
if has_static |
||||
test('test static', exe_static) |
||||
endif |
||||
test('test dynamic', exe_dynamic) |
||||
# first step: the executable should compile and work |
||||
test('test zlib', exe) |
||||
|
||||
if has_static |
||||
test('verify static linking', find_program('verify_static.py'), |
||||
args: ['--platform=' + host_machine.system(), exe_static.full_path()]) |
||||
endif |
||||
test('verify dynamic linking', find_program('verify_static.py'), |
||||
args: ['--platform=' + host_machine.system(), exe_dynamic.full_path()], |
||||
should_fail: true) |
||||
# to check the zlib static/dynamic symbols in the resulting binary |
||||
find_program('nm') |
||||
|
||||
# second step: static linkage |
||||
test('verify static zlib linking', find_program('verify_zlib_linkage.py'), |
||||
args: ['--platform=' + host_machine.system(), '--static', exe.full_path()], |
||||
depends: [exe], should_fail: not s) |
||||
|
||||
# third step: dynamic linkage |
||||
test('verify dynamic zlib linking', find_program('verify_zlib_linkage.py'), |
||||
args: ['--platform=' + host_machine.system(), exe.full_path()], |
||||
depends: [exe], should_fail: s) |
||||
|
@ -0,0 +1 @@ |
||||
option('static', type: 'boolean', value: false) |
@ -0,0 +1,10 @@ |
||||
{ |
||||
"matrix": { |
||||
"options": { |
||||
"static": [ |
||||
{ "val": "true", "skip_on_env": [ "SKIP_STATIC_ZLIB" ] }, |
||||
{ "val": "false" } |
||||
] |
||||
} |
||||
} |
||||
} |
@ -1,37 +0,0 @@ |
||||
#!/usr/bin/env python3 |
||||
"""Test script that checks if zlib was statically linked to executable""" |
||||
import subprocess |
||||
import sys |
||||
|
||||
def handle_common(path): |
||||
"""Handle the common case.""" |
||||
try: |
||||
output = subprocess.check_output(['nm', '--defined-only', '-P', '-A', path]).decode('utf-8') |
||||
except subprocess.CalledProcessError: |
||||
# some NMs only support -U. Older binutils only supports --defined-only. |
||||
output = subprocess.check_output(['nm', '-UPA', path]).decode('utf-8') |
||||
# POSIX format. Prints all *defined* symbols, looks like this: |
||||
# builddir/main_static: zlibVersion T 1190 39 |
||||
# or |
||||
# builddir/main_static: zlibVersion D 1fde0 30 |
||||
if ': zlibVersion ' in output: |
||||
return 0 |
||||
return 1 |
||||
|
||||
def handle_cygwin(path): |
||||
"""Handle the Cygwin case.""" |
||||
output = subprocess.check_output(['nm', path]).decode('utf-8') |
||||
if (('I __imp_zlibVersion' in output) or ('D __imp_zlibVersion' in output)): |
||||
return 1 |
||||
return 0 |
||||
|
||||
def main(): |
||||
"""Main function""" |
||||
if len(sys.argv) > 2 and sys.argv[1] == '--platform=cygwin': |
||||
return handle_cygwin(sys.argv[2]) |
||||
else: |
||||
return handle_common(sys.argv[2]) |
||||
|
||||
|
||||
if __name__ == '__main__': |
||||
sys.exit(main()) |
@ -0,0 +1,49 @@ |
||||
#!/usr/bin/env python3 |
||||
"""Test script that checks if zlib was statically or dynamically linked to executable""" |
||||
import subprocess |
||||
import sys |
||||
import argparse |
||||
|
||||
def check_zlib_symbol_common(path, is_static): |
||||
"""Tests if the binary contains zlibVersion symbol (non-Cygwin version).""" |
||||
try: |
||||
sym_opt = '--defined-only' if is_static else '--undefined-only' |
||||
output = subprocess.check_output(['nm', sym_opt, '-P', '-A', path]).decode('utf-8') |
||||
except subprocess.CalledProcessError: |
||||
# some NMs only support -U. Older binutils only supports --defined-only. |
||||
opts = '-UPA' if is_static else '-uPA' |
||||
output = subprocess.check_output(['nm', opts, path]).decode('utf-8') |
||||
# POSIX format. Prints all *defined* symbols, looks like this: |
||||
# builddir/main_static: zlibVersion T 1190 39 |
||||
# or |
||||
# builddir/main_static: zlibVersion D 1fde0 30 |
||||
if ': zlibVersion ' in output: |
||||
return 0 |
||||
return 1 |
||||
|
||||
def check_zlib_symbol_cygwin(path, is_static): |
||||
"""Tests if the binary contains zlibVersion symbol (Cygwin case).""" |
||||
output = subprocess.check_output(['nm', path]).decode('utf-8') |
||||
# No matter static or dynamic, the name must exist in nm output |
||||
if ' zlibVersion' not in output: |
||||
return 2 |
||||
is_dynamic = ('I __imp_zlibVersion' in output) or ('D __imp_zlibVersion' in output) |
||||
if is_dynamic == is_static: # expected/got mismatch? |
||||
return 3 |
||||
return 0 |
||||
|
||||
def main(): |
||||
"""Main function""" |
||||
parser = argparse.ArgumentParser() |
||||
parser.add_argument('path', help='executable path') |
||||
parser.add_argument('-p', '--platform') |
||||
parser.add_argument('-s', '--static', action='store_true', default=False) |
||||
args = parser.parse_args() |
||||
if args.platform == 'cygwin': |
||||
return check_zlib_symbol_cygwin(args.path, args.static) |
||||
else: |
||||
return check_zlib_symbol_common(args.path, args.static) |
||||
|
||||
|
||||
if __name__ == '__main__': |
||||
sys.exit(main()) |
Loading…
Reference in new issue