我创建了一个用 C++17 编写的应用程序,并在使用最新编译器和 Catalina 版本的 MacOS 的 Mac 上编译。我正在使用 CMake 和 CPack 创建一个包并将其打包到.dmg. 当我使用 Catalina 在另一台计算机上获取生成的文件时,一切正常。但是当尝试在装有 MacOS 10.12 的机器上运行时,会出现错误:
dyld: Symbol not found: __ZNSt19bad_optional_accessD1Ev
Expected in: /usr/lib/libc++.1.dylib
Run Code Online (Sandbox Code Playgroud)
在对符号进行解构时,它实际上是bad_optional_access异常的析构函数:std::bad_optional_access::~bad_optional_access()
的std::optional是在C ++ 17导入。因此,装有 MacOS 10.12 的计算机在其 libc++ 中没有该符号。我试图找出如何将libc++.1.dylibfor C++17打包到包中,以便它不会使用系统一。
要创建我的包,我有:
# Installation
set(prefix "${PROJECT_NAME}.app/Contents")
set(INSTALL_RUNTIME_DIR "${prefix}/MacOS")
set(INSTALL_CMAKE_DIR "${prefix}/Resources")
set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR})
# based on code from CMake's QtDialog/CMakeLists.txt
macro(install_qt5_plugin _qt_plugin_name _qt_plugins_var _prefix)
get_target_property(_qt_plugin_path "${_qt_plugin_name}" LOCATION)
if(EXISTS "${_qt_plugin_path}")
get_filename_component(_qt_plugin_file "${_qt_plugin_path}" NAME)
get_filename_component(_qt_plugin_type "${_qt_plugin_path}" PATH)
get_filename_component(_qt_plugin_type "${_qt_plugin_type}" NAME)
set(_qt_plugin_dest "${_prefix}/PlugIns/${_qt_plugin_type}")
install(FILES "${_qt_plugin_path}"
DESTINATION "${_qt_plugin_dest}")
set(${_qt_plugins_var}
"${${_qt_plugins_var}};\$ENV{DEST_DIR}\${CMAKE_INSTALL_PREFIX}/${_qt_plugin_dest}/${_qt_plugin_file}")
else()
message(FATAL_ERROR "QT plugin ${_qt_plugin_name} not found")
endif()
endmacro()
install_qt5_plugin("Qt5::QCocoaIntegrationPlugin" QT_PLUGINS ${prefix})
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
"[Paths]\nPlugins = ${_qt_plugin_dir}\n")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
DESTINATION "${INSTALL_CMAKE_DIR}")
# Destination paths below are relative to ${CMAKE_INSTALL_PREFIX}
install(TARGETS ${PROJECT_NAME}
BUNDLE DESTINATION . COMPONENT Runtime
RUNTIME DESTINATION ${INSTALL_RUNTIME_DIR} COMPONENT Runtime
)
# Note Mac specific extension .app
set(APPS "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}.app")
# Directories to look for dependencies
set(DIRS "${CMAKE_BINARY_DIR}")
# Path used for searching by FIND_XXX(), with appropriate suffixes added
if(CMAKE_PREFIX_PATH)
foreach(dir ${CMAKE_PREFIX_PATH})
list(APPEND DIRS "${dir}/bin" "${dir}/lib")
endforeach()
endif()
list(APPEND DIRS "$ENV{VULKAN_SDK}/lib")
list(APPEND QT_PLUGINS "${APPS}/Contents/Resources/MoltenVk/lib/libMoltenVK.dylib")
# Append Qt's lib folder which is two levels above Qt5Widgets_DIR
list(APPEND DIRS "${Qt5Widgets_DIR}/../..")
include(InstallRequiredSystemLibraries)
message(STATUS "APPS: ${APPS}")
message(STATUS "QT_PLUGINS: ${QT_PLUGINS}")
message(STATUS "DIRS: ${DIRS}")
install(CODE "include(BundleUtilities)
fixup_bundle(\"${APPS}\" \"${QT_PLUGINS}\" \"${DIRS}\")")
install(CODE "include(BundleUtilities)
fixup_bundle(\"${APPS}\" \"${MOLTEN_LIB}\" \"${DIRS}\")")
set(CPACK_GENERATOR "DRAGNDROP")
include(CPack)
Run Code Online (Sandbox Code Playgroud)
它为 Qt Vulkan 和 MoltenVK 库做了正确的工作。我能够在另一台运行 Catalina 的计算机上运行,该计算机上未安装 Vulkan 和 MoltenVk 库,并且otool -L在可执行文件上运行表明它正在使用嵌入式 Qt 库。然而,它指的是/usr/lib/libc++.1.dylib图书馆。
我不明白如何正确嵌入系统文件夹 /usr/lib 中的 C++ 标准库,而不包括该文件夹中的其他库,并确保fixup_bundle正确地更新该库的链接。如果有人知道如何正确执行此操作,我将不胜感激。
| 归档时间: |
|
| 查看次数: |
397 次 |
| 最近记录: |