test: also test all _public_ functions are listed in .sym files

Co-authored-by: Frantisek Sumsal <frantisek@sumsal.cz>
This commit is contained in:
Yu Watanabe 2023-04-29 13:56:40 +09:00
parent 9857de4f1c
commit 4c1b6e699f
4 changed files with 85 additions and 28 deletions

View file

@ -126,8 +126,10 @@ libsystemd_static = static_library(
userspace],
build_by_default : false)
libsystemd_dir_path = meson.current_source_dir()
libsystemd_sym = files('libsystemd.sym')
libsystemd_sym_path = meson.current_source_dir() / 'libsystemd.sym'
libsystemd_sym_path = libsystemd_dir_path / 'libsystemd.sym'
static_libsystemd = get_option('static-libsystemd')
static_libsystemd_pic = static_libsystemd == 'true' or static_libsystemd == 'pic'

View file

@ -15,11 +15,13 @@ libudev_sources = files(
libudev_includes = [includes, include_directories('.')]
libudev_dir_path = meson.current_source_dir()
libudev_sym = files('libudev.sym')
libudev_sym_path = meson.current_source_dir() / 'libudev.sym'
libudev_sym_path = libudev_dir_path / 'libudev.sym'
install_headers('libudev.h')
libudev_h_path = meson.current_source_dir() / 'libudev.h'
libudev_h_path = libudev_dir_path / 'libudev.h'
libudev_basic = static_library(
'udev-basic',

View file

@ -1,36 +1,89 @@
#!/usr/bin/env python3
# SPDX-License-Identifier: LGPL-2.1-or-later
import sys, re
import os
import re
import sys
print('#include <stdio.h>')
for header in sys.argv[2:]:
def process_sym_file(file):
for line in file:
m = re.search(r'^ +([a-zA-Z0-9_]+);', line)
if m:
if m[1] == 'sd_bus_object_vtable_format':
print(' {{"{0}", &{0}}},'.format(m[1]))
else:
print(' {{"{0}", {0}}},'.format(m[1]))
def process_source_file(file):
for line in file:
# Functions
m = re.search(r'^_public_\s+(\S+\s+)+\**(\w+)\s*\(', line)
if m:
print(' {{ "{0}", {0} }},'.format(m[2]))
# Variables
m = re.search(r'^_public_\s+(\S+\s+)+\**(\w+)\s*=', line)
if m:
print(' {{ "{0}", &{0} }},'.format(m[2]))
# Functions defined through a macro
m = re.search(r'^DEFINE_PUBLIC_TRIVIAL_REF_FUNC\([^,]+,\s*(\w+)\s*\)', line)
if m:
print(' {{ "{0}_ref", {0}_ref }},'.format(m[1]))
m = re.search(r'^DEFINE_PUBLIC_TRIVIAL_UNREF_FUNC\([^,]+,\s*(\w+)\s*,', line)
if m:
print(' {{ "{0}_unref", {0}_unref }},'.format(m[1]))
m = re.search(r"^DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC\([^,]+,\s*(\w+)\s*,", line)
if m:
print(' {{ "{0}_ref", {0}_ref }},'.format(m[1]))
print(' {{ "{0}_unref", {0}_unref }},'.format(m[1]))
print('''/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <stdio.h>
#include <stdlib.h>
''')
for header in sys.argv[3:]:
print('#include "{}"'.format(header.split('/')[-1]))
print('''
/* We want to check deprecated symbols too, without complaining */
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
''')
const struct {
print('''
static const struct {
const char *name;
const void *symbol;
} symbols[] = {''')
} symbols_from_sym[] = {''')
count = 0
for line in open(sys.argv[1]):
match = re.search('^ +([a-zA-Z0-9_]+);', line)
if match:
s = match.group(1)
if s == 'sd_bus_object_vtable_format':
print(f' {{"{s}", &{s}}},')
else:
print(f' {{"{s}", {s}}},')
count += 1
with open(sys.argv[1], "r") as f:
process_sym_file(f)
print(f'''}};
print(''' {}
}, symbols_from_source[] = {''')
int main(void) {{
for (size_t i = 0; i < {count}; i++)
printf("%p: %s\\n", symbols[i].symbol, symbols[i].name);
return 0;
}}''')
for dirpath, _, filenames in os.walk(sys.argv[2]):
for filename in filenames:
with open(os.path.join(dirpath, filename), "r") as f:
process_source_file(f)
print(''' {}
};
int main(void) {
size_t i, j;
puts("From symbol file:");
for (i = 0; symbols_from_sym[i].name; i++)
printf("%p: %s\\n", symbols_from_sym[i].symbol, symbols_from_sym[i].name);
puts("\\nFrom source files:");
for (j = 0; symbols_from_source[j].name; j++)
printf("%p: %s\\n", symbols_from_source[j].symbol, symbols_from_source[j].name);
puts("");
printf("Found %zu symbols from symbol file.\\n", i);
printf("Found %zu symbols from source files.\\n", j);
return i == j ? EXIT_SUCCESS : EXIT_FAILURE;
}''')

View file

@ -21,17 +21,17 @@ generate_sym_test_py = find_program('generate-sym-test.py')
test_libsystemd_sym_c = custom_target(
'test-libsystemd-sym.c',
input : [libsystemd_sym_path] + systemd_headers,
input : [libsystemd_sym_path] + systemd_headers + libsystemd_sources,
output : 'test-libsystemd-sym.c',
command : [generate_sym_test_py, libsystemd_sym_path] + systemd_headers,
command : [generate_sym_test_py, libsystemd_sym_path, libsystemd_dir_path] + systemd_headers,
capture : true,
build_by_default : want_tests != 'false')
test_libudev_sym_c = custom_target(
'test-libudev-sym.c',
input : [libudev_sym_path, libudev_h_path],
input : [libudev_sym_path, libudev_h_path] + libudev_sources,
output : 'test-libudev-sym.c',
command : [generate_sym_test_py, '@INPUT0@', '@INPUT1@'],
command : [generate_sym_test_py, libudev_sym_path, libudev_dir_path, libudev_h_path],
capture : true,
build_by_default : want_tests != 'false')