From b47a80c5ce2a12c94f02fd3eef97ed5d791a98f9 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 2 Feb 2021 16:10:45 +0100 Subject: [PATCH] CMake/iOS: Set up CMake configuration For Qt6/iOS we need to use the Xcode generator, and set CMAKE_OSX_SYSROOT, CMAKE_OSX_ARCHITECTURES, and the Qt toolchain file with CMAKE_TOOLCHAIN_FILE. We also may not automatically add the CMAKE_SYSROOT and CMAKE_C(XX)_COMPILER_TARGET variables, since this is handled differently for iOS targets. With this building, running and debugging on the simulator works, if the CMake project correctly sets up a MACOSX_BUNDLE_GUI_IDENTIFIER, MACOSX_BUNDLE_BUNDLE_VERSION, MACOSX_BUNDLE_SHORT_VERSION_STRING and MACOSX_BUNDLE_LONG_VERSION_STRING. For the device build the signing and provisioning details are still missing. Task-number: QTCREATORBUG-23574 Change-Id: I12be0d102b57d834d7cae06c87842638f693c087 Reviewed-by: Cristian Adam --- .../cmakebuildconfiguration.cpp | 51 +++++++++++++++---- .../cmakekitinformation.cpp | 15 +++++- 2 files changed, 55 insertions(+), 11 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp index d9496fad466..aab4fb9f5bf 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp @@ -32,6 +32,7 @@ #include "cmakeprojectconstants.h" #include +#include #include #include #include @@ -67,6 +68,13 @@ const char CONFIGURATION_KEY[] = "CMake.Configuration"; // Helper: // ----------------------------------------------------------------------------- +static bool isIos(const Kit *k) +{ + const Id deviceType = DeviceTypeKitAspect::deviceTypeId(k); + return deviceType == Ios::Constants::IOS_DEVICE_TYPE + || deviceType == Ios::Constants::IOS_SIMULATOR_TYPE; +} + static QStringList defaultInitialCMakeArguments(const Kit *k, const QString buildType) { // Generator: @@ -78,15 +86,17 @@ static QStringList defaultInitialCMakeArguments(const Kit *k, const QString buil } // Cross-compilation settings: - const QString sysRoot = SysRootKitAspect::sysRoot(k).toString(); - if (!sysRoot.isEmpty()) { - initialArgs.append(QString::fromLatin1("-DCMAKE_SYSROOT:PATH=%1").arg(sysRoot)); - if (ToolChain *tc = ToolChainKitAspect::cxxToolChain(k)) { - const QString targetTriple = tc->originalTargetTriple(); - initialArgs.append( - QString::fromLatin1("-DCMAKE_C_COMPILER_TARGET:STRING=%1").arg(targetTriple)); - initialArgs.append( - QString::fromLatin1("-DCMAKE_CXX_COMPILER_TARGET:STRING=%1").arg(targetTriple)); + if (!isIos(k)) { // iOS handles this differently + const QString sysRoot = SysRootKitAspect::sysRoot(k).toString(); + if (!sysRoot.isEmpty()) { + initialArgs.append(QString::fromLatin1("-DCMAKE_SYSROOT:PATH=%1").arg(sysRoot)); + if (ToolChain *tc = ToolChainKitAspect::cxxToolChain(k)) { + const QString targetTriple = tc->originalTargetTriple(); + initialArgs.append( + QString::fromLatin1("-DCMAKE_C_COMPILER_TARGET:STRING=%1").arg(targetTriple)); + initialArgs.append( + QString::fromLatin1("-DCMAKE_CXX_COMPILER_TARGET:STRING=%1").arg(targetTriple)); + } } } @@ -187,6 +197,29 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(Target *target, Utils::Id id) } } + if (isIos(k)) { + QtSupport::BaseQtVersion *qt = QtSupport::QtKitAspect::qtVersion(k); + if (qt && qt->qtVersion().majorVersion >= 6) { + // TODO it would be better if we could set + // CMAKE_SYSTEM_NAME=iOS and CMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH=YES + // and build with "cmake --build . -- -arch " instead of setting the architecture + // and sysroot in the CMake configuration, but that currently doesn't work with Qt/CMake + // https://gitlab.kitware.com/cmake/cmake/-/issues/21276 + const Id deviceType = DeviceTypeKitAspect::deviceTypeId(k); + // TODO the architectures are probably not correct with Apple Silicon in the mix... + const QString architecture = deviceType == Ios::Constants::IOS_DEVICE_TYPE + ? QLatin1String("arm64") + : QLatin1String("x86_64"); + const QString sysroot = deviceType == Ios::Constants::IOS_DEVICE_TYPE + ? QLatin1String("iphoneos") + : QLatin1String("iphonesimulator"); + initialArgs.append("-DCMAKE_TOOLCHAIN_FILE:PATH=%{Qt:QT_INSTALL_PREFIX}/lib/cmake/" + "Qt6/qt.toolchain.cmake"); + initialArgs.append("-DCMAKE_OSX_ARCHITECTURES:STRING=" + architecture); + initialArgs.append("-DCMAKE_OSX_SYSROOT:STRING=" + sysroot); + } + } + if (info.buildDirectory.isEmpty()) { setBuildDirectory(shadowBuildDirectory(target->project()->projectFilePath(), k, diff --git a/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp b/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp index eff5367ab39..1a338af1a39 100644 --- a/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp +++ b/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp @@ -32,14 +32,15 @@ #include "cmaketoolmanager.h" #include +#include #include #include +#include #include #include #include #include #include -#include #include @@ -66,6 +67,13 @@ namespace CMakeProjectManager { // CMakeKitAspect: // -------------------------------------------------------------------- +static bool isIos(const Kit *k) +{ + const Utils::Id deviceType = DeviceTypeKitAspect::deviceTypeId(k); + return deviceType == Ios::Constants::IOS_DEVICE_TYPE + || deviceType == Ios::Constants::IOS_SIMULATOR_TYPE; +} + static Utils::Id defaultCMakeToolId() { CMakeTool *defaultTool = CMakeToolManager::defaultCMakeTool(); @@ -635,6 +643,9 @@ QVariant CMakeGeneratorKitAspect::defaultValue(const Kit *k) const if (!tool) return QVariant(); + if (isIos(k)) + return GeneratorInfo("Xcode").toVariant(); + const QList known = tool->supportedGenerators(); auto it = std::find_if(known.constBegin(), known.constEnd(), [](const CMakeTool::Generator &g) { return g.matches("Ninja"); @@ -765,7 +776,7 @@ void CMakeGeneratorKitAspect::fix(Kit *k) dv.fromVariant(defaultValue(k)); setGeneratorInfo(k, dv); } else { - const GeneratorInfo dv(info.generator, + const GeneratorInfo dv(isIos(k) ? QString("Xcode") : info.generator, info.extraGenerator, it->supportsPlatform ? info.platform : QString(), it->supportsToolset ? info.toolset : QString());