unify {,obj}c++{source,header} handling in qmake project manager

consistently with Xcode, qmake nowadays knows only one SOURCES list,
which is automatically classified by extension.
to replicate that, we actually copy the objective_c.prf file from qt
5.6.3 and use it to override whatever comes with qt, so we can treat all
qt versions uniformly.

also, the code model throws away the information which files were listed
as sources and which as headers. this is technically incorrect, as a
source may be only included rather than compiled, but there is no point
in extracting information which is not used.

conclusion: lump all c-like sources into one variable as far as project
processing is concerned.

and as far as configuration goes, our code model doesn't differentiate
anyway, so the duplicated setup paths can be eliminated as well.

Change-Id: I24b1bc056f8d9eb579c9378817f602912ab49971
Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
This commit is contained in:
Oswald Buddenhagen
2016-10-25 16:28:40 +02:00
parent 4148b05e0a
commit 7e86b98836
7 changed files with 73 additions and 73 deletions

View File

@@ -1414,13 +1414,11 @@ QString QmakePriFileNode::varNameForAdding(const QString &mimeType)
} }
if (mimeType == QLatin1String(ProjectExplorer::Constants::CPP_SOURCE_MIMETYPE) if (mimeType == QLatin1String(ProjectExplorer::Constants::CPP_SOURCE_MIMETYPE)
|| mimeType == QLatin1String(CppTools::Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE)
|| mimeType == QLatin1String(ProjectExplorer::Constants::C_SOURCE_MIMETYPE)) { || mimeType == QLatin1String(ProjectExplorer::Constants::C_SOURCE_MIMETYPE)) {
return QLatin1String("SOURCES"); return QLatin1String("SOURCES");
} }
if (mimeType == QLatin1String(CppTools::Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE))
return QLatin1String("OBJECTIVE_SOURCES");
if (mimeType == QLatin1String(ProjectExplorer::Constants::RESOURCE_MIMETYPE)) if (mimeType == QLatin1String(ProjectExplorer::Constants::RESOURCE_MIMETYPE))
return QLatin1String("RESOURCES"); return QLatin1String("RESOURCES");
@@ -1932,13 +1930,12 @@ EvalResult *QmakeProFileNode::evaluate(const EvalInput &input)
result->newVarValues[IncludePathVar] = includePaths(input.readerExact, input.sysroot, result->newVarValues[IncludePathVar] = includePaths(input.readerExact, input.sysroot,
input.buildDirectory, input.projectDir); input.buildDirectory, input.projectDir);
result->newVarValues[CppFlagsVar] = input.readerExact->values(QLatin1String("QMAKE_CXXFLAGS")); result->newVarValues[CppFlagsVar] = input.readerExact->values(QLatin1String("QMAKE_CXXFLAGS"));
result->newVarValues[CppHeaderVar] = fileListForVar(input.readerExact, input.readerCumulative, result->newVarValues[SourceVar] =
QLatin1String("HEADERS"), input.projectDir, input.buildDirectory); fileListForVar(input.readerExact, input.readerCumulative,
result->newVarValues[CppSourceVar] = fileListForVar(input.readerExact, input.readerCumulative, QLatin1String("SOURCES"), input.projectDir, input.buildDirectory) +
QLatin1String("SOURCES"), input.projectDir, input.buildDirectory); fileListForVar(input.readerExact, input.readerCumulative,
result->newVarValues[ObjCSourceVar] = fileListForVar(input.readerExact, input.readerCumulative, QLatin1String("HEADERS"), input.projectDir, input.buildDirectory) +
QLatin1String("OBJECTIVE_SOURCES"), input.projectDir, input.buildDirectory); fileListForVar(input.readerExact, input.readerCumulative,
result->newVarValues[ObjCHeaderVar] = fileListForVar(input.readerExact, input.readerCumulative,
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(input.readerExact, input.buildDirectory);
result->newVarValues[HeaderExtensionVar] = QStringList() << input.readerExact->value(QLatin1String("QMAKE_EXT_H")); result->newVarValues[HeaderExtensionVar] = QStringList() << input.readerExact->value(QLatin1String("QMAKE_EXT_H"));

View File

@@ -78,10 +78,7 @@ enum QmakeVariable {
DefinesVar = 1, DefinesVar = 1,
IncludePathVar, IncludePathVar,
CppFlagsVar, CppFlagsVar,
CppHeaderVar, SourceVar,
CppSourceVar,
ObjCSourceVar,
ObjCHeaderVar,
ExactResourceVar, ExactResourceVar,
CumulativeResourceVar, CumulativeResourceVar,
UiDirVar, UiDirVar,

View File

@@ -458,40 +458,27 @@ void QmakeProject::updateCppCodeModel()
// part->precompiledHeaders // part->precompiledHeaders
templatePart->precompiledHeaders.append(pro->variableValue(PrecompiledHeaderVar)); templatePart->precompiledHeaders.append(pro->variableValue(PrecompiledHeaderVar));
templatePart->updateLanguageFeatures(); // TODO: there is no LANG_OBJCXX, so:
const QStringList cxxflags = pro->variableValue(CppFlagsVar);
CppTools::ProjectPartBuilder::evaluateProjectPartToolchain(
templatePart.data(), ToolChainKitInformation::toolChain(k, ToolChain::Language::Cxx),
cxxflags, SysRootKitInformation::sysRoot(k));
setProjectLanguage(ProjectExplorer::Constants::LANG_CXX, true);
ProjectPart::Ptr cppPart = templatePart->copy(); ProjectPart::Ptr cppPart = templatePart->copy();
{ // C++ files:
// part->files
foreach (const QString &file, pro->variableValue(CppSourceVar)) {
cppPart->files << ProjectFile(file, ProjectFile::CXXSource);
}
foreach (const QString &file, pro->variableValue(CppHeaderVar)) {
cppPart->files << ProjectFile(file, ProjectFile::CXXHeader);
}
}
ProjectPart::Ptr objcppPart = templatePart->copy(); ProjectPart::Ptr objcppPart = templatePart->copy();
{ // ObjC++ files: foreach (const QString &file, pro->variableValue(SourceVar)) {
foreach (const QString &file, pro->variableValue(ObjCSourceVar)) { ProjectFile::Kind kind = ProjectFile::classify(file);
// Although the enum constant is called ObjCSourceVar, it actually is ObjC++ source switch (kind) {
// code, as qmake does not handle C (and ObjC). case ProjectFile::ObjCHeader:
objcppPart->files << ProjectFile(file, ProjectFile::ObjCXXSource); case ProjectFile::ObjCSource:
} case ProjectFile::ObjCXXHeader:
foreach (const QString &file, pro->variableValue(ObjCHeaderVar)) { case ProjectFile::ObjCXXSource:
objcppPart->files << ProjectFile(file, ProjectFile::ObjCXXHeader); objcppPart->files << ProjectFile(file, kind);
} break;
default:
const QStringList cxxflags = pro->variableValue(CppFlagsVar); cppPart->files << ProjectFile(file, kind);
CppTools::ProjectPartBuilder::evaluateProjectPartToolchain(objcppPart.data(), break;
ToolChainKitInformation::toolChain(k, ToolChain::Language::Cxx),
cxxflags,
SysRootKitInformation::sysRoot(k));
if (!objcppPart->files.isEmpty()) {
pinfo.appendProjectPart(objcppPart);
// TODO: there is no LANG_OBJCXX, so:
setProjectLanguage(ProjectExplorer::Constants::LANG_CXX, true);
} }
} }
@@ -523,19 +510,12 @@ void QmakeProject::updateCppCodeModel()
cppPart->files.prepend(ProjectFile(CppTools::CppModelManager::configurationFileName(), cppPart->files.prepend(ProjectFile(CppTools::CppModelManager::configurationFileName(),
ProjectFile::CXXSource)); ProjectFile::CXXSource));
const QStringList cxxflags = pro->variableValue(CppFlagsVar);
CppTools::ProjectPartBuilder::evaluateProjectPartToolchain(
cppPart.data(), ToolChainKitInformation::toolChain(k, ToolChain::Language::Cxx),
cxxflags, SysRootKitInformation::sysRoot(k));
if (!cppPart->files.isEmpty()) {
pinfo.appendProjectPart(cppPart); pinfo.appendProjectPart(cppPart);
setProjectLanguage(ProjectExplorer::Constants::LANG_CXX, true);
}
if (!objcppPart->files.isEmpty())
cppPart->displayName += QLatin1String(" (C++)");
if (!cppPart->files.isEmpty())
objcppPart->displayName += QLatin1String(" (ObjC++)"); objcppPart->displayName += QLatin1String(" (ObjC++)");
if (!objcppPart->files.isEmpty()) {
pinfo.appendProjectPart(objcppPart);
cppPart->displayName += QLatin1String(" (C++)");
}
} }
pinfo.finish(); pinfo.finish();

View File

@@ -0,0 +1,12 @@
# Objective-C/C++ sources go in SOURCES, like all other sources
SOURCES += $$OBJECTIVE_SOURCES
unset(OBJECTIVE_SOURCES)
# Strip C/C++ flags from QMAKE_OBJECTIVE_CFLAGS just in case
QMAKE_OBJECTIVE_CFLAGS -= $$QMAKE_CFLAGS $$QMAKE_CXXFLAGS
# Add Objective-C/C++ flags to C/C++ flags, the compiler can handle it
QMAKE_CFLAGS += $$QMAKE_OBJECTIVE_CFLAGS
QMAKE_CXXFLAGS += $$QMAKE_OBJECTIVE_CFLAGS
unset(QMAKE_OBJECTIVE_CFLAGS)

View File

@@ -29,4 +29,4 @@ SOURCES += \
ioutils.cpp ioutils.cpp
RESOURCES += proparser.qrc RESOURCES += proparser.qrc
DEFINES += QMAKE_BUILTIN_PRFS DEFINES += QMAKE_BUILTIN_PRFS QMAKE_OVERRIDE_PRFS

View File

@@ -3,4 +3,7 @@
<file>spec_pre.prf</file> <file>spec_pre.prf</file>
<file>spec_post.prf</file> <file>spec_post.prf</file>
</qresource> </qresource>
<qresource prefix="/qmake/override_features" >
<file>objective_c.prf</file>
</qresource>
</RCC> </RCC>

View File

@@ -1953,6 +1953,16 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateFeatureFile(
// needs to be determined. Failed lookups are represented via non-null empty strings. // needs to be determined. Failed lookups are represented via non-null empty strings.
QString *fnp = &m_featureRoots->cache[qMakePair(fn, currFn)]; QString *fnp = &m_featureRoots->cache[qMakePair(fn, currFn)];
if (fnp->isNull()) { if (fnp->isNull()) {
#ifdef QMAKE_OVERRIDE_PRFS
{
QString ovrfn(QLatin1String(":/qmake/override_features/") + fn);
if (QFileInfo::exists(ovrfn)) {
fn = ovrfn;
goto cool;
}
}
#endif
{
int start_root = 0; int start_root = 0;
const QStringList &paths = m_featureRoots->paths; const QStringList &paths = m_featureRoots->paths;
if (!currFn.isEmpty()) { if (!currFn.isEmpty()) {
@@ -1970,6 +1980,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateFeatureFile(
goto cool; goto cool;
} }
} }
}
#ifdef QMAKE_BUILTIN_PRFS #ifdef QMAKE_BUILTIN_PRFS
fn.prepend(QLatin1String(":/qmake/features/")); fn.prepend(QLatin1String(":/qmake/features/"));
if (QFileInfo::exists(fn)) if (QFileInfo::exists(fn))