iOS -ObjC link option leads to "duplicate symbol" for QtCore.framework
-
wrote on 19 May 2025, 12:44 last edited by MarcoDC
Im am working on porting my Qt app (with support for mac, iOS and Android) from Qt 5.15.17 to Qt 6.9 (which already worked out so far :D) and now from QMake using .pro files to CMake.
The initial cause for my problem was this error message when trying to call
"[FIRApp configure]" from my objective-c file application.mm:*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[NSData gul_dataByGzippingData:error:]: unrecognized selector sent to class 0x1f10f4610' *** First throw call stack: (0x188a725fc 0x185fed244 0x188bcb008 0x188a755c8 0x188a74ef0 0x1012ce1fc 0x1010cd7d4 0x1010cd60c 0x190806fa8 0x19080a45c 0x19081e620 0x19081d1e8 0x190818ec0 0x1908196c4 0x2137dc644 0x2137da474) libc++abi: terminating due to uncaught exception of type NSException
After a quick search I noted that this is possibly because I did not compile with "-ObjC" flag.
So I tried to do some modifications in my project:
1. I tried to use the flag "-ObjC" using this blocktarget_link_options(${PROJECT_NAME} PUBLIC -ObjC)
But when trying to compile, I receive a lot of errors like
Undefined symbols for architecture arm64: "__swift_FORCE_LOAD_$_swiftCompatibility50", referenced from: __swift_FORCE_LOAD_$_swiftCompatibility50_$_FirebaseCoreInternal in FirebaseCoreInternal[4](_ObjC_HeartbeatController.o) __swift_FORCE_LOAD_$_swiftCompatibility50_$_FirebaseCrashlytics in FirebaseCrashlytics[84](CrashlyticsRemoteConfigManager.o) __swift_FORCE_LOAD_$_swiftCompatibility50_$_FirebaseRemoteConfigInterop in FirebaseRemoteConfigInterop[4](RemoteConfigConstants.o) __swift_FORCE_LOAD_$_swiftCompatibility50_$_FirebaseSessions in FirebaseSessions[6](ApplicationInfo.o) __swift_FORCE_LOAD_$_swiftCompatibility50_$_Promises in Promises[4](Promise.o) __swift_FORCE_LOAD_$_swiftCompatibility50_$_GoogleMobileAds in GoogleMobileAds[arm64][430](GADMarketplaceKitSignals.o) __swift_FORCE_LOAD_$_swiftCompatibility50_$_FBAdMAISKOverlayManager in FBAudienceNetwork[4](FBAdMAISKOverlayManager.o) ... "__swift_FORCE_LOAD_$_swiftCompatibilityConcurrency", referenced from: __swift_FORCE_LOAD_$_swiftCompatibilityConcurrency_$_FirebaseCoreInternal in FirebaseCoreInternal[4](_ObjC_HeartbeatController.o) __swift_FORCE_LOAD_$_swiftCompatibilityConcurrency_$_FirebaseCrashlytics in FirebaseCrashlytics[84](CrashlyticsRemoteConfigManager.o) __swift_FORCE_LOAD_$_swiftCompatibilityConcurrency_$_FirebaseRemoteConfigInterop in FirebaseRemoteConfigInterop[4](RemoteConfigConstants.o) __swift_FORCE_LOAD_$_swiftCompatibilityConcurrency_$_FirebaseSessions in FirebaseSessions[6](ApplicationInfo.o) __swift_FORCE_LOAD_$_swiftCompatibilityConcurrency_$_FirebaseSharedSwift in FirebaseSharedSwift[4](FirebaseDataEncoder.o) __swift_FORCE_LOAD_$_swiftCompatibilityConcurrency_$_Promises in Promises[4](Promise.o) __swift_FORCE_LOAD_$_swiftCompatibilityConcurrency_$_GoogleMobileAds in GoogleMobileAds[arm64][430](GADMarketplaceKitSignals.o) ... "__swift_FORCE_LOAD_$_swiftCompatibilityDynamicReplacements", referenced from: __swift_FORCE_LOAD_$_swiftCompatibilityDynamicReplacements_$_FirebaseCoreInternal in FirebaseCoreInternal[4](_ObjC_HeartbeatController.o) __swift_FORCE_LOAD_$_swiftCompatibilityDynamicReplacements_$_FirebaseCrashlytics in FirebaseCrashlytics[84](CrashlyticsRemoteConfigManager.o) __swift_FORCE_LOAD_$_swiftCompatibilityDynamicReplacements_$_FirebaseRemoteConfigInterop in FirebaseRemoteConfigInterop[4](RemoteConfigConstants.o) __swift_FORCE_LOAD_$_swiftCompatibilityDynamicReplacements_$_FirebaseSessions in FirebaseSessions[6](ApplicationInfo.o) __swift_FORCE_LOAD_$_swiftCompatibilityDynamicReplacements_$_Promises in Promises[4](Promise.o) __swift_FORCE_LOAD_$_swiftCompatibilityDynamicReplacements_$_GoogleMobileAds in GoogleMobileAds[arm64][430](GADMarketplaceKitSignals.o) __swift_FORCE_LOAD_$_swiftCompatibilityDynamicReplacements_$_FBAdMAISKOverlayManager in FBAudienceNetwork[4](FBAdMAISKOverlayManager.o) ... ld: symbol(s) not found for architecture arm64 clang++: error: linker command failed with exit code 1 (use -v to see invocation)
2. Thats why I added the base swift directories to my linker settings using
target_link_directories(${PROJECT_NAME} PUBLIC "/usr/lib/swift" "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphoneos" )
But now this leads to a lot of duplicated symbol errors:
duplicate symbol '_OBJC_METACLASS_$_WeakPointerLifetimeTracker' in: /Users/user/Qt/6.9.0/ios/lib/QtCore.framework/QtCore[arm64][166](qcore_mac.mm.o) /Users/user/Qt/6.9.0/ios/lib/QtCore.framework/QtCore[arm64][166](qcore_mac.mm.o) /Users/user/Qt/6.9.0/ios/lib/QtCore.framework/QtCore[arm64][166](qcore_mac.mm.o) duplicate symbol '_OBJC_CLASS_$_RunLoopModeTracker' in: /Users/user/Qt/6.9.0/ios/lib/QtCore.framework/QtCore[arm64][168](qeventdispatcher_cf.mm.o) /Users/user/Qt/6.9.0/ios/lib/QtCore.framework/QtCore[arm64][168](qeventdispatcher_cf.mm.o) /Users/user/Qt/6.9.0/ios/lib/QtCore.framework/QtCore[arm64][168](qeventdispatcher_cf.mm.o) duplicate symbol 'AppleUnifiedLogger::messageHandler(QtMsgType, QMessageLogContext const&, QString const&, QString const&)' in: /Users/user/Qt/6.9.0/ios/lib/QtCore.framework/QtCore[arm64][166](qcore_mac.mm.o) /Users/user/Qt/6.9.0/ios/lib/QtCore.framework/QtCore[arm64][166](qcore_mac.mm.o) /Users/user/Qt/6.9.0/ios/lib/QtCore.framework/QtCore[arm64][166](qcore_mac.mm.o) ...
After a few days of research (and ChatGPTing like a vibe coder xD) I tried a lot of things but wasn't really able to solve this problem at all /
Am I missing something important here or doing anything completely wrong?3. I have created a new empty Test project and tried to dabble around with some flags and compiler properties to embed swift libraries like
XCODE_ATTRIBUTE_ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES
but the problem is the same :/ld: 98 duplicate symbols
clang++: error: linker command failed with exit code 1 (use -v to see invocation)cmake_minimum_required(VERSION 3.16) project(Test VERSION 1.00 LANGUAGES C CXX OBJC OBJCXX Swift) set(CMAKE_INCLUDE_CURRENT_DIR ON) # Set C++ standard (if needed) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(BUILD_SHARED_LIBS OFF) find_package(Qt6 REQUIRED COMPONENTS Quick) qt_standard_project_setup(REQUIRES 6.9) qt_add_executable(appTest main.cpp ) qt_add_qml_module(appTest URI Test VERSION 1.0 QML_FILES Main.qml ) # Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. # If you are developing for iOS or macOS you should consider setting an # explicit, fixed bundle identifier manually though. set_target_properties(appTest PROPERTIES MACOSX_BUNDLE TRUE WIN32_EXECUTABLE TRUE # MACOSX_BUNDLE_GUI_IDENTIFIER com.example.appTest # MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/ios/Info.plist" MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} # Sign embedded frameworks # XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY ON # Embed Swift libraries # XCODE_ATTRIBUTE_ENABLE_BITCODE "NO" # XCODE_ATTRIBUTE_SWIFT_VERSION "5.6" XCODE_ATTRIBUTE_ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES "NO" # XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/Frameworks" ) target_link_options(appTest PUBLIC -ObjC) # -lz -lswiftCompatibility51 -lswiftCompatibility56) # Link additional Library directory for swift support #target_link_directories(appTest PRIVATE # "/usr/lib/swift" # "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphoneos" #) target_link_libraries(appTest PRIVATE Qt6::Quick ) include(GNUInstallDirs) install(TARGETS appTest BUNDLE DESTINATION . LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} )
-
wrote 29 days ago last edited by
I actually found a solution to my problem :DDD
In fact this was a bug in Qt since 6.7.3:
https://bugreports.qt.io/browse/QTBUG-135978?gerritReviewStatus=Open
which now seems to be fixed https://codereview.qt-project.org/c/qt/qtbase/+/643588A workaround for now suggest here https://bugreports.qt.io/browse/QTBUG-132412
is toConfigure with cmake 3.29+ and the extra -DQT_FORCE_CMP0156_TO_NEW=ON option.
which I did by setting the policy in my root project cmake file right before find_package:
# Enable CMP0156 explicitly to prevent duplicate symbol errors when using -ObjC linker flag if (POLICY CMP0156) message(STATUS "Setting CMP0156 policy to NEW...") set(QT_FORCE_CMP0156_TO_NEW ON CACHE BOOL "Force CMake policy CMP0156 to NEW behavior for Qt6") elseif () message(ERROR "CMP0156 policy not available! Please switch to cmake 3.29+ and Qt6.9") endif ()
-
1/2