From e7ac9333babf0ad5fe16f52186cc9e8c0e97ed77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=BB=D0=B0=D0=B4=D0=B8=D1=81=D0=BB=D0=B0=D0=B2=20?= =?UTF-8?q?=D0=A9=D0=B0=D0=BF=D0=BE=D0=B2?= Date: Tue, 1 Jun 2021 01:50:42 +0500 Subject: [PATCH] Fix "undefined reference to `fmt::v7::detail::basic_data::digits'" Remove unused FMT_EXTERN_TEMPLATE_API --- include/fmt/core.h | 7 +++--- include/fmt/format.h | 2 +- test/CMakeLists.txt | 15 +++++++++++++ test/static-export-test/CMakeLists.txt | 30 ++++++++++++++++++++++++++ test/static-export-test/library.cc | 5 +++++ test/static-export-test/main.cc | 6 ++++++ 6 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 test/static-export-test/CMakeLists.txt create mode 100644 test/static-export-test/library.cc create mode 100644 test/static-export-test/main.cc diff --git a/include/fmt/core.h b/include/fmt/core.h index d71a2ab180f5..94d0784fd71b 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -253,9 +253,10 @@ # endif #else # define FMT_CLASS_API -# if defined(__GNUC__) || defined(__clang__) -# define FMT_API __attribute__((visibility("default"))) -# define FMT_EXTERN_TEMPLATE_API FMT_API +# if defined(FMT_EXPORT) || defined(FMT_SHARED) +# if defined(__GNUC__) || defined(__clang__) +# define FMT_API __attribute__((visibility("default"))) +# endif # endif #endif #ifndef FMT_API diff --git a/include/fmt/format.h b/include/fmt/format.h index 633fa11954ec..19d0a8af199c 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -903,7 +903,7 @@ template struct basic_data { FMT_API static constexpr const char right_padding_shifts[] = {0, 31, 0, 1, 0}; }; -#ifndef FMT_HEADER_ONLY +#ifdef FMT_SHARED // Required for -flto, -fivisibility=hidden and -shared to work extern template struct basic_data; #endif diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index bd94b95ec23f..97d16f43a8c0 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -213,6 +213,21 @@ if (FMT_PEDANTIC AND NOT WIN32) "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}") endif () +# This test are disabled on Windows because it is only *NIX issue. +if (FMT_PEDANTIC AND NOT WIN32) + add_test(static-export-test ${CMAKE_CTEST_COMMAND} + -C ${CMAKE_BUILD_TYPE} + --build-and-test + "${CMAKE_CURRENT_SOURCE_DIR}/static-export-test" + "${CMAKE_CURRENT_BINARY_DIR}/static-export-test" + --build-generator ${CMAKE_GENERATOR} + --build-makeprogram ${CMAKE_MAKE_PROGRAM} + --build-options + "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}" + "-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}" + "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}") +endif () + # Activate optional CUDA tests if CUDA is found. For version selection see # https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#cpp14-language-features if (FMT_CUDA_TEST) diff --git a/test/static-export-test/CMakeLists.txt b/test/static-export-test/CMakeLists.txt new file mode 100644 index 000000000000..7690d7b5a845 --- /dev/null +++ b/test/static-export-test/CMakeLists.txt @@ -0,0 +1,30 @@ +cmake_minimum_required(VERSION 3.1...3.18) + +project(fmt-link CXX) + +set(BUILD_SHARED_LIBS OFF) +set(CMAKE_VISIBILITY_INLINES_HIDDEN TRUE) +set(CMAKE_CXX_VISIBILITY_PRESET "hidden") + +# Broken LTO on GCC 4 +if (CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5) + set(BROKEN_LTO ON) +endif () + +if (NOT BROKEN_LTO AND CMAKE_VERSION VERSION_GREATER "3.8") + # CMake 3.9+ + include(CheckIPOSupported) + check_ipo_supported(RESULT HAVE_IPO) + if (HAVE_IPO) + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) + endif () +endif () + +add_subdirectory(../.. fmt) +set_property(TARGET fmt PROPERTY POSITION_INDEPENDENT_CODE ON) + +add_library(library-test SHARED library.cc) +target_link_libraries(library-test PRIVATE fmt::fmt) + +add_executable(exe-test main.cc) +target_link_libraries(exe-test PRIVATE library-test) diff --git a/test/static-export-test/library.cc b/test/static-export-test/library.cc new file mode 100644 index 000000000000..fe4801ba58a4 --- /dev/null +++ b/test/static-export-test/library.cc @@ -0,0 +1,5 @@ +#include + +__attribute__((visibility("default"))) std::string foo() { + return fmt::format(FMT_COMPILE("foo bar {}"), 4242); +} diff --git a/test/static-export-test/main.cc b/test/static-export-test/main.cc new file mode 100644 index 000000000000..38f7999ed3dd --- /dev/null +++ b/test/static-export-test/main.cc @@ -0,0 +1,6 @@ +#include +#include + +extern std::string foo(); + +int main() { std::cout << foo() << std::endl; }