生成导出头

为库生成导出宏的函数

该模块提供函数``GENERATE_EXPORT_HEADER()``。

在 3.12 版本加入: 添加了对 C 项目的支持。以前的版本仅支持 C++ 项目。

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_EXPORT”、“SOMELIB_NO_EXPORT”、“SOMELIB_DEPRECATED”、“SOMELIB_DEPRECATED_EXPORT” ` 和 SOMELIB_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_EXPORT”、“OTHER_NAME_NO_EXPORT”和“OTHER_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”。