GenerateExportHeader

用于生成库导出宏的函数

此模块提供函数 GENERATE_EXPORT_HEADER()

3.12 版新增:增加了 c 项目支持。早期版本仅支持 c++ 项目。

函数 GENERATE_EXPORT_HEADER 可用于生成适合预处理器包含的文件,其中包含库类中要使用的导出宏

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( [<output_variable>] )

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

ADD_COMPILER_EXPORT_FLAGS 函数将 -fvisibility=hidden 添加到 CMAKE_CXX_FLAGS(如果受支持),并且在不需要额外编译器标志以支持导出功能的 Windows 上不执行任何操作。您可以根据需要将单个参数传递给 ADD_COMPILER_EXPORT_FLAGS,该参数将使用启用所用编译器/架构的可见性支持所需的 CXX_FLAGS 填充。