forked from qt-creator/qt-creator
apply a build pass to retrieve all project variables
so far, we used a build pass only to retrieve accurate target information from the exact evaluator. however, this is insufficient for at least two reasons: - the recently introduced postprocessing of RESOURCES in resources.prf is executed only during build passes - some relevant variables are build pass specific, for example INCLUDEPATH when it includes RCC_DIR an additional upside is that using the build pass' values is consistent with qmake's vcxproj generation mode. on the downside, the extra cumulative build pass adds 33% of pure project evaluation time. however, this isn't as bad, as the pro files are already loaded and parsed, and the expensive source file resolution moves completely to the build pass. the alternative of defeating the build pass logic (as lupdate does) is not feasible, as we rely on accurate target information from an actual build pass for the run configurations. note that this all applies only to windows (and macos when explicitly configured with -debug-and-release). Task-number: QTCREATORBUG-16019 Change-Id: I8a97856b3b738aa1a581d24ba24bb3e7199d8078 Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
This commit is contained in:
@@ -1794,13 +1794,50 @@ void QmakeProFileNode::setupReader()
|
|||||||
m_readerCumulative->setCumulative(true);
|
m_readerCumulative->setCumulative(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QmakeProFileNode::evaluateOne(
|
||||||
|
const EvalInput &input, ProFile *pro, QtSupport::ProFileReader *reader,
|
||||||
|
QtSupport::ProFileReader **buildPassReader)
|
||||||
|
{
|
||||||
|
if (!reader->accept(pro, QMakeEvaluator::LoadAll))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
QStringList builds = reader->values(QLatin1String("BUILDS"));
|
||||||
|
if (builds.isEmpty()) {
|
||||||
|
*buildPassReader = reader;
|
||||||
|
} else {
|
||||||
|
QString build = builds.first();
|
||||||
|
QHash<QString, QStringList> basevars;
|
||||||
|
QStringList basecfgs = reader->values(build + QLatin1String(".CONFIG"));
|
||||||
|
basecfgs += build;
|
||||||
|
basecfgs += QLatin1String("build_pass");
|
||||||
|
basevars[QLatin1String("BUILD_PASS")] = QStringList(build);
|
||||||
|
QStringList buildname = reader->values(build + QLatin1String(".name"));
|
||||||
|
basevars[QLatin1String("BUILD_NAME")] = (buildname.isEmpty() ? QStringList(build) : buildname);
|
||||||
|
|
||||||
|
// We don't increase/decrease m_qmakeGlobalsRefCnt here, because the outer profilereaders keep m_qmakeGlobals alive anyway
|
||||||
|
auto bpReader = new QtSupport::ProFileReader(input.qmakeGlobals, input.qmakeVfs); // needs to access m_qmakeGlobals, m_qmakeVfs
|
||||||
|
bpReader->setOutputDir(input.buildDirectory);
|
||||||
|
bpReader->setExtraVars(basevars);
|
||||||
|
bpReader->setExtraConfigs(basecfgs);
|
||||||
|
|
||||||
|
if (bpReader->accept(pro, QMakeEvaluator::LoadAll))
|
||||||
|
*buildPassReader = bpReader;
|
||||||
|
else
|
||||||
|
delete bpReader;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
EvalResult *QmakeProFileNode::evaluate(const EvalInput &input)
|
EvalResult *QmakeProFileNode::evaluate(const EvalInput &input)
|
||||||
{
|
{
|
||||||
EvalResult *result = new EvalResult;
|
EvalResult *result = new EvalResult;
|
||||||
|
QtSupport::ProFileReader *exactBuildPassReader = nullptr;
|
||||||
|
QtSupport::ProFileReader *cumulativeBuildPassReader = nullptr;
|
||||||
ProFile *pro;
|
ProFile *pro;
|
||||||
if ((pro = input.readerExact->parsedProFile(input.projectFilePath.toString()))) {
|
if ((pro = input.readerExact->parsedProFile(input.projectFilePath.toString()))) {
|
||||||
bool exactOk = input.readerExact->accept(pro, QMakeEvaluator::LoadAll);
|
bool exactOk = evaluateOne(input, pro, input.readerExact, &exactBuildPassReader);
|
||||||
bool cumulOk = input.readerCumulative->accept(pro, QMakeEvaluator::LoadPreFiles);
|
bool cumulOk = evaluateOne(input, pro, input.readerCumulative, &cumulativeBuildPassReader);
|
||||||
pro->deref();
|
pro->deref();
|
||||||
result->state = exactOk ? EvalResult::EvalOk : cumulOk ? EvalResult::EvalPartial : EvalResult::EvalFail;
|
result->state = exactOk ? EvalResult::EvalOk : cumulOk ? EvalResult::EvalPartial : EvalResult::EvalFail;
|
||||||
} else {
|
} else {
|
||||||
@@ -1884,105 +1921,70 @@ EvalResult *QmakeProFileNode::evaluate(const EvalInput &input)
|
|||||||
toBuild.append(current->children.values());
|
toBuild.append(current->children.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto exactReader = exactBuildPassReader ? exactBuildPassReader : input.readerExact;
|
||||||
|
auto cumulativeReader = cumulativeBuildPassReader ? cumulativeBuildPassReader : input.readerCumulative;
|
||||||
|
|
||||||
if (result->state == EvalResult::EvalOk) {
|
if (result->state == EvalResult::EvalOk) {
|
||||||
// create build_pass reader
|
result->targetInformation = targetInformation(input.readerExact, exactBuildPassReader,
|
||||||
QtSupport::ProFileReader *readerBuildPass = 0;
|
|
||||||
QStringList builds = input.readerExact->values(QLatin1String("BUILDS"));
|
|
||||||
if (builds.isEmpty()) {
|
|
||||||
readerBuildPass = input.readerExact;
|
|
||||||
} else {
|
|
||||||
QString build = builds.first();
|
|
||||||
QHash<QString, QStringList> basevars;
|
|
||||||
QStringList basecfgs = input.readerExact->values(build + QLatin1String(".CONFIG"));
|
|
||||||
basecfgs += build;
|
|
||||||
basecfgs += QLatin1String("build_pass");
|
|
||||||
basevars[QLatin1String("BUILD_PASS")] = QStringList(build);
|
|
||||||
QStringList buildname = input.readerExact->values(build + QLatin1String(".name"));
|
|
||||||
basevars[QLatin1String("BUILD_NAME")] = (buildname.isEmpty() ? QStringList(build) : buildname);
|
|
||||||
|
|
||||||
// We don't increase/decrease m_qmakeGlobalsRefCnt here, because the outer profilereaders keep m_qmakeGlobals alive anyway
|
|
||||||
readerBuildPass = new QtSupport::ProFileReader(input.qmakeGlobals, input.qmakeVfs); // needs to access m_qmakeGlobals, m_qmakeVfs
|
|
||||||
readerBuildPass->setOutputDir(input.buildDirectory);
|
|
||||||
readerBuildPass->setExtraVars(basevars);
|
|
||||||
readerBuildPass->setExtraConfigs(basecfgs);
|
|
||||||
|
|
||||||
EvalResult::EvalResultState evalResultBuildPass = EvalResult::EvalOk;
|
|
||||||
if (ProFile *pro = readerBuildPass->parsedProFile(input.projectFilePath.toString())) {
|
|
||||||
if (!readerBuildPass->accept(pro, QMakeEvaluator::LoadAll))
|
|
||||||
evalResultBuildPass = EvalResult::EvalPartial;
|
|
||||||
pro->deref();
|
|
||||||
} else {
|
|
||||||
evalResultBuildPass = EvalResult::EvalFail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (evalResultBuildPass != EvalResult::EvalOk) {
|
|
||||||
delete readerBuildPass;
|
|
||||||
readerBuildPass = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result->targetInformation = targetInformation(input.readerExact, readerBuildPass,
|
|
||||||
input.buildDirectory, input.projectFilePath.toString());
|
input.buildDirectory, input.projectFilePath.toString());
|
||||||
result->installsList = installsList(readerBuildPass, input.projectFilePath.toString(),
|
result->installsList = installsList(exactBuildPassReader, input.projectFilePath.toString(),
|
||||||
input.projectDir, input.buildDirectory);
|
input.projectDir, input.buildDirectory);
|
||||||
|
|
||||||
// update other variables
|
// update other variables
|
||||||
result->newVarValues[DefinesVar] = input.readerExact->values(QLatin1String("DEFINES"));
|
result->newVarValues[DefinesVar] = exactReader->values(QLatin1String("DEFINES"));
|
||||||
result->newVarValues[IncludePathVar] = includePaths(input.readerExact, input.sysroot,
|
result->newVarValues[IncludePathVar] = includePaths(exactReader, input.sysroot,
|
||||||
input.buildDirectory, input.projectDir);
|
input.buildDirectory, input.projectDir);
|
||||||
result->newVarValues[CppFlagsVar] = input.readerExact->values(QLatin1String("QMAKE_CXXFLAGS"));
|
result->newVarValues[CppFlagsVar] = exactReader->values(QLatin1String("QMAKE_CXXFLAGS"));
|
||||||
result->newVarValues[SourceVar] =
|
result->newVarValues[SourceVar] =
|
||||||
fileListForVar(input.readerExact, input.readerCumulative,
|
fileListForVar(exactReader, cumulativeReader,
|
||||||
QLatin1String("SOURCES"), input.projectDir, input.buildDirectory) +
|
QLatin1String("SOURCES"), input.projectDir, input.buildDirectory) +
|
||||||
fileListForVar(input.readerExact, input.readerCumulative,
|
fileListForVar(exactReader, cumulativeReader,
|
||||||
QLatin1String("HEADERS"), input.projectDir, input.buildDirectory) +
|
QLatin1String("HEADERS"), input.projectDir, input.buildDirectory) +
|
||||||
fileListForVar(input.readerExact, input.readerCumulative,
|
fileListForVar(exactReader, cumulativeReader,
|
||||||
QLatin1String("OBJECTIVE_HEADERS"), input.projectDir, input.buildDirectory);
|
QLatin1String("OBJECTIVE_HEADERS"), input.projectDir, input.buildDirectory);
|
||||||
result->newVarValues[UiDirVar] = QStringList() << uiDirPath(input.readerExact, input.buildDirectory);
|
result->newVarValues[UiDirVar] = QStringList() << uiDirPath(exactReader, input.buildDirectory);
|
||||||
result->newVarValues[HeaderExtensionVar] = QStringList() << input.readerExact->value(QLatin1String("QMAKE_EXT_H"));
|
result->newVarValues[HeaderExtensionVar] = QStringList() << exactReader->value(QLatin1String("QMAKE_EXT_H"));
|
||||||
result->newVarValues[CppExtensionVar] = QStringList() << input.readerExact->value(QLatin1String("QMAKE_EXT_CPP"));
|
result->newVarValues[CppExtensionVar] = QStringList() << exactReader->value(QLatin1String("QMAKE_EXT_CPP"));
|
||||||
result->newVarValues[MocDirVar] = QStringList() << mocDirPath(input.readerExact, input.buildDirectory);
|
result->newVarValues[MocDirVar] = QStringList() << mocDirPath(exactReader, input.buildDirectory);
|
||||||
result->newVarValues[ExactResourceVar] = fileListForVar(input.readerExact, 0,
|
result->newVarValues[ExactResourceVar] = fileListForVar(exactReader, 0,
|
||||||
QLatin1String("RESOURCES"), input.projectDir, input.buildDirectory);
|
QLatin1String("RESOURCES"), input.projectDir, input.buildDirectory);
|
||||||
result->newVarValues[CumulativeResourceVar] = fileListForVar(input.readerCumulative, 0,
|
result->newVarValues[CumulativeResourceVar] = fileListForVar(cumulativeReader, 0,
|
||||||
QLatin1String("RESOURCES"), input.projectDir, input.buildDirectory);
|
QLatin1String("RESOURCES"), input.projectDir, input.buildDirectory);
|
||||||
result->newVarValues[PkgConfigVar] = input.readerExact->values(QLatin1String("PKGCONFIG"));
|
result->newVarValues[PkgConfigVar] = exactReader->values(QLatin1String("PKGCONFIG"));
|
||||||
result->newVarValues[PrecompiledHeaderVar] = input.readerExact->fixifiedValues(
|
result->newVarValues[PrecompiledHeaderVar] = exactReader->fixifiedValues(
|
||||||
QLatin1String("PRECOMPILED_HEADER"), input.projectDir, input.buildDirectory);
|
QLatin1String("PRECOMPILED_HEADER"), input.projectDir, input.buildDirectory);
|
||||||
result->newVarValues[LibDirectoriesVar] = libDirectories(input.readerExact);
|
result->newVarValues[LibDirectoriesVar] = libDirectories(exactReader);
|
||||||
result->newVarValues[ConfigVar] = input.readerExact->values(QLatin1String("CONFIG"));
|
result->newVarValues[ConfigVar] = exactReader->values(QLatin1String("CONFIG"));
|
||||||
result->newVarValues[QmlImportPathVar] = input.readerExact->absolutePathValues(
|
result->newVarValues[QmlImportPathVar] = exactReader->absolutePathValues(
|
||||||
QLatin1String("QML_IMPORT_PATH"), input.projectDir);
|
QLatin1String("QML_IMPORT_PATH"), input.projectDir);
|
||||||
result->newVarValues[QmlDesignerImportPathVar] = input.readerExact->absolutePathValues(
|
result->newVarValues[QmlDesignerImportPathVar] = exactReader->absolutePathValues(
|
||||||
QLatin1String("QML_DESIGNER_IMPORT_PATH"), input.projectDir);
|
QLatin1String("QML_DESIGNER_IMPORT_PATH"), input.projectDir);
|
||||||
result->newVarValues[Makefile] = input.readerExact->values(QLatin1String("MAKEFILE"));
|
result->newVarValues[Makefile] = exactReader->values(QLatin1String("MAKEFILE"));
|
||||||
result->newVarValues[QtVar] = input.readerExact->values(QLatin1String("QT"));
|
result->newVarValues[QtVar] = exactReader->values(QLatin1String("QT"));
|
||||||
result->newVarValues[ObjectExt] = input.readerExact->values(QLatin1String("QMAKE_EXT_OBJ"));
|
result->newVarValues[ObjectExt] = exactReader->values(QLatin1String("QMAKE_EXT_OBJ"));
|
||||||
result->newVarValues[ObjectsDir] = input.readerExact->values(QLatin1String("OBJECTS_DIR"));
|
result->newVarValues[ObjectsDir] = exactReader->values(QLatin1String("OBJECTS_DIR"));
|
||||||
result->newVarValues[VersionVar] = input.readerExact->values(QLatin1String("VERSION"));
|
result->newVarValues[VersionVar] = exactReader->values(QLatin1String("VERSION"));
|
||||||
result->newVarValues[TargetExtVar] = input.readerExact->values(QLatin1String("TARGET_EXT"));
|
result->newVarValues[TargetExtVar] = exactReader->values(QLatin1String("TARGET_EXT"));
|
||||||
result->newVarValues[TargetVersionExtVar]
|
result->newVarValues[TargetVersionExtVar]
|
||||||
= input.readerExact->values(QLatin1String("TARGET_VERSION_EXT"));
|
= exactReader->values(QLatin1String("TARGET_VERSION_EXT"));
|
||||||
result->newVarValues[StaticLibExtensionVar] = input.readerExact->values(QLatin1String("QMAKE_EXTENSION_STATICLIB"));
|
result->newVarValues[StaticLibExtensionVar] = exactReader->values(QLatin1String("QMAKE_EXTENSION_STATICLIB"));
|
||||||
result->newVarValues[ShLibExtensionVar] = input.readerExact->values(QLatin1String("QMAKE_EXTENSION_SHLIB"));
|
result->newVarValues[ShLibExtensionVar] = exactReader->values(QLatin1String("QMAKE_EXTENSION_SHLIB"));
|
||||||
result->newVarValues[AndroidArchVar] = input.readerExact->values(QLatin1String("ANDROID_TARGET_ARCH"));
|
result->newVarValues[AndroidArchVar] = exactReader->values(QLatin1String("ANDROID_TARGET_ARCH"));
|
||||||
result->newVarValues[AndroidDeploySettingsFile] = input.readerExact->values(QLatin1String("ANDROID_DEPLOYMENT_SETTINGS_FILE"));
|
result->newVarValues[AndroidDeploySettingsFile] = exactReader->values(QLatin1String("ANDROID_DEPLOYMENT_SETTINGS_FILE"));
|
||||||
result->newVarValues[AndroidPackageSourceDir] = input.readerExact->values(QLatin1String("ANDROID_PACKAGE_SOURCE_DIR"));
|
result->newVarValues[AndroidPackageSourceDir] = exactReader->values(QLatin1String("ANDROID_PACKAGE_SOURCE_DIR"));
|
||||||
result->newVarValues[AndroidExtraLibs] = input.readerExact->values(QLatin1String("ANDROID_EXTRA_LIBS"));
|
result->newVarValues[AndroidExtraLibs] = exactReader->values(QLatin1String("ANDROID_EXTRA_LIBS"));
|
||||||
result->newVarValues[IsoIconsVar] = input.readerExact->values(QLatin1String("ISO_ICONS"));
|
result->newVarValues[IsoIconsVar] = exactReader->values(QLatin1String("ISO_ICONS"));
|
||||||
result->newVarValues[QmakeProjectName] = input.readerExact->values(QLatin1String("QMAKE_PROJECT_NAME"));
|
result->newVarValues[QmakeProjectName] = exactReader->values(QLatin1String("QMAKE_PROJECT_NAME"));
|
||||||
result->newVarValues[QmakeCc] = input.readerExact->values("QMAKE_CC");
|
result->newVarValues[QmakeCc] = exactReader->values("QMAKE_CC");
|
||||||
result->newVarValues[QmakeCxx] = input.readerExact->values("QMAKE_CXX");
|
result->newVarValues[QmakeCxx] = exactReader->values("QMAKE_CXX");
|
||||||
|
|
||||||
if (readerBuildPass && readerBuildPass != input.readerExact)
|
|
||||||
delete readerBuildPass;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result->state == EvalResult::EvalOk || result->state == EvalResult::EvalPartial) {
|
if (result->state == EvalResult::EvalOk || result->state == EvalResult::EvalPartial) {
|
||||||
|
|
||||||
QList<QList<VariableAndVPathInformation>> variableAndVPathInformation;
|
QList<QList<VariableAndVPathInformation>> variableAndVPathInformation;
|
||||||
{ // Collect information on VPATHS and qmake variables
|
{ // Collect information on VPATHS and qmake variables
|
||||||
QStringList baseVPathsExact = baseVPaths(input.readerExact, input.projectDir, input.buildDirectory);
|
QStringList baseVPathsExact = baseVPaths(exactReader, input.projectDir, input.buildDirectory);
|
||||||
QStringList baseVPathsCumulative = baseVPaths(input.readerCumulative, input.projectDir, input.buildDirectory);
|
QStringList baseVPathsCumulative = baseVPaths(cumulativeReader, input.projectDir, input.buildDirectory);
|
||||||
|
|
||||||
const QVector<QmakeNodeStaticData::FileTypeData> &fileTypes = qmakeNodeStaticData()->fileTypeData;
|
const QVector<QmakeNodeStaticData::FileTypeData> &fileTypes = qmakeNodeStaticData()->fileTypeData;
|
||||||
|
|
||||||
@@ -1991,13 +1993,13 @@ EvalResult *QmakeProFileNode::evaluate(const EvalInput &input)
|
|||||||
FileType type = fileTypes.at(i).type;
|
FileType type = fileTypes.at(i).type;
|
||||||
|
|
||||||
QList<VariableAndVPathInformation> list;
|
QList<VariableAndVPathInformation> list;
|
||||||
QStringList qmakeVariables = varNames(type, input.readerExact);
|
QStringList qmakeVariables = varNames(type, exactReader);
|
||||||
list.reserve(qmakeVariables.size());
|
list.reserve(qmakeVariables.size());
|
||||||
foreach (const QString &qmakeVariable, qmakeVariables) {
|
foreach (const QString &qmakeVariable, qmakeVariables) {
|
||||||
VariableAndVPathInformation info;
|
VariableAndVPathInformation info;
|
||||||
info.variable = qmakeVariable;
|
info.variable = qmakeVariable;
|
||||||
info.vPathsExact = fullVPaths(baseVPathsExact, input.readerExact, qmakeVariable, input.projectDir);
|
info.vPathsExact = fullVPaths(baseVPathsExact, exactReader, qmakeVariable, input.projectDir);
|
||||||
info.vPathsCumulative = fullVPaths(baseVPathsCumulative, input.readerCumulative, qmakeVariable, input.projectDir);
|
info.vPathsCumulative = fullVPaths(baseVPathsCumulative, cumulativeReader, qmakeVariable, input.projectDir);
|
||||||
list.append(info);
|
list.append(info);
|
||||||
}
|
}
|
||||||
variableAndVPathInformation.append(list);
|
variableAndVPathInformation.append(list);
|
||||||
@@ -2014,6 +2016,11 @@ EvalResult *QmakeProFileNode::evaluate(const EvalInput &input)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (exactBuildPassReader && exactBuildPassReader != input.readerExact)
|
||||||
|
delete exactBuildPassReader;
|
||||||
|
if (cumulativeBuildPassReader && cumulativeBuildPassReader != input.readerCumulative)
|
||||||
|
delete cumulativeBuildPassReader;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -376,6 +376,7 @@ private:
|
|||||||
void setupReader();
|
void setupReader();
|
||||||
Internal::EvalInput evalInput() const;
|
Internal::EvalInput evalInput() const;
|
||||||
|
|
||||||
|
static bool evaluateOne(const Internal::EvalInput &input, ProFile *pro, QtSupport::ProFileReader *reader, QtSupport::ProFileReader **buildPassReader);
|
||||||
static Internal::EvalResult *evaluate(const Internal::EvalInput &input);
|
static Internal::EvalResult *evaluate(const Internal::EvalInput &input);
|
||||||
void applyEvaluate(Internal::EvalResult *parseResult);
|
void applyEvaluate(Internal::EvalResult *parseResult);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user