logic: Added PCH support to CDB source groups (issue #311)

* added PCH Flags list and checkbox to reuse compiler flags and cdb flags to source group setup
* added UI tests for C++ and CDB source groups
This commit is contained in:
Eberhard Graether
2019-07-31 00:41:08 +02:00
parent b8d0f88336
commit c6adbab340
45 changed files with 926 additions and 232 deletions
@@ -21,6 +21,7 @@ void SourceGroupSettingsCxxCdb::load(std::shared_ptr<const ConfigManager> config
const std::string key = s_keyPrefix + getId();
SourceGroupSettingsWithCxxPchOptions::load(config, key);
SourceGroupSettingsWithExcludeFilters::load(config, key);
SourceGroupSettingsWithIndexedHeaderPaths::load(config, key);
@@ -33,6 +34,7 @@ void SourceGroupSettingsCxxCdb::save(std::shared_ptr<ConfigManager> config)
const std::string key = s_keyPrefix + getId();
SourceGroupSettingsWithCxxPchOptions::save(config, key);
SourceGroupSettingsWithExcludeFilters::save(config, key);
SourceGroupSettingsWithIndexedHeaderPaths::save(config, key);
@@ -46,6 +48,7 @@ bool SourceGroupSettingsCxxCdb::equals(std::shared_ptr<SourceGroupSettings> othe
return (
otherCxxCdb &&
SourceGroupSettingsCxx::equals(other) &&
SourceGroupSettingsWithCxxPchOptions::equals(otherCxxCdb) &&
SourceGroupSettingsWithExcludeFilters::equals(otherCxxCdb) &&
SourceGroupSettingsWithIndexedHeaderPaths::equals(otherCxxCdb) &&
m_compilationDatabasePath == otherCxxCdb->m_compilationDatabasePath
@@ -2,12 +2,14 @@
#define SOURCE_GROUP_SETTINGS_CXX_CDB_H
#include "SourceGroupSettingsCxx.h"
#include "SourceGroupSettingsWithCxxPchOptions.h"
#include "SourceGroupSettingsWithExcludeFilters.h"
#include "SourceGroupSettingsWithIndexedHeaderPaths.h"
#include "FilePath.h"
class SourceGroupSettingsCxxCdb
: public SourceGroupSettingsCxx
, public SourceGroupSettingsWithCxxPchOptions
, public SourceGroupSettingsWithExcludeFilters
, public SourceGroupSettingsWithIndexedHeaderPaths
{
@@ -1,24 +1,31 @@
#include "SourceGroupSettingsWithCxxPchOptions.h"
#include "ProjectSettings.h"
#include "utility.h"
#include "utilityFile.h"
bool SourceGroupSettingsWithCxxPchOptions::equals(std::shared_ptr<SourceGroupSettingsWithCxxPchOptions> other) const
{
return (
other &&
m_pchInputFilePath == other->m_pchInputFilePath
m_pchInputFilePath == other->m_pchInputFilePath &&
utility::isPermutation(m_pchFlags, other->m_pchFlags) &&
m_useCompilerFlags == other->m_useCompilerFlags
);
}
void SourceGroupSettingsWithCxxPchOptions::load(std::shared_ptr<const ConfigManager> config, const std::string& key)
{
setPchInputFilePathFilePath(config->getValueOrDefault(key + "/pch_input_file_path", FilePath(L"")));
setPchFlags(config->getValuesOrDefaults(key + "/pch_flags/pch_flag", std::vector<std::wstring>()));
setUseCompilerFlags(config->getValueOrDefault(key + "/pch_flags/use_compiler_flags", false));
}
void SourceGroupSettingsWithCxxPchOptions::save(std::shared_ptr<ConfigManager> config, const std::string& key)
{
config->setValue(key + "/pch_input_file_path", getPchInputFilePath().wstr());
config->setValues(key + "/pch_flags/pch_flag", getPchFlags());
config->setValue(key + "/pch_flags/use_compiler_flags", getUseCompilerFlags());
}
FilePath SourceGroupSettingsWithCxxPchOptions::getPchDependenciesDirectoryPath() const
@@ -40,3 +47,23 @@ void SourceGroupSettingsWithCxxPchOptions::setPchInputFilePathFilePath(const Fil
{
m_pchInputFilePath = path;
}
bool SourceGroupSettingsWithCxxPchOptions::getUseCompilerFlags() const
{
return m_useCompilerFlags;
}
void SourceGroupSettingsWithCxxPchOptions::setUseCompilerFlags(bool useCompilerFlags)
{
m_useCompilerFlags = useCompilerFlags;
}
std::vector<std::wstring> SourceGroupSettingsWithCxxPchOptions::getPchFlags() const
{
return m_pchFlags;
}
void SourceGroupSettingsWithCxxPchOptions::setPchFlags(const std::vector<std::wstring>& pchFlags)
{
m_pchFlags = pchFlags;
}
@@ -24,12 +24,20 @@ public:
FilePath getPchInputFilePathExpandedAndAbsolute() const;
void setPchInputFilePathFilePath(const FilePath& path);
std::vector<std::wstring> getPchFlags() const;
void setPchFlags(const std::vector<std::wstring>& pchFlags);
bool getUseCompilerFlags() const;
void setUseCompilerFlags(bool useCompilerFlags);
protected:
void load(std::shared_ptr<const ConfigManager> config, const std::string& key);
void save(std::shared_ptr<ConfigManager> config, const std::string& key);
private:
FilePath m_pchInputFilePath;
std::vector<std::wstring> m_pchFlags;
bool m_useCompilerFlags = true;
};
#endif // SOURCE_GROUP_SETTINGS_WITH_CXX_PCH_OPTIONS_H
+4
View File
@@ -45,6 +45,8 @@ add_files(
data/parser/cxx/CanonicalFilePathCache.h
data/parser/cxx/CommentHandler.cpp
data/parser/cxx/CommentHandler.h
data/parser/cxx/ClangInvocationInfo.cpp
data/parser/cxx/ClangInvocationInfo.h
data/parser/cxx/CxxAstVisitor.cpp
data/parser/cxx/CxxAstVisitor.h
data/parser/cxx/CxxAstVisitorComponent.cpp
@@ -90,6 +92,8 @@ add_files(
project/SourceGroupCxxSonargraph.h
project/SourceGroupFactoryModuleCxx.cpp
project/SourceGroupFactoryModuleCxx.h
project/utilitySourceGroupCxx.cpp
project/utilitySourceGroupCxx.h
utility/codeblocks/CodeblocksCompiler.cpp
utility/codeblocks/CodeblocksCompiler.h
+27 -5
View File
@@ -12,11 +12,21 @@
#include "utility.h"
#include "utilityString.h"
std::vector<FilePath> IndexerCommandCxx::getSourceFilesFromCDB(const FilePath& compilationDatabasePath)
std::shared_ptr<clang::tooling::JSONCompilationDatabase> IndexerCommandCxx::loadCDB(const FilePath& cdbPath)
{
if (cdbPath.empty() || !cdbPath.exists())
{
return nullptr;
}
std::string error;
std::shared_ptr<clang::tooling::JSONCompilationDatabase> cdb = std::shared_ptr<clang::tooling::JSONCompilationDatabase>
(clang::tooling::JSONCompilationDatabase::loadFromFile(utility::encodeToUtf8(compilationDatabasePath.wstr()), error, clang::tooling::JSONCommandLineSyntax::AutoDetect));
std::shared_ptr<clang::tooling::JSONCompilationDatabase> cdb = std::shared_ptr<clang::tooling::JSONCompilationDatabase>(
clang::tooling::JSONCompilationDatabase::loadFromFile(
utility::encodeToUtf8(cdbPath.wstr()),
error,
clang::tooling::JSONCommandLineSyntax::AutoDetect
)
);
if (!error.empty())
{
@@ -25,6 +35,17 @@ std::vector<FilePath> IndexerCommandCxx::getSourceFilesFromCDB(const FilePath& c
MessageStatus(message, true).dispatch();
}
return cdb;
}
std::vector<FilePath> IndexerCommandCxx::getSourceFilesFromCDB(const FilePath& cdbPath)
{
return getSourceFilesFromCDB(loadCDB(cdbPath), cdbPath);
}
std::vector<FilePath> IndexerCommandCxx::getSourceFilesFromCDB(
std::shared_ptr<clang::tooling::JSONCompilationDatabase> cdb, const FilePath& cdbPath)
{
std::vector<FilePath> filePaths;
if (cdb)
{
@@ -43,7 +64,7 @@ std::vector<FilePath> IndexerCommandCxx::getSourceFilesFromCDB(const FilePath& c
}
if (!path.isAbsolute())
{
path = compilationDatabasePath.getParentDirectory().getConcatenated(path).makeCanonical();
path = cdbPath.getParentDirectory().getConcatenated(path).makeCanonical();
}
filePaths.push_back(canonicalDirectoryPathCache.getValue(path.getParentDirectory()).concatenate(path.fileName()));
}
@@ -56,7 +77,8 @@ std::wstring IndexerCommandCxx::getCompilerFlagLanguageStandard(const std::wstri
return L"-std=" + languageStandard;
}
std::vector<std::wstring> IndexerCommandCxx::getCompilerFlagsForSystemHeaderSearchPaths(const std::vector<FilePath>& systemHeaderSearchPaths)
std::vector<std::wstring> IndexerCommandCxx::getCompilerFlagsForSystemHeaderSearchPaths(
const std::vector<FilePath>& systemHeaderSearchPaths)
{
std::vector<std::wstring> compilerFlags;
compilerFlags.reserve(systemHeaderSearchPaths.size() * 2);
+10 -1
View File
@@ -7,12 +7,21 @@
#include "IndexerCommand.h"
class FilePath;
namespace clang {
namespace tooling {
class JSONCompilationDatabase;
}
}
class IndexerCommandCxx
: public IndexerCommand
{
public:
static std::vector<FilePath> getSourceFilesFromCDB(const FilePath& compilationDatabasePath);
static std::shared_ptr<clang::tooling::JSONCompilationDatabase> loadCDB(const FilePath& cdbPath);
static std::vector<FilePath> getSourceFilesFromCDB(const FilePath& cdbPath);
static std::vector<FilePath> getSourceFilesFromCDB(
std::shared_ptr<clang::tooling::JSONCompilationDatabase> cdb, const FilePath& cdbPath);
static std::wstring getCompilerFlagLanguageStandard(const std::wstring &languageStandard);
static std::vector<std::wstring> getCompilerFlagsForSystemHeaderSearchPaths(const std::vector<FilePath>& systemHeaderSearchPaths);
static std::vector<std::wstring> getCompilerFlagsForFrameworkSearchPaths(const std::vector<FilePath>& frameworkSearchPaths);
@@ -0,0 +1,78 @@
#include "ClangInvocationInfo.h"
#include <clang/Driver/Compilation.h>
#include <clang/Driver/Driver.h>
#include <clang/Driver/Options.h>
#include <clang/Frontend/CompilerInvocation.h>
#include <clang/Tooling/Tooling.h>
#include <llvm/Option/ArgList.h>
#include <llvm/Support/TargetSelect.h>
#include "CxxCompilationDatabaseSingle.h"
#include "CxxDiagnosticConsumer.h"
#include "utilityString.h"
namespace
{
// copied from clang codebase
clang::driver::Driver *newDriver(
clang::DiagnosticsEngine *Diagnostics, const char *BinaryName,
clang::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {
clang::driver::Driver *CompilerDriver =
new clang::driver::Driver(BinaryName, llvm::sys::getDefaultTargetTriple(),
*Diagnostics, std::move(VFS));
CompilerDriver->setTitle("clang_based_tool");
return CompilerDriver;
}
}
// copied and stitched together from clang codebase
ClangInvocationInfo ClangInvocationInfo::getClangInvocationString(const clang::tooling::CompilationDatabase* compilationDatabase)
{
ClangInvocationInfo invocationInfo;
if (!compilationDatabase->getAllCompileCommands().empty())
{
std::vector<std::string> CommandLine = compilationDatabase->getAllCompileCommands().front().CommandLine;
std::vector<const char*> Argv;
for (const std::string &Str : CommandLine)
Argv.push_back(Str.c_str());
const char *const BinaryName = Argv[0];
clang::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagOpts = new clang::DiagnosticOptions();
unsigned MissingArgIndex, MissingArgCount;
std::unique_ptr<llvm::opt::OptTable> Opts = clang::driver::createDriverOptTable();
llvm::opt::InputArgList ParsedArgs = Opts->ParseArgs(
clang::ArrayRef<const char *>(Argv).slice(1), MissingArgIndex, MissingArgCount);
clang::ParseDiagnosticArgs(*DiagOpts, ParsedArgs);
llvm::raw_string_ostream diagnosticsStream(invocationInfo.errors);
clang::TextDiagnosticPrinter DiagnosticPrinter(
diagnosticsStream, &*DiagOpts);
clang::DiagnosticsEngine Diagnostics(
clang::IntrusiveRefCntPtr<clang::DiagnosticIDs>(new clang::DiagnosticIDs()), &*DiagOpts,
&DiagnosticPrinter, false);
llvm::IntrusiveRefCntPtr<clang::FileManager> Files(new clang::FileManager(clang::FileSystemOptions()));
const std::unique_ptr<clang::driver::Driver> Driver(
newDriver(&Diagnostics, BinaryName, Files->getVirtualFileSystem()));
// Since the input might only be virtual, don't check whether it exists.
Driver->setCheckInputsExist(false);
const std::unique_ptr<clang::driver::Compilation> Compilation(
Driver->BuildCompilation(llvm::makeArrayRef(Argv)));
if (Compilation)
{
llvm::raw_string_ostream ss(invocationInfo.invocation);
Compilation->getJobs().Print(ss, "", true);
ss.flush();
}
diagnosticsStream.flush();
invocationInfo.invocation = utility::trim(invocationInfo.invocation);
invocationInfo.errors = utility::trim(invocationInfo.errors);
}
return invocationInfo;
}
@@ -0,0 +1,22 @@
#ifndef CLANG_INVOCATION_INFO_H
#define CLANG_INVOCATION_INFO_H
#include <string>
namespace clang
{
namespace tooling
{
class CompilationDatabase;
}
}
struct ClangInvocationInfo
{
static ClangInvocationInfo getClangInvocationString(const clang::tooling::CompilationDatabase* compilationDatabase);
std::string invocation;
std::string errors;
};
#endif // CLANG_INVOCATION_INFO_H
+3 -70
View File
@@ -12,6 +12,7 @@
#include "ApplicationSettings.h"
#include "ASTAction.h"
#include "CanonicalFilePathCache.h"
#include "ClangInvocationInfo.h"
#include "CxxCompilationDatabaseSingle.h"
#include "CxxDiagnosticConsumer.h"
#include "FilePath.h"
@@ -27,74 +28,6 @@
namespace
{
struct ClangInvocationInfo
{
std::string invocation;
std::string errors;
};
// copied from clang codebase
clang::driver::Driver *newDriver(
clang::DiagnosticsEngine *Diagnostics, const char *BinaryName,
clang::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {
clang::driver::Driver *CompilerDriver =
new clang::driver::Driver(BinaryName, llvm::sys::getDefaultTargetTriple(),
*Diagnostics, std::move(VFS));
CompilerDriver->setTitle("clang_based_tool");
return CompilerDriver;
}
// copied and stitched together from clang codebase
ClangInvocationInfo getClangInvocationString(const clang::tooling::CompilationDatabase* compilationDatabase)
{
ClangInvocationInfo invocationInfo;
if (!compilationDatabase->getAllCompileCommands().empty())
{
std::vector<std::string> CommandLine = compilationDatabase->getAllCompileCommands().front().CommandLine;
std::vector<const char*> Argv;
for (const std::string &Str : CommandLine)
Argv.push_back(Str.c_str());
const char *const BinaryName = Argv[0];
clang::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagOpts = new clang::DiagnosticOptions();
unsigned MissingArgIndex, MissingArgCount;
std::unique_ptr<llvm::opt::OptTable> Opts = clang::driver::createDriverOptTable();
llvm::opt::InputArgList ParsedArgs = Opts->ParseArgs(
clang::ArrayRef<const char *>(Argv).slice(1), MissingArgIndex, MissingArgCount);
clang::ParseDiagnosticArgs(*DiagOpts, ParsedArgs);
llvm::raw_string_ostream diagnosticsStream(invocationInfo.errors);
clang::TextDiagnosticPrinter DiagnosticPrinter(
diagnosticsStream, &*DiagOpts);
clang::DiagnosticsEngine Diagnostics(
clang::IntrusiveRefCntPtr<clang::DiagnosticIDs>(new clang::DiagnosticIDs()), &*DiagOpts,
&DiagnosticPrinter, false);
llvm::IntrusiveRefCntPtr<clang::FileManager> Files(new clang::FileManager(clang::FileSystemOptions()));
const std::unique_ptr<clang::driver::Driver> Driver(
newDriver(&Diagnostics, BinaryName, Files->getVirtualFileSystem()));
// Since the input might only be virtual, don't check whether it exists.
Driver->setCheckInputsExist(false);
const std::unique_ptr<clang::driver::Compilation> Compilation(
Driver->BuildCompilation(llvm::makeArrayRef(Argv)));
if (Compilation)
{
llvm::raw_string_ostream ss(invocationInfo.invocation);
Compilation->getJobs().Print(ss, "", true);
ss.flush();
}
diagnosticsStream.flush();
invocationInfo.invocation = utility::trim(invocationInfo.invocation);
invocationInfo.errors = utility::trim(invocationInfo.errors);
}
return invocationInfo;
}
std::vector<std::string> prependSyntaxOnlyToolArgs(const std::vector<std::string>& args)
{
return utility::concat(std::vector<std::string>({ "clang-tool", "-fsyntax-only" }), args);
@@ -244,7 +177,7 @@ void CxxParser::runTool(clang::tooling::CompilationDatabase* compilationDatabase
ClangInvocationInfo info;
if (LogManager::getInstance()->getLoggingEnabled())
{
info = getClangInvocationString(compilationDatabase);
info = ClangInvocationInfo::getClangInvocationString(compilationDatabase);
LOG_INFO("Clang Invocation: " + info.invocation.substr(0, ApplicationSettings::getInstance()->getVerboseIndexerLoggingEnabled() ? std::string::npos : 20000));
if (!info.errors.empty())
@@ -260,7 +193,7 @@ void CxxParser::runTool(clang::tooling::CompilationDatabase* compilationDatabase
{
if (info.invocation.empty())
{
info = getClangInvocationString(compilationDatabase);
info = ClangInvocationInfo::getClangInvocationString(compilationDatabase);
}
if (!info.errors.empty())
+133 -69
View File
@@ -5,12 +5,16 @@
#include "Application.h"
#include "ApplicationSettings.h"
#include "ClangInvocationInfo.h"
#include "CxxCompilationDatabaseSingle.h"
#include "CxxIndexerCommandProvider.h"
#include "IndexerCommandCxx.h"
#include "logging.h"
#include "MessageStatus.h"
#include "SourceGroupSettingsCxxCdb.h"
#include "TaskLambda.h"
#include "utility.h"
#include "utilitySourceGroupCxx.h"
SourceGroupCxxCdb::SourceGroupCxxCdb(std::shared_ptr<SourceGroupSettingsCxxCdb> settings)
: m_settings(settings)
@@ -50,15 +54,19 @@ std::set<FilePath> SourceGroupCxxCdb::filterToContainedFilePaths(const std::set<
}
std::set<FilePath> SourceGroupCxxCdb::getAllSourceFilePaths() const
{
return getAllSourceFilePaths(IndexerCommandCxx::loadCDB(m_settings->getCompilationDatabasePathExpandedAndAbsolute()));
}
std::set<FilePath> SourceGroupCxxCdb::getAllSourceFilePaths(std::shared_ptr<clang::tooling::JSONCompilationDatabase> cdb) const
{
std::set<FilePath> sourceFilePaths;
const std::vector<FilePathFilter> excludeFilters = m_settings->getExcludeFiltersExpandedAndAbsolute();
const FilePath cdbPath = m_settings->getCompilationDatabasePathExpandedAndAbsolute();
if (!cdbPath.empty() && cdbPath.exists())
if (cdb)
{
for (const FilePath& path : IndexerCommandCxx::getSourceFilesFromCDB(cdbPath))
const std::vector<FilePathFilter> excludeFilters = m_settings->getExcludeFiltersExpandedAndAbsolute();
for (const FilePath& path :
IndexerCommandCxx::getSourceFilesFromCDB(cdb, m_settings->getCompilationDatabasePathExpandedAndAbsolute()))
{
bool excluded = false;
for (const FilePathFilter& filter : excludeFilters)
@@ -85,76 +93,52 @@ std::shared_ptr<IndexerCommandProvider> SourceGroupCxxCdb::getIndexerCommandProv
std::shared_ptr<CxxIndexerCommandProvider> provider = std::make_shared<CxxIndexerCommandProvider>();
const FilePath cdbPath = m_settings->getCompilationDatabasePathExpandedAndAbsolute();
if (cdbPath.exists())
std::shared_ptr<clang::tooling::JSONCompilationDatabase> cdb = IndexerCommandCxx::loadCDB(cdbPath);
if (!cdb)
{
std::shared_ptr<ApplicationSettings> appSettings = ApplicationSettings::getInstance();
return provider;
}
std::vector<std::wstring> compilerFlags;
std::vector<std::wstring> compilerFlags = getBaseCompilerFlags();
utility::append(compilerFlags, m_settings->getCompilerFlags());
utility::append(compilerFlags, utility::getIncludePchFlags(m_settings.get()));
const std::set<FilePath> indexedHeaderPaths = utility::toSet(m_settings->getIndexedHeaderPathsExpandedAndAbsolute());
const std::set<FilePathFilter> excludeFilters = utility::toSet(m_settings->getExcludeFiltersExpandedAndAbsolute());
const std::set<FilePath>& sourceFilePaths = getAllSourceFilePaths(cdb);
for (const clang::tooling::CompileCommand& command: cdb->getAllCompileCommands())
{
FilePath sourcePath = FilePath(utility::decodeFromUtf8(command.Filename)).makeCanonical();
if (!sourcePath.isAbsolute())
{
utility::append(compilerFlags, IndexerCommandCxx::getCompilerFlagsForSystemHeaderSearchPaths(
utility::concat(m_settings->getHeaderSearchPathsExpandedAndAbsolute(), appSettings->getHeaderSearchPathsExpanded())));
utility::append(compilerFlags, IndexerCommandCxx::getCompilerFlagsForFrameworkSearchPaths(
utility::concat(m_settings->getFrameworkSearchPathsExpandedAndAbsolute(), appSettings->getFrameworkSearchPathsExpanded())));
utility::append(compilerFlags, m_settings->getCompilerFlags());
}
const std::set<FilePath> indexedHeaderPaths = utility::toSet(m_settings->getIndexedHeaderPathsExpandedAndAbsolute());
const std::set<FilePathFilter> excludeFilters = utility::toSet(m_settings->getExcludeFiltersExpandedAndAbsolute());
std::string error;
std::shared_ptr<clang::tooling::JSONCompilationDatabase> cdb = std::shared_ptr<clang::tooling::JSONCompilationDatabase>(
clang::tooling::JSONCompilationDatabase::loadFromFile(utility::encodeToUtf8(cdbPath.wstr()),
error,
clang::tooling::JSONCommandLineSyntax::AutoDetect
)
);
if (!error.empty())
{
const std::wstring message = L"Loading Clang compilation database failed with error: \"" + utility::decodeFromUtf8(error) + L"\"";
LOG_ERROR(message);
MessageStatus(message, true).dispatch();
}
const std::set<FilePath>& sourceFilePaths = getAllSourceFilePaths();
if (cdb)
{
for (const clang::tooling::CompileCommand& command: cdb->getAllCompileCommands())
sourcePath = FilePath(utility::decodeFromUtf8(command.Directory + '/' + command.Filename)).makeCanonical();
if (!sourcePath.isAbsolute())
{
FilePath sourcePath = FilePath(utility::decodeFromUtf8(command.Filename)).makeCanonical();
if (!sourcePath.isAbsolute())
{
sourcePath = FilePath(utility::decodeFromUtf8(command.Directory + '/' + command.Filename)).makeCanonical();
}
if (!sourcePath.isAbsolute())
{
sourcePath = cdbPath.getParentDirectory().getConcatenated(sourcePath).makeCanonical();
}
if (filesToIndex.find(sourcePath) != filesToIndex.end() &&
sourceFilePaths.find(sourcePath) != sourceFilePaths.end())
{
std::vector<std::wstring> mergedCompilerFlags;
mergedCompilerFlags.reserve(compilerFlags.size() + command.CommandLine.size());
for (const std::string& arg : command.CommandLine)
{
mergedCompilerFlags.emplace_back(utility::decodeFromUtf8(arg));
}
mergedCompilerFlags.insert(mergedCompilerFlags.end(), compilerFlags.begin(), compilerFlags.end());
provider->addCommand(std::make_shared<IndexerCommandCxx>(
sourcePath,
utility::concat(indexedHeaderPaths, { sourcePath }),
excludeFilters,
std::set<FilePathFilter>(),
FilePath(utility::decodeFromUtf8(command.Directory)),
mergedCompilerFlags
));
}
sourcePath = cdbPath.getParentDirectory().getConcatenated(sourcePath).makeCanonical();
}
}
if (filesToIndex.find(sourcePath) != filesToIndex.end() &&
sourceFilePaths.find(sourcePath) != sourceFilePaths.end())
{
std::vector<std::wstring> mergedCompilerFlags;
mergedCompilerFlags.reserve(compilerFlags.size() + command.CommandLine.size());
for (const std::string& arg : command.CommandLine)
{
mergedCompilerFlags.emplace_back(utility::decodeFromUtf8(arg));
}
mergedCompilerFlags.insert(mergedCompilerFlags.end(), compilerFlags.begin(), compilerFlags.end());
provider->addCommand(std::make_shared<IndexerCommandCxx>(
sourcePath,
utility::concat(indexedHeaderPaths, { sourcePath }),
excludeFilters,
std::set<FilePathFilter>(),
FilePath(utility::decodeFromUtf8(command.Directory)),
mergedCompilerFlags
));
}
}
provider->logStats();
@@ -167,6 +151,71 @@ std::vector<std::shared_ptr<IndexerCommand>> SourceGroupCxxCdb::getIndexerComman
return getIndexerCommandProvider(filesToIndex)->consumeAllCommands();
}
std::shared_ptr<Task> SourceGroupCxxCdb::getPreIndexTask(std::shared_ptr<DialogView> dialogView) const
{
if (m_settings->getPchInputFilePath().empty())
{
return std::make_shared<TaskLambda>([](){});
}
std::vector<std::wstring> compilerFlags;
if (m_settings->getUseCompilerFlags())
{
const FilePath cdbPath = m_settings->getCompilationDatabasePathExpandedAndAbsolute();
std::shared_ptr<clang::tooling::JSONCompilationDatabase> cdb = IndexerCommandCxx::loadCDB(cdbPath);
if (cdb)
{
const std::set<FilePath>& sourceFilePaths = getAllSourceFilePaths(cdb);
for (const clang::tooling::CompileCommand& command: cdb->getAllCompileCommands())
{
FilePath sourcePath = FilePath(utility::decodeFromUtf8(command.Filename)).makeCanonical();
if (!sourcePath.isAbsolute())
{
sourcePath = FilePath(utility::decodeFromUtf8(command.Directory + '/' + command.Filename)).makeCanonical();
if (!sourcePath.isAbsolute())
{
sourcePath = cdbPath.getParentDirectory().getConcatenated(sourcePath).makeCanonical();
}
}
if (sourceFilePaths.find(sourcePath) != sourceFilePaths.end())
{
for (const std::string& arg : command.CommandLine)
{
if ((compilerFlags.size() || utility::isPrefix<std::string>("-", arg)) &&
FilePath(arg).fileName() != sourcePath.fileName())
{
compilerFlags.emplace_back(utility::decodeFromUtf8(arg));
}
}
CxxCompilationDatabaseSingle compilationDatabase(command);
ClangInvocationInfo info = ClangInvocationInfo::getClangInvocationString(&compilationDatabase);
if (info.invocation.find("\"-x\" \"c++\""))
{
compilerFlags.push_back(L"-x");
compilerFlags.push_back(L"c++");
}
break;
}
}
}
}
utility::append(compilerFlags, getBaseCompilerFlags());
if (m_settings->getUseCompilerFlags())
{
utility::append(compilerFlags, m_settings->getCompilerFlags());
}
utility::append(compilerFlags, m_settings->getPchFlags());
return utility::createBuildPchTask(m_settings.get(), compilerFlags, dialogView);
}
std::shared_ptr<SourceGroupSettings> SourceGroupCxxCdb::getSourceGroupSettings()
{
return m_settings;
@@ -176,3 +225,18 @@ std::shared_ptr<const SourceGroupSettings> SourceGroupCxxCdb::getSourceGroupSett
{
return m_settings;
}
std::vector<std::wstring> SourceGroupCxxCdb::getBaseCompilerFlags() const
{
std::vector<std::wstring> compilerFlags;
std::shared_ptr<ApplicationSettings> appSettings = ApplicationSettings::getInstance();
utility::append(compilerFlags, IndexerCommandCxx::getCompilerFlagsForSystemHeaderSearchPaths(
utility::concat(m_settings->getHeaderSearchPathsExpandedAndAbsolute(), appSettings->getHeaderSearchPathsExpanded())));
utility::append(compilerFlags, IndexerCommandCxx::getCompilerFlagsForFrameworkSearchPaths(
utility::concat(m_settings->getFrameworkSearchPathsExpandedAndAbsolute(), appSettings->getFrameworkSearchPathsExpanded())));
return compilerFlags;
}
+10
View File
@@ -7,6 +7,13 @@
#include "SourceGroup.h"
class FilePath;
namespace clang {
namespace tooling {
class JSONCompilationDatabase;
}
}
class SourceGroupSettingsCxxCdb;
class SourceGroupCxxCdb: public SourceGroup
@@ -17,12 +24,15 @@ public:
bool prepareIndexing() override;
std::set<FilePath> filterToContainedFilePaths(const std::set<FilePath>& filePaths) const override;
std::set<FilePath> getAllSourceFilePaths() const override;
std::set<FilePath> getAllSourceFilePaths(std::shared_ptr<clang::tooling::JSONCompilationDatabase> cdb) const;
std::shared_ptr<IndexerCommandProvider> getIndexerCommandProvider(const std::set<FilePath>& filesToIndex) const override;
std::vector<std::shared_ptr<IndexerCommand>> getIndexerCommands(const std::set<FilePath>& filesToIndex) const override;
std::shared_ptr<Task> getPreIndexTask(std::shared_ptr<DialogView> dialogView) const override;
private:
std::shared_ptr<SourceGroupSettings> getSourceGroupSettings() override;
std::shared_ptr<const SourceGroupSettings> getSourceGroupSettings() const override;
std::vector<std::wstring> getBaseCompilerFlags() const;
std::shared_ptr<SourceGroupSettingsCxxCdb> m_settings;
};
+20 -82
View File
@@ -1,22 +1,16 @@
#include "SourceGroupCxxEmpty.h"
#include "ApplicationSettings.h"
#include "CxxCompilationDatabaseSingle.h"
#include "CxxIndexerCommandProvider.h"
#include "CxxParser.h"
#include "DialogView.h"
#include "FileManager.h"
#include "FileSystem.h"
#include "GeneratePCHAction.h"
#include "IndexerCommandCxx.h"
#include "logging.h"
#include "SingleFrontendActionFactory.h"
#include "SourceGroupSettingsCEmpty.h"
#include "SourceGroupSettingsCppEmpty.h"
#include "SourceGroupSettingsWithCppStandard.h"
#include "SourceGroupSettingsWithCStandard.h"
#include "TaskLambda.h"
#include "utility.h"
#include "utilitySourceGroupCxx.h"
SourceGroupCxxEmpty::SourceGroupCxxEmpty(std::shared_ptr<SourceGroupSettingsCxx> settings)
: m_settings(settings)
@@ -77,34 +71,22 @@ std::shared_ptr<IndexerCommandProvider> SourceGroupCxxEmpty::getIndexerCommandPr
{
std::set<FilePath> indexedPaths;
std::set<FilePathFilter> excludeFilters;
FilePath pchInputFilePath;
FilePath pchDependenciesDirectoryPath;
if (std::shared_ptr<SourceGroupSettingsCEmpty> settings =
std::dynamic_pointer_cast<SourceGroupSettingsCEmpty>(m_settings))
{
indexedPaths = utility::toSet(settings->getSourcePathsExpandedAndAbsolute());
excludeFilters = utility::toSet(settings->getExcludeFiltersExpandedAndAbsolute());
pchInputFilePath = settings->getPchInputFilePathExpandedAndAbsolute();
pchDependenciesDirectoryPath = settings->getPchDependenciesDirectoryPath();
}
else if (std::shared_ptr<SourceGroupSettingsCppEmpty> settings =
std::dynamic_pointer_cast<SourceGroupSettingsCppEmpty>(m_settings))
{
indexedPaths = utility::toSet(settings->getSourcePathsExpandedAndAbsolute());
excludeFilters = utility::toSet(settings->getExcludeFiltersExpandedAndAbsolute());
pchInputFilePath = settings->getPchInputFilePathExpandedAndAbsolute();
pchDependenciesDirectoryPath = settings->getPchDependenciesDirectoryPath();
}
std::vector<std::wstring> compilerFlags = getCompilerFlags();
if (!pchInputFilePath.empty() && !pchDependenciesDirectoryPath.empty())
{
const FilePath pchOutputFilePath = pchDependenciesDirectoryPath.getConcatenated(pchInputFilePath.fileName()).replaceExtension(L"pch");
compilerFlags.push_back(L"-fallow-pch-with-compiler-errors");
compilerFlags.push_back(L"-include-pch");
compilerFlags.push_back(pchOutputFilePath.wstr());
}
std::vector<std::wstring> compilerFlags = getBaseCompilerFlags();
utility::append(compilerFlags, m_settings->getCompilerFlags());
utility::append(compilerFlags, utility::getIncludePchFlags(m_settings.get()));
std::shared_ptr<CxxIndexerCommandProvider> provider = std::make_shared<CxxIndexerCommandProvider>();
for (const FilePath& sourcePath: getAllSourceFilePaths())
@@ -132,69 +114,27 @@ std::vector<std::shared_ptr<IndexerCommand>> SourceGroupCxxEmpty::getIndexerComm
std::shared_ptr<Task> SourceGroupCxxEmpty::getPreIndexTask(std::shared_ptr<DialogView> dialogView) const
{
FilePath pchInputFilePath;
FilePath pchDependenciesDirectoryPath;
if (std::shared_ptr<SourceGroupSettingsCEmpty> settings =
std::dynamic_pointer_cast<SourceGroupSettingsCEmpty>(m_settings))
const SourceGroupSettingsWithCxxPchOptions* pchSettings =
dynamic_cast<const SourceGroupSettingsWithCxxPchOptions*>(m_settings.get());
if (!pchSettings || pchSettings->getPchInputFilePath().empty())
{
pchInputFilePath = settings->getPchInputFilePathExpandedAndAbsolute();
pchDependenciesDirectoryPath = settings->getPchDependenciesDirectoryPath();
}
else if (std::shared_ptr<SourceGroupSettingsCppEmpty> settings =
std::dynamic_pointer_cast<SourceGroupSettingsCppEmpty>(m_settings))
{
pchInputFilePath = settings->getPchInputFilePathExpandedAndAbsolute();
pchDependenciesDirectoryPath = settings->getPchDependenciesDirectoryPath();
return std::make_shared<TaskLambda>([](){});
}
if (pchInputFilePath.empty() || pchDependenciesDirectoryPath.empty())
std::vector<std::wstring> compilerFlags = getBaseCompilerFlags();
if (std::shared_ptr<SourceGroupSettingsWithCxxPchOptions> pchSettings =
std::dynamic_pointer_cast<SourceGroupSettingsWithCxxPchOptions>(m_settings))
{
return std::make_shared<TaskLambda>([]() {});
}
if (!pchInputFilePath.exists())
{
LOG_ERROR(L"Precompiled header input file \"" + pchInputFilePath.wstr() + L"\" does not exist.");
return std::make_shared<TaskLambda>([]() {});
}
const FilePath pchOutputFilePath = pchDependenciesDirectoryPath.getConcatenated(pchInputFilePath.fileName()).replaceExtension(L"pch");
std::vector<std::wstring> compilerFlags = getCompilerFlags();
compilerFlags.push_back(pchInputFilePath.wstr());
compilerFlags.push_back(L"-emit-pch");
compilerFlags.push_back(L"-o");
compilerFlags.push_back(pchOutputFilePath.wstr());
return std::make_shared<TaskLambda>(
[dialogView, pchInputFilePath, pchOutputFilePath, compilerFlags]()
if (pchSettings->getUseCompilerFlags())
{
dialogView->showUnknownProgressDialog(L"Preparing Indexing", L"Processing Precompiled Headers");
LOG_INFO(
L"Generating precompiled header output for input file \"" + pchInputFilePath.wstr() +
L"\" at location \"" + pchOutputFilePath.wstr() + L"\""
);
CxxParser::initializeLLVM();
if (!pchOutputFilePath.getParentDirectory().exists())
{
FileSystem::createDirectory(pchOutputFilePath.getParentDirectory());
}
clang::tooling::CompileCommand pchCommand;
pchCommand.Filename = utility::encodeToUtf8(pchInputFilePath.fileName());
pchCommand.Directory = pchOutputFilePath.getParentDirectory().str();
// DON'T use "-fsyntax-only" here because it will cause the output file to be erased
pchCommand.CommandLine = utility::concat({ "clang-tool" }, CxxParser::getCommandlineArgumentsEssential(compilerFlags));
CxxCompilationDatabaseSingle compilationDatabase(pchCommand);
clang::tooling::ClangTool tool(compilationDatabase, std::vector<std::string>(1, utility::encodeToUtf8(pchInputFilePath.wstr())));
GeneratePCHAction* action = new GeneratePCHAction();
tool.clearArgumentsAdjusters();
tool.run(new SingleFrontendActionFactory(action));
utility::append(compilerFlags, m_settings->getCompilerFlags());
}
);
utility::append(compilerFlags, pchSettings->getPchFlags());
}
return utility::createBuildPchTask(m_settings.get(), compilerFlags, dialogView);
}
std::shared_ptr<SourceGroupSettings> SourceGroupCxxEmpty::getSourceGroupSettings()
@@ -207,7 +147,7 @@ std::shared_ptr<const SourceGroupSettings> SourceGroupCxxEmpty::getSourceGroupSe
return m_settings;
}
std::vector<std::wstring> SourceGroupCxxEmpty::getCompilerFlags() const
std::vector<std::wstring> SourceGroupCxxEmpty::getBaseCompilerFlags() const
{
std::vector<std::wstring> compilerFlags;
@@ -267,8 +207,6 @@ std::vector<std::wstring> SourceGroupCxxEmpty::getCompilerFlags() const
utility::concat(m_settings->getFrameworkSearchPathsExpandedAndAbsolute(), appSettings->getFrameworkSearchPathsExpanded())));
}
utility::append(compilerFlags, m_settings->getCompilerFlags());
return compilerFlags;
}
+1 -1
View File
@@ -22,7 +22,7 @@ public:
private:
std::shared_ptr<SourceGroupSettings> getSourceGroupSettings() override;
std::shared_ptr<const SourceGroupSettings> getSourceGroupSettings() const override;
std::vector<std::wstring> getCompilerFlags() const;
std::vector<std::wstring> getBaseCompilerFlags() const;
std::shared_ptr<SourceGroupSettingsCxx> m_settings;
};
@@ -0,0 +1,98 @@
#include "utilitySourceGroupCxx.h"
#include "CxxCompilationDatabaseSingle.h"
#include "CxxParser.h"
#include "DialogView.h"
#include "FileSystem.h"
#include "GeneratePCHAction.h"
#include "logging.h"
#include "SingleFrontendActionFactory.h"
#include "SourceGroupSettingsCxx.h"
#include "SourceGroupSettingsWithCxxPchOptions.h"
#include "TaskLambda.h"
#include "utility.h"
namespace utility
{
std::shared_ptr<Task> createBuildPchTask(
const SourceGroupSettingsCxx* settings, std::vector<std::wstring> compilerFlags, std::shared_ptr<DialogView> dialogView)
{
const SourceGroupSettingsWithCxxPchOptions* pchSettings = dynamic_cast<const SourceGroupSettingsWithCxxPchOptions*>(settings);
if (!pchSettings)
{
return std::make_shared<TaskLambda>([](){});
}
FilePath pchInputFilePath = pchSettings->getPchInputFilePathExpandedAndAbsolute();
FilePath pchDependenciesDirectoryPath = pchSettings->getPchDependenciesDirectoryPath();
if (pchInputFilePath.empty() || pchDependenciesDirectoryPath.empty())
{
return std::make_shared<TaskLambda>([](){});
}
if (!pchInputFilePath.exists())
{
LOG_ERROR(L"Precompiled header input file \"" + pchInputFilePath.wstr() + L"\" does not exist.");
return std::make_shared<TaskLambda>([]() {});
}
const FilePath pchOutputFilePath = pchDependenciesDirectoryPath.getConcatenated(pchInputFilePath.fileName()).replaceExtension(L"pch");
compilerFlags.push_back(pchInputFilePath.wstr());
compilerFlags.push_back(L"-emit-pch");
compilerFlags.push_back(L"-o");
compilerFlags.push_back(pchOutputFilePath.wstr());
return std::make_shared<TaskLambda>(
[dialogView, pchInputFilePath, pchOutputFilePath, compilerFlags]()
{
dialogView->showUnknownProgressDialog(L"Preparing Indexing", L"Processing Precompiled Headers");
LOG_INFO(
L"Generating precompiled header output for input file \"" + pchInputFilePath.wstr() +
L"\" at location \"" + pchOutputFilePath.wstr() + L"\""
);
CxxParser::initializeLLVM();
if (!pchOutputFilePath.getParentDirectory().exists())
{
FileSystem::createDirectory(pchOutputFilePath.getParentDirectory());
}
clang::tooling::CompileCommand pchCommand;
pchCommand.Filename = utility::encodeToUtf8(pchInputFilePath.fileName());
pchCommand.Directory = pchOutputFilePath.getParentDirectory().str();
// DON'T use "-fsyntax-only" here because it will cause the output file to be erased
pchCommand.CommandLine = utility::concat({ "clang-tool" }, CxxParser::getCommandlineArgumentsEssential(compilerFlags));
CxxCompilationDatabaseSingle compilationDatabase(pchCommand);
clang::tooling::ClangTool tool(compilationDatabase, std::vector<std::string>(1, utility::encodeToUtf8(pchInputFilePath.wstr())));
GeneratePCHAction* action = new GeneratePCHAction();
tool.clearArgumentsAdjusters();
tool.run(new SingleFrontendActionFactory(action));
}
);
}
std::vector<std::wstring> getIncludePchFlags(const SourceGroupSettingsCxx* settings)
{
const SourceGroupSettingsWithCxxPchOptions* pchSettings = dynamic_cast<const SourceGroupSettingsWithCxxPchOptions*>(settings);
if (pchSettings)
{
const FilePath pchInputFilePath = pchSettings->getPchInputFilePathExpandedAndAbsolute();
const FilePath pchDependenciesDirectoryPath = pchSettings->getPchDependenciesDirectoryPath();
if (!pchInputFilePath.empty() && !pchDependenciesDirectoryPath.empty())
{
const FilePath pchOutputFilePath = pchDependenciesDirectoryPath.getConcatenated(pchInputFilePath.fileName()).replaceExtension(L"pch");
return {
L"-fallow-pch-with-compiler-errors",
L"-include-pch",
pchOutputFilePath.wstr()
};
}
}
return {};
}
}
@@ -0,0 +1,19 @@
#ifndef UTILITY_SOURCE_GROUP_CXX_H
#define UTILITY_SOURCE_GROUP_CXX_H
#include <memory>
#include <string>
#include <vector>
class DialogView;
class SourceGroupSettingsCxx;
class Task;
namespace utility
{
std::shared_ptr<Task> createBuildPchTask(
const SourceGroupSettingsCxx* settings, std::vector<std::wstring> compilerFlags, std::shared_ptr<DialogView> dialogView);
std::vector<std::wstring> getIncludePchFlags(const SourceGroupSettingsCxx* settings);
}
#endif // UTILITY_SOURCE_GROUP_CXX_H
+2
View File
@@ -190,6 +190,8 @@ add_files(
qt/project_wizard/content/QtProjectWizardContentCStandard.h
qt/project_wizard/content/QtProjectWizardContentCustomCommand.cpp
qt/project_wizard/content/QtProjectWizardContentCustomCommand.h
qt/project_wizard/content/QtProjectWizardContentCxxPchFlags.cpp
qt/project_wizard/content/QtProjectWizardContentCxxPchFlags.h
qt/project_wizard/content/QtProjectWizardContentExtensions.cpp
qt/project_wizard/content/QtProjectWizardContentExtensions.h
qt/project_wizard/content/QtProjectWizardContentFlags.cpp
@@ -12,6 +12,7 @@
#include "QtProjectWizardContentCrossCompilationOptions.h"
#include "QtProjectWizardContentCStandard.h"
#include "QtProjectWizardContentCustomCommand.h"
#include "QtProjectWizardContentCxxPchFlags.h"
#include "QtProjectWizardContentExtensions.h"
#include "QtProjectWizardContentFlags.h"
#include "QtProjectWizardContentGroup.h"
@@ -147,6 +148,7 @@ namespace
return new QtProjectWizardContentPathCxxPch(settings, settings, window);
}
);
page.addContentCreatorWithSettings<QtProjectWizardContentCxxPchFlags>(WIZARD_CONTENT_CONTEXT_ALL, false);
pages.push_back(page);
}
@@ -193,6 +195,7 @@ namespace
return new QtProjectWizardContentPathCxxPch(settings, settings, window);
}
);
page.addContentCreatorWithSettings<QtProjectWizardContentCxxPchFlags>(WIZARD_CONTENT_CONTEXT_ALL, false);
pages.push_back(page);
}
@@ -226,6 +229,14 @@ namespace
{
QtSourceGroupWizardPage<SourceGroupSettingsCxxCdb> page("Advanced (optional)");
page.addContentCreatorWithSettings<QtProjectWizardContentFlags>(WIZARD_CONTENT_CONTEXT_SUMMARY, true);
page.addContentCreator(
WIZARD_CONTENT_CONTEXT_ALL,
[](std::shared_ptr<SourceGroupSettingsCxxCdb> settings, QtProjectWizardWindow* window)
{
return new QtProjectWizardContentPathCxxPch(settings, settings, window);
}
);
page.addContentCreatorWithSettings<QtProjectWizardContentCxxPchFlags>(WIZARD_CONTENT_CONTEXT_ALL, true);
pages.push_back(page);
}
@@ -0,0 +1,85 @@
#include "QtProjectWizardContentCxxPchFlags.h"
#include <QCheckBox>
#include <QMessageBox>
#include "QtStringListBox.h"
#include "SourceGroupSettingsWithCxxPchOptions.h"
QtProjectWizardContentCxxPchFlags::QtProjectWizardContentCxxPchFlags(
std::shared_ptr<SourceGroupSettingsWithCxxPchOptions> settings,
QtProjectWizardWindow* window,
bool isCDB
)
: QtProjectWizardContent(window)
, m_settings(settings)
, m_isCDB(isCDB)
{
}
void QtProjectWizardContentCxxPchFlags::populate(QGridLayout* layout, int& row)
{
const QString labelText("Precompiled Header Flags");
layout->addWidget(createFormLabel(labelText), row, QtProjectWizardWindow::FRONT_COL, 2, 1, Qt::AlignTop);
const QString optionText(m_isCDB ?
"Use flags of first indexed file and 'Additional Compiler Flags'" : "Use 'Compiler Flags'");
const QString optionHelp(m_isCDB ?
"Check <b>" + optionText + "</b> to use the flags specified "
"in the first compile command of the Compilation Database and all flags specified at 'Additional Compiler Flags'." :
"Check <b>" + optionText + "</b> to reuse the flags specified at 'Compiler Flags'.");
addHelpButton(
"Precompiled Header Flags",
"<p>Define compiler flags used during precompiled header file generation.</p>"
"<p>" + optionHelp + "</p>"
"<p>Additionally add compiler flags to the list for precompiled header generation only. Some examples:</p>"
"<p>* use \"-DRELEASE\" to add a preprocessor #define for \"RELEASE\"</p>"
"<p>* use \"-U__clang__\" to remove the preprocessor #define for \"__clang__\"</p>",
layout, row
);
m_useCompilerFlags = new QCheckBox(optionText);
layout->addWidget(m_useCompilerFlags, row, QtProjectWizardWindow::BACK_COL);
row++;
m_list = new QtStringListBox(this, labelText);
layout->addWidget(m_list, row, QtProjectWizardWindow::BACK_COL);
row++;
}
void QtProjectWizardContentCxxPchFlags::load()
{
m_useCompilerFlags->setChecked(m_settings->getUseCompilerFlags());
m_list->setStrings(m_settings->getPchFlags());
}
void QtProjectWizardContentCxxPchFlags::save()
{
m_settings->setUseCompilerFlags(m_useCompilerFlags->isChecked());
m_settings->setPchFlags(m_list->getStrings());
}
bool QtProjectWizardContentCxxPchFlags::check()
{
std::wstring error;
for (const std::wstring& flag : m_list->getStrings())
{
if (utility::isPrefix<std::wstring>(L"-include ", flag) || utility::isPrefix<std::wstring>(L"--include ", flag))
{
error = L"The entered flag \"" + flag + L"\" contains an error. Please remove the intermediate space character.\n";
}
}
if (!error.empty())
{
QMessageBox msgBox;
msgBox.setText(QString::fromStdWString(error));
msgBox.exec();
return false;
}
return true;
}
@@ -0,0 +1,37 @@
#ifndef QT_PROJECT_WIZARD_CONTENT_CXX_PCH_FLAGS_H
#define QT_PROJECT_WIZARD_CONTENT_CXX_PCH_FLAGS_H
#include "QtProjectWizardContent.h"
class QCheckBox;
class QtStringListBox;
class SourceGroupSettingsWithCxxPchOptions;
class QtProjectWizardContentCxxPchFlags
: public QtProjectWizardContent
{
Q_OBJECT
public:
QtProjectWizardContentCxxPchFlags(
std::shared_ptr<SourceGroupSettingsWithCxxPchOptions> settings,
QtProjectWizardWindow* window,
bool isCDB
);
// QtProjectWizardContent implementation
virtual void populate(QGridLayout* layout, int& row) override;
virtual void load() override;
virtual void save() override;
virtual bool check() override;
private:
std::shared_ptr<SourceGroupSettingsWithCxxPchOptions> m_settings;
const bool m_isCDB;
QCheckBox* m_useCompilerFlags;
QtStringListBox* m_list;
};
#endif // QT_PROJECT_WIZARD_CONTENT_CXX_PCH_FLAGS_H
@@ -15,12 +15,12 @@ QtProjectWizardContentPathCxxPch::QtProjectWizardContentPathCxxPch(
{
setTitleString("Precompiled Header File");
setHelpString(
"Specify the path to the input header file that should be used to generate a precompiled header during indexing.<br />"
"Specify the path to the input header file that should be used to generate a precompiled header before indexing.<br />"
"If the indexed source code is usually built using precompiled headers, using this option will speed up your indexing performance.<br />"
"Leave blank to disable the use of precompiled headers. You can make use of environment variables with ${ENV_VAR}."
);
setAllowEmpty(true);
setPlaceholderString("Not Using Precompiled Headers");
setPlaceholderString("Not Using Precompiled Header");
}
void QtProjectWizardContentPathCxxPch::populate(QGridLayout* layout, int& row)
+19
View File
@@ -0,0 +1,19 @@
#!/bin/bash
# get absolute path to parent directory of script
MY_PATH=`dirname "$0"`
if [[ "${MY_PATH}" != *\\* ]]
then
cd $MY_PATH
MY_PATH=`pwd`
fi
MY_PATH="${MY_PATH//\\//}"
SRC_PATH=$MY_PATH/data
WORKING_COPY_PATH=$MY_PATH/working_copy
mkdir -p $WORKING_COPY_PATH
cp -a $SRC_PATH/. $WORKING_COPY_PATH
echo "Setup Complete"
+16
View File
@@ -0,0 +1,16 @@
#!/bin/bash
# get absolute path to parent directory of script
MY_PATH=`dirname "$0"`
if [[ "${MY_PATH}" != *\\* ]]
then
cd $MY_PATH
MY_PATH=`pwd`
fi
MY_PATH="${MY_PATH//\\//}"
WORKING_COPY_PATH=$MY_PATH/working_copy
rm -rf $WORKING_COPY_PATH
echo "Teardown Complete"
@@ -0,0 +1,25 @@
* Run "1_setup.sh"
* Start up Sourcetrail
* Click "New Project"
* Enter a project name
* Set "./working_copy" as project location
* Click "Add Source Group"
* Select "C++" -> Empty C++ Source Group"
* Click "Next"
* Click "Next"
* Add "./src" to "Files & Directories to Index"
* Add "**/Foo.h" to "Excluded Files & Directories"
* Click "Next"
* Click "Next"
* Click "Next"
* Add "-DCOMPILER_FLAG" to "Compiler Flags"
* Add "./src/pch.h" to "Precompiled Header File"
* Add "-DPCH_FLAG" to "Precompiled Header Flags"
* Click "Next"
* Click "Create"
* Validate "All files" is the only option selectable
* Click "Start"
* Validate Project indexed without error
* Click "OK"
* Close Sourcetrail
* Run "2_teardown.sh"
@@ -0,0 +1,10 @@
#ifndef FOO_H
#define FOO_H
#include "FooBar.h"
class Bar : public FooBar
{
};
#endif // FOO_H
@@ -0,0 +1,10 @@
#ifndef BAR_H
#define BAR_H
#include "FooBar.h"
class Foo : public FooBar
{
};
#endif // FOO_BAR_H
@@ -0,0 +1,12 @@
#ifndef FOO_BAR_H
#define FOO_BAR_H
#ifdef COMPILER_FLAG
class FooBar
{
};
#endif
#endif // FOO_BAR_H
@@ -0,0 +1,7 @@
#include "pch.h"
void test()
{
Foo foo;
Bar bar;
}
@@ -0,0 +1,7 @@
#ifdef PCH_FLAG
#include "Foo.h"
#include "Bar.h"
#endif
+1 -1
View File
@@ -21,7 +21,7 @@ cp -a $SRC_PATH/. $WORKING_COPY_PATH
echo "[" >> $CDB_PATH
echo " {" >> $CDB_PATH
echo " \"directory\": \"${WORKING_COPY_PATH}\"," >> $CDB_PATH
echo " \"command\": \"clang-tool -fms-extensions -fms-compatibility -fms-compatibility-version=19 -isystem \\\"${WORKING_COPY_SRC_PATH}/include\\\" -D _DEBUG -D _MT -D _DLL -D WIN32 -D _WINDOWS -D BUILD_TYPE=\\\"\\\" -D QT_WIDGETS_LIB -D QT_GUI_LIB -D QT_CORE_LIB -D QT_NETWORK_LIB -D QT_WINEXTRAS_LIB -D QT_SVG_LIB -D CMAKE_INTDIR=\\\"Debug\\\" -D _MBCS -std=c++14 \\\"${WORKING_COPY_SRC_PATH}/main.cpp\\\"\"" >> $CDB_PATH
echo " \"command\": \"clang-tool -fms-extensions -fms-compatibility -fms-compatibility-version=19 -isystem \\\"${WORKING_COPY_SRC_PATH}/include\\\" -D _DEBUG -D _MT -D _DLL -D WIN32 -D _WINDOWS -D BUILD_TYPE=\\\"\\\" -D QT_WIDGETS_LIB -D QT_GUI_LIB -D QT_CORE_LIB -D QT_NETWORK_LIB -D QT_WINEXTRAS_LIB -D QT_SVG_LIB -D CMAKE_INTDIR=\\\"Debug\\\" -D _MBCS -std=c++14 \\\"${WORKING_COPY_SRC_PATH}/main.cpp\\\"\"," >> $CDB_PATH
echo " \"file\": \"${WORKING_COPY_SRC_PATH}/main.cpp\"" >> $CDB_PATH
echo " }" >> $CDB_PATH
echo "]" >> $CDB_PATH
+29
View File
@@ -0,0 +1,29 @@
#!/bin/bash
# get absolute path to parent directory of script
MY_PATH=`dirname "$0"`
if [[ "${MY_PATH}" != *\\* ]]
then
cd $MY_PATH
MY_PATH=`pwd`
fi
MY_PATH="${MY_PATH//\\//}"
SRC_PATH=$MY_PATH/data
WORKING_COPY_PATH=$MY_PATH/working_copy
WORKING_COPY_SRC_PATH=$WORKING_COPY_PATH/src
CDB_PATH=$WORKING_COPY_PATH/compile_commands.json
mkdir -p $WORKING_COPY_PATH
cp -a $SRC_PATH/. $WORKING_COPY_PATH
echo "[" >> $CDB_PATH
echo " {" >> $CDB_PATH
echo " \"directory\": \"${WORKING_COPY_PATH}\"," >> $CDB_PATH
echo " \"command\": \"clang-tool -fms-extensions -fms-compatibility -fms-compatibility-version=19 -isystem \\\"${WORKING_COPY_SRC_PATH}/include\\\" -DCDB_FLAG -D _DEBUG -D _MT -D _DLL -D WIN32 -D _WINDOWS -D BUILD_TYPE=\\\"\\\" -D QT_WIDGETS_LIB -D QT_GUI_LIB -D QT_CORE_LIB -D QT_NETWORK_LIB -D QT_WINEXTRAS_LIB -D QT_SVG_LIB -D CMAKE_INTDIR=\\\"Debug\\\" -D _MBCS -std=c++14 \\\"${WORKING_COPY_SRC_PATH}/main.cpp\\\"\"," >> $CDB_PATH
echo " \"file\": \"${WORKING_COPY_SRC_PATH}/main.cpp\"" >> $CDB_PATH
echo " }" >> $CDB_PATH
echo "]" >> $CDB_PATH
echo "Setup Complete"
+16
View File
@@ -0,0 +1,16 @@
#!/bin/bash
# get absolute path to parent directory of script
MY_PATH=`dirname "$0"`
if [[ "${MY_PATH}" != *\\* ]]
then
cd $MY_PATH
MY_PATH=`pwd`
fi
MY_PATH="${MY_PATH//\\//}"
WORKING_COPY_PATH=$MY_PATH/working_copy
rm -rf $WORKING_COPY_PATH
echo "Teardown Complete"
@@ -0,0 +1,26 @@
* Run "1_setup.sh"
* Start up Sourcetrail
* Click "New Project"
* Enter a project name
* Set "./working_copy" as project location
* Click "Add Source Group"
* Select "C++" -> C/C++ from Compilation Database"
* Click "Next"
* Pick "compile_commands.json" at "Compilation Database"
* Click "show source files" button
* Validate "Source Files" list contains "src/main.cpp"
* Click "OK"
* Validate "Header Files & Directories to Index" contains "src" entry
* Add "**/Foo.h" to "Excluded Files & Directories"
* Click "Next"
* Click "Next"
* Add "-DCOMPILER_FLAG" to "Additional Compiler Flags"
* Add "./src/pch.h" to "Precompiled Header File"
* Add "-DPCH_FLAG" to "Precompiled Header Flags"
* Click "Create"
* Validate "All files" is the only option selectable
* Click "Start"
* Validate Project indexed without error
* Click "OK"
* Close Sourcetrail
* Run "2_teardown.sh"
@@ -0,0 +1,17 @@
#ifndef FOO_H
#define FOO_H
#include "FooBar.h"
#ifndef COMPILER_FLAG
#error "COMPILER_FLAG not defined"
#else
class Bar : public FooBar
{
};
#endif
#endif // FOO_H
@@ -0,0 +1,14 @@
#ifndef BAR_H
#define BAR_H
#include "FooBar.h"
#ifndef CDB_FLAG
#error "CDB_FLAG not defined"
#endif
class Foo : public FooBar
{
};
#endif // FOO_BAR_H
@@ -0,0 +1,8 @@
#ifndef FOO_BAR_H
#define FOO_BAR_H
class FooBar
{
};
#endif // FOO_BAR_H
@@ -0,0 +1,8 @@
#include "pch.h"
void test()
{
Foo foo;
Bar bar;
}
@@ -0,0 +1,9 @@
#ifndef PCH_FLAG
#error "PCH_FLAG not defined"
#else
#include "Foo.h"
#include "Bar.h"
#endif
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8" ?>
<config>
<source_groups>
<source_group_ffef4a06-185d-4b00-99b1-5c32b26cecf9>
<build_file_path>
<compilation_db_path>compile_commands.json</compilation_db_path>
</build_file_path>
<compiler_flags>
<compiler_flag>-DCOMPILER_FLAG</compiler_flag>
</compiler_flags>
<indexed_header_paths>
<indexed_header_path>src</indexed_header_path>
</indexed_header_paths>
<name>C/C++ from Compilation Database</name>
<pch_flags>
<pch_flag>-DPCH_FLAG</pch_flag>
<use_cdb_flags>1</use_cdb_flags>
<use_compiler_flags>1</use_compiler_flags>
</pch_flags>
<pch_input_file_path>src/pch.hpp</pch_input_file_path>
<status>enabled</status>
<type>C/C++ from Compilation Database</type>
</source_group_ffef4a06-185d-4b00-99b1-5c32b26cecf9>
</source_groups>
<version>8</version>
</config>
@@ -0,0 +1,7 @@
[
{
"directory": "/Users/ebsi/Documents/Coati/testing/project_setup/cxx_cdb_pch/working_copy",
"command": "clang-tool -fms-extensions -fms-compatibility -fms-compatibility-version=19 -isystem \"/Users/ebsi/Documents/Coati/testing/project_setup/cxx_cdb_pch/working_copy/src/include\" -DCDB_FLAG -D _DEBUG -D _MT -D _DLL -D WIN32 -D _WINDOWS -D BUILD_TYPE=\"\" -D QT_WIDGETS_LIB -D QT_GUI_LIB -D QT_CORE_LIB -D QT_NETWORK_LIB -D QT_WINEXTRAS_LIB -D QT_SVG_LIB -D CMAKE_INTDIR=\"Debug\" -D _MBCS -std=c++14 \"/Users/ebsi/Documents/Coati/testing/project_setup/cxx_cdb_pch/working_copy/src/main.cpp\"",
"file": "/Users/ebsi/Documents/Coati/testing/project_setup/cxx_cdb_pch/working_copy/src/main.cpp"
}
]
@@ -0,0 +1,17 @@
#ifndef FOO_H
#define FOO_H
#include "FooBar.h"
#ifndef COMPILER_FLAG
#error "COMPILER_FLAG not defined"
#else
class Bar : public FooBar
{
};
#endif
#endif // FOO_H
@@ -0,0 +1,14 @@
#ifndef BAR_H
#define BAR_H
#include "FooBar.h"
#ifndef CDB_FLAG
#error "CDB_FLAG not defined"
#endif
class Foo : public FooBar
{
};
#endif // FOO_BAR_H
@@ -0,0 +1,8 @@
#ifndef FOO_BAR_H
#define FOO_BAR_H
class FooBar
{
};
#endif // FOO_BAR_H
@@ -0,0 +1,8 @@
#include "pch.hpp"
void test()
{
Foo foo;
Bar bar;
}
@@ -0,0 +1,9 @@
#ifndef PCH_FLAG
#error "PCH_FLAG not defined"
#else
#include "Foo.h"
#include "Bar.h"
#endif