From c6adbab340f2d3893b9a4bb03bf2c102a009b8f0 Mon Sep 17 00:00:00 2001 From: Eberhard Graether Date: Wed, 31 Jul 2019 00:41:08 +0200 Subject: [PATCH] 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 --- .../SourceGroupSettingsCxxCdb.cpp | 3 + .../source_group/SourceGroupSettingsCxxCdb.h | 2 + .../SourceGroupSettingsWithCxxPchOptions.cpp | 29 ++- .../SourceGroupSettingsWithCxxPchOptions.h | 8 + src/lib_cxx/CMakeLists.txt | 4 + .../data/indexer/IndexerCommandCxx.cpp | 32 ++- src/lib_cxx/data/indexer/IndexerCommandCxx.h | 11 +- .../data/parser/cxx/ClangInvocationInfo.cpp | 78 +++++++ .../data/parser/cxx/ClangInvocationInfo.h | 22 ++ src/lib_cxx/data/parser/cxx/CxxParser.cpp | 73 +------ src/lib_cxx/project/SourceGroupCxxCdb.cpp | 202 ++++++++++++------ src/lib_cxx/project/SourceGroupCxxCdb.h | 10 + src/lib_cxx/project/SourceGroupCxxEmpty.cpp | 102 ++------- src/lib_cxx/project/SourceGroupCxxEmpty.h | 2 +- src/lib_cxx/project/utilitySourceGroupCxx.cpp | 98 +++++++++ src/lib_cxx/project/utilitySourceGroupCxx.h | 19 ++ src/lib_gui/CMakeLists.txt | 2 + .../qt/project_wizard/QtProjectWizard.cpp | 11 + .../QtProjectWizardContentCxxPchFlags.cpp | 85 ++++++++ .../QtProjectWizardContentCxxPchFlags.h | 37 ++++ .../path/QtProjectWizardContentPathCxxPch.cpp | 4 +- .../project_setup/cpp_empty_pch/1_setup.sh | 19 ++ .../project_setup/cpp_empty_pch/2_teardown.sh | 16 ++ .../project_setup/cpp_empty_pch/checklist.txt | 25 +++ .../cpp_empty_pch/data/src/Bar.h | 10 + .../cpp_empty_pch/data/src/Foo.h | 10 + .../cpp_empty_pch/data/src/FooBar.h | 12 ++ .../cpp_empty_pch/data/src/main.cpp | 7 + .../cpp_empty_pch/data/src/pch.h | 7 + testing/project_setup/cxx_cdb/1_setup.sh | 2 +- testing/project_setup/cxx_cdb_pch/1_setup.sh | 29 +++ .../project_setup/cxx_cdb_pch/2_teardown.sh | 16 ++ .../project_setup/cxx_cdb_pch/checklist.txt | 26 +++ .../cxx_cdb_pch/data/src/include/Bar.h | 17 ++ .../cxx_cdb_pch/data/src/include/Foo.h | 14 ++ .../cxx_cdb_pch/data/src/include/FooBar.h | 8 + .../cxx_cdb_pch/data/src/main.cpp | 8 + .../project_setup/cxx_cdb_pch/data/src/pch.h | 9 + .../cxx_cdb_pch/working_copy/asdf.srctrlprj | 26 +++ .../working_copy/compile_commands.json | 7 + .../working_copy/src/include/Bar.h | 17 ++ .../working_copy/src/include/Foo.h | 14 ++ .../working_copy/src/include/FooBar.h | 8 + .../cxx_cdb_pch/working_copy/src/main.cpp | 8 + .../cxx_cdb_pch/working_copy/src/pch.hpp | 9 + 45 files changed, 926 insertions(+), 232 deletions(-) create mode 100644 src/lib_cxx/data/parser/cxx/ClangInvocationInfo.cpp create mode 100644 src/lib_cxx/data/parser/cxx/ClangInvocationInfo.h create mode 100644 src/lib_cxx/project/utilitySourceGroupCxx.cpp create mode 100644 src/lib_cxx/project/utilitySourceGroupCxx.h create mode 100644 src/lib_gui/qt/project_wizard/content/QtProjectWizardContentCxxPchFlags.cpp create mode 100644 src/lib_gui/qt/project_wizard/content/QtProjectWizardContentCxxPchFlags.h create mode 100755 testing/project_setup/cpp_empty_pch/1_setup.sh create mode 100755 testing/project_setup/cpp_empty_pch/2_teardown.sh create mode 100644 testing/project_setup/cpp_empty_pch/checklist.txt create mode 100644 testing/project_setup/cpp_empty_pch/data/src/Bar.h create mode 100644 testing/project_setup/cpp_empty_pch/data/src/Foo.h create mode 100644 testing/project_setup/cpp_empty_pch/data/src/FooBar.h create mode 100644 testing/project_setup/cpp_empty_pch/data/src/main.cpp create mode 100644 testing/project_setup/cpp_empty_pch/data/src/pch.h create mode 100755 testing/project_setup/cxx_cdb_pch/1_setup.sh create mode 100755 testing/project_setup/cxx_cdb_pch/2_teardown.sh create mode 100644 testing/project_setup/cxx_cdb_pch/checklist.txt create mode 100644 testing/project_setup/cxx_cdb_pch/data/src/include/Bar.h create mode 100644 testing/project_setup/cxx_cdb_pch/data/src/include/Foo.h create mode 100644 testing/project_setup/cxx_cdb_pch/data/src/include/FooBar.h create mode 100644 testing/project_setup/cxx_cdb_pch/data/src/main.cpp create mode 100644 testing/project_setup/cxx_cdb_pch/data/src/pch.h create mode 100644 testing/project_setup/cxx_cdb_pch/working_copy/asdf.srctrlprj create mode 100644 testing/project_setup/cxx_cdb_pch/working_copy/compile_commands.json create mode 100644 testing/project_setup/cxx_cdb_pch/working_copy/src/include/Bar.h create mode 100644 testing/project_setup/cxx_cdb_pch/working_copy/src/include/Foo.h create mode 100644 testing/project_setup/cxx_cdb_pch/working_copy/src/include/FooBar.h create mode 100644 testing/project_setup/cxx_cdb_pch/working_copy/src/main.cpp create mode 100644 testing/project_setup/cxx_cdb_pch/working_copy/src/pch.hpp diff --git a/src/lib/settings/source_group/SourceGroupSettingsCxxCdb.cpp b/src/lib/settings/source_group/SourceGroupSettingsCxxCdb.cpp index af4c0af5..e43e2f6b 100644 --- a/src/lib/settings/source_group/SourceGroupSettingsCxxCdb.cpp +++ b/src/lib/settings/source_group/SourceGroupSettingsCxxCdb.cpp @@ -21,6 +21,7 @@ void SourceGroupSettingsCxxCdb::load(std::shared_ptr 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 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 othe return ( otherCxxCdb && SourceGroupSettingsCxx::equals(other) && + SourceGroupSettingsWithCxxPchOptions::equals(otherCxxCdb) && SourceGroupSettingsWithExcludeFilters::equals(otherCxxCdb) && SourceGroupSettingsWithIndexedHeaderPaths::equals(otherCxxCdb) && m_compilationDatabasePath == otherCxxCdb->m_compilationDatabasePath diff --git a/src/lib/settings/source_group/SourceGroupSettingsCxxCdb.h b/src/lib/settings/source_group/SourceGroupSettingsCxxCdb.h index 6631e403..d02b0949 100644 --- a/src/lib/settings/source_group/SourceGroupSettingsCxxCdb.h +++ b/src/lib/settings/source_group/SourceGroupSettingsCxxCdb.h @@ -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 { diff --git a/src/lib/settings/source_group/SourceGroupSettingsWithCxxPchOptions.cpp b/src/lib/settings/source_group/SourceGroupSettingsWithCxxPchOptions.cpp index 95dc43b1..14039e4f 100644 --- a/src/lib/settings/source_group/SourceGroupSettingsWithCxxPchOptions.cpp +++ b/src/lib/settings/source_group/SourceGroupSettingsWithCxxPchOptions.cpp @@ -1,24 +1,31 @@ #include "SourceGroupSettingsWithCxxPchOptions.h" #include "ProjectSettings.h" +#include "utility.h" #include "utilityFile.h" bool SourceGroupSettingsWithCxxPchOptions::equals(std::shared_ptr 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 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())); + setUseCompilerFlags(config->getValueOrDefault(key + "/pch_flags/use_compiler_flags", false)); } void SourceGroupSettingsWithCxxPchOptions::save(std::shared_ptr 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 SourceGroupSettingsWithCxxPchOptions::getPchFlags() const +{ + return m_pchFlags; +} + +void SourceGroupSettingsWithCxxPchOptions::setPchFlags(const std::vector& pchFlags) +{ + m_pchFlags = pchFlags; +} diff --git a/src/lib/settings/source_group/SourceGroupSettingsWithCxxPchOptions.h b/src/lib/settings/source_group/SourceGroupSettingsWithCxxPchOptions.h index 98592b0a..02861fb0 100644 --- a/src/lib/settings/source_group/SourceGroupSettingsWithCxxPchOptions.h +++ b/src/lib/settings/source_group/SourceGroupSettingsWithCxxPchOptions.h @@ -24,12 +24,20 @@ public: FilePath getPchInputFilePathExpandedAndAbsolute() const; void setPchInputFilePathFilePath(const FilePath& path); + std::vector getPchFlags() const; + void setPchFlags(const std::vector& pchFlags); + + bool getUseCompilerFlags() const; + void setUseCompilerFlags(bool useCompilerFlags); + protected: void load(std::shared_ptr config, const std::string& key); void save(std::shared_ptr config, const std::string& key); private: FilePath m_pchInputFilePath; + std::vector m_pchFlags; + bool m_useCompilerFlags = true; }; #endif // SOURCE_GROUP_SETTINGS_WITH_CXX_PCH_OPTIONS_H diff --git a/src/lib_cxx/CMakeLists.txt b/src/lib_cxx/CMakeLists.txt index b7e230f8..e44f3494 100644 --- a/src/lib_cxx/CMakeLists.txt +++ b/src/lib_cxx/CMakeLists.txt @@ -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 diff --git a/src/lib_cxx/data/indexer/IndexerCommandCxx.cpp b/src/lib_cxx/data/indexer/IndexerCommandCxx.cpp index 2346a562..23d32307 100644 --- a/src/lib_cxx/data/indexer/IndexerCommandCxx.cpp +++ b/src/lib_cxx/data/indexer/IndexerCommandCxx.cpp @@ -12,11 +12,21 @@ #include "utility.h" #include "utilityString.h" -std::vector IndexerCommandCxx::getSourceFilesFromCDB(const FilePath& compilationDatabasePath) +std::shared_ptr IndexerCommandCxx::loadCDB(const FilePath& cdbPath) { + if (cdbPath.empty() || !cdbPath.exists()) + { + return nullptr; + } + std::string error; - std::shared_ptr cdb = std::shared_ptr - (clang::tooling::JSONCompilationDatabase::loadFromFile(utility::encodeToUtf8(compilationDatabasePath.wstr()), error, clang::tooling::JSONCommandLineSyntax::AutoDetect)); + std::shared_ptr cdb = std::shared_ptr( + clang::tooling::JSONCompilationDatabase::loadFromFile( + utility::encodeToUtf8(cdbPath.wstr()), + error, + clang::tooling::JSONCommandLineSyntax::AutoDetect + ) + ); if (!error.empty()) { @@ -25,6 +35,17 @@ std::vector IndexerCommandCxx::getSourceFilesFromCDB(const FilePath& c MessageStatus(message, true).dispatch(); } + return cdb; +} + +std::vector IndexerCommandCxx::getSourceFilesFromCDB(const FilePath& cdbPath) +{ + return getSourceFilesFromCDB(loadCDB(cdbPath), cdbPath); +} + +std::vector IndexerCommandCxx::getSourceFilesFromCDB( + std::shared_ptr cdb, const FilePath& cdbPath) +{ std::vector filePaths; if (cdb) { @@ -43,7 +64,7 @@ std::vector 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 IndexerCommandCxx::getCompilerFlagsForSystemHeaderSearchPaths(const std::vector& systemHeaderSearchPaths) +std::vector IndexerCommandCxx::getCompilerFlagsForSystemHeaderSearchPaths( + const std::vector& systemHeaderSearchPaths) { std::vector compilerFlags; compilerFlags.reserve(systemHeaderSearchPaths.size() * 2); diff --git a/src/lib_cxx/data/indexer/IndexerCommandCxx.h b/src/lib_cxx/data/indexer/IndexerCommandCxx.h index 3ea11b3f..67167d9a 100644 --- a/src/lib_cxx/data/indexer/IndexerCommandCxx.h +++ b/src/lib_cxx/data/indexer/IndexerCommandCxx.h @@ -7,12 +7,21 @@ #include "IndexerCommand.h" class FilePath; +namespace clang { + namespace tooling { + class JSONCompilationDatabase; + } +} class IndexerCommandCxx : public IndexerCommand { public: - static std::vector getSourceFilesFromCDB(const FilePath& compilationDatabasePath); + static std::shared_ptr loadCDB(const FilePath& cdbPath); + static std::vector getSourceFilesFromCDB(const FilePath& cdbPath); + static std::vector getSourceFilesFromCDB( + std::shared_ptr cdb, const FilePath& cdbPath); + static std::wstring getCompilerFlagLanguageStandard(const std::wstring &languageStandard); static std::vector getCompilerFlagsForSystemHeaderSearchPaths(const std::vector& systemHeaderSearchPaths); static std::vector getCompilerFlagsForFrameworkSearchPaths(const std::vector& frameworkSearchPaths); diff --git a/src/lib_cxx/data/parser/cxx/ClangInvocationInfo.cpp b/src/lib_cxx/data/parser/cxx/ClangInvocationInfo.cpp new file mode 100644 index 00000000..43f63a59 --- /dev/null +++ b/src/lib_cxx/data/parser/cxx/ClangInvocationInfo.cpp @@ -0,0 +1,78 @@ +#include "ClangInvocationInfo.h" + +#include +#include +#include +#include +#include +#include +#include + +#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 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 CommandLine = compilationDatabase->getAllCompileCommands().front().CommandLine; + + std::vector Argv; + for (const std::string &Str : CommandLine) + Argv.push_back(Str.c_str()); + const char *const BinaryName = Argv[0]; + clang::IntrusiveRefCntPtr DiagOpts = new clang::DiagnosticOptions(); + unsigned MissingArgIndex, MissingArgCount; + std::unique_ptr Opts = clang::driver::createDriverOptTable(); + llvm::opt::InputArgList ParsedArgs = Opts->ParseArgs( + clang::ArrayRef(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(new clang::DiagnosticIDs()), &*DiagOpts, + &DiagnosticPrinter, false); + + llvm::IntrusiveRefCntPtr Files(new clang::FileManager(clang::FileSystemOptions())); + + const std::unique_ptr 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 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; +} diff --git a/src/lib_cxx/data/parser/cxx/ClangInvocationInfo.h b/src/lib_cxx/data/parser/cxx/ClangInvocationInfo.h new file mode 100644 index 00000000..946dddc5 --- /dev/null +++ b/src/lib_cxx/data/parser/cxx/ClangInvocationInfo.h @@ -0,0 +1,22 @@ +#ifndef CLANG_INVOCATION_INFO_H +#define CLANG_INVOCATION_INFO_H + +#include + +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 diff --git a/src/lib_cxx/data/parser/cxx/CxxParser.cpp b/src/lib_cxx/data/parser/cxx/CxxParser.cpp index b1fc04e1..91223538 100644 --- a/src/lib_cxx/data/parser/cxx/CxxParser.cpp +++ b/src/lib_cxx/data/parser/cxx/CxxParser.cpp @@ -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 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 CommandLine = compilationDatabase->getAllCompileCommands().front().CommandLine; - - std::vector Argv; - for (const std::string &Str : CommandLine) - Argv.push_back(Str.c_str()); - const char *const BinaryName = Argv[0]; - clang::IntrusiveRefCntPtr DiagOpts = new clang::DiagnosticOptions(); - unsigned MissingArgIndex, MissingArgCount; - std::unique_ptr Opts = clang::driver::createDriverOptTable(); - llvm::opt::InputArgList ParsedArgs = Opts->ParseArgs( - clang::ArrayRef(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(new clang::DiagnosticIDs()), &*DiagOpts, - &DiagnosticPrinter, false); - - llvm::IntrusiveRefCntPtr Files(new clang::FileManager(clang::FileSystemOptions())); - - const std::unique_ptr 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 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 prependSyntaxOnlyToolArgs(const std::vector& args) { return utility::concat(std::vector({ "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()) diff --git a/src/lib_cxx/project/SourceGroupCxxCdb.cpp b/src/lib_cxx/project/SourceGroupCxxCdb.cpp index 41e4bbbb..6bb0b9ac 100644 --- a/src/lib_cxx/project/SourceGroupCxxCdb.cpp +++ b/src/lib_cxx/project/SourceGroupCxxCdb.cpp @@ -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 settings) : m_settings(settings) @@ -50,15 +54,19 @@ std::set SourceGroupCxxCdb::filterToContainedFilePaths(const std::set< } std::set SourceGroupCxxCdb::getAllSourceFilePaths() const +{ + return getAllSourceFilePaths(IndexerCommandCxx::loadCDB(m_settings->getCompilationDatabasePathExpandedAndAbsolute())); +} + +std::set SourceGroupCxxCdb::getAllSourceFilePaths(std::shared_ptr cdb) const { std::set sourceFilePaths; - const std::vector 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 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 SourceGroupCxxCdb::getIndexerCommandProv std::shared_ptr provider = std::make_shared(); const FilePath cdbPath = m_settings->getCompilationDatabasePathExpandedAndAbsolute(); - if (cdbPath.exists()) + std::shared_ptr cdb = IndexerCommandCxx::loadCDB(cdbPath); + if (!cdb) { - std::shared_ptr appSettings = ApplicationSettings::getInstance(); + return provider; + } - std::vector compilerFlags; + std::vector compilerFlags = getBaseCompilerFlags(); + utility::append(compilerFlags, m_settings->getCompilerFlags()); + utility::append(compilerFlags, utility::getIncludePchFlags(m_settings.get())); + + const std::set indexedHeaderPaths = utility::toSet(m_settings->getIndexedHeaderPathsExpandedAndAbsolute()); + const std::set excludeFilters = utility::toSet(m_settings->getExcludeFiltersExpandedAndAbsolute()); + const std::set& 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 indexedHeaderPaths = utility::toSet(m_settings->getIndexedHeaderPathsExpandedAndAbsolute()); - const std::set excludeFilters = utility::toSet(m_settings->getExcludeFiltersExpandedAndAbsolute()); - - std::string error; - std::shared_ptr cdb = std::shared_ptr( - 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& 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 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( - sourcePath, - utility::concat(indexedHeaderPaths, { sourcePath }), - excludeFilters, - std::set(), - 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 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( + sourcePath, + utility::concat(indexedHeaderPaths, { sourcePath }), + excludeFilters, + std::set(), + FilePath(utility::decodeFromUtf8(command.Directory)), + mergedCompilerFlags + )); + } } provider->logStats(); @@ -167,6 +151,71 @@ std::vector> SourceGroupCxxCdb::getIndexerComman return getIndexerCommandProvider(filesToIndex)->consumeAllCommands(); } +std::shared_ptr SourceGroupCxxCdb::getPreIndexTask(std::shared_ptr dialogView) const +{ + if (m_settings->getPchInputFilePath().empty()) + { + return std::make_shared([](){}); + } + + std::vector compilerFlags; + + if (m_settings->getUseCompilerFlags()) + { + const FilePath cdbPath = m_settings->getCompilationDatabasePathExpandedAndAbsolute(); + std::shared_ptr cdb = IndexerCommandCxx::loadCDB(cdbPath); + if (cdb) + { + const std::set& 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("-", 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 SourceGroupCxxCdb::getSourceGroupSettings() { return m_settings; @@ -176,3 +225,18 @@ std::shared_ptr SourceGroupCxxCdb::getSourceGroupSett { return m_settings; } + +std::vector SourceGroupCxxCdb::getBaseCompilerFlags() const +{ + std::vector compilerFlags; + + std::shared_ptr 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; +} diff --git a/src/lib_cxx/project/SourceGroupCxxCdb.h b/src/lib_cxx/project/SourceGroupCxxCdb.h index 0f71854e..3f15e8f1 100644 --- a/src/lib_cxx/project/SourceGroupCxxCdb.h +++ b/src/lib_cxx/project/SourceGroupCxxCdb.h @@ -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 filterToContainedFilePaths(const std::set& filePaths) const override; std::set getAllSourceFilePaths() const override; + std::set getAllSourceFilePaths(std::shared_ptr cdb) const; std::shared_ptr getIndexerCommandProvider(const std::set& filesToIndex) const override; std::vector> getIndexerCommands(const std::set& filesToIndex) const override; + std::shared_ptr getPreIndexTask(std::shared_ptr dialogView) const override; private: std::shared_ptr getSourceGroupSettings() override; std::shared_ptr getSourceGroupSettings() const override; + std::vector getBaseCompilerFlags() const; std::shared_ptr m_settings; }; diff --git a/src/lib_cxx/project/SourceGroupCxxEmpty.cpp b/src/lib_cxx/project/SourceGroupCxxEmpty.cpp index 93b341b1..2766282a 100644 --- a/src/lib_cxx/project/SourceGroupCxxEmpty.cpp +++ b/src/lib_cxx/project/SourceGroupCxxEmpty.cpp @@ -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 settings) : m_settings(settings) @@ -77,34 +71,22 @@ std::shared_ptr SourceGroupCxxEmpty::getIndexerCommandPr { std::set indexedPaths; std::set excludeFilters; - FilePath pchInputFilePath; - FilePath pchDependenciesDirectoryPath; if (std::shared_ptr settings = std::dynamic_pointer_cast(m_settings)) { indexedPaths = utility::toSet(settings->getSourcePathsExpandedAndAbsolute()); excludeFilters = utility::toSet(settings->getExcludeFiltersExpandedAndAbsolute()); - pchInputFilePath = settings->getPchInputFilePathExpandedAndAbsolute(); - pchDependenciesDirectoryPath = settings->getPchDependenciesDirectoryPath(); } else if (std::shared_ptr settings = std::dynamic_pointer_cast(m_settings)) { indexedPaths = utility::toSet(settings->getSourcePathsExpandedAndAbsolute()); excludeFilters = utility::toSet(settings->getExcludeFiltersExpandedAndAbsolute()); - pchInputFilePath = settings->getPchInputFilePathExpandedAndAbsolute(); - pchDependenciesDirectoryPath = settings->getPchDependenciesDirectoryPath(); } - std::vector 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 compilerFlags = getBaseCompilerFlags(); + utility::append(compilerFlags, m_settings->getCompilerFlags()); + utility::append(compilerFlags, utility::getIncludePchFlags(m_settings.get())); std::shared_ptr provider = std::make_shared(); for (const FilePath& sourcePath: getAllSourceFilePaths()) @@ -132,69 +114,27 @@ std::vector> SourceGroupCxxEmpty::getIndexerComm std::shared_ptr SourceGroupCxxEmpty::getPreIndexTask(std::shared_ptr dialogView) const { - FilePath pchInputFilePath; - FilePath pchDependenciesDirectoryPath; - if (std::shared_ptr settings = - std::dynamic_pointer_cast(m_settings)) + const SourceGroupSettingsWithCxxPchOptions* pchSettings = + dynamic_cast(m_settings.get()); + if (!pchSettings || pchSettings->getPchInputFilePath().empty()) { - pchInputFilePath = settings->getPchInputFilePathExpandedAndAbsolute(); - pchDependenciesDirectoryPath = settings->getPchDependenciesDirectoryPath(); - } - else if (std::shared_ptr settings = - std::dynamic_pointer_cast(m_settings)) - { - pchInputFilePath = settings->getPchInputFilePathExpandedAndAbsolute(); - pchDependenciesDirectoryPath = settings->getPchDependenciesDirectoryPath(); + return std::make_shared([](){}); } - if (pchInputFilePath.empty() || pchDependenciesDirectoryPath.empty()) + std::vector compilerFlags = getBaseCompilerFlags(); + + if (std::shared_ptr pchSettings = + std::dynamic_pointer_cast(m_settings)) { - return std::make_shared([]() {}); - } - - if (!pchInputFilePath.exists()) - { - LOG_ERROR(L"Precompiled header input file \"" + pchInputFilePath.wstr() + L"\" does not exist."); - return std::make_shared([]() {}); - } - - const FilePath pchOutputFilePath = pchDependenciesDirectoryPath.getConcatenated(pchInputFilePath.fileName()).replaceExtension(L"pch"); - - std::vector 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( - [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(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 SourceGroupCxxEmpty::getSourceGroupSettings() @@ -207,7 +147,7 @@ std::shared_ptr SourceGroupCxxEmpty::getSourceGroupSe return m_settings; } -std::vector SourceGroupCxxEmpty::getCompilerFlags() const +std::vector SourceGroupCxxEmpty::getBaseCompilerFlags() const { std::vector compilerFlags; @@ -267,8 +207,6 @@ std::vector SourceGroupCxxEmpty::getCompilerFlags() const utility::concat(m_settings->getFrameworkSearchPathsExpandedAndAbsolute(), appSettings->getFrameworkSearchPathsExpanded()))); } - utility::append(compilerFlags, m_settings->getCompilerFlags()); - return compilerFlags; } diff --git a/src/lib_cxx/project/SourceGroupCxxEmpty.h b/src/lib_cxx/project/SourceGroupCxxEmpty.h index 156bcf5f..0daecd01 100644 --- a/src/lib_cxx/project/SourceGroupCxxEmpty.h +++ b/src/lib_cxx/project/SourceGroupCxxEmpty.h @@ -22,7 +22,7 @@ public: private: std::shared_ptr getSourceGroupSettings() override; std::shared_ptr getSourceGroupSettings() const override; - std::vector getCompilerFlags() const; + std::vector getBaseCompilerFlags() const; std::shared_ptr m_settings; }; diff --git a/src/lib_cxx/project/utilitySourceGroupCxx.cpp b/src/lib_cxx/project/utilitySourceGroupCxx.cpp new file mode 100644 index 00000000..e0e262b4 --- /dev/null +++ b/src/lib_cxx/project/utilitySourceGroupCxx.cpp @@ -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 createBuildPchTask( + const SourceGroupSettingsCxx* settings, std::vector compilerFlags, std::shared_ptr dialogView) + { + const SourceGroupSettingsWithCxxPchOptions* pchSettings = dynamic_cast(settings); + if (!pchSettings) + { + return std::make_shared([](){}); + } + + FilePath pchInputFilePath = pchSettings->getPchInputFilePathExpandedAndAbsolute(); + FilePath pchDependenciesDirectoryPath = pchSettings->getPchDependenciesDirectoryPath(); + + if (pchInputFilePath.empty() || pchDependenciesDirectoryPath.empty()) + { + return std::make_shared([](){}); + } + + if (!pchInputFilePath.exists()) + { + LOG_ERROR(L"Precompiled header input file \"" + pchInputFilePath.wstr() + L"\" does not exist."); + return std::make_shared([]() {}); + } + + 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( + [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(1, utility::encodeToUtf8(pchInputFilePath.wstr()))); + GeneratePCHAction* action = new GeneratePCHAction(); + tool.clearArgumentsAdjusters(); + tool.run(new SingleFrontendActionFactory(action)); + } + ); + } + + std::vector getIncludePchFlags(const SourceGroupSettingsCxx* settings) + { + const SourceGroupSettingsWithCxxPchOptions* pchSettings = dynamic_cast(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 {}; + } +} diff --git a/src/lib_cxx/project/utilitySourceGroupCxx.h b/src/lib_cxx/project/utilitySourceGroupCxx.h new file mode 100644 index 00000000..d7f0366f --- /dev/null +++ b/src/lib_cxx/project/utilitySourceGroupCxx.h @@ -0,0 +1,19 @@ +#ifndef UTILITY_SOURCE_GROUP_CXX_H +#define UTILITY_SOURCE_GROUP_CXX_H + +#include +#include +#include + +class DialogView; +class SourceGroupSettingsCxx; +class Task; + +namespace utility +{ + std::shared_ptr createBuildPchTask( + const SourceGroupSettingsCxx* settings, std::vector compilerFlags, std::shared_ptr dialogView); + std::vector getIncludePchFlags(const SourceGroupSettingsCxx* settings); +} + +#endif // UTILITY_SOURCE_GROUP_CXX_H diff --git a/src/lib_gui/CMakeLists.txt b/src/lib_gui/CMakeLists.txt index 1762330a..a7b891c3 100644 --- a/src/lib_gui/CMakeLists.txt +++ b/src/lib_gui/CMakeLists.txt @@ -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 diff --git a/src/lib_gui/qt/project_wizard/QtProjectWizard.cpp b/src/lib_gui/qt/project_wizard/QtProjectWizard.cpp index e07af1c7..cc90fd1c 100644 --- a/src/lib_gui/qt/project_wizard/QtProjectWizard.cpp +++ b/src/lib_gui/qt/project_wizard/QtProjectWizard.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(WIZARD_CONTENT_CONTEXT_ALL, false); pages.push_back(page); } @@ -193,6 +195,7 @@ namespace return new QtProjectWizardContentPathCxxPch(settings, settings, window); } ); + page.addContentCreatorWithSettings(WIZARD_CONTENT_CONTEXT_ALL, false); pages.push_back(page); } @@ -226,6 +229,14 @@ namespace { QtSourceGroupWizardPage page("Advanced (optional)"); page.addContentCreatorWithSettings(WIZARD_CONTENT_CONTEXT_SUMMARY, true); + page.addContentCreator( + WIZARD_CONTENT_CONTEXT_ALL, + [](std::shared_ptr settings, QtProjectWizardWindow* window) + { + return new QtProjectWizardContentPathCxxPch(settings, settings, window); + } + ); + page.addContentCreatorWithSettings(WIZARD_CONTENT_CONTEXT_ALL, true); pages.push_back(page); } diff --git a/src/lib_gui/qt/project_wizard/content/QtProjectWizardContentCxxPchFlags.cpp b/src/lib_gui/qt/project_wizard/content/QtProjectWizardContentCxxPchFlags.cpp new file mode 100644 index 00000000..083876ad --- /dev/null +++ b/src/lib_gui/qt/project_wizard/content/QtProjectWizardContentCxxPchFlags.cpp @@ -0,0 +1,85 @@ +#include "QtProjectWizardContentCxxPchFlags.h" + +#include +#include + +#include "QtStringListBox.h" +#include "SourceGroupSettingsWithCxxPchOptions.h" + +QtProjectWizardContentCxxPchFlags::QtProjectWizardContentCxxPchFlags( + std::shared_ptr 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 " + optionText + " to use the flags specified " + "in the first compile command of the Compilation Database and all flags specified at 'Additional Compiler Flags'." : + "Check " + optionText + " to reuse the flags specified at 'Compiler Flags'."); + + addHelpButton( + "Precompiled Header Flags", + "

Define compiler flags used during precompiled header file generation.

" + "

" + optionHelp + "

" + "

Additionally add compiler flags to the list for precompiled header generation only. Some examples:

" + "

* use \"-DRELEASE\" to add a preprocessor #define for \"RELEASE\"

" + "

* use \"-U__clang__\" to remove the preprocessor #define for \"__clang__\"

", + 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(L"-include ", flag) || utility::isPrefix(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; +} diff --git a/src/lib_gui/qt/project_wizard/content/QtProjectWizardContentCxxPchFlags.h b/src/lib_gui/qt/project_wizard/content/QtProjectWizardContentCxxPchFlags.h new file mode 100644 index 00000000..fcfd72a5 --- /dev/null +++ b/src/lib_gui/qt/project_wizard/content/QtProjectWizardContentCxxPchFlags.h @@ -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 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 m_settings; + const bool m_isCDB; + + QCheckBox* m_useCompilerFlags; + QtStringListBox* m_list; +}; + +#endif // QT_PROJECT_WIZARD_CONTENT_CXX_PCH_FLAGS_H diff --git a/src/lib_gui/qt/project_wizard/content/path/QtProjectWizardContentPathCxxPch.cpp b/src/lib_gui/qt/project_wizard/content/path/QtProjectWizardContentPathCxxPch.cpp index 706e9a4b..af726ed8 100644 --- a/src/lib_gui/qt/project_wizard/content/path/QtProjectWizardContentPathCxxPch.cpp +++ b/src/lib_gui/qt/project_wizard/content/path/QtProjectWizardContentPathCxxPch.cpp @@ -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.
" + "Specify the path to the input header file that should be used to generate a precompiled header before indexing.
" "If the indexed source code is usually built using precompiled headers, using this option will speed up your indexing performance.
" "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) diff --git a/testing/project_setup/cpp_empty_pch/1_setup.sh b/testing/project_setup/cpp_empty_pch/1_setup.sh new file mode 100755 index 00000000..7e4992e7 --- /dev/null +++ b/testing/project_setup/cpp_empty_pch/1_setup.sh @@ -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" diff --git a/testing/project_setup/cpp_empty_pch/2_teardown.sh b/testing/project_setup/cpp_empty_pch/2_teardown.sh new file mode 100755 index 00000000..0877a78a --- /dev/null +++ b/testing/project_setup/cpp_empty_pch/2_teardown.sh @@ -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" diff --git a/testing/project_setup/cpp_empty_pch/checklist.txt b/testing/project_setup/cpp_empty_pch/checklist.txt new file mode 100644 index 00000000..e0768a51 --- /dev/null +++ b/testing/project_setup/cpp_empty_pch/checklist.txt @@ -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" diff --git a/testing/project_setup/cpp_empty_pch/data/src/Bar.h b/testing/project_setup/cpp_empty_pch/data/src/Bar.h new file mode 100644 index 00000000..1cb93caf --- /dev/null +++ b/testing/project_setup/cpp_empty_pch/data/src/Bar.h @@ -0,0 +1,10 @@ +#ifndef FOO_H +#define FOO_H + +#include "FooBar.h" + +class Bar : public FooBar +{ +}; + +#endif // FOO_H diff --git a/testing/project_setup/cpp_empty_pch/data/src/Foo.h b/testing/project_setup/cpp_empty_pch/data/src/Foo.h new file mode 100644 index 00000000..1ad18563 --- /dev/null +++ b/testing/project_setup/cpp_empty_pch/data/src/Foo.h @@ -0,0 +1,10 @@ +#ifndef BAR_H +#define BAR_H + +#include "FooBar.h" + +class Foo : public FooBar +{ +}; + +#endif // FOO_BAR_H diff --git a/testing/project_setup/cpp_empty_pch/data/src/FooBar.h b/testing/project_setup/cpp_empty_pch/data/src/FooBar.h new file mode 100644 index 00000000..e523d616 --- /dev/null +++ b/testing/project_setup/cpp_empty_pch/data/src/FooBar.h @@ -0,0 +1,12 @@ +#ifndef FOO_BAR_H +#define FOO_BAR_H + +#ifdef COMPILER_FLAG + +class FooBar +{ +}; + +#endif + +#endif // FOO_BAR_H diff --git a/testing/project_setup/cpp_empty_pch/data/src/main.cpp b/testing/project_setup/cpp_empty_pch/data/src/main.cpp new file mode 100644 index 00000000..e2196113 --- /dev/null +++ b/testing/project_setup/cpp_empty_pch/data/src/main.cpp @@ -0,0 +1,7 @@ +#include "pch.h" + +void test() +{ + Foo foo; + Bar bar; +} diff --git a/testing/project_setup/cpp_empty_pch/data/src/pch.h b/testing/project_setup/cpp_empty_pch/data/src/pch.h new file mode 100644 index 00000000..b93595ba --- /dev/null +++ b/testing/project_setup/cpp_empty_pch/data/src/pch.h @@ -0,0 +1,7 @@ + +#ifdef PCH_FLAG + +#include "Foo.h" +#include "Bar.h" + +#endif diff --git a/testing/project_setup/cxx_cdb/1_setup.sh b/testing/project_setup/cxx_cdb/1_setup.sh index 62405028..06034ca4 100755 --- a/testing/project_setup/cxx_cdb/1_setup.sh +++ b/testing/project_setup/cxx_cdb/1_setup.sh @@ -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 diff --git a/testing/project_setup/cxx_cdb_pch/1_setup.sh b/testing/project_setup/cxx_cdb_pch/1_setup.sh new file mode 100755 index 00000000..61fd4519 --- /dev/null +++ b/testing/project_setup/cxx_cdb_pch/1_setup.sh @@ -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" diff --git a/testing/project_setup/cxx_cdb_pch/2_teardown.sh b/testing/project_setup/cxx_cdb_pch/2_teardown.sh new file mode 100755 index 00000000..0877a78a --- /dev/null +++ b/testing/project_setup/cxx_cdb_pch/2_teardown.sh @@ -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" diff --git a/testing/project_setup/cxx_cdb_pch/checklist.txt b/testing/project_setup/cxx_cdb_pch/checklist.txt new file mode 100644 index 00000000..2262b9e5 --- /dev/null +++ b/testing/project_setup/cxx_cdb_pch/checklist.txt @@ -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" diff --git a/testing/project_setup/cxx_cdb_pch/data/src/include/Bar.h b/testing/project_setup/cxx_cdb_pch/data/src/include/Bar.h new file mode 100644 index 00000000..3b69a8bc --- /dev/null +++ b/testing/project_setup/cxx_cdb_pch/data/src/include/Bar.h @@ -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 diff --git a/testing/project_setup/cxx_cdb_pch/data/src/include/Foo.h b/testing/project_setup/cxx_cdb_pch/data/src/include/Foo.h new file mode 100644 index 00000000..e8d82cf0 --- /dev/null +++ b/testing/project_setup/cxx_cdb_pch/data/src/include/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 diff --git a/testing/project_setup/cxx_cdb_pch/data/src/include/FooBar.h b/testing/project_setup/cxx_cdb_pch/data/src/include/FooBar.h new file mode 100644 index 00000000..0e9062d4 --- /dev/null +++ b/testing/project_setup/cxx_cdb_pch/data/src/include/FooBar.h @@ -0,0 +1,8 @@ +#ifndef FOO_BAR_H +#define FOO_BAR_H + +class FooBar +{ +}; + +#endif // FOO_BAR_H diff --git a/testing/project_setup/cxx_cdb_pch/data/src/main.cpp b/testing/project_setup/cxx_cdb_pch/data/src/main.cpp new file mode 100644 index 00000000..25345514 --- /dev/null +++ b/testing/project_setup/cxx_cdb_pch/data/src/main.cpp @@ -0,0 +1,8 @@ +#include "pch.h" + +void test() +{ + Foo foo; + Bar bar; +} + diff --git a/testing/project_setup/cxx_cdb_pch/data/src/pch.h b/testing/project_setup/cxx_cdb_pch/data/src/pch.h new file mode 100644 index 00000000..bee5a38a --- /dev/null +++ b/testing/project_setup/cxx_cdb_pch/data/src/pch.h @@ -0,0 +1,9 @@ + +#ifndef PCH_FLAG + #error "PCH_FLAG not defined" +#else + +#include "Foo.h" +#include "Bar.h" + +#endif diff --git a/testing/project_setup/cxx_cdb_pch/working_copy/asdf.srctrlprj b/testing/project_setup/cxx_cdb_pch/working_copy/asdf.srctrlprj new file mode 100644 index 00000000..90eb2e36 --- /dev/null +++ b/testing/project_setup/cxx_cdb_pch/working_copy/asdf.srctrlprj @@ -0,0 +1,26 @@ + + + + + + compile_commands.json + + + -DCOMPILER_FLAG + + + src + + C/C++ from Compilation Database + + -DPCH_FLAG + 1 + 1 + + src/pch.hpp + enabled + C/C++ from Compilation Database + + + 8 + diff --git a/testing/project_setup/cxx_cdb_pch/working_copy/compile_commands.json b/testing/project_setup/cxx_cdb_pch/working_copy/compile_commands.json new file mode 100644 index 00000000..aaa876cf --- /dev/null +++ b/testing/project_setup/cxx_cdb_pch/working_copy/compile_commands.json @@ -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" + } +] diff --git a/testing/project_setup/cxx_cdb_pch/working_copy/src/include/Bar.h b/testing/project_setup/cxx_cdb_pch/working_copy/src/include/Bar.h new file mode 100644 index 00000000..3b69a8bc --- /dev/null +++ b/testing/project_setup/cxx_cdb_pch/working_copy/src/include/Bar.h @@ -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 diff --git a/testing/project_setup/cxx_cdb_pch/working_copy/src/include/Foo.h b/testing/project_setup/cxx_cdb_pch/working_copy/src/include/Foo.h new file mode 100644 index 00000000..e8d82cf0 --- /dev/null +++ b/testing/project_setup/cxx_cdb_pch/working_copy/src/include/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 diff --git a/testing/project_setup/cxx_cdb_pch/working_copy/src/include/FooBar.h b/testing/project_setup/cxx_cdb_pch/working_copy/src/include/FooBar.h new file mode 100644 index 00000000..0e9062d4 --- /dev/null +++ b/testing/project_setup/cxx_cdb_pch/working_copy/src/include/FooBar.h @@ -0,0 +1,8 @@ +#ifndef FOO_BAR_H +#define FOO_BAR_H + +class FooBar +{ +}; + +#endif // FOO_BAR_H diff --git a/testing/project_setup/cxx_cdb_pch/working_copy/src/main.cpp b/testing/project_setup/cxx_cdb_pch/working_copy/src/main.cpp new file mode 100644 index 00000000..d7e8211a --- /dev/null +++ b/testing/project_setup/cxx_cdb_pch/working_copy/src/main.cpp @@ -0,0 +1,8 @@ +#include "pch.hpp" + +void test() +{ + Foo foo; + Bar bar; +} + diff --git a/testing/project_setup/cxx_cdb_pch/working_copy/src/pch.hpp b/testing/project_setup/cxx_cdb_pch/working_copy/src/pch.hpp new file mode 100644 index 00000000..bee5a38a --- /dev/null +++ b/testing/project_setup/cxx_cdb_pch/working_copy/src/pch.hpp @@ -0,0 +1,9 @@ + +#ifndef PCH_FLAG + #error "PCH_FLAG not defined" +#else + +#include "Foo.h" +#include "Bar.h" + +#endif