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();
|
||||
}
|
||||
|
||||
if (role == Ios::Constants::IosBuildDir)
|
||||
return {}; // defaults to build configuration build directory
|
||||
if (role == Ios::Constants::IosBuildDir) {
|
||||
// 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());
|
||||
// Better guess than "not present".
|
||||
|
@@ -47,6 +47,7 @@ const char IOS_DEPLOY_STEP_ID[] = "Qt4ProjectManager.IosDeployStep";
|
||||
|
||||
const char IosTarget[] = "IosTarget"; // QString
|
||||
const char IosBuildDir[] = "IosBuildDir"; // QString
|
||||
const char IosCmakeGenerator[] = "IosCmakeGenerator";
|
||||
|
||||
const quint16 IOS_DEVICE_PORT_START = 30000;
|
||||
const quint16 IOS_DEVICE_PORT_END = 31000;
|
||||
|
@@ -169,12 +169,66 @@ FilePath IosRunConfiguration::bundleDirectory() const
|
||||
return {};
|
||||
}
|
||||
FilePath res;
|
||||
bool shouldAppendBuildTypeAndPlatform = true;
|
||||
if (BuildConfiguration *bc = target()->activeBuildConfiguration()) {
|
||||
Project *project = target()->project();
|
||||
if (ProjectNode *node = project->findNodeForBuildKey(buildKey()))
|
||||
res = FilePath::fromString(node->data(Constants::IosBuildDir).toString());
|
||||
if (res.isEmpty())
|
||||
if (ProjectNode *node = project->findNodeForBuildKey(buildKey())) {
|
||||
QString pathStr = node->data(Constants::IosBuildDir).toString();
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (res.isEmpty()) {
|
||||
// Fallback
|
||||
res = bc->buildDirectory();
|
||||
shouldAppendBuildTypeAndPlatform = true;
|
||||
}
|
||||
|
||||
if (shouldAppendBuildTypeAndPlatform) {
|
||||
switch (bc->buildType()) {
|
||||
case BuildConfiguration::Debug :
|
||||
case BuildConfiguration::Unknown :
|
||||
@@ -195,6 +249,7 @@ FilePath IosRunConfiguration::bundleDirectory() const
|
||||
<< target()->activeBuildConfiguration()->buildType();
|
||||
}
|
||||
}
|
||||
}
|
||||
return res.pathAppended(applicationName() + ".app");
|
||||
}
|
||||
|
||||
|
@@ -409,6 +409,11 @@ QVariant QmakeProFileNode::data(Utils::Id role) const
|
||||
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)
|
||||
return !proFile()->variableValue(Variable::Config).contains("no_keywords");
|
||||
|
||||
|
Reference in New Issue
Block a user