CMakeProjectManager: Support for multi-config generators

CMake has multi-config generators like:

  * Visual Studio
  * Xcode
  * Ninja Multi-Config

The first two have different special targets for "all", "install",
"package", "test" namely: "ALL_BUILD", "INSTALL", "PACKAGE",
"RUN_TESTS".

All of them need to get the build type passed via "--config <build-
type>" and not via "CMAKE_BUILD_TYPE".

The multi-config generators will use only one build directory.

Fixes: QTCREATORBUG-24984
Change-Id: I8aa7ff73ce2af1e163b21a6504d26fcf95530edf
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
Cristian Adam
2021-01-14 16:38:55 +01:00
parent f3d7717b31
commit 6cbdae8070
22 changed files with 238 additions and 140 deletions

View File

@@ -142,6 +142,7 @@ static ReplyFileContents readReplyFile(const QFileInfo &fi, QString &errorMessag
const QJsonObject generator = cmakeObject.value("generator").toObject();
{
result.generator = generator.value("name").toString();
result.isMultiConfig = generator.value("multiConfig").toBool();
}
}
}
@@ -855,23 +856,22 @@ bool FileApiParser::setupCMakeFileApi(const FilePath &buildDirectory, Utils::Fil
return true;
}
static QStringList uniqueTargetFiles(const std::vector<Configuration> &configs)
static QStringList uniqueTargetFiles(const Configuration &config)
{
QSet<QString> knownIds;
QStringList files;
for (const Configuration &config : configs) {
for (const Target &t : config.targets) {
const int knownCount = knownIds.count();
knownIds.insert(t.id);
if (knownIds.count() > knownCount) {
files.append(t.jsonFile);
}
for (const Target &t : config.targets) {
const int knownCount = knownIds.count();
knownIds.insert(t.id);
if (knownIds.count() > knownCount) {
files.append(t.jsonFile);
}
}
return files;
}
FileApiData FileApiParser::parseData(const QFileInfo &replyFileInfo, QString &errorMessage)
FileApiData FileApiParser::parseData(const QFileInfo &replyFileInfo, const QString &cmakeBuildType,
QString &errorMessage)
{
QTC_CHECK(errorMessage.isEmpty());
const QDir replyDir = replyFileInfo.dir();
@@ -882,9 +882,24 @@ FileApiData FileApiParser::parseData(const QFileInfo &replyFileInfo, QString &er
result.cache = readCacheFile(result.replyFile.jsonFile("cache", replyDir), errorMessage);
result.cmakeFiles = readCMakeFilesFile(result.replyFile.jsonFile("cmakeFiles", replyDir),
errorMessage);
result.codemodel = readCodemodelFile(result.replyFile.jsonFile("codemodel", replyDir),
auto codeModels = readCodemodelFile(result.replyFile.jsonFile("codemodel", replyDir),
errorMessage);
if (codeModels.size() == 0) {
errorMessage = "No CMake configuration found!";
qWarning() << errorMessage;
return result;
}
auto it = std::find_if(codeModels.cbegin(), codeModels.cend(),
[cmakeBuildType](const Configuration& cfg) { return cfg.name == cmakeBuildType; });
if (it == codeModels.cend()) {
errorMessage = QString("No '%1' CMake configuration found!").arg(cmakeBuildType);
qWarning() << errorMessage;
return result;
}
result.codemodel = std::move(*it);
const QStringList targetFiles = uniqueTargetFiles(result.codemodel);
for (const QString &targetFile : targetFiles) {