From patchwork Mon Oct 7 15:45:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bruce Richardson X-Patchwork-Id: 60631 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id D7F831C216; Mon, 7 Oct 2019 17:46:14 +0200 (CEST) Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by dpdk.org (Postfix) with ESMTP id E87491C216 for ; Mon, 7 Oct 2019 17:46:12 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 07 Oct 2019 08:46:11 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.67,268,1566889200"; d="scan'208";a="368152567" Received: from silpixa00399126.ir.intel.com (HELO silpixa00399126.ger.corp.intel.com) ([10.237.223.2]) by orsmga005.jf.intel.com with ESMTP; 07 Oct 2019 08:46:08 -0700 From: Bruce Richardson To: dev@dpdk.org Cc: Andrzej Ostruszka , Neil Horman , bluca@debian.org, thomas@monjalon.net, Bruce Richardson Date: Mon, 7 Oct 2019 16:45:49 +0100 Message-Id: <20191007154550.46655-2-bruce.richardson@intel.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191007154550.46655-1-bruce.richardson@intel.com> References: <20190927194932.22197-1-bruce.richardson@intel.com> <20191007154550.46655-1-bruce.richardson@intel.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v3 1/2] eal: split compat header file X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" The compat.h header file provided macros for two purposes: 1. it provided the macros for marking functions as rte_experimental 2. it provided the macros for doing function versioning Although these were in the same file, #1 is something that is for use by public header files, which #2 is for internal use only. Therefore, we can split these into two headers, keeping #1 in rte_compat.h and #2 in a new file rte_function_versioning.h. For "make" builds, since internal objects pick up the headers from the "include/" folder, we need to add the new header to the installation list, but for "meson" builds it does not need to be installed as it's not for public use. The rework also serves to allow the use of the function versioning macros to files that actually need them, so the use of experimental functions does not need including of the versioning code. Signed-off-by: Bruce Richardson --- doc/api/doxy-api-index.md | 3 +- doc/guides/contributing/versioning.rst | 4 +- lib/librte_distributor/rte_distributor.c | 2 +- lib/librte_distributor/rte_distributor_v20.c | 2 +- lib/librte_eal/common/Makefile | 1 + lib/librte_eal/common/include/rte_compat.h | 70 ---------------- .../common/include/rte_function_versioning.h | 79 +++++++++++++++++++ lib/librte_lpm/rte_lpm.c | 1 + lib/librte_lpm/rte_lpm.h | 1 - lib/librte_lpm/rte_lpm6.c | 1 + lib/librte_timer/rte_timer.c | 2 +- 11 files changed, 89 insertions(+), 77 deletions(-) create mode 100644 lib/librte_eal/common/include/rte_function_versioning.h diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md index 6c2d888ee..9acf36ba1 100644 --- a/doc/api/doxy-api-index.md +++ b/doc/api/doxy-api-index.md @@ -171,5 +171,6 @@ The public API headers are grouped by topics: - **misc**: [EAL config] (@ref rte_eal.h), [common] (@ref rte_common.h), - [ABI compat] (@ref rte_compat.h), + [experimental APIs] (@ref rte_compat.h), + [ABI versioning] (@ref rte_function_versioning.h), [version] (@ref rte_version.h) diff --git a/doc/guides/contributing/versioning.rst b/doc/guides/contributing/versioning.rst index 3ab2c4346..64984c54e 100644 --- a/doc/guides/contributing/versioning.rst +++ b/doc/guides/contributing/versioning.rst @@ -206,7 +206,7 @@ functionality or behavior. When that occurs, it is desirable to allow for backward compatibility for a time with older binaries that are dynamically linked to the DPDK. -To support backward compatibility the ``rte_compat.h`` +To support backward compatibility the ``rte_function_versioning.h`` header file provides macros to use when updating exported functions. These macros are used in conjunction with the ``rte__version.map`` file for a given library to allow multiple versions of a symbol to exist in a shared @@ -362,7 +362,7 @@ the function, we add this line of code VERSION_SYMBOL(rte_acl_create, _v20, 2.0); -Remembering to also add the rte_compat.h header to the requisite c file where +Remembering to also add the rte_function_versioning.h header to the requisite c file where these changes are being made. The above macro instructs the linker to create a new symbol ``rte_acl_create@DPDK_2.0``, which matches the symbol created in older builds, but now points to the above newly named function. We have now mapped diff --git a/lib/librte_distributor/rte_distributor.c b/lib/librte_distributor/rte_distributor.c index 21eb1fb0a..6d1e971a9 100644 --- a/lib/librte_distributor/rte_distributor.c +++ b/lib/librte_distributor/rte_distributor.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/lib/librte_distributor/rte_distributor_v20.c b/lib/librte_distributor/rte_distributor_v20.c index cdc0969a8..64c611fa9 100644 --- a/lib/librte_distributor/rte_distributor_v20.c +++ b/lib/librte_distributor/rte_distributor_v20.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile index a00d4fcad..d70f84fd7 100644 --- a/lib/librte_eal/common/Makefile +++ b/lib/librte_eal/common/Makefile @@ -4,6 +4,7 @@ include $(RTE_SDK)/mk/rte.vars.mk INC := rte_branch_prediction.h rte_common.h rte_compat.h +INC += rte_function_versioning.h INC += rte_debug.h rte_eal.h rte_eal_interrupts.h INC += rte_errno.h rte_launch.h rte_lcore.h INC += rte_log.h rte_memory.h rte_memzone.h diff --git a/lib/librte_eal/common/include/rte_compat.h b/lib/librte_eal/common/include/rte_compat.h index 92ff28faf..3eb33784b 100644 --- a/lib/librte_eal/common/include/rte_compat.h +++ b/lib/librte_eal/common/include/rte_compat.h @@ -5,76 +5,6 @@ #ifndef _RTE_COMPAT_H_ #define _RTE_COMPAT_H_ -#include - -#ifdef RTE_BUILD_SHARED_LIB - -/* - * Provides backwards compatibility when updating exported functions. - * When a symol is exported from a library to provide an API, it also provides a - * calling convention (ABI) that is embodied in its name, return type, - * arguments, etc. On occasion that function may need to change to accommodate - * new functionality, behavior, etc. When that occurs, it is desirable to - * allow for backwards compatibility for a time with older binaries that are - * dynamically linked to the dpdk. To support that, the __vsym and - * VERSION_SYMBOL macros are created. They, in conjunction with the - * _version.map file for a given library allow for multiple versions of - * a symbol to exist in a shared library so that older binaries need not be - * immediately recompiled. - * - * Refer to the guidelines document in the docs subdirectory for details on the - * use of these macros - */ - -/* - * Macro Parameters: - * b - function base name - * e - function version extension, to be concatenated with base name - * n - function symbol version string to be applied - * f - function prototype - * p - full function symbol name - */ - -/* - * VERSION_SYMBOL - * Creates a symbol version table entry binding symbol @DPDK_ to the internal - * function name _ - */ -#define VERSION_SYMBOL(b, e, n) __asm__(".symver " RTE_STR(b) RTE_STR(e) ", " RTE_STR(b) "@DPDK_" RTE_STR(n)) - -/* - * BIND_DEFAULT_SYMBOL - * Creates a symbol version entry instructing the linker to bind references to - * symbol to the internal symbol _ - */ -#define BIND_DEFAULT_SYMBOL(b, e, n) __asm__(".symver " RTE_STR(b) RTE_STR(e) ", " RTE_STR(b) "@@DPDK_" RTE_STR(n)) -#define __vsym __attribute__((used)) - -/* - * MAP_STATIC_SYMBOL - * If a function has been bifurcated into multiple versions, none of which - * are defined as the exported symbol name in the map file, this macro can be - * used to alias a specific version of the symbol to its exported name. For - * example, if you have 2 versions of a function foo_v1 and foo_v2, where the - * former is mapped to foo@DPDK_1 and the latter is mapped to foo@DPDK_2 when - * building a shared library, this macro can be used to map either foo_v1 or - * foo_v2 to the symbol foo when building a static library, e.g.: - * MAP_STATIC_SYMBOL(void foo(), foo_v2); - */ -#define MAP_STATIC_SYMBOL(f, p) - -#else -/* - * No symbol versioning in use - */ -#define VERSION_SYMBOL(b, e, n) -#define __vsym -#define BIND_DEFAULT_SYMBOL(b, e, n) -#define MAP_STATIC_SYMBOL(f, p) f __attribute__((alias(RTE_STR(p)))) -/* - * RTE_BUILD_SHARED_LIB=n - */ -#endif #ifndef ALLOW_EXPERIMENTAL_API diff --git a/lib/librte_eal/common/include/rte_function_versioning.h b/lib/librte_eal/common/include/rte_function_versioning.h new file mode 100644 index 000000000..ce963d4b1 --- /dev/null +++ b/lib/librte_eal/common/include/rte_function_versioning.h @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2015 Neil Horman . + * All rights reserved. + */ + +#ifndef _RTE_FUNCTION_VERSIONING_H_ +#define _RTE_FUNCTION_VERSIONING_H_ +#include + +#ifdef RTE_BUILD_SHARED_LIB + +/* + * Provides backwards compatibility when updating exported functions. + * When a symol is exported from a library to provide an API, it also provides a + * calling convention (ABI) that is embodied in its name, return type, + * arguments, etc. On occasion that function may need to change to accommodate + * new functionality, behavior, etc. When that occurs, it is desirable to + * allow for backwards compatibility for a time with older binaries that are + * dynamically linked to the dpdk. To support that, the __vsym and + * VERSION_SYMBOL macros are created. They, in conjunction with the + * _version.map file for a given library allow for multiple versions of + * a symbol to exist in a shared library so that older binaries need not be + * immediately recompiled. + * + * Refer to the guidelines document in the docs subdirectory for details on the + * use of these macros + */ + +/* + * Macro Parameters: + * b - function base name + * e - function version extension, to be concatenated with base name + * n - function symbol version string to be applied + * f - function prototype + * p - full function symbol name + */ + +/* + * VERSION_SYMBOL + * Creates a symbol version table entry binding symbol @DPDK_ to the internal + * function name _ + */ +#define VERSION_SYMBOL(b, e, n) __asm__(".symver " RTE_STR(b) RTE_STR(e) ", " RTE_STR(b) "@DPDK_" RTE_STR(n)) + +/* + * BIND_DEFAULT_SYMBOL + * Creates a symbol version entry instructing the linker to bind references to + * symbol to the internal symbol _ + */ +#define BIND_DEFAULT_SYMBOL(b, e, n) __asm__(".symver " RTE_STR(b) RTE_STR(e) ", " RTE_STR(b) "@@DPDK_" RTE_STR(n)) +#define __vsym __attribute__((used)) + +/* + * MAP_STATIC_SYMBOL + * If a function has been bifurcated into multiple versions, none of which + * are defined as the exported symbol name in the map file, this macro can be + * used to alias a specific version of the symbol to its exported name. For + * example, if you have 2 versions of a function foo_v1 and foo_v2, where the + * former is mapped to foo@DPDK_1 and the latter is mapped to foo@DPDK_2 when + * building a shared library, this macro can be used to map either foo_v1 or + * foo_v2 to the symbol foo when building a static library, e.g.: + * MAP_STATIC_SYMBOL(void foo(), foo_v2); + */ +#define MAP_STATIC_SYMBOL(f, p) + +#else +/* + * No symbol versioning in use + */ +#define VERSION_SYMBOL(b, e, n) +#define __vsym +#define BIND_DEFAULT_SYMBOL(b, e, n) +#define MAP_STATIC_SYMBOL(f, p) f __attribute__((alias(RTE_STR(p)))) +/* + * RTE_BUILD_SHARED_LIB=n + */ +#endif + +#endif /* _RTE_FUNCTION_VERSIONING_H_ */ diff --git a/lib/librte_lpm/rte_lpm.c b/lib/librte_lpm/rte_lpm.c index 3a929a1b1..c96395e26 100644 --- a/lib/librte_lpm/rte_lpm.c +++ b/lib/librte_lpm/rte_lpm.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "rte_lpm.h" diff --git a/lib/librte_lpm/rte_lpm.h b/lib/librte_lpm/rte_lpm.h index 906ec4483..26303e628 100644 --- a/lib/librte_lpm/rte_lpm.h +++ b/lib/librte_lpm/rte_lpm.h @@ -20,7 +20,6 @@ #include #include #include -#include #ifdef __cplusplus extern "C" { diff --git a/lib/librte_lpm/rte_lpm6.c b/lib/librte_lpm/rte_lpm6.c index 9b8aeb972..e20f82460 100644 --- a/lib/librte_lpm/rte_lpm6.c +++ b/lib/librte_lpm/rte_lpm6.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "rte_lpm6.h" diff --git a/lib/librte_timer/rte_timer.c b/lib/librte_timer/rte_timer.c index bdcf05d06..3834c9473 100644 --- a/lib/librte_timer/rte_timer.c +++ b/lib/librte_timer/rte_timer.c @@ -25,8 +25,8 @@ #include #include #include -#include #include +#include #include "rte_timer.h" From patchwork Mon Oct 7 15:45:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bruce Richardson X-Patchwork-Id: 60632 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id A677E1C027; Mon, 7 Oct 2019 17:46:18 +0200 (CEST) Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by dpdk.org (Postfix) with ESMTP id 8EFAE1C1C3 for ; Mon, 7 Oct 2019 17:46:14 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 07 Oct 2019 08:46:14 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.67,268,1566889200"; d="scan'208";a="368152574" Received: from silpixa00399126.ir.intel.com (HELO silpixa00399126.ger.corp.intel.com) ([10.237.223.2]) by orsmga005.jf.intel.com with ESMTP; 07 Oct 2019 08:46:12 -0700 From: Bruce Richardson To: dev@dpdk.org Cc: Andrzej Ostruszka , Neil Horman , bluca@debian.org, thomas@monjalon.net, Bruce Richardson Date: Mon, 7 Oct 2019 16:45:50 +0100 Message-Id: <20191007154550.46655-3-bruce.richardson@intel.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191007154550.46655-1-bruce.richardson@intel.com> References: <20190927194932.22197-1-bruce.richardson@intel.com> <20191007154550.46655-1-bruce.richardson@intel.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v3 2/2] build: support building ABI versioned files twice X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Any file with ABI versioned functions needs different macros for shared and static builds, so we need to accomodate that. Rather than building everything twice, we just flag to the build system which libraries need that handling, by setting use_function_versioning in the meson.build files. To ensure we don't get silent errors at build time due to this meson flag being missed, we add an explicit error to the function versioning header file if a known C macro is not defined. Since "make" builds always only build one of shared or static libraries, this define can be always set, and so is added to the global CFLAGS. For meson, the build flag - and therefore the C define - is set for the three libraries that need the function versioning: "distributor", "lpm" and "timer". Signed-off-by: Bruce Richardson Tested-by: Andrzej Ostruszka --- v3: move define from common_base to generic/rte.vars.mk --- config/rte_config.h | 3 --- doc/guides/contributing/coding_style.rst | 7 +++++++ lib/librte_distributor/meson.build | 1 + .../common/include/rte_function_versioning.h | 4 ++++ lib/librte_lpm/meson.build | 1 + lib/librte_timer/meson.build | 1 + lib/meson.build | 16 +++++++++++++--- mk/target/generic/rte.vars.mk | 8 ++++++++ 8 files changed, 35 insertions(+), 6 deletions(-) diff --git a/config/rte_config.h b/config/rte_config.h index 0bbbe274f..b63a2fdea 100644 --- a/config/rte_config.h +++ b/config/rte_config.h @@ -31,9 +31,6 @@ /****** library defines ********/ -/* compat defines */ -#define RTE_BUILD_SHARED_LIB - /* EAL defines */ #define RTE_MAX_HEAPS 32 #define RTE_MAX_MEMSEG_LISTS 128 diff --git a/doc/guides/contributing/coding_style.rst b/doc/guides/contributing/coding_style.rst index 449b33494..e95a1a2be 100644 --- a/doc/guides/contributing/coding_style.rst +++ b/doc/guides/contributing/coding_style.rst @@ -948,6 +948,13 @@ reason built. For missing dependencies this should be of the form ``'missing dependency, "libname"'``. +use_function_versioning + **Default Value = false**. + Specifies if the library in question has ABI versioned functions. If it + has, this value should be set to ensure that the C files are compiled + twice with suitable parameters for each of shared or static library + builds. + version **Default Value = 1**. Specifies the ABI version of the library, and is used as the major diff --git a/lib/librte_distributor/meson.build b/lib/librte_distributor/meson.build index dba7e3b2a..5149f9bf5 100644 --- a/lib/librte_distributor/meson.build +++ b/lib/librte_distributor/meson.build @@ -9,3 +9,4 @@ else endif headers = files('rte_distributor.h') deps += ['mbuf'] +use_function_versioning = true diff --git a/lib/librte_eal/common/include/rte_function_versioning.h b/lib/librte_eal/common/include/rte_function_versioning.h index ce963d4b1..55e88ffae 100644 --- a/lib/librte_eal/common/include/rte_function_versioning.h +++ b/lib/librte_eal/common/include/rte_function_versioning.h @@ -7,6 +7,10 @@ #define _RTE_FUNCTION_VERSIONING_H_ #include +#ifndef RTE_USE_FUNCTION_VERSIONING +#error Use of function versioning disabled, is "use_function_versioning=true" in meson.build? +#endif + #ifdef RTE_BUILD_SHARED_LIB /* diff --git a/lib/librte_lpm/meson.build b/lib/librte_lpm/meson.build index a5176d8ae..4e3920660 100644 --- a/lib/librte_lpm/meson.build +++ b/lib/librte_lpm/meson.build @@ -8,3 +8,4 @@ headers = files('rte_lpm.h', 'rte_lpm6.h') # without worrying about which architecture we actually need headers += files('rte_lpm_altivec.h', 'rte_lpm_neon.h', 'rte_lpm_sse.h') deps += ['hash'] +use_function_versioning = true diff --git a/lib/librte_timer/meson.build b/lib/librte_timer/meson.build index d3b828ce9..b7edfe2e7 100644 --- a/lib/librte_timer/meson.build +++ b/lib/librte_timer/meson.build @@ -4,3 +4,4 @@ sources = files('rte_timer.c') headers = files('rte_timer.h') allow_experimental_apis = true +use_function_versioning = true diff --git a/lib/meson.build b/lib/meson.build index e5ff83893..1b0ed767c 100644 --- a/lib/meson.build +++ b/lib/meson.build @@ -47,6 +47,7 @@ foreach l:libraries name = l version = 1 allow_experimental_apis = false + use_function_versioning = false sources = [] headers = [] includes = [] @@ -96,6 +97,9 @@ foreach l:libraries if allow_experimental_apis cflags += '-DALLOW_EXPERIMENTAL_API' endif + if use_function_versioning + cflags += '-DRTE_USE_FUNCTION_VERSIONING' + endif if get_option('per_library_versions') lib_version = '@0@.1'.format(version) @@ -117,9 +121,15 @@ foreach l:libraries include_directories: includes, dependencies: static_deps) - # then use pre-build objects to build shared lib - sources = [] - objs += static_lib.extract_all_objects(recursive: false) + if not use_function_versioning + # use pre-build objects to build shared lib + sources = [] + objs += static_lib.extract_all_objects(recursive: false) + else + # for compat we need to rebuild with + # RTE_BUILD_SHARED_LIB defined + cflags += '-DRTE_BUILD_SHARED_LIB' + endif version_map = '@0@/@1@/rte_@2@_version.map'.format( meson.current_source_dir(), dir_name, name) implib = dir_name + '.dll.a' diff --git a/mk/target/generic/rte.vars.mk b/mk/target/generic/rte.vars.mk index 5f00a0bfa..374722173 100644 --- a/mk/target/generic/rte.vars.mk +++ b/mk/target/generic/rte.vars.mk @@ -90,6 +90,14 @@ ASFLAGS += $(TARGET_ASFLAGS) CFLAGS += -I$(RTE_OUTPUT)/include LDFLAGS += -L$(RTE_OUTPUT)/lib +# add in flag for supporting function versioning. The define is used in meson +# builds to ensure that the user has properly flagged the unit in question as +# using function versioning so it can be built twice - once for static lib and +# then a second time for the shared lib. Since make only builds one library +# type at a time, such precautions aren't necessary, so we can globally define +# the flag +CFLAGS += -DRTE_USE_FUNCTION_VERSIONING + # always include rte_config.h: the one in $(RTE_OUTPUT)/include is # the configuration of SDK when $(BUILDING_RTE_SDK) is true, or the # configuration of the application if $(BUILDING_RTE_SDK) is not