From 25ed1343eb103b831f8665ad18595f86a528fb04 Mon Sep 17 00:00:00 2001 From: Pino Toscano Date: Sun, 18 Apr 2021 10:29:59 +0200 Subject: [PATCH 1/3] Export YAML::detail::node::m_amount The internal header node/detail/node.h is included by public headers; YAML::detail::node is implemented in the header itself, and thus it gets inlined... except for its static m_amount class member, which is instantiated in the library only. Right now all the symbols of yaml-cpp are exported (nothing is hidden), so the linker will find node::m_amount in the yaml-cpp library. As solution/workaround, explicitly export YAML::detail::node::m_amount. --- src/node_data.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node_data.cpp b/src/node_data.cpp index da2aefce9..8f5422ae6 100644 --- a/src/node_data.cpp +++ b/src/node_data.cpp @@ -13,7 +13,7 @@ namespace YAML { namespace detail { -std::atomic node::m_amount{0}; +YAML_CPP_API std::atomic node::m_amount{0}; const std::string& node_data::empty_scalar() { static const std::string svalue; From 762e6f6c70ce8b4cff8972fbaa9a7d5c0db5df6b Mon Sep 17 00:00:00 2001 From: Pino Toscano Date: Sun, 18 Apr 2021 10:25:08 +0200 Subject: [PATCH 2/3] CMake: use GenerateExportHeader Make use of the GenerateExportHeader CMake module to generate the dll.h header with export macros. While the produced dll.h is different, the result should be the same, i.e. nothing changes for yaml-cpp or its users. --- CMakeLists.txt | 11 +++++++++++ include/yaml-cpp/dll.h | 33 --------------------------------- 2 files changed, 11 insertions(+), 33 deletions(-) delete mode 100644 include/yaml-cpp/dll.h diff --git a/CMakeLists.txt b/CMakeLists.txt index b230b9e6d..912b09bce 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,7 @@ include(CMakeDependentOption) include(CheckCXXCompilerFlag) include(GNUInstallDirs) include(CTest) +include(GenerateExportHeader) find_program(YAML_CPP_CLANG_FORMAT_EXE NAMES clang-format) @@ -81,6 +82,7 @@ set_property(TARGET yaml-cpp target_include_directories(yaml-cpp PUBLIC $ + $ $ PRIVATE $) @@ -136,6 +138,12 @@ write_basic_package_version_file( "${PROJECT_BINARY_DIR}/yaml-cpp-config-version.cmake" COMPATIBILITY AnyNewerVersion) +generate_export_header(yaml-cpp + BASE_NAME YAML_CPP + EXPORT_FILE_NAME "${PROJECT_BINARY_DIR}/include/yaml-cpp/dll.h" + EXPORT_MACRO_NAME YAML_CPP_API +) + configure_file(yaml-cpp.pc.in yaml-cpp.pc @ONLY) if (YAML_CPP_INSTALL) @@ -145,6 +153,9 @@ if (YAML_CPP_INSTALL) LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + FILES_MATCHING PATTERN "*.h") + install(DIRECTORY ${PROJECT_BINARY_DIR}/include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} FILES_MATCHING PATTERN "*.h") install(EXPORT yaml-cpp-targets diff --git a/include/yaml-cpp/dll.h b/include/yaml-cpp/dll.h deleted file mode 100644 index a32c06b2e..000000000 --- a/include/yaml-cpp/dll.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 -#define DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - -#if defined(_MSC_VER) || \ - (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ - (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -// The following ifdef block is the standard way of creating macros which make -// exporting from a DLL simpler. All files within this DLL are compiled with the -// yaml_cpp_EXPORTS symbol defined on the command line. This symbol should not -// be defined on any project that uses this DLL. This way any other project -// whose source files include this file see YAML_CPP_API functions as being -// imported from a DLL, whereas this DLL sees symbols defined with this macro as -// being exported. -#undef YAML_CPP_API - -#ifdef YAML_CPP_DLL // Using or Building YAML-CPP DLL (definition defined - // manually) -#ifdef yaml_cpp_EXPORTS // Building YAML-CPP DLL (definition created by CMake - // or defined manually) -// #pragma message( "Defining YAML_CPP_API for DLL export" ) -#define YAML_CPP_API __declspec(dllexport) -#else // yaml_cpp_EXPORTS -// #pragma message( "Defining YAML_CPP_API for DLL import" ) -#define YAML_CPP_API __declspec(dllimport) -#endif // yaml_cpp_EXPORTS -#else // YAML_CPP_DLL -#define YAML_CPP_API -#endif // YAML_CPP_DLL - -#endif // DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 From 5fe6157d87cb9af4d8548960d45dac8835db2860 Mon Sep 17 00:00:00 2001 From: Pino Toscano Date: Sun, 18 Apr 2021 10:34:01 +0200 Subject: [PATCH 3/3] CMake: hide all the symbols by default Hide all the symbols that are not explicitly exported with YAML_CPP_API. This way the ABI will be way smaller, and only actually exposing the public classes/functions. --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 912b09bce..73fd8e551 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,10 @@ include(GNUInstallDirs) include(CTest) include(GenerateExportHeader) +set(CMAKE_C_VISIBILITY_PRESET hidden) +set(CMAKE_CXX_VISIBILITY_PRESET hidden) +set(CMAKE_VISIBILITY_INLINES_HIDDEN 1) + find_program(YAML_CPP_CLANG_FORMAT_EXE NAMES clang-format) option(YAML_CPP_BUILD_CONTRIB "Enable yaml-cpp contrib in library" ON)