GenerateExportHeader

此模块提供了 generate_export_header() 函数,用于为库生成导出宏。

版本 3.12 新增: 添加了对 C 项目的支持。之前的版本仅支持 C++ 项目。

generate_export_header

generate_export_header() 函数可用于生成一个适用于预处理器包含的文件,其中包含将在库类中使用的 EXPORT 宏

generate_export_header(LIBRARY_TARGET
         [BASE_NAME <base_name>]
         [EXPORT_MACRO_NAME <export_macro_name>]
         [EXPORT_FILE_NAME <export_file_name>]
         [DEPRECATED_MACRO_NAME <deprecated_macro_name>]
         [NO_EXPORT_MACRO_NAME <no_export_macro_name>]
         [INCLUDE_GUARD_NAME <include_guard_name>]
         [STATIC_DEFINE <static_define>]
         [NO_DEPRECATED_MACRO_NAME <no_deprecated_macro_name>]
         [DEFINE_NO_DEPRECATED]
         [PREFIX_NAME <prefix_name>]
         [CUSTOM_CONTENT_FROM_VARIABLE <variable>]
)

目标属性 CXX_VISIBILITY_PRESETVISIBILITY_INLINES_HIDDEN 可用于为目标添加适当的编译标志。请参阅这些目标属性的文档,以及便利变量 CMAKE_CXX_VISIBILITY_PRESETCMAKE_VISIBILITY_INLINES_HIDDEN

默认情况下,generate_export_header() 在由库名称确定的文件名中生成宏名称。这意味着在最简单的情况下,GenerateExportHeader 的用户将等同于

set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
add_library(somelib someclass.cpp)
generate_export_header(somelib)
install(TARGETS somelib DESTINATION ${LIBRARY_INSTALL_DIR})
install(FILES
 someclass.h
 ${PROJECT_BINARY_DIR}/somelib_export.h DESTINATION ${INCLUDE_INSTALL_DIR}
)

并且在 ABI 头文件中

#include "somelib_export.h"
class SOMELIB_EXPORT SomeClass {
  ...
};

CMake 代码片段将在 ${CMAKE_CURRENT_BINARY_DIR} 中生成一个名为 somelib_export.h 的文件,其中包含宏 SOMELIB_EXPORTSOMELIB_NO_EXPORTSOMELIB_DEPRECATEDSOMELIB_DEPRECATED_EXPORTSOMELIB_DEPRECATED_NO_EXPORT。 之后会跟随从 CUSTOM_CONTENT_FROM_VARIABLE 选项指定的变量中获取的内容(如果有)。生成的文件应与库中的其他头文件一起安装。

可以使用 BASE_NAME 参数来覆盖文件名和用于宏的名称

add_library(somelib someclass.cpp)
generate_export_header(somelib
  BASE_NAME other_name
)

生成一个名为 other_name_export.h 的文件,其中包含宏 OTHER_NAME_EXPORTOTHER_NAME_NO_EXPORTOTHER_NAME_DEPRECATED 等。

可以通过在函数中指定其他选项来覆盖 BASE_NAME。 例如

add_library(somelib someclass.cpp)
generate_export_header(somelib
  EXPORT_MACRO_NAME OTHER_NAME_EXPORT
)

创建宏 OTHER_NAME_EXPORT 而不是 SOMELIB_EXPORT,但其他宏和生成的文件名与默认值相同

add_library(somelib someclass.cpp)
generate_export_header(somelib
  DEPRECATED_MACRO_NAME KDE_DEPRECATED
)

创建宏 KDE_DEPRECATED 而不是 SOMELIB_DEPRECATED

如果 LIBRARY_TARGET 是一个静态库,则宏定义时不带值。

如果相同的源文件用于创建共享库和静态库,则在构建静态库时应使用大写的符号 ${BASE_NAME}_STATIC_DEFINE

add_library(shared_variant SHARED ${lib_SRCS})
add_library(static_variant ${lib_SRCS})
generate_export_header(shared_variant BASE_NAME libshared_and_static)
set_target_properties(static_variant PROPERTIES
  COMPILE_FLAGS -DLIBSHARED_AND_STATIC_STATIC_DEFINE)

这将导致导出宏在构建静态库时扩展为空。

如果指定了 DEFINE_NO_DEPRECATED,则将定义宏 ${BASE_NAME}_NO_DEPRECATED。此宏可用于从预处理器输出中删除已弃用的代码

option(EXCLUDE_DEPRECATED "Exclude deprecated parts of the library" FALSE)
if (EXCLUDE_DEPRECATED)
  set(NO_BUILD_DEPRECATED DEFINE_NO_DEPRECATED)
endif()
generate_export_header(somelib ${NO_BUILD_DEPRECATED})

然后在 somelib 中

class SOMELIB_EXPORT SomeClass
{
public:
#ifndef SOMELIB_NO_DEPRECATED
  SOMELIB_DEPRECATED void oldMethod();
#endif
};
#ifndef SOMELIB_NO_DEPRECATED
void SomeClass::oldMethod() {  }
#endif

如果指定了 PREFIX_NAME,则该参数将用作所有生成的宏的前缀。

例如

generate_export_header(somelib PREFIX_NAME VTK_)

生成宏 VTK_SOMELIB_EXPORT 等。

版本 3.1 新增: 库目标可以是 OBJECT 库。

版本 3.7 新增: 添加了 CUSTOM_CONTENT_FROM_VARIABLE 选项。

版本 3.11 新增: 添加了 INCLUDE_GUARD_NAME 选项。

add_compiler_export_flags
add_compiler_export_flags([<output_variable>])

自版本 3.0 起已弃用: 请改用目标属性 CXX_VISIBILITY_PRESETVISIBILITY_INLINES_HIDDEN

add_compiler_export_flags() 函数将 -fvisibility=hidden 添加到 CMAKE_CXX_FLAGS (如果支持),并且在 Windows 上是空操作,Windows 不需要额外的编译器标志来支持导出。您可以选择性地向 add_compiler_export_flags() 传递单个参数,该参数将填充启用正在使用的编译器/架构的可见性支持所需的 CXX_FLAGS