CMake: Avoid needless cmake runs after kit changes

Do not run cmake if the kit has changed in ways that
do not effect cmake. Do clean rebuilds for changes to the generator
or cmake tool, etc. which do not work without that.

Change-Id: I4e9d43c5161246c3ded7f784cb0d44c3bd4b04e9
Reviewed-by: Alexander Drozdov <adrozdoff@gmail.com>
Reviewed-by: Tim Jenssen <tim.jenssen@theqtcompany.com>
This commit is contained in:
Tobias Hunger
2016-03-10 17:34:47 +01:00
parent 99a884051f
commit 38a051b6a4
3 changed files with 61 additions and 1 deletions

View File

@@ -595,5 +595,58 @@ CMakeConfig BuildDirManager::parseConfiguration(const Utils::FileName &cacheFile
return result; return result;
} }
void BuildDirManager::maybeForceReparse()
{
const QByteArray GENERATOR_KEY = "CMAKE_GENERATOR";
const QByteArray EXTRA_GENERATOR_KEY = "CMAKE_EXTRA_GENERATOR";
const QByteArray CMAKE_COMMAND_KEY = "CMAKE_COMMAND";
if (!m_hasData)
return;
const CMakeConfig currentConfig = parsedConfiguration();
const QString kitGenerator = CMakeGeneratorKitInformation::generator(kit());
int pos = kitGenerator.lastIndexOf(QLatin1String(" - "));
const QString extraKitGenerator = (pos > 0) ? kitGenerator.left(pos) : QString();
const QString mainKitGenerator = (pos > 0) ? kitGenerator.mid(pos + 3) : kitGenerator;
CMakeConfig targetConfig = m_buildConfiguration->cmakeConfiguration();
targetConfig.append(CMakeConfigItem(GENERATOR_KEY, CMakeConfigItem::INTERNAL,
QByteArray(), mainKitGenerator.toUtf8()));
if (!extraKitGenerator.isEmpty())
targetConfig.append(CMakeConfigItem(EXTRA_GENERATOR_KEY, CMakeConfigItem::INTERNAL,
QByteArray(), extraKitGenerator.toUtf8()));
const CMakeTool *tool = CMakeKitInformation::cmakeTool(kit());
if (tool)
targetConfig.append(CMakeConfigItem(CMAKE_COMMAND_KEY, CMakeConfigItem::INTERNAL,
QByteArray(), tool->cmakeExecutable().toUserOutput().toUtf8()));
Utils::sort(targetConfig, CMakeConfigItem::sortOperator());
auto ccit = currentConfig.constBegin();
auto kcit = targetConfig.constBegin();
while (ccit != currentConfig.constEnd() && kcit != targetConfig.constEnd()) {
if (ccit->key == kcit->key) {
if (ccit->value != kcit->value)
break;
++ccit;
++kcit;
} else {
if (ccit->key < kcit->key)
++ccit;
else
break;
}
}
if (kcit != targetConfig.end()) {
if (kcit->key == GENERATOR_KEY
|| kcit->key == EXTRA_GENERATOR_KEY
|| kcit->key == CMAKE_COMMAND_KEY)
clearCache();
else
forceReparse();
}
}
} // namespace Internal } // namespace Internal
} // namespace CMakeProjectManager } // namespace CMakeProjectManager

View File

@@ -77,6 +77,7 @@ public:
void parse(); void parse();
void clearCache(); void clearCache();
void forceReparse(); void forceReparse();
void maybeForceReparse(); // Only reparse if the configuration has changed...
void resetData(); void resetData();
bool persistCMakeState(); bool persistCMakeState();

View File

@@ -80,7 +80,13 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(ProjectExplorer::Target *parent
m_buildDirManager, &BuildDirManager::forceReparse); m_buildDirManager, &BuildDirManager::forceReparse);
connect(this, &CMakeBuildConfiguration::buildDirectoryChanged, connect(this, &CMakeBuildConfiguration::buildDirectoryChanged,
m_buildDirManager, &BuildDirManager::forceReparse); m_buildDirManager, &BuildDirManager::forceReparse);
connect(target(), &Target::kitChanged, m_buildDirManager, &BuildDirManager::forceReparse); connect(target(), &Target::kitChanged, this, [this]() {
ProjectExplorer::Kit *k = target()->kit();
CMakeConfig config = cmakeConfiguration();
config.append(CMakeConfigurationKitInformation::configuration(k)); // last value wins...
setCMakeConfiguration(config);
m_buildDirManager->maybeForceReparse();
});
connect(this, &CMakeBuildConfiguration::parsingStarted, project, &CMakeProject::handleParsingStarted); connect(this, &CMakeBuildConfiguration::parsingStarted, project, &CMakeProject::handleParsingStarted);
connect(this, &CMakeBuildConfiguration::dataAvailable, project, &CMakeProject::parseCMakeOutput); connect(this, &CMakeBuildConfiguration::dataAvailable, project, &CMakeProject::parseCMakeOutput);