From 314e15001f1d2f6b23c3ca21c4dcf676ce842d97 Mon Sep 17 00:00:00 2001 From: Milian Wolff Date: Thu, 30 Jan 2020 15:26:18 +0100 Subject: [PATCH] Fix symbol visibility on Linux when compiling with -fvisibility=hidden (#1535) Make FMT_API symbols use the default visibility on non-Windows platforms. Otherwise, one cannot use the generated fmt library when compiling globally with -fvisibility=hidden. Fixes compile errors like: ``` ../3rdParty/fmt/include/fmt/core.h:757: error: undefined reference to 'fmt::v6::internal::assert_fail(char const*, int, char const*)' ``` Note that the symbol exists, but is local: ``` $ nm -C libfmtd.so.6.1.3 | grep assert_fail U __assert_fail 0000000000233ffa t fmt::v6::internal::assert_fail(char const*, int, char const*) ``` With this patch, the compile error is gone and the symbol is properly exported: ``` $ nm -a bin/libfmtd.so -C | grep assert_fail U __assert_fail 00000000002366ba T fmt::v6::internal::assert_fail(char const*, int, char const*) ``` Change-Id: I96054e622d9a2ae81907e1b01a1033e629767a91 --- include/fmt/core.h | 11 ++++++++++- src/format.cc | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/include/fmt/core.h b/include/fmt/core.h index 5aefcc14..32bc88e3 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -185,11 +185,20 @@ # define FMT_CLASS_API #endif #ifndef FMT_API -# define FMT_API +# if FMT_GCC_VERSION || FMT_CLANG_VERSION +# define FMT_API __attribute__((visibility("default"))) +# define FMT_EXTERN_TEMPLATE_API FMT_API +# define FMT_INSTANTIATION_DEF_API +# else +# define FMT_API +# endif #endif #ifndef FMT_EXTERN_TEMPLATE_API # define FMT_EXTERN_TEMPLATE_API #endif +#ifndef FMT_INSTANTIATION_DEF_API +# define FMT_INSTANTIATION_DEF_API FMT_API +#endif #ifndef FMT_HEADER_ONLY # define FMT_EXTERN extern diff --git a/src/format.cc b/src/format.cc index e6fde7c3..9a9abf8d 100644 --- a/src/format.cc +++ b/src/format.cc @@ -121,7 +121,7 @@ template FMT_API char* internal::sprintf_format(long double, internal::buffer&, sprintf_specs); -template struct FMT_API internal::basic_data; +template struct FMT_INSTANTIATION_DEF_API internal::basic_data; // Workaround a bug in MSVC2013 that prevents instantiation of format_float. int (*instantiate_format_float)(double, int, internal::float_specs,