Clang: Improve compilation database generation

Do not use CompilerOptionsBuilder anymore because we don't
need much tweaking for projectPart data and can do it better
specifically for the generator.

Fixes: QTCREATORBUG-21936
Change-Id: I00ad872c703598a9a88af29399b428520dd5cb3b
Reviewed-by: Marco Bubke <marco.bubke@qt.io>
This commit is contained in:
Ivan Donchevskii
2019-03-13 10:22:16 +01:00
parent 3115d082d3
commit a0072afd49
3 changed files with 70 additions and 18 deletions

View File

@@ -34,12 +34,13 @@
#include <coreplugin/idocument.h> #include <coreplugin/idocument.h>
#include <cpptools/baseeditordocumentparser.h> #include <cpptools/baseeditordocumentparser.h>
#include <cpptools/compileroptionsbuilder.h> #include <cpptools/compileroptionsbuilder.h>
#include <cpptools/cppcodemodelsettings.h>
#include <cpptools/cppmodelmanager.h> #include <cpptools/cppmodelmanager.h>
#include <cpptools/cpptoolsreuse.h>
#include <cpptools/editordocumenthandle.h> #include <cpptools/editordocumenthandle.h>
#include <cpptools/projectpart.h> #include <cpptools/projectpart.h>
#include <cpptools/cppcodemodelsettings.h>
#include <cpptools/cpptoolsreuse.h>
#include <projectexplorer/buildconfiguration.h> #include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/target.h> #include <projectexplorer/target.h>
@@ -300,6 +301,18 @@ QString diagnosticCategoryPrefixRemoved(const QString &text)
return text; return text;
} }
static ::Utils::FileName compilerPath(const CppTools::ProjectPart &projectPart)
{
ProjectExplorer::Target *target = projectPart.project->activeTarget();
if (!target)
return ::Utils::FileName();
ProjectExplorer::ToolChain *toolchain = ProjectExplorer::ToolChainKitInformation::toolChain(
target->kit(), ProjectExplorer::Constants::CXX_LANGUAGE_ID);
return toolchain->compilerCommand();
}
static ::Utils::FileName buildDirectory(const CppTools::ProjectPart &projectPart) static ::Utils::FileName buildDirectory(const CppTools::ProjectPart &projectPart)
{ {
ProjectExplorer::Target *target = projectPart.project->activeTarget(); ProjectExplorer::Target *target = projectPart.project->activeTarget();
@@ -313,17 +326,60 @@ static ::Utils::FileName buildDirectory(const CppTools::ProjectPart &projectPart
return buildConfig->buildDirectory(); return buildConfig->buildDirectory();
} }
static QJsonObject createFileObject(CompilerOptionsBuilder &optionsBuilder, static QStringList projectPartArguments(const ProjectPart &projectPart)
const ProjectFile &projFile,
const ::Utils::FileName &buildDir)
{ {
const ProjectFile::Kind kind = ProjectFile::classify(projFile.path); QStringList args;
optionsBuilder.updateFileLanguage(kind); args << compilerPath(projectPart).toString();
args << "-c";
if (projectPart.toolchainType != ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) {
args << "--target=" + projectPart.toolChainTargetTriple;
args << (projectPart.toolChainWordWidth == ProjectPart::WordWidth64Bit
? QLatin1String("-m64")
: QLatin1String("-m32"));
}
args << projectPart.compilerFlags;
for (const ProjectExplorer::HeaderPath &headerPath : projectPart.headerPaths) {
if (headerPath.type == ProjectExplorer::HeaderPathType::User) {
args << "-I" + headerPath.path;
} else if (headerPath.type == ProjectExplorer::HeaderPathType::System) {
args << (projectPart.toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID
? "-I"
: "-isystem")
+ headerPath.path;
}
}
for (const ProjectExplorer::Macro &macro : projectPart.projectMacros) {
args.append(QString::fromUtf8(
macro.toKeyValue(macro.type == ProjectExplorer::MacroType::Define ? "-D" : "-U")));
}
return args;
}
static QJsonObject createFileObject(const ::Utils::FileName &buildDir,
const QStringList &arguments,
const ProjectPart &projectPart,
const ProjectFile &projFile)
{
QJsonObject fileObject; QJsonObject fileObject;
fileObject["file"] = projFile.path; fileObject["file"] = projFile.path;
QJsonArray args = QJsonArray::fromStringList(optionsBuilder.options()); QJsonArray args = QJsonArray::fromStringList(arguments);
args.prepend(kind == ProjectFile::CXXSource ? "clang++" : "clang");
const ProjectFile::Kind kind = ProjectFile::classify(projFile.path);
if (projectPart.toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID
|| projectPart.toolchainType == ProjectExplorer::Constants::CLANG_CL_TOOLCHAIN_TYPEID) {
if (ProjectFile::isC(kind))
args.append("/TC");
else if (ProjectFile::isCxx(kind))
args.append("/TP");
} else {
QStringList langOption
= createLanguageOptionGcc(kind,
projectPart.languageExtensions
& ::Utils::LanguageExtension::ObjectiveC);
for (const QString &langOptionPart : langOption)
args.append(langOptionPart);
}
args.append(QDir::toNativeSeparators(projFile.path)); args.append(QDir::toNativeSeparators(projFile.path));
fileObject["arguments"] = args; fileObject["arguments"] = args;
fileObject["directory"] = buildDir.toString(); fileObject["directory"] = buildDir.toString();
@@ -338,17 +394,12 @@ void generateCompilationDB(::Utils::FileName projectDir, CppTools::ProjectInfo p
if (!fileOpened) if (!fileOpened)
return; return;
compileCommandsFile.write("["); compileCommandsFile.write("[");
for (ProjectPart::Ptr projectPart : projectInfo.projectParts()) { for (ProjectPart::Ptr projectPart : projectInfo.projectParts()) {
const ::Utils::FileName buildDir = buildDirectory(*projectPart); const ::Utils::FileName buildDir = buildDirectory(*projectPart);
const QStringList args = projectPartArguments(*projectPart);
CompilerOptionsBuilder optionsBuilder(*projectPart,
UseSystemHeader::No,
UseTweakedHeaderPaths::No);
optionsBuilder.build(CppTools::ProjectFile::Unclassified,
CppTools::UsePrecompiledHeaders::No);
for (const ProjectFile &projFile : projectPart->files) { for (const ProjectFile &projFile : projectPart->files) {
const QJsonObject json = createFileObject(optionsBuilder, projFile, buildDir); const QJsonObject json = createFileObject(buildDir, args, *projectPart, projFile);
if (compileCommandsFile.size() > 1) if (compileCommandsFile.size() > 1)
compileCommandsFile.write(","); compileCommandsFile.write(",");
compileCommandsFile.write('\n' + QJsonDocument(json).toJson().trimmed()); compileCommandsFile.write('\n' + QJsonDocument(json).toJson().trimmed());

View File

@@ -172,7 +172,7 @@ void CompilerOptionsBuilder::addSyntaxOnly()
isClStyle() ? add("/Zs") : add("-fsyntax-only"); isClStyle() ? add("/Zs") : add("-fsyntax-only");
} }
static QStringList createLanguageOptionGcc(ProjectFile::Kind fileKind, bool objcExt) QStringList createLanguageOptionGcc(ProjectFile::Kind fileKind, bool objcExt)
{ {
QStringList options; QStringList options;

View File

@@ -40,6 +40,7 @@ enum class UseBuildSystemWarnings : char { Yes, No };
CPPTOOLS_EXPORT QStringList XclangArgs(const QStringList &args); CPPTOOLS_EXPORT QStringList XclangArgs(const QStringList &args);
CPPTOOLS_EXPORT QStringList clangArgsForCl(const QStringList &args); CPPTOOLS_EXPORT QStringList clangArgsForCl(const QStringList &args);
CPPTOOLS_EXPORT QStringList createLanguageOptionGcc(ProjectFile::Kind fileKind, bool objcExt);
class CPPTOOLS_EXPORT CompilerOptionsBuilder class CPPTOOLS_EXPORT CompilerOptionsBuilder
{ {