forked from qt-creator/qt-creator
iOS/CMake: Fix running non-Xcode targets and targets in subdirectories
Improve support for running iOS bundle built with CMake introduced in
3a294f670d
.
Currently it supports only Xcode generator and does not work if target is
created in a subdirectory.
This patch adds support for non-Xcode generators (tested with Ninja) and
targets created in a subdirectories with any generators.
The solution is not pretty due to the need to keep qmake compatibility.
Would be glad to refactor if there's more correct approach.
Change-Id: Ieaf7e3186ab55cadc643d9bd3d94442f9ac72228
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
@@ -156,8 +156,19 @@ QVariant CMakeTargetNode::data(Utils::Id role) const
|
|||||||
return m_artifact.fileName();
|
return m_artifact.fileName();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (role == Ios::Constants::IosBuildDir)
|
if (role == Ios::Constants::IosBuildDir) {
|
||||||
return {}; // defaults to build configuration build directory
|
// This is a path relative to root build directory.
|
||||||
|
// When generating Xcode project, CMake may put here a "${EFFECTIVE_PLATFORM_NAME}" macro,
|
||||||
|
// which is expanded by Xcode at build time.
|
||||||
|
// To get an actual executable path, iOS plugin replaces this macro with either "-iphoneos"
|
||||||
|
// or "-iphonesimulator" depending on the device type (which is unavailable here).
|
||||||
|
|
||||||
|
// dir/target.app/target -> dir
|
||||||
|
return m_artifact.parentDir().parentDir().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (role == Ios::Constants::IosCmakeGenerator)
|
||||||
|
return value("CMAKE_GENERATOR");
|
||||||
|
|
||||||
QTC_ASSERT(false, qDebug() << "Unknown role" << role.toString());
|
QTC_ASSERT(false, qDebug() << "Unknown role" << role.toString());
|
||||||
// Better guess than "not present".
|
// Better guess than "not present".
|
||||||
|
@@ -47,6 +47,7 @@ const char IOS_DEPLOY_STEP_ID[] = "Qt4ProjectManager.IosDeployStep";
|
|||||||
|
|
||||||
const char IosTarget[] = "IosTarget"; // QString
|
const char IosTarget[] = "IosTarget"; // QString
|
||||||
const char IosBuildDir[] = "IosBuildDir"; // QString
|
const char IosBuildDir[] = "IosBuildDir"; // QString
|
||||||
|
const char IosCmakeGenerator[] = "IosCmakeGenerator";
|
||||||
|
|
||||||
const quint16 IOS_DEVICE_PORT_START = 30000;
|
const quint16 IOS_DEVICE_PORT_START = 30000;
|
||||||
const quint16 IOS_DEVICE_PORT_END = 31000;
|
const quint16 IOS_DEVICE_PORT_END = 31000;
|
||||||
|
@@ -169,12 +169,66 @@ FilePath IosRunConfiguration::bundleDirectory() const
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
FilePath res;
|
FilePath res;
|
||||||
|
bool shouldAppendBuildTypeAndPlatform = true;
|
||||||
if (BuildConfiguration *bc = target()->activeBuildConfiguration()) {
|
if (BuildConfiguration *bc = target()->activeBuildConfiguration()) {
|
||||||
Project *project = target()->project();
|
Project *project = target()->project();
|
||||||
if (ProjectNode *node = project->findNodeForBuildKey(buildKey()))
|
if (ProjectNode *node = project->findNodeForBuildKey(buildKey())) {
|
||||||
res = FilePath::fromString(node->data(Constants::IosBuildDir).toString());
|
QString pathStr = node->data(Constants::IosBuildDir).toString();
|
||||||
if (res.isEmpty())
|
const QString cmakeGenerator = node->data(Constants::IosCmakeGenerator).toString();
|
||||||
|
|
||||||
|
if (cmakeGenerator.isEmpty()) {
|
||||||
|
// qmake node gives absolute IosBuildDir
|
||||||
|
res = FilePath::fromString(pathStr);
|
||||||
|
} else {
|
||||||
|
// CMake node gives IosBuildDir relative to root build directory
|
||||||
|
|
||||||
|
bool useCmakePath = true;
|
||||||
|
|
||||||
|
if (pathStr.isEmpty())
|
||||||
|
useCmakePath = false;
|
||||||
|
|
||||||
|
if (useCmakePath && cmakeGenerator == "Xcode") {
|
||||||
|
// When generating Xcode project, CMake may put a "${EFFECTIVE_PLATFORM_NAME}" macro,
|
||||||
|
// which is expanded by Xcode at build time.
|
||||||
|
// To get an actual executable path at configure time, replace this macro here
|
||||||
|
// depending on the device type.
|
||||||
|
|
||||||
|
const QString before = "${EFFECTIVE_PLATFORM_NAME}";
|
||||||
|
|
||||||
|
int idx = pathStr.indexOf(before);
|
||||||
|
|
||||||
|
if (idx == -1) {
|
||||||
|
useCmakePath = false;
|
||||||
|
} else {
|
||||||
|
QString after;
|
||||||
|
if (isDevice)
|
||||||
|
after = "-iphoneos";
|
||||||
|
else
|
||||||
|
after = "-iphonesimulator";
|
||||||
|
|
||||||
|
pathStr.replace(idx, before.length(), after);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (useCmakePath) {
|
||||||
|
// With Ninja generator IosBuildDir may be just "." when executable is in the root directory,
|
||||||
|
// so use canonical path to ensure that redundand dot is removed.
|
||||||
|
res = bc->buildDirectory().pathAppended(pathStr).canonicalPath();
|
||||||
|
// All done with path provided by CMake
|
||||||
|
shouldAppendBuildTypeAndPlatform = false;
|
||||||
|
} else {
|
||||||
res = bc->buildDirectory();
|
res = bc->buildDirectory();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res.isEmpty()) {
|
||||||
|
// Fallback
|
||||||
|
res = bc->buildDirectory();
|
||||||
|
shouldAppendBuildTypeAndPlatform = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldAppendBuildTypeAndPlatform) {
|
||||||
switch (bc->buildType()) {
|
switch (bc->buildType()) {
|
||||||
case BuildConfiguration::Debug :
|
case BuildConfiguration::Debug :
|
||||||
case BuildConfiguration::Unknown :
|
case BuildConfiguration::Unknown :
|
||||||
@@ -195,6 +249,7 @@ FilePath IosRunConfiguration::bundleDirectory() const
|
|||||||
<< target()->activeBuildConfiguration()->buildType();
|
<< target()->activeBuildConfiguration()->buildType();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return res.pathAppended(applicationName() + ".app");
|
return res.pathAppended(applicationName() + ".app");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -409,6 +409,11 @@ QVariant QmakeProFileNode::data(Utils::Id role) const
|
|||||||
return info.buildDir.toString();
|
return info.buildDir.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (role == Ios::Constants::IosCmakeGenerator) {
|
||||||
|
// qmake is not CMake, so return empty value
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
if (role == ProjectExplorer::Constants::QT_KEYWORDS_ENABLED)
|
if (role == ProjectExplorer::Constants::QT_KEYWORDS_ENABLED)
|
||||||
return !proFile()->variableValue(Variable::Config).contains("no_keywords");
|
return !proFile()->variableValue(Variable::Config).contains("no_keywords");
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user