5 # Function for generation of export macros for libraries 7 # This module provides the function GENERATE_EXPORT_HEADER(). 9 # The ``GENERATE_EXPORT_HEADER`` function can be used to generate a file 10 # suitable for preprocessor inclusion which contains EXPORT macros to be 11 # used in library classes:: 13 # GENERATE_EXPORT_HEADER( LIBRARY_TARGET 14 # [BASE_NAME <base_name>] 15 # [EXPORT_MACRO_NAME <export_macro_name>] 16 # [EXPORT_FILE_NAME <export_file_name>] 17 # [DEPRECATED_MACRO_NAME <deprecated_macro_name>] 18 # [NO_EXPORT_MACRO_NAME <no_export_macro_name>] 19 # [STATIC_DEFINE <static_define>] 20 # [NO_DEPRECATED_MACRO_NAME <no_deprecated_macro_name>] 21 # [DEFINE_NO_DEPRECATED] 22 # [PREFIX_NAME <prefix_name>] 26 # The target properties :prop_tgt:`CXX_VISIBILITY_PRESET <<LANG>_VISIBILITY_PRESET>` 27 # and :prop_tgt:`VISIBILITY_INLINES_HIDDEN` can be used to add the appropriate 28 # compile flags for targets. See the documentation of those target properties, 29 # and the convenience variables 30 # :variable:`CMAKE_CXX_VISIBILITY_PRESET <CMAKE_<LANG>_VISIBILITY_PRESET>` and 31 # :variable:`CMAKE_VISIBILITY_INLINES_HIDDEN`. 33 # By default ``GENERATE_EXPORT_HEADER()`` generates macro names in a file 34 # name determined by the name of the library. This means that in the 35 # simplest case, users of ``GenerateExportHeader`` will be equivalent to: 37 # .. code-block:: cmake 39 # set(CMAKE_CXX_VISIBILITY_PRESET hidden) 40 # set(CMAKE_VISIBILITY_INLINES_HIDDEN 1) 41 # add_library(somelib someclass.cpp) 42 # generate_export_header(somelib) 43 # install(TARGETS somelib DESTINATION ${LIBRARY_INSTALL_DIR}) 46 # ${PROJECT_BINARY_DIR}/somelib_export.h DESTINATION ${INCLUDE_INSTALL_DIR} 50 # And in the ABI header files: 54 # #include "somelib_export.h" 55 # class SOMELIB_EXPORT SomeClass { 60 # The CMake fragment will generate a file in the 61 # ``${CMAKE_CURRENT_BINARY_DIR}`` called ``somelib_export.h`` containing the 62 # macros ``SOMELIB_EXPORT``, ``SOMELIB_NO_EXPORT``, ``SOMELIB_DEPRECATED``, 63 # ``SOMELIB_DEPRECATED_EXPORT`` and ``SOMELIB_DEPRECATED_NO_EXPORT``. The 64 # resulting file should be installed with other headers in the library. 66 # The ``BASE_NAME`` argument can be used to override the file name and the 67 # names used for the macros: 69 # .. code-block:: cmake 71 # add_library(somelib someclass.cpp) 72 # generate_export_header(somelib 73 # BASE_NAME other_name 77 # Generates a file called ``other_name_export.h`` containing the macros 78 # ``OTHER_NAME_EXPORT``, ``OTHER_NAME_NO_EXPORT`` and ``OTHER_NAME_DEPRECATED`` 81 # The ``BASE_NAME`` may be overridden by specifiying other options in the 82 # function. For example: 84 # .. code-block:: cmake 86 # add_library(somelib someclass.cpp) 87 # generate_export_header(somelib 88 # EXPORT_MACRO_NAME OTHER_NAME_EXPORT 92 # creates the macro ``OTHER_NAME_EXPORT`` instead of ``SOMELIB_EXPORT``, but 93 # other macros and the generated file name is as default: 95 # .. code-block:: cmake 97 # add_library(somelib someclass.cpp) 98 # generate_export_header(somelib 99 # DEPRECATED_MACRO_NAME KDE_DEPRECATED 103 # creates the macro ``KDE_DEPRECATED`` instead of ``SOMELIB_DEPRECATED``. 105 # If ``LIBRARY_TARGET`` is a static library, macros are defined without 108 # If the same sources are used to create both a shared and a static 109 # library, the uppercased symbol ``${BASE_NAME}_STATIC_DEFINE`` should be 110 # used when building the static library: 112 # .. code-block:: cmake 114 # add_library(shared_variant SHARED ${lib_SRCS}) 115 # add_library(static_variant ${lib_SRCS}) 116 # generate_export_header(shared_variant BASE_NAME libshared_and_static) 117 # set_target_properties(static_variant PROPERTIES 118 # COMPILE_FLAGS -DLIBSHARED_AND_STATIC_STATIC_DEFINE) 120 # This will cause the export macros to expand to nothing when building 121 # the static library. 123 # If ``DEFINE_NO_DEPRECATED`` is specified, then a macro 124 # ``${BASE_NAME}_NO_DEPRECATED`` will be defined This macro can be used to 125 # remove deprecated code from preprocessor output: 127 # .. code-block:: cmake 129 # option(EXCLUDE_DEPRECATED "Exclude deprecated parts of the library" FALSE) 130 # if (EXCLUDE_DEPRECATED) 131 # set(NO_BUILD_DEPRECATED DEFINE_NO_DEPRECATED) 133 # generate_export_header(somelib ${NO_BUILD_DEPRECATED}) 136 # And then in somelib: 138 # .. code-block:: c++ 140 # class SOMELIB_EXPORT SomeClass 143 # #ifndef SOMELIB_NO_DEPRECATED 144 # SOMELIB_DEPRECATED void oldMethod(); 148 # .. code-block:: c++ 150 # #ifndef SOMELIB_NO_DEPRECATED 151 # void SomeClass::oldMethod() { } 155 # If ``PREFIX_NAME`` is specified, the argument will be used as a prefix to 156 # all generated macros. 160 # .. code-block:: cmake 162 # generate_export_header(somelib PREFIX_NAME VTK_) 164 # Generates the macros ``VTK_SOMELIB_EXPORT`` etc. 168 # ADD_COMPILER_EXPORT_FLAGS( [<output_variable>] ) 170 # The ``ADD_COMPILER_EXPORT_FLAGS`` function adds ``-fvisibility=hidden`` to 171 # :variable:`CMAKE_CXX_FLAGS <CMAKE_<LANG>_FLAGS>` if supported, and is a no-op 172 # on Windows which does not need extra compiler flags for exporting support. 173 # You may optionally pass a single argument to ``ADD_COMPILER_EXPORT_FLAGS`` 174 # that will be populated with the ``CXX_FLAGS`` required to enable visibility 175 # support for the compiler/architecture in use. 177 # This function is deprecated. Set the target properties 178 # :prop_tgt:`CXX_VISIBILITY_PRESET <<LANG>_VISIBILITY_PRESET>` and 179 # :prop_tgt:`VISIBILITY_INLINES_HIDDEN` instead. 181 #============================================================================= 182 # Copyright 2011 Stephen Kelly <steveire@gmail.com> 184 # Distributed under the OSI-approved BSD License (the "License"); 185 # see accompanying file Copyright.txt for details. 187 # This software is distributed WITHOUT ANY WARRANTY; without even the 188 # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 189 # See the License for more information. 190 #============================================================================= 191 # (To distribute this file outside of CMake, substitute the full 192 # License text for the above reference.) 194 include(CMakeParseArguments)
195 include(CheckCXXCompilerFlag)
197 # TODO: Install this macro separately? 198 macro(_check_cxx_compiler_attribute _ATTRIBUTE _RESULT)
199 check_cxx_source_compiles(
"${_ATTRIBUTE} int somefunc() { return 0; } 200 int main() { return somefunc();}" ${_RESULT}
204 macro(_test_compiler_hidden_visibility)
206 if(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.2")
207 set(GCC_TOO_OLD TRUE)
208 elseif(CMAKE_COMPILER_IS_GNUC AND CMAKE_C_COMPILER_VERSION VERSION_LESS "4.2")
209 set(GCC_TOO_OLD TRUE)
210 elseif(CMAKE_CXX_COMPILER_ID MATCHES Intel AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "12.0")
211 set(_INTEL_TOO_OLD TRUE)
214 # Exclude XL here because it misinterprets -fvisibility=hidden even though 215 # the check_cxx_compiler_flag passes 217 AND NOT _INTEL_TOO_OLD
220 AND NOT CMAKE_CXX_COMPILER_ID MATCHES XL
221 AND NOT CMAKE_CXX_COMPILER_ID MATCHES PGI
222 AND NOT CMAKE_CXX_COMPILER_ID MATCHES Watcom)
223 check_cxx_compiler_flag(-fvisibility=hidden COMPILER_HAS_HIDDEN_VISIBILITY)
224 check_cxx_compiler_flag(-fvisibility-inlines-hidden
225 COMPILER_HAS_HIDDEN_INLINE_VISIBILITY)
226 option(USE_COMPILER_HIDDEN_VISIBILITY
227 "Use HIDDEN visibility support if available." ON)
228 mark_as_advanced(USE_COMPILER_HIDDEN_VISIBILITY)
232 macro(_test_compiler_has_deprecated)
233 # NOTE: Some Embarcadero compilers silently compile __declspec(deprecated) 234 # without error, but this is not a documented feature and the attribute does 235 # not actually generate any warnings. 236 if(CMAKE_CXX_COMPILER_ID MATCHES Borland
237 OR CMAKE_CXX_COMPILER_ID MATCHES Embarcadero
238 OR CMAKE_CXX_COMPILER_ID MATCHES HP
240 OR CMAKE_CXX_COMPILER_ID MATCHES PGI
241 OR CMAKE_CXX_COMPILER_ID MATCHES Watcom)
242 set(COMPILER_HAS_DEPRECATED
"" CACHE INTERNAL
243 "Compiler support for a deprecated attribute")
245 _check_cxx_compiler_attribute(
"__attribute__((__deprecated__))" 246 COMPILER_HAS_DEPRECATED_ATTR)
247 if(COMPILER_HAS_DEPRECATED_ATTR)
248 set(COMPILER_HAS_DEPRECATED "${COMPILER_HAS_DEPRECATED_ATTR}
" 249 CACHE INTERNAL "Compiler support
for a deprecated attribute
") 251 _check_cxx_compiler_attribute("__declspec(deprecated)
" 252 COMPILER_HAS_DEPRECATED) 257 get_filename_component(_GENERATE_EXPORT_HEADER_MODULE_DIR 258 "${CMAKE_CURRENT_LIST_FILE}
" PATH) 260 macro(_DO_SET_MACRO_VALUES TARGET_LIBRARY) 261 set(DEFINE_DEPRECATED) 264 set(DEFINE_NO_EXPORT) 266 if (COMPILER_HAS_DEPRECATED_ATTR) 267 set(DEFINE_DEPRECATED "__attribute__ ((__deprecated__))
") 268 elseif(COMPILER_HAS_DEPRECATED) 269 set(DEFINE_DEPRECATED "__declspec(deprecated)
") 272 get_property(type TARGET ${TARGET_LIBRARY} PROPERTY TYPE) 274 if(NOT ${type} STREQUAL "STATIC_LIBRARY
") 276 set(DEFINE_EXPORT "__declspec(dllexport)
") 277 set(DEFINE_IMPORT "__declspec(dllimport)
") 278 elseif(COMPILER_HAS_HIDDEN_VISIBILITY AND USE_COMPILER_HIDDEN_VISIBILITY) 279 set(DEFINE_EXPORT "__attribute__((visibility(\
"default\")))")
280 set(DEFINE_IMPORT
"__attribute__((visibility(\"default\")))")
281 set(DEFINE_NO_EXPORT
"__attribute__((visibility(\"hidden\")))")
286 macro(_DO_GENERATE_EXPORT_HEADER TARGET_LIBRARY)
288 set(options DEFINE_NO_DEPRECATED)
289 set(oneValueArgs PREFIX_NAME BASE_NAME EXPORT_MACRO_NAME EXPORT_FILE_NAME
290 DEPRECATED_MACRO_NAME NO_EXPORT_MACRO_NAME STATIC_DEFINE
291 NO_DEPRECATED_MACRO_NAME)
294 cmake_parse_arguments(_GEH
"${options}" "${oneValueArgs}" "${multiValueArgs}" 297 set(BASE_NAME
"${TARGET_LIBRARY}")
300 set(BASE_NAME ${_GEH_BASE_NAME})
303 string(TOUPPER ${BASE_NAME} BASE_NAME_UPPER)
304 string(TOLOWER ${BASE_NAME} BASE_NAME_LOWER)
307 set(EXPORT_MACRO_NAME
"${_GEH_PREFIX_NAME}${BASE_NAME_UPPER}_EXPORT")
308 set(NO_EXPORT_MACRO_NAME
"${_GEH_PREFIX_NAME}${BASE_NAME_UPPER}_NO_EXPORT")
309 set(EXPORT_FILE_NAME
"${CMAKE_CURRENT_BINARY_DIR}/${BASE_NAME_LOWER}_export.h")
310 set(DEPRECATED_MACRO_NAME
"${_GEH_PREFIX_NAME}${BASE_NAME_UPPER}_DEPRECATED")
311 set(STATIC_DEFINE
"${_GEH_PREFIX_NAME}${BASE_NAME_UPPER}_STATIC_DEFINE")
312 set(NO_DEPRECATED_MACRO_NAME
313 "${_GEH_PREFIX_NAME}${BASE_NAME_UPPER}_NO_DEPRECATED")
315 if(_GEH_UNPARSED_ARGUMENTS)
316 message(FATAL_ERROR
"Unknown keywords given to GENERATE_EXPORT_HEADER(): \"${_GEH_UNPARSED_ARGUMENTS}\"")
319 if(_GEH_EXPORT_MACRO_NAME)
320 set(EXPORT_MACRO_NAME ${_GEH_PREFIX_NAME}${_GEH_EXPORT_MACRO_NAME})
322 string(MAKE_C_IDENTIFIER ${EXPORT_MACRO_NAME} EXPORT_MACRO_NAME)
323 if(_GEH_EXPORT_FILE_NAME)
324 if(IS_ABSOLUTE ${_GEH_EXPORT_FILE_NAME})
325 set(EXPORT_FILE_NAME ${_GEH_EXPORT_FILE_NAME})
327 set(EXPORT_FILE_NAME
"${CMAKE_CURRENT_BINARY_DIR}/${_GEH_EXPORT_FILE_NAME}")
330 if(_GEH_DEPRECATED_MACRO_NAME)
331 set(DEPRECATED_MACRO_NAME ${_GEH_PREFIX_NAME}${_GEH_DEPRECATED_MACRO_NAME})
333 string(MAKE_C_IDENTIFIER ${DEPRECATED_MACRO_NAME} DEPRECATED_MACRO_NAME)
334 if(_GEH_NO_EXPORT_MACRO_NAME)
335 set(NO_EXPORT_MACRO_NAME ${_GEH_PREFIX_NAME}${_GEH_NO_EXPORT_MACRO_NAME})
337 string(MAKE_C_IDENTIFIER ${NO_EXPORT_MACRO_NAME} NO_EXPORT_MACRO_NAME)
338 if(_GEH_STATIC_DEFINE)
339 set(STATIC_DEFINE ${_GEH_PREFIX_NAME}${_GEH_STATIC_DEFINE})
341 string(MAKE_C_IDENTIFIER ${STATIC_DEFINE} STATIC_DEFINE)
343 if(_GEH_DEFINE_NO_DEPRECATED)
344 set(DEFINE_NO_DEPRECATED 1)
346 set(DEFINE_NO_DEPRECATED 0)
349 if(_GEH_NO_DEPRECATED_MACRO_NAME)
350 set(NO_DEPRECATED_MACRO_NAME
351 ${_GEH_PREFIX_NAME}${_GEH_NO_DEPRECATED_MACRO_NAME})
353 string(MAKE_C_IDENTIFIER ${NO_DEPRECATED_MACRO_NAME} NO_DEPRECATED_MACRO_NAME)
355 set(INCLUDE_GUARD_NAME
"${EXPORT_MACRO_NAME}_H")
357 get_target_property(EXPORT_IMPORT_CONDITION ${TARGET_LIBRARY} DEFINE_SYMBOL)
359 if(NOT EXPORT_IMPORT_CONDITION)
360 set(EXPORT_IMPORT_CONDITION ${TARGET_LIBRARY}_EXPORTS)
362 string(MAKE_C_IDENTIFIER ${EXPORT_IMPORT_CONDITION} EXPORT_IMPORT_CONDITION)
364 configure_file(
"${_GENERATE_EXPORT_HEADER_MODULE_DIR}/exportheader.cmake.in" 365 "${EXPORT_FILE_NAME}" @ONLY)
369 get_property(type TARGET ${TARGET_LIBRARY} PROPERTY TYPE)
370 if(NOT ${type} STREQUAL
"STATIC_LIBRARY" 371 AND NOT ${type} STREQUAL
"SHARED_LIBRARY" 372 AND NOT ${type} STREQUAL
"OBJECT_LIBRARY" 373 AND NOT ${type} STREQUAL
"MODULE_LIBRARY")
374 message(WARNING
"This macro can only be used with libraries")
377 _test_compiler_hidden_visibility()
378 _test_compiler_has_deprecated()
379 _do_set_macro_values(${TARGET_LIBRARY})
380 _do_generate_export_header(${TARGET_LIBRARY} ${ARGN})
384 if(NOT CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 2.8.12)
385 message(DEPRECATION
"The add_compiler_export_flags function is obsolete. Use the CXX_VISIBILITY_PRESET and VISIBILITY_INLINES_HIDDEN target properties instead.")
388 _test_compiler_hidden_visibility()
389 _test_compiler_has_deprecated()
391 if(NOT (USE_COMPILER_HIDDEN_VISIBILITY AND COMPILER_HAS_HIDDEN_VISIBILITY))
392 # Just
return if there are no flags to add.
396 set (EXTRA_FLAGS
"-fvisibility=hidden")
398 if(COMPILER_HAS_HIDDEN_INLINE_VISIBILITY)
399 set (EXTRA_FLAGS
"${EXTRA_FLAGS} -fvisibility-inlines-hidden")
402 # Either
return the extra flags needed in the supplied argument, or to the
403 # CMAKE_CXX_FLAGS
if no argument
is supplied.
405 set(${ARGV0}
"${EXTRA_FLAGS}" PARENT_SCOPE)
407 set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} ${EXTRA_FLAGS}" PARENT_SCOPE)
function is(in result, in expected, in name)
Test whether a given result is equal to the expected result.