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 <cristian.adam@qt.io>
This commit is contained in:
Eike Ziller
2021-02-02 16:10:45 +01:00
parent f626e27370
commit b47a80c5ce
2 changed files with 55 additions and 11 deletions

View File

@@ -32,6 +32,7 @@
#include "cmakeprojectconstants.h"
#include <android/androidconstants.h>
#include <ios/iosconstants.h>
#include <projectexplorer/buildaspects.h>
#include <projectexplorer/buildinfo.h>
#include <projectexplorer/buildmanager.h>
@@ -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 <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,

View File

@@ -32,14 +32,15 @@
#include "cmaketoolmanager.h"
#include <coreplugin/icore.h>
#include <ios/iosconstants.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/projectexplorersettings.h>
#include <projectexplorer/task.h>
#include <projectexplorer/toolchain.h>
#include <qtsupport/baseqtversion.h>
#include <qtsupport/qtkitinformation.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <app/app_version.h>
@@ -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<CMakeTool::Generator> 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());