如何使用 CMake 定义在 dllexport 和 dllimport 属性宏之间切换的切换宏?

问题描述 投票:0回答:1

所以我有一个项目(旨在在 MacOS、Linux 和 Windows 上受支持),我正在其中构建一个共享库和一组链接到该库的可执行文件。在我的根

CMakeLists.txt
我添加了:

set(CMAKE_CXX_VISIBILITY_PRESET hidden)

因此,无论在 Windows(默认情况下这样做)还是 Linux 上,所有符号都默认隐藏。这将需要我手动导出公共 API 的符号。为了帮助实现这一点,我在项目的

defines.hpp
目录中编写了一个
utils/
标头,其中包含以下内容:

#ifndef __DEFINES_H_
#define __DEFINES_H_

#if defined(linux) || defined(__linux__)
    #define EXPORT __attribute__((visibility("default"))) 
#elif defined(_WIN64) || defined(__WIN32__)
    #if defined(COMPILE_LIB)
        #define EXPORT __declspec(dllexport)
    #elif
        #define EXPORT __declspec(dllimport)
    #endif
#endif

#endif

然后我的想法是将此标头包含到任何包含需要导出(以及随后导入)的声明的标头中:

#include "utils/defines.hpp"

class EXPORT MyCoolClass();

EXPORT void MyCoolFunction();

(我还没有测试过,所以如果我写的内容有任何明显的问题,请告诉我!)

我的问题是,鉴于库和可执行文件是使用相同的 CMake 设置构建/链接的,我并不完全清楚如何定义

COMPILE_LIB
宏。如何确保使用
dllexport
构建库,然后在同一 CMake 构建中使用
dllimport
链接到可执行文件?或者我需要采取不同的方法吗?

之前的SO帖子中接受的答案似乎表明使用编译器参数并单独构建每个参数,这并不是我正在寻找的。 单独的答案表示您应该使用 CMake 定义的

projectname
,因为编译 DLL 时它将定义宏
projectname_EXPORTS
。我也不确定这是否会再次工作我的共享库,并且可执行文件都在同一个 CMake 项目中构建。 (相关
CMakeLists.txt
文件):

CMakeLists.txt
对于可执行文件:

add_executable(quick-render quick_render.cpp)
target_link_libraries(quick-render ${PROJECT_NAME})
INSTALL(TARGETS quick-render DESTINATION bin)
...

CMakeLists.txt
图书馆:

...

add_library(${PROJECT_NAME} SHARED
   ...
)

target_link_libraries(${PROJECT_NAME} PUBLIC
   ...
)
...

这种方法在这里仍然有效,还是我的 CMake 设置不适合以多种方式使用该项目?

c++ cmake shared-libraries dllimport dllexport
1个回答
2
投票

正如 Tsyvarev 在评论中所说,

使用

target_compile_definitions
命令和
PRIVATE
关键字定义宏。这样,只有在编译库本身时才会定义宏。

补充 Tsyvarev 所说的,如果您只使用

GenerateExportHeader
模块,该部分将自动为您完成。它还会负责为您配置构建系统使用的编译器生成 C++ 属性。另请参阅使用 CMake 时是否有办法避免在每个源文件中重新定义共享库导出属性的样板宏?.

© www.soinside.com 2019 - 2024. All rights reserved.