From: Bruce Richardson <bruce.richardson@intel.com>
To: Tyler Retzlaff <roretzla@linux.microsoft.com>
Cc: <dev@dpdk.org>, Harman Kalra <hkalra@marvell.com>
Subject: Re: [PATCH v2 1/2] build: build only one library type on Windows
Date: Fri, 12 Apr 2024 14:00:43 +0100 [thread overview]
Message-ID: <ZhkweyKGUH25-oix@bricha3-mobl1.ger.corp.intel.com> (raw)
In-Reply-To: <1710484222-17310-2-git-send-email-roretzla@linux.microsoft.com>
On Thu, Mar 14, 2024 at 11:30:21PM -0700, Tyler Retzlaff wrote:
> MSVC is the only compiler that can produce usable shared libraries for
> DPDK on Windows because of the use of exported TLS variables.
>
> Disable building of shared libraries with LLVM and MinGW so that
> remaining __declspec macros needed for the functional libraries built by
> MSVC can be used without triggering errors in LLVM and MinGW builds.
>
> For Windows only install the default_library type to avoid confusion.
> Windows builds cannot build both shared and static in a single pass so
> install only the functional variant.
>
> Signed-off-by: Tyler Retzlaff <roretzla@linux.microsoft.com>
Comments inline below.
/Bruce
> ---
> app/meson.build | 6 +++
> config/meson.build | 27 ++++++++++++
> drivers/meson.build | 72 +++++++++++++++----------------
> drivers/net/octeontx/base/meson.build | 2 +-
> examples/meson.build | 6 +++
> lib/meson.build | 79 +++++++++++++++--------------------
> 6 files changed, 108 insertions(+), 84 deletions(-)
>
> diff --git a/app/meson.build b/app/meson.build
> index 21b6da2..f4ed0f1 100644
> --- a/app/meson.build
> +++ b/app/meson.build
> @@ -46,6 +46,8 @@ default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API']
> default_ldflags = []
> if get_option('default_library') == 'static' and not is_windows
> default_ldflags += ['-Wl,--export-dynamic']
> +elif get_option('default_library') == 'shared' and is_ms_compiler
> + default_ldflags += ['/experimental:tlsDllInterface']
> endif
>
Is this necessary, given that you add this flag as a project-wide argument
below in config/meson.build?
> foreach app:apps
> @@ -104,6 +106,10 @@ foreach app:apps
> link_libs = dpdk_static_libraries + dpdk_drivers
> endif
>
> + if is_windows and is_shared_enabled
> + cflags += '-DRTE_BUILD_SHARED_LIB'
> + endif
> +
> exec = executable('dpdk-' + name,
> sources,
> c_args: cflags,
> diff --git a/config/meson.build b/config/meson.build
> index 8c8b019..dd7971e 100644
> --- a/config/meson.build
> +++ b/config/meson.build
> @@ -53,6 +53,9 @@ if is_ms_compiler
>
> # enable statement expressions extension
> add_project_arguments('/experimental:statementExpressions', language: 'c')
> +
> + # enable export of thread_local variables
> + add_project_arguments('/experimental:tlsDllInterface', language: 'c')
> endif
>
> # set the major version, which might be used by drivers and libraries
> @@ -516,4 +519,28 @@ if get_option('default_library') == 'both'
> NOTE: DPDK always builds both shared and static libraries. Please set
> "default_library" to either "static" or "shared" to select default linkage
> for apps and any examples.''')
> +elif get_option('default_library') == 'shared' and is_windows and not is_ms_compiler
> + error( '''
> + Unsupported value "shared" for "default_library" option.
> +
> + NOTE: DPDK Windows shared is only supported when building with MSVC. Please set
> + "default_library" to either "static" or use MSVC.''')
> +endif
> +
> +if is_windows
> + if is_ms_compiler and get_option('default_library') == 'shared'
> + is_shared_enabled=true
> + else
> + is_shared_enabled=false
> + endif
> +else
> + is_shared_enabled=true
> +endif
> +
This can be shortened to:
is_shared_enabled=true
if is_windows and (not is_ms_compiler or not get_option(...) == 'shared')
is_shared_enabled=false
endif
> +if is_windows
> + install_static = get_option('default_library') == 'static'
> + install_shared = get_option('default_library') == 'shared'
> +else
> + install_static=true
> + install_shared=true
> endif
Might be better merged with the block above:
is_shared_enabled = true
install_static = true
install_shared = true
if is_windows
install_static = get_option('default_library') == 'static'
install_shared = get_option('default_library') == 'shared'
if not is_ms_compiler or not install_shared
is_shared_enabled = false
endif
endif
> diff --git a/drivers/meson.build b/drivers/meson.build
> index 66931d4..c8b2d13 100644
> --- a/drivers/meson.build
> +++ b/drivers/meson.build
> @@ -80,7 +80,7 @@ foreach subpath:subdirs
> subdir(class)
> skip_class = false
> foreach d:std_deps
> - if not is_variable('shared_rte_' + d)
> + if not is_variable('static_rte_' + d)
> skip_class = true
> reason = 'missing internal dependency, "@0@"'.format(d)
> if dpdk_libs_deprecated.contains(d)
> @@ -173,7 +173,7 @@ foreach subpath:subdirs
> if not build
> break
> endif
> - if not is_variable('shared_rte_' + d)
> + if not is_variable('static_rte_' + d)
> build = false
> reason = 'missing internal dependency, "@0@"'.format(d)
> if dpdk_libs_deprecated.contains(d)
> @@ -188,7 +188,9 @@ foreach subpath:subdirs
> +'\tPlease enable missing dependency "@0@"'.format(d))
> endif
> else
> - shared_deps += [get_variable('shared_rte_' + d)]
> + if is_shared_enabled
> + shared_deps += [get_variable('shared_rte_' + d)]
> + endif
> static_deps += [get_variable('static_rte_' + d)]
> endif
> endforeach
> @@ -208,6 +210,9 @@ foreach subpath:subdirs
> enabled_drivers += name
> lib_name = '_'.join(['rte', class, name])
> cflags += '-DRTE_LOG_DEFAULT_LOGTYPE=' + '.'.join([log_prefix, name])
> + if is_windows and is_shared_enabled
> + cflags += '-DRTE_BUILD_SHARED_LIB'
> + endif
Rather than setting this in cflags in the drivers or lib meson.build files,
can we set this once as a project-level cflag and be done with it?
> if annotate_locks and cc.get_id() == 'clang' and cc.version().version_compare('>=3.5.0')
> cflags += '-DRTE_ANNOTATE_LOCKS'
> cflags += '-Wthread-safety'
> @@ -247,7 +252,7 @@ foreach subpath:subdirs
> include_directories: includes,
> dependencies: static_deps,
> c_args: cflags,
> - install: true)
> + install: install_static)
>
> # now build the shared driver
> version_map = '@0@/@1@/version.map'.format(meson.current_source_dir(), drv_path)
> @@ -271,55 +276,46 @@ foreach subpath:subdirs
> endif
> endif
>
> - if is_windows
> - if is_ms_linker
> + if is_shared_enabled
> + if is_ms_compiler
> def_file = custom_target(lib_name + '_def',
> command: [map_to_win_cmd, '@INPUT@', '@OUTPUT@'],
> input: version_map,
> output: '@0@_exports.def'.format(lib_name))
> lk_deps += [def_file]
> -
> - lk_args = ['-Wl,/def:' + def_file.full_path()]
> - if meson.version().version_compare('<0.54.0')
> - lk_args += ['-Wl,/implib:drivers\\lib' + lib_name + '.dll.a']
> - endif
> + lk_args = ['/experimental:tlsDllInterface', '/def:' + def_file.full_path()]
Again, the /experimental flag shouldn't be necessary, since it's set as
project option in config/meson.build.
> else
> - mingw_map = custom_target(lib_name + '_mingw',
> - command: [map_to_win_cmd, '@INPUT@', '@OUTPUT@'],
> - input: version_map,
> - output: '@0@_mingw.map'.format(lib_name))
> - lk_deps += [mingw_map]
> -
> - lk_args = ['-Wl,--version-script=' + mingw_map.full_path()]
> + lk_args = ['-Wl,--version-script=' + version_map]
> endif
> - else
> - lk_args = ['-Wl,--version-script=' + version_map]
> endif
>
> - shared_lib = shared_library(lib_name, sources,
> - objects: objs,
> - include_directories: includes,
> - dependencies: shared_deps,
> - c_args: cflags,
> - link_args: lk_args,
> - link_depends: lk_deps,
> - version: abi_version,
> - soversion: so_version,
> - install: true,
> - install_dir: driver_install_path)
> -
> - # create a dependency object and add it to the global dictionary so
> - # testpmd or other built-in apps can find it if necessary
> - shared_dep = declare_dependency(link_with: shared_lib,
> - include_directories: includes,
> - dependencies: shared_deps)
> + if is_shared_enabled
> + shared_lib = shared_library(lib_name, sources,
> + objects: objs,
> + include_directories: includes,
> + dependencies: shared_deps,
> + c_args: cflags,
> + link_args: lk_args,
> + link_depends: lk_deps,
> + version: abi_version,
> + soversion: so_version,
> + install: install_shared,
> + install_dir: driver_install_path)
> +
> + # create a dependency object and add it to the global dictionary so
> + # testpmd or other built-in apps can find it if necessary
> + shared_dep = declare_dependency(link_with: shared_lib,
> + include_directories: includes,
> + dependencies: shared_deps)
> +
> + set_variable('shared_@0@'.format(lib_name), shared_dep)
Just a thought - could you avoid some of the changes throughout this set,
if you add an else-leg to the "is_shared_enabled" check, where, if shared
is not enabled, you assign shared_dep to be an empty string, or an empty
object or something.
That would mean that you wouldn't need to move the set_variable line as
here, you also wouldn't need to put conditionals around all the
Just a thought - could you avoid some of the changes throughout this set,
if you add an else-leg to the "is_shared_enabled" check, where, if shared
is not enabled, you assign shared_dep to be an empty string, or an empty
object or something.
That would mean that you wouldn't need to move the set_variable line as
here, you also wouldn't need to put conditionals around all the
'shared_deps +=' lines when processing deps for a component, and lastly,
you may not even need to change all the searches for shared_rte_ to
static_rte, since the variables would exist for shared - they'd just be
empty!
> + endif
> static_dep = declare_dependency(
> include_directories: includes,
> dependencies: static_deps)
>
> dpdk_drivers += static_lib
<snip for brevity>
next prev parent reply other threads:[~2024-04-12 13:00 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-14 19:44 [PATCH] build and install " Tyler Retzlaff
2024-03-14 19:44 ` [PATCH] build: build " Tyler Retzlaff
2024-03-15 6:30 ` [PATCH v2 0/2] build and install " Tyler Retzlaff
2024-03-15 6:30 ` [PATCH v2 1/2] build: build " Tyler Retzlaff
2024-04-12 13:00 ` Bruce Richardson [this message]
2024-04-12 23:04 ` Tyler Retzlaff
2024-04-15 9:42 ` Bruce Richardson
2024-03-15 6:30 ` [PATCH v2 2/2] buildtools: when building static library use static deps Tyler Retzlaff
2024-03-15 8:28 ` Bruce Richardson
2024-04-04 18:47 ` Tyler Retzlaff
2024-04-05 9:11 ` Bruce Richardson
2024-04-12 14:09 ` Bruce Richardson
2024-04-12 22:52 ` Tyler Retzlaff
2024-04-12 22:52 ` [PATCH v3 0/2] build and install only one library type on Windows Tyler Retzlaff
2024-04-12 22:52 ` [PATCH v3 1/2] build: build " Tyler Retzlaff
2024-04-15 9:55 ` Bruce Richardson
2024-04-12 22:52 ` [PATCH v3 2/2] buildtools: when building static library use static deps Tyler Retzlaff
2024-04-15 9:56 ` Bruce Richardson
2024-04-15 16:45 ` [PATCH v4 0/2] build and install only one library type on Windows Tyler Retzlaff
2024-04-15 16:45 ` [PATCH v4 1/2] build: build " Tyler Retzlaff
2024-04-15 16:45 ` [PATCH v4 2/2] buildtools: when building static library use static deps Tyler Retzlaff
2024-04-15 17:12 ` [PATCH v5 0/2] build and install only one library type on Windows Tyler Retzlaff
2024-04-15 17:12 ` [PATCH v5 1/2] build: build " Tyler Retzlaff
2024-04-15 17:24 ` Bruce Richardson
2024-04-15 17:12 ` [PATCH v5 2/2] buildtools: when building static library use static deps Tyler Retzlaff
2024-06-14 15:00 ` [PATCH v5 0/2] build and install only one library type on Windows David Marchand
2024-06-14 15:15 ` David Marchand
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=ZhkweyKGUH25-oix@bricha3-mobl1.ger.corp.intel.com \
--to=bruce.richardson@intel.com \
--cc=dev@dpdk.org \
--cc=hkalra@marvell.com \
--cc=roretzla@linux.microsoft.com \
/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).