From ccf1e4557797374c839c567ae14fe12cc1bcffb3 Mon Sep 17 00:00:00 2001 From: Manuel Nickschas Date: Sun, 2 Sep 2018 23:06:18 +0200 Subject: [PATCH] cmake: Support generation of export headers For using shared libraries without globally exporting all symbols, one has to explicitly mark classes and free functions to be exported. This is more efficient on platforms like Linux (enabling the use of -fvisibility=hidden on GCC/Clang), and a hard requirement for using DLLs on Windows (which don't support global export at all). Extend the quassel_add_module() macro with an optional EXPORT argument, which, if provided, uses CMake's built-in support for generating an export header that provides macros for exporting symbols. The same macro will also import the marked symbols when building against a library. While we're at it, also fix the install rule to use the proper install locations for RUNTIME/LIBRARY/ARCHIVE target types. --- cmake/QuasselMacros.cmake | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/cmake/QuasselMacros.cmake b/cmake/QuasselMacros.cmake index 19649da8..8ad37f7e 100644 --- a/cmake/QuasselMacros.cmake +++ b/cmake/QuasselMacros.cmake @@ -7,14 +7,13 @@ ################################################################################################### include(CMakeParseArguments) +include(GenerateExportHeader) include(QuasselCompileFeatures) ################################################################################################### # Adds a library target for a Quassel module. # -# quassel_add_module(Module -# [STATIC] -# ) +# quassel_add_module(Module [STATIC] [EXPORT]) # # The function expects the (CamelCased) module name as a parameter, and derives various # strings from it. For example, quassel_add_module(Client) produces @@ -25,13 +24,16 @@ include(QuasselCompileFeatures) # platforms other than Windows, a shared library is created. For shared libraries, also # an install rule is added. # +# To generate an export header for the library, specify EXPORT. The header will be named +# ${module}-export.h (where ${module} is the lower-case name of the module). +# # The function exports the TARGET variable which can be used in the current scope # for setting source files, properties, link dependencies and so on. # To refer to the target outside of the current scope, e.g. for linking, use # the alias name. # function(quassel_add_module _module) - set(options STATIC) + set(options EXPORT STATIC) set(oneValueArgs ) set(multiValueArgs ) cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) @@ -67,7 +69,23 @@ function(quassel_add_module _module) ) if (buildmode STREQUAL "SHARED") - install(TARGETS ${target} DESTINATION ${CMAKE_INSTALL_LIBDIR}) + install(TARGETS ${target} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) + endif() + + if (ARG_EXPORT) + string(TOLOWER ${_module} lower_module) + string(TOUPPER ${_module} upper_module) + string(REPLACE "::" "-" header_base ${lower_module}) + string(REPLACE "::" "_" macro_base ${upper_module}) + generate_export_header(${target} + BASE_NAME ${macro_base} + EXPORT_FILE_NAME ${CMAKE_BINARY_DIR}/export/${header_base}-export.h + ) + target_include_directories(${target} PUBLIC ${CMAKE_BINARY_DIR}/export) endif() # Export the target name for further use -- 2.20.1