QmakeProjectManager: Make target search operate on project nodes

This makes the using code a bit less dependent on qmake specifics
(qmake related ProjectNode specialization vs qmake-only class)

Change-Id: Ied6ced70694b3ac0665d88ec86c4a66577f3a672
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
hjk
2018-11-13 16:58:02 +01:00
parent e744dbab8e
commit ccd5955843
5 changed files with 63 additions and 60 deletions

View File

@@ -140,7 +140,7 @@ QStringList QmakeAndroidSupport::soLibSearchPath(const ProjectExplorer::Target *
if (!project) if (!project)
return {}; return {};
foreach (QmakeProFile *file, project->allProFiles()) { for (const QmakeProFileNode *file : project->allProFiles()) {
TargetInformation info = file->targetInformation(); TargetInformation info = file->targetInformation();
res.insert(info.buildDir.toString()); res.insert(info.buildDir.toString());
Utils::FileName destDir = info.destDir; Utils::FileName destDir = info.destDir;
@@ -174,13 +174,13 @@ QStringList QmakeAndroidSupport::projectTargetApplications(const ProjectExplorer
auto qmakeProject = qobject_cast<QmakeProject *>(target->project()); auto qmakeProject = qobject_cast<QmakeProject *>(target->project());
if (!qmakeProject) if (!qmakeProject)
return apps; return apps;
for (QmakeProFile *proFile : qmakeProject->applicationProFiles()) { for (const QmakeProFileNode *proFile : qmakeProject->applicationProFiles()) {
if (proFile->projectType() == ProjectType::ApplicationTemplate) { if (proFile->projectType() == ProjectType::ApplicationTemplate) {
if (proFile->targetInformation().target.startsWith(QLatin1String("lib")) const QString target = proFile->targetInformation().target;
&& proFile->targetInformation().target.endsWith(QLatin1String(".so"))) if (target.startsWith("lib") && target.endsWith(".so"))
apps << proFile->targetInformation().target.mid(3, proFile->targetInformation().target.lastIndexOf(QLatin1Char('.')) - 3); apps << target.mid(3, target.lastIndexOf('.') - 3);
else else
apps << proFile->targetInformation().target; apps << target;
} }
} }
apps.sort(); apps.sort();

View File

@@ -307,4 +307,9 @@ QString QmakeProFileNode::objectExtension() const
return exts.first(); return exts.first();
} }
TargetInformation QmakeProFileNode::targetInformation() const
{
return proFile() ? proFile()->targetInformation() : TargetInformation();
}
} // namespace QmakeProjectManager } // namespace QmakeProjectManager

View File

@@ -101,6 +101,7 @@ public:
QString singleVariableValue(const Variable var) const; QString singleVariableValue(const Variable var) const;
QmakeProFileNode *findProFileFor(const Utils::FileName &string) const; QmakeProFileNode *findProFileFor(const Utils::FileName &string) const;
TargetInformation targetInformation() const;
bool showInSimpleTree(ProjectType projectType) const; bool showInSimpleTree(ProjectType projectType) const;
}; };

View File

@@ -753,35 +753,27 @@ QmakeProFileNode *QmakeProject::rootProjectNode() const
return static_cast<QmakeProFileNode *>(Project::rootProjectNode()); return static_cast<QmakeProFileNode *>(Project::rootProjectNode());
} }
QList<QmakeProFile *> QList<const QmakeProFileNode *> QmakeProject::applicationProFiles(Parsing parse) const
QmakeProject::collectAllProFiles(QmakeProFile *file, Parsing parse,
const QList<ProjectType> &projectTypes)
{
QList<QmakeProFile *> result;
if (parse == ExactAndCumulativeParse || file->includedInExactParse())
if (projectTypes.isEmpty() || projectTypes.contains(file->projectType()))
result.append(file);
for (QmakePriFile *f : file->children()) {
auto qmakeProFileNode = dynamic_cast<QmakeProFile *>(f);
if (qmakeProFileNode)
result.append(collectAllProFiles(qmakeProFileNode, parse, projectTypes));
}
return result;
}
QList<QmakeProFile *> QmakeProject::applicationProFiles(Parsing parse) const
{ {
return allProFiles({ProjectType::ApplicationTemplate, ProjectType::ScriptTemplate}, parse); return allProFiles({ProjectType::ApplicationTemplate, ProjectType::ScriptTemplate}, parse);
} }
QList<QmakeProFile *> QmakeProject::allProFiles(const QList<ProjectType> &projectTypes, Parsing parse) const const QList<const QmakeProFileNode *>
QmakeProject::allProFiles(const QList<ProjectType> &projectTypes, Parsing parse) const
{ {
QList<QmakeProFile *> list; QList<const QmakeProFileNode *> list;
if (!rootProFile())
return list; rootProjectNode()->forEachProjectNode([&list, projectTypes, parse](const ProjectNode *node) {
list = collectAllProFiles(rootProFile(), parse, projectTypes); if (auto qmakeNode = dynamic_cast<const QmakeProFileNode *>(node)) {
QmakeProFile *file = qmakeNode->proFile();
QTC_ASSERT(file, return);
if (parse == ExactAndCumulativeParse || file->includedInExactParse()) {
if (projectTypes.isEmpty() || projectTypes.contains(file->projectType()))
list.append(qmakeNode);
}
}
});
return list; return list;
} }
@@ -1033,16 +1025,16 @@ void QmakeProject::updateBuildSystemData()
return; return;
DeploymentData deploymentData; DeploymentData deploymentData;
collectData(file, deploymentData); collectData(rootProjectNode(), deploymentData);
target->setDeploymentData(deploymentData); target->setDeploymentData(deploymentData);
BuildTargetInfoList appTargetList; BuildTargetInfoList appTargetList;
for (const QmakeProFile * const proFile : applicationProFiles()) { for (const QmakeProFileNode * const node : applicationProFiles()) {
TargetInformation ti = proFile->targetInformation(); TargetInformation ti = node->targetInformation();
if (!ti.valid) if (!ti.valid)
continue; continue;
const QStringList &config = proFile->variableValue(Variable::Config); const QStringList &config = node->variableValue(Variable::Config);
QString destDir = ti.destDir.toString(); QString destDir = ti.destDir.toString();
QString workingDir; QString workingDir;
@@ -1065,15 +1057,15 @@ void QmakeProject::updateBuildSystemData()
workingDir += '/' + ti.target + ".app/Contents/MacOS"; workingDir += '/' + ti.target + ".app/Contents/MacOS";
BuildTargetInfo bti; BuildTargetInfo bti;
bti.targetFilePath = FileName::fromString(executableFor(proFile)); bti.targetFilePath = FileName::fromString(executableFor(node));
bti.projectFilePath = proFile->filePath(); bti.projectFilePath = node->filePath();
bti.workingDirectory = FileName::fromString(workingDir); bti.workingDirectory = FileName::fromString(workingDir);
bti.displayName = proFile->filePath().toFileInfo().completeBaseName(); bti.displayName = bti.projectFilePath.toFileInfo().completeBaseName();
bti.buildKey = bti.projectFilePath.toString(); bti.buildKey = bti.projectFilePath.toString();
bti.isQtcRunnable = config.contains("qtc_runnable"); bti.isQtcRunnable = config.contains("qtc_runnable");
if (config.contains("console") && !config.contains("testcase")) { if (config.contains("console") && !config.contains("testcase")) {
const QStringList qt = proFile->variableValue(Variable::Qt); const QStringList qt = node->variableValue(Variable::Qt);
bti.usesTerminal = !qt.contains("testlib") && !qt.contains("qmltest"); bti.usesTerminal = !qt.contains("testlib") && !qt.contains("qmltest");
} }
@@ -1082,8 +1074,10 @@ void QmakeProject::updateBuildSystemData()
// The user could be linking to a library found via a -L/some/dir switch // The user could be linking to a library found via a -L/some/dir switch
// to find those libraries while actually running we explicitly prepend those // to find those libraries while actually running we explicitly prepend those
// dirs to the library search path // dirs to the library search path
const QStringList libDirectories = proFile->variableValue(Variable::LibDirectories); const QStringList libDirectories = node->variableValue(Variable::LibDirectories);
if (!libDirectories.isEmpty()) { if (!libDirectories.isEmpty()) {
QmakeProFile *proFile = node->proFile();
QTC_ASSERT(proFile, return);
const QString proDirectory = proFile->buildDir().toString(); const QString proDirectory = proFile->buildDir().toString();
foreach (QString dir, libDirectories) { foreach (QString dir, libDirectories) {
// Fix up relative entries like "LIBS+=-L.." // Fix up relative entries like "LIBS+=-L.."
@@ -1108,8 +1102,9 @@ void QmakeProject::updateBuildSystemData()
target->setApplicationTargets(appTargetList); target->setApplicationTargets(appTargetList);
} }
void QmakeProject::collectData(const QmakeProFile *file, DeploymentData &deploymentData) void QmakeProject::collectData(const QmakeProFileNode *node, DeploymentData &deploymentData)
{ {
QmakeProFile *file = node->proFile();
if (!file->isSubProjectDeployable(file->filePath())) if (!file->isSubProjectDeployable(file->filePath()))
return; return;
@@ -1124,29 +1119,31 @@ void QmakeProject::collectData(const QmakeProFile *file, DeploymentData &deploym
switch (file->projectType()) { switch (file->projectType()) {
case ProjectType::ApplicationTemplate: case ProjectType::ApplicationTemplate:
if (!installsList.targetPath.isEmpty()) if (!installsList.targetPath.isEmpty())
collectApplicationData(file, deploymentData); collectApplicationData(node, deploymentData);
break; break;
case ProjectType::SharedLibraryTemplate: case ProjectType::SharedLibraryTemplate:
case ProjectType::StaticLibraryTemplate: case ProjectType::StaticLibraryTemplate:
collectLibraryData(file, deploymentData); collectLibraryData(file, deploymentData);
break; break;
case ProjectType::SubDirsTemplate: case ProjectType::SubDirsTemplate:
for (const QmakePriFile *const subPriFile : file->subPriFilesExact()) { node->forEachNode({}, [this, &deploymentData](Node *subNode) {
auto subProFile = dynamic_cast<const QmakeProFile *>(subPriFile); if (auto subProject = dynamic_cast<QmakeProFileNode *>(subNode)) {
if (subProFile) QTC_ASSERT(subProject->priFile(), return );
collectData(subProFile, deploymentData); if (subProject->priFile()->includedInExactParse())
collectData(subProject, deploymentData);
} }
});
break; break;
default: default:
break; break;
} }
} }
void QmakeProject::collectApplicationData(const QmakeProFile *file, DeploymentData &deploymentData) void QmakeProject::collectApplicationData(const QmakeProFileNode *node, DeploymentData &deploymentData)
{ {
QString executable = executableFor(file); QString executable = executableFor(node);
if (!executable.isEmpty()) if (!executable.isEmpty())
deploymentData.addFile(executable, file->installsList().targetPath, deploymentData.addFile(executable, node->proFile()->installsList().targetPath,
DeployableFile::TypeExecutable); DeployableFile::TypeExecutable);
} }
@@ -1332,16 +1329,19 @@ void QmakeProject::warnOnToolChainMismatch(const QmakeProFile *pro) const
getFullPathOf(pro, Variable::QmakeCxx, bc)); getFullPathOf(pro, Variable::QmakeCxx, bc));
} }
QString QmakeProject::executableFor(const QmakeProFile *file) QString QmakeProject::executableFor(const QmakeProFileNode *node)
{ {
const Kit *const kit = activeTarget() ? activeTarget()->kit() : nullptr; const Kit *const kit = activeTarget() ? activeTarget()->kit() : nullptr;
const ToolChain *const tc = ToolChainKitInformation::toolChain(kit, ProjectExplorer::Constants::CXX_LANGUAGE_ID); const ToolChain *const tc = ToolChainKitInformation::toolChain(kit, ProjectExplorer::Constants::CXX_LANGUAGE_ID);
if (!tc) if (!tc)
return QString(); return QString();
TargetInformation ti = file->targetInformation(); TargetInformation ti = node->targetInformation();
QString target; QString target;
QmakeProFile *file = node->proFile();
QTC_ASSERT(file, return QString());
if (tc->targetAbi().os() == Abi::DarwinOS if (tc->targetAbi().os() == Abi::DarwinOS
&& file->variableValue(Variable::Config).contains("app_bundle")) { && file->variableValue(Variable::Config).contains("app_bundle")) {
target = ti.target + ".app/Contents/MacOS/" + ti.target; target = ti.target + ".app/Contents/MacOS/" + ti.target;

View File

@@ -67,9 +67,9 @@ public:
QStringList filesGeneratedFrom(const QString &file) const final; QStringList filesGeneratedFrom(const QString &file) const final;
enum Parsing {ExactParse, ExactAndCumulativeParse }; enum Parsing {ExactParse, ExactAndCumulativeParse };
QList<QmakeProFile *> allProFiles(const QList<ProjectType> &projectTypes = QList<ProjectType>(), const QList<const QmakeProFileNode *> allProFiles(const QList<ProjectType> &projectTypes = {},
Parsing parse = ExactParse) const; Parsing parse = ExactParse) const;
QList<QmakeProFile *> applicationProFiles(Parsing parse = ExactParse) const; QList<const QmakeProFileNode *> applicationProFiles(Parsing parse = ExactParse) const;
static void notifyChanged(const Utils::FileName &name); static void notifyChanged(const Utils::FileName &name);
@@ -131,20 +131,17 @@ private:
void setAllBuildConfigurationsEnabled(bool enabled); void setAllBuildConfigurationsEnabled(bool enabled);
QString executableFor(const QmakeProFile *file); QString executableFor(const QmakeProFileNode *node);
void updateRunConfigurations(); void updateRunConfigurations();
void updateCppCodeModel(); void updateCppCodeModel();
void updateQmlJSCodeModel(); void updateQmlJSCodeModel();
static QList<QmakeProFile *> collectAllProFiles(QmakeProFile *file, Parsing parse,
const QList<ProjectType> &projectTypes);
static bool equalFileList(const QStringList &a, const QStringList &b); static bool equalFileList(const QStringList &a, const QStringList &b);
void updateBuildSystemData(); void updateBuildSystemData();
void collectData(const QmakeProFile *file, ProjectExplorer::DeploymentData &deploymentData); void collectData(const QmakeProFileNode *node, ProjectExplorer::DeploymentData &deploymentData);
void collectApplicationData(const QmakeProFile *file, void collectApplicationData(const QmakeProFileNode *file,
ProjectExplorer::DeploymentData &deploymentData); ProjectExplorer::DeploymentData &deploymentData);
void collectLibraryData(const QmakeProFile *file, void collectLibraryData(const QmakeProFile *file,
ProjectExplorer::DeploymentData &deploymentData); ProjectExplorer::DeploymentData &deploymentData);