Last active
May 29, 2020 13:18
-
-
Save agirault/3244bf956c2cad7217b148291135f85e to your computer and use it in GitHub Desktop.
CMake configuration for a shared ios framework linking against static Qt5 libs to be embedded in an iOS app
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# cmake /path/to/src \ | |
# -GXcode \ # or Ninja | |
# -DQt5_DIR=/path/to/Qt/5.13.0/ios/lib/cmake/Qt5 \ | |
# -DCMAKE_SYSTEM_NAME=iOS \ | |
# -DCMAKE_OSX_DEPLOYMENT_TARGET=11 \ | |
# -DCMAKE_INSTALL_PREFIX=/usr/local/frameworks \ | |
# -DCMAKE_OSX_ARCHITECTURES="arm64" \ # arm64 for device, x86_64 for simulator (but x86_64 not in installed Qt5 ios static libs?) | |
cmake_minimum_required (VERSION 3.14 FATAL_ERROR) | |
project (Foo VERSION 1.0 LANGUAGES C CXX) | |
# Find QT | |
set(QT5_MODULES | |
Core | |
Widgets | |
Gui | |
Quick | |
Qml | |
# other modules needed... | |
) | |
find_package (Qt5 | |
COMPONENTS ${QT5_MODULES} | |
REQUIRED | |
) | |
# Options for QT | |
set (CMAKE_AUTOMOC ON) | |
set (CMAKE_AUTORCC ON) | |
set (CMAKE_AUTOUIC ON) | |
# Set files | |
set (PRIVATE_HEADER_DIRS | |
# private include directories | |
) | |
set (PUBLIC_HEADER_DIRS | |
# public include directories | |
) | |
set (PRIVATE_HEADERS | |
# private include files | |
) | |
set (PUBLIC_HEADERS | |
# public include files | |
) | |
set (SOURCES | |
# source files (c, cpp, mm) | |
) | |
set (RESOURCES | |
# qrc files | |
) | |
set (UIS | |
# ui files | |
) | |
# Create library | |
add_library (${PROJECT_NAME} SHARED | |
${PUBLIC_HEADERS} # needed for set_target_properties to work for framework | |
${PRIVATE_HEADERS} # needed for set_target_properties to work for framework | |
${SOURCES} | |
${RESOURCES} | |
${UIS} | |
) | |
# Find Qt targets for modules and plugins | |
# Note: Missing more things? | |
# Should be fixed in 5.14: https://bugreports.qt.io/browse/QTBUG-38913 | |
set (QT5_TARGETS "") | |
foreach (QT5_MODULE ${QT5_MODULES}) | |
set (QT5_TARGET Qt5::${QT5_MODULE}) | |
list (APPEND QT5_TARGETS ${QT5_TARGET}) | |
set (QT5_MODULE_PLUGINS ${Qt5${QT5_MODULE}_PLUGINS}) | |
if (QT5_MODULE_PLUGINS) | |
list(APPEND QT5_TARGETS ${QT5_MODULE_PLUGINS}) | |
endif() | |
endforeach() | |
# Link | |
target_link_libraries (${PROJECT_NAME} | |
PUBLIC | |
${QT5_TARGETS} | |
# other dependency targets | |
) | |
# Include directories | |
# Note: not needed if not exporting since we are already creating a framework? | |
target_include_directories (${PROJECT_NAME} | |
PRIVATE ${PRIVATE_HEADER_DIRS} | |
PUBLIC ${PUBLIC_HEADER_DIRS} | |
) | |
# Add BITCODE for other generators than Xcode | |
# Note: Does not seem to last in install tree | |
target_compile_options(${PROJECT_NAME} | |
PUBLIC | |
"-fembed-bitcode" | |
) | |
# Framework | |
set_target_properties (${PROJECT_NAME} PROPERTIES | |
FRAMEWORK TRUE | |
INSTALL_NAME_DIR "@rpath" # Note: did not seem to work with MACOSX_RPATH TRUE instead. Needed to embed the framework in an iOS app | |
# BUILD_WITH_INSTALL_NAME_DIR TRUE # Needed to set install_name to @rpath in build tree also | |
PRIVATE_HEADER "${PRIVATE_HEADERS}" # Needed for set_target_properties to work for framework | |
PUBLIC_HEADER "${PUBLIC_HEADERS}" # Needed for set_target_properties to work for framework | |
MACOSX_FRAMEWORK_IDENTIFIER "com.your-organization.${PROJECT_NAME}" #CFBundleIdentifier | |
MACOSX_FRAMEWORK_SHORT_VERSION_STRING "${PROJECT_VERSION}" #CFBundleShortVersionString | |
#MACOSX_FRAMEWORK_BUNDLE_VERSION B001 #CFBundleVersion | |
#XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "iPhone Developer" | |
) | |
# Install | |
install (TARGETS ${PROJECT_NAME} | |
FRAMEWORK DESTINATION . # relative to CMAKE_INSTALL_PREFIX | |
PRIVATE_HEADER | |
PUBLIC_HEADER | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Using:
This CMake config file manages to create a framework with headers, and a shared library (foo) with a proper
@rpath
in its install name. That framework can then be embedded in an iOS app directly in XCode successfully.However, there are a couple of issues left with using Qt5 ios static libraries:
Remaining issues
1. Missing Qt platform plugin "ios" (and others plugins?)
Even though the foo library and the iOS App build fine, the current configuration without any additional code will trigger the following error message at runtime when the app loads the foo library:
This is because the ios static plugin is not imported, which can be done by adding
Q_IMPORT_PLUGIN(QIOSIntegrationPlugin)
in code within the foo library.Doing this triggers the next issue, so it's uncertain if this is enough to fix it. Also, there are probably more plugins that need to be loaded after that.
2. Linking issues against static Qt5 libs
2.1. Missing plugins
Adding
Q_IMPORT_PLUGIN
for the ios plugin caused the foo library build to fail at link time when only linking against the qt5 module targets and not linking against the qt5 plugin targets:Analyzing the linker showed that the foo library is not linking against
libqios.a
, which is located in/ios/plugins/platforms/
of the Qt5 install directory. A look at the content of/ios/lib/cmake/Qt5Gui
shows thatQt5Gui_QIOSIntegrationPlugin.cmake
defines a CMake targetQt5::QIOSIntegrationPlugin
, that is stored in a CMake variableQt5Gui_PLUGINS
. This is the same template for all plugins of every module, so we should be able to retrieve all the needed Qt5 targets (modules and plugins) with this:This properly add the ios plugin static library to the linker command, as well as all the other plugins (too many?) from the linked qt5 modules. However, this leads to the following linker errors:
2.2. Missing frameworks and libs
Those symbols are from:
QuartzCore
framework for the_OBJC_CLASS_
symbolsQt5FontDatabaseSupport
library for theQCoreTextFontDatabase
symbolsQt5GraphicsSupport
library for theQRasterBackingStore
symbolsQt5ClipboardSupport
library for theQMacInternalPasteboardMime
symbolsImageIO
framework for the_CGImage
symbols (after addingQt5ClipboardSupport
)AudioToolbox
framework for the_AudioServicesPlayAlertSound
symbolAdding
-framework <FrameworkName>
as well as the qt5 libraries (manually) to foo'starget_link_libraries
resolved most of them, but then leads to the latest error:2.3. Missing frameworks and libs
The "_main" symbol is required for this library. This was brought up here also and saying it just was not supported.
Alexandru Croitor (Qt) provided this explanation:
However, this would work maybe when linking against an executable (with a loader), but it would not work for the shared library, to what Alexandru answered:
Aka: creating a shared library that links against qt5 static libraries is simply not supported at the moment.