From: David Marchand <david.marchand@redhat.com>
To: dev@dpdk.org
Cc: thomas@monjalon.net, bruce.richardson@intel.com,
andremue@linux.microsoft.com,
Jasvinder Singh <jasvinder.singh@intel.com>
Subject: [RFC v2 2/2] build: generate symbol maps
Date: Thu, 6 Mar 2025 13:50:21 +0100 [thread overview]
Message-ID: <20250306125021.2231121-2-david.marchand@redhat.com> (raw)
In-Reply-To: <20250306125021.2231121-1-david.marchand@redhat.com>
Rather than maintain a file in parallel of the code, symbols to be
exported can be marked with a token.
The build framework then generates map files in a format that can satisfy
GNU linker.
Apply those macros to lib/net as an example.
Documentation is missing.
Converting from .map to Windows export file is not done.
Checks on map files are left in place, though they could be removed once
the whole tree is converted.
Experimental and internal symbol types are not handled.
Probably something else is missing, but this patch is still at RFC level.
Signed-off-by: David Marchand <david.marchand@redhat.com>
---
buildtools/gen-version-map.py | 65 +++++++++++++++++++++++++++++++++++
buildtools/meson.build | 1 +
drivers/meson.build | 2 --
lib/meson.build | 19 ++++++++--
lib/net/rte_arp.c | 1 +
lib/net/rte_ether.c | 3 ++
lib/net/rte_net.c | 2 ++
lib/net/rte_net_crc.c | 1 +
lib/net/version.map | 23 -------------
meson.build | 3 +-
10 files changed, 91 insertions(+), 29 deletions(-)
create mode 100755 buildtools/gen-version-map.py
delete mode 100644 lib/net/version.map
diff --git a/buildtools/gen-version-map.py b/buildtools/gen-version-map.py
new file mode 100755
index 0000000000..2b03f328ea
--- /dev/null
+++ b/buildtools/gen-version-map.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright (c) 2024 Red Hat, Inc.
+
+"""Generate a version map file used by GNU linker."""
+
+import re
+import sys
+
+# From meson.build
+sym_export_regexp = re.compile(r"^RTE_EXPORT_SYMBOL\(([^,]+)\)$")
+# From rte_function_versioning.h
+sym_ver_regexp = re.compile(r"^RTE_VERSION_SYMBOL\(([^,]+), [^,]+, ([^,]+),")
+sym_default_regexp = re.compile(r"^RTE_DEFAULT_SYMBOL\(([^,]+), [^,]+, ([^,]+),")
+
+with open("../ABI_VERSION") as f:
+ abi = re.match("([0-9]+).[0-9]", f.readline()).group(1)
+
+symbols = {}
+
+for file in sys.argv[2:]:
+ with open(file, encoding="utf-8") as f:
+ for ln in f.readlines():
+ node = None
+ symbol = None
+ if sym_export_regexp.match(ln):
+ symbol = sym_export_regexp.match(ln).group(1)
+ elif sym_ver_regexp.match(ln):
+ node = sym_ver_regexp.match(ln).group(1)
+ symbol = sym_ver_regexp.match(ln).group(2)
+ elif sym_default_regexp.match(ln):
+ node = sym_default_regexp.match(ln).group(1)
+ symbol = sym_default_regexp.match(ln).group(2)
+
+ if not symbol:
+ continue
+
+ if not node:
+ node = abi
+ if node not in symbols:
+ symbols[node] = []
+ symbols[node].append(symbol)
+
+with open(sys.argv[1], "w") as outfile:
+ local_token = False
+ if abi in symbols:
+ outfile.writelines(f"DPDK_{abi} {{\n\tglobal:\n\n")
+ for symbol in sorted(symbols[abi]):
+ outfile.writelines(f"\t{symbol};\n")
+ outfile.writelines("\n")
+ if not local_token:
+ outfile.writelines("\tlocal: *;\n")
+ local_token = True
+ outfile.writelines("};\n")
+ del symbols[abi]
+ for key in sorted(symbols.keys()):
+ outfile.writelines(f"DPDK_{key} {{\n\tglobal:\n\n")
+ for symbol in sorted(symbols[key]):
+ outfile.writelines(f"\t{symbol};\n")
+ outfile.writelines("\n")
+ if not local_token:
+ outfile.writelines("\tlocal: *;\n")
+ local_token = True
+ outfile.writelines(f"}} DPDK_{abi};\n")
+ del symbols[key]
diff --git a/buildtools/meson.build b/buildtools/meson.build
index 4e2c1217a2..b745e9afa4 100644
--- a/buildtools/meson.build
+++ b/buildtools/meson.build
@@ -16,6 +16,7 @@ else
py3 = ['meson', 'runpython']
endif
echo = py3 + ['-c', 'import sys; print(*sys.argv[1:])']
+gen_version_map = py3 + files('gen-version-map.py')
list_dir_globs = py3 + files('list-dir-globs.py')
map_to_win_cmd = py3 + files('map_to_win.py')
sphinx_wrapper = py3 + files('call-sphinx-build.py')
diff --git a/drivers/meson.build b/drivers/meson.build
index 05391a575d..d5fe3749c4 100644
--- a/drivers/meson.build
+++ b/drivers/meson.build
@@ -5,8 +5,6 @@ if is_ms_compiler
subdir_done()
endif
-fs = import('fs')
-
# Defines the order of dependencies evaluation
subdirs = [
'common',
diff --git a/lib/meson.build b/lib/meson.build
index ce92cb5537..4db1864241 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -110,6 +110,7 @@ endif
default_cflags = machine_args
default_cflags += ['-DALLOW_EXPERIMENTAL_API']
default_cflags += ['-DALLOW_INTERNAL_API']
+default_cflags += ['-DRTE_EXPORT_SYMBOL(a)=']
if cc.has_argument('-Wno-format-truncation')
default_cflags += '-Wno-format-truncation'
@@ -254,6 +255,9 @@ foreach l:libraries
include_directories: includes,
dependencies: static_deps)
+ version_map = '@0@/@1@/version.map'.format(meson.current_source_dir(), l)
+ lk_deps = []
+
if not use_function_versioning or is_windows
# use pre-build objects to build shared lib
sources = []
@@ -262,10 +266,19 @@ foreach l:libraries
# for compat we need to rebuild with
# RTE_BUILD_SHARED_LIB defined
cflags += '-DRTE_BUILD_SHARED_LIB'
- endif
- version_map = '@0@/@1@/version.map'.format(meson.current_source_dir(), l)
- lk_deps = [version_map]
+ # POC: generate version.map if absent.
+ if not fs.is_file(version_map)
+ map_file = custom_target(libname + '_map',
+ command: [gen_version_map, '@OUTPUT@', '@INPUT@'],
+ input: sources,
+ output: '@0@_version.map'.format(libname))
+ version_map = map_file.full_path()
+ lk_deps += [map_file]
+ else
+ lk_deps += [version_map]
+ endif
+ endif
if is_ms_linker
def_file = custom_target(libname + '_def',
diff --git a/lib/net/rte_arp.c b/lib/net/rte_arp.c
index 22af519586..cd0f49a7a9 100644
--- a/lib/net/rte_arp.c
+++ b/lib/net/rte_arp.c
@@ -47,3 +47,4 @@ rte_net_make_rarp_packet(struct rte_mempool *mpool,
return mbuf;
}
+RTE_EXPORT_SYMBOL(rte_net_make_rarp_packet)
diff --git a/lib/net/rte_ether.c b/lib/net/rte_ether.c
index f59c20289d..9d02db1676 100644
--- a/lib/net/rte_ether.c
+++ b/lib/net/rte_ether.c
@@ -17,6 +17,7 @@ rte_eth_random_addr(uint8_t *addr)
addr[0] &= (uint8_t)~RTE_ETHER_GROUP_ADDR; /* clear multicast bit */
addr[0] |= RTE_ETHER_LOCAL_ADMIN_ADDR; /* set local assignment bit */
}
+RTE_EXPORT_SYMBOL(rte_eth_random_addr)
void
rte_ether_format_addr(char *buf, uint16_t size,
@@ -25,6 +26,7 @@ rte_ether_format_addr(char *buf, uint16_t size,
snprintf(buf, size, RTE_ETHER_ADDR_PRT_FMT,
RTE_ETHER_ADDR_BYTES(eth_addr));
}
+RTE_EXPORT_SYMBOL(rte_ether_format_addr)
static int8_t get_xdigit(char ch)
{
@@ -153,3 +155,4 @@ rte_ether_unformat_addr(const char *s, struct rte_ether_addr *ea)
rte_errno = EINVAL;
return -1;
}
+RTE_EXPORT_SYMBOL(rte_ether_unformat_addr)
diff --git a/lib/net/rte_net.c b/lib/net/rte_net.c
index 0c32e78a13..9a1bc3fb7d 100644
--- a/lib/net/rte_net.c
+++ b/lib/net/rte_net.c
@@ -306,6 +306,7 @@ rte_net_skip_ip6_ext(uint16_t proto, const struct rte_mbuf *m, uint32_t *off,
}
return -1;
}
+RTE_EXPORT_SYMBOL(rte_net_skip_ip6_ext)
/* parse mbuf data to get packet type */
uint32_t rte_net_get_ptype(const struct rte_mbuf *m,
@@ -601,3 +602,4 @@ uint32_t rte_net_get_ptype(const struct rte_mbuf *m,
return pkt_type;
}
+RTE_EXPORT_SYMBOL(rte_net_get_ptype)
diff --git a/lib/net/rte_net_crc.c b/lib/net/rte_net_crc.c
index dd93d43c2e..03be816509 100644
--- a/lib/net/rte_net_crc.c
+++ b/lib/net/rte_net_crc.c
@@ -417,6 +417,7 @@ void rte_net_crc_free(struct rte_net_crc *crc)
{
rte_free(crc);
}
+RTE_EXPORT_SYMBOL(rte_net_crc_free)
RTE_VERSION_SYMBOL(25, uint32_t, rte_net_crc_calc, (const void *data, uint32_t data_len,
enum rte_net_crc_type type)
diff --git a/lib/net/version.map b/lib/net/version.map
deleted file mode 100644
index f4dd673fa3..0000000000
--- a/lib/net/version.map
+++ /dev/null
@@ -1,23 +0,0 @@
-DPDK_25 {
- global:
-
- rte_eth_random_addr;
- rte_ether_format_addr;
- rte_ether_unformat_addr;
- rte_net_crc_calc;
- rte_net_crc_free;
- rte_net_crc_set_alg;
- rte_net_get_ptype;
- rte_net_make_rarp_packet;
- rte_net_skip_ip6_ext;
-
- local: *;
-};
-
-DPDK_26 {
- global:
-
- rte_net_crc_calc;
- rte_net_crc_set_alg;
-
-} DPDK_25;
diff --git a/meson.build b/meson.build
index 8436d1dff8..dfb4cb3aee 100644
--- a/meson.build
+++ b/meson.build
@@ -13,10 +13,11 @@ project('DPDK', 'c',
meson_version: '>= 0.57'
)
+fs = import('fs')
+
# check for developer mode
developer_mode = false
if get_option('developer_mode').auto()
- fs = import('fs')
developer_mode = fs.exists('.git')
else
developer_mode = get_option('developer_mode').enabled()
--
2.48.1
next prev parent reply other threads:[~2025-03-06 12:50 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-03-05 21:23 [RFC] eal: add new function versioning macros David Marchand
2025-03-06 2:57 ` Patrick Robb
2025-03-06 10:23 ` Bruce Richardson
2025-03-06 12:50 ` [RFC v2 1/2] " David Marchand
2025-03-06 12:50 ` David Marchand [this message]
2025-03-06 15:45 ` Andre Muezerie
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250306125021.2231121-2-david.marchand@redhat.com \
--to=david.marchand@redhat.com \
--cc=andremue@linux.microsoft.com \
--cc=bruce.richardson@intel.com \
--cc=dev@dpdk.org \
--cc=jasvinder.singh@intel.com \
--cc=thomas@monjalon.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).