《QDebug 2023年3月》

一、Qt Widgets 问题交流

二、Qt Quick 问题交流

三、其他

1.Qt qmake 在 Mac 上生成 dylib 相关的问题

默认的 lib 工程 qmake 输出如图,会生成带版本号的软链接:

一般我们只需要一个 lib 文件,可以增加设置:

CONFIG += unversioned_libname unversioned_soname

unversioned_libname 去掉了 lib 的版本号,unversioned_soname 去掉了链接里的版本号(Windows 版本对应的设置叫 skip_target_version_ext)。网上有的是用 CONFIG += plugin,这样写 QMAKE_SONAME_PREFIX 设置 rpath 就没生效。

一般还需要给库设置链接路径 rpath,不然运行时报错找不到库,qmake 设置:

QMAKE_SONAME_PREFIX = @rpath

这样引用这个库的可执行程序就会去如 Frameworks 之类的目录查找,如果不设置 dylib 中的路径最后还得设置可执行程序链接库的路径,qmake 构建的时候默认可执行程序的查找路径和 dylib 中的似乎是一样的。

上面去掉库文件名的版本号后,Qt5 在 mac 上用 profile 模式编译还会报错:

因为 qmake 的脚本有 bug,dylib 虽然是没版本号了,但是调试文件 dSYM 还是带版本号的,因为有一段逻辑里没判断 unversioned_libname 这个设置。

参考 Qt BUG Tracker:https://bugreports.qt.io/browse/QTBUG-64290

直接打开安装目录下的 mkspecs/features/resolve_target.prf ,修改如图,增加了 unversioned_libname  判断:

2.CMake 在 Windows 上生成 dll 时生成导入库 lib 

方式一:使用 def 模块定义文件

参考文档:https://learn.microsoft.com/zh-cn/cpp/build/reference/module-definition-dot-def-files

写好 def 文件后,在 add_library 中包含这个文件:

add_library(${PROJECT_NAME} SHARED ${head_files} ${source_files} xxx.def)

方式二:使用 __declspec(dllexport)

__declspec(dllexport) void __cdecl Function1(void);

方式三:CMAKE 变量 CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS

参考文档:https://cmake.org/cmake/help/latest/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.html

set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
add_library(${PROJECT_NAME} SHARED ${head_files} ${source_files})

该设置会导出所有符号,但对于全局变量还是需要前面两种方式来显式导出。很多 GUN 风格的库没有声明导出符号,用这个变量设置再好不过了。

3.Windows 上一些和 std 冲突的处理

std::byte 由 /std:c++17 或更高版本启用,using namespace std 后会和 Windows SDK 中的 byte 定义冲突,可以增加宏定义:_HAS_STD_BYTE=0 屏蔽 std::byte,但是这又会导致某些库中的 std::byte 未定义,所以最好不要 using namespace std。

Windows SDK 中的 min max 函数有时候会和标准库中的冲突,可以增加宏定义:NOMINMAX

宏定义要么在工程配置里加,要么在 include Windows 头文件之前加,qmake 写法:

# conflict c++17 std::byte and window byte
DEFINES += _HAS_STD_BYTE=0

# std::min std::max
DEFINES += NOMINMAX

猜你喜欢

转载自blog.csdn.net/gongjianbo1992/article/details/129889588