diff --git a/bin/app/data/fallback/ApplicationSettings.xml b/bin/app/data/fallback/ApplicationSettings.xml
index e2685652..10367d1d 100644
--- a/bin/app/data/fallback/ApplicationSettings.xml
+++ b/bin/app/data/fallback/ApplicationSettings.xml
@@ -14,5 +14,5 @@
./projects/javaparser/javaparser.srctrlprj
- 5
+ 6
diff --git a/src/app/main.cpp b/src/app/main.cpp
index 62059f4e..3f16a1eb 100644
--- a/src/app/main.cpp
+++ b/src/app/main.cpp
@@ -137,6 +137,8 @@ void prefillCxxHeaderPaths()
std::shared_ptr cxxHeaderDetector = utility::getCxxHeaderPathDetector();
std::vector paths = cxxHeaderDetector->getPaths();
+ paths = utility::replaceOrAddCxxCompilerHeaderPath(paths);
+
if (!paths.empty())
{
MessageStatus(L"Ran C/C++ header path detection, found " + std::to_wstring(paths.size()) + L" path" +
diff --git a/src/lib/settings/ApplicationSettings.cpp b/src/lib/settings/ApplicationSettings.cpp
index 8ebe06a3..e1d543e3 100644
--- a/src/lib/settings/ApplicationSettings.cpp
+++ b/src/lib/settings/ApplicationSettings.cpp
@@ -13,7 +13,7 @@
#include "UserPaths.h"
#include "Version.h"
-const size_t ApplicationSettings::VERSION = 5;
+const size_t ApplicationSettings::VERSION = 6;
std::shared_ptr ApplicationSettings::s_instance;
@@ -78,11 +78,11 @@ bool ApplicationSettings::load(const FilePath& filePath, bool readOnly)
}
}
));
- migrator.addMigration(5, std::make_shared(
+ migrator.addMigration(6, std::make_shared(
[](const SettingsMigration* migration, Settings* settings)
{
std::vector cxxHeaderSearchPaths = migration->getValuesFromSettings(
- settings, "indexing/cxx/header_search_paths/header_search_path", std::vector());
+ settings, "indexing/cxx/header_search_paths/header_search_path", std::vector());
cxxHeaderSearchPaths = utility::replaceOrAddCxxCompilerHeaderPath(cxxHeaderSearchPaths);
diff --git a/src/lib/utility/ResourcePaths.cpp b/src/lib/utility/ResourcePaths.cpp
index adfc6376..b61c4438 100644
--- a/src/lib/utility/ResourcePaths.cpp
+++ b/src/lib/utility/ResourcePaths.cpp
@@ -34,5 +34,5 @@ FilePath ResourcePaths::getJavaPath()
FilePath ResourcePaths::getCxxCompilerHeaderPath()
{
- return AppPath::getAppPath().concatenate(L"data/cxx/include/");
+ return AppPath::getAppPath().concatenate(L"data/cxx/include/").getCanonical();
}
diff --git a/src/lib/utility/utilityCxx.cpp b/src/lib/utility/utilityCxx.cpp
index ac9b0ea5..1a28b362 100644
--- a/src/lib/utility/utilityCxx.cpp
+++ b/src/lib/utility/utilityCxx.cpp
@@ -1,30 +1,23 @@
#include "utilityCxx.h"
#include "ResourcePaths.h"
-#include "utilityApp.h"
namespace utility
{
std::vector replaceOrAddCxxCompilerHeaderPath(const std::vector& headerSearchPaths)
{
std::vector newHeaderSearchPaths;
+ const FilePath cxxCompilerHeaderPath = ResourcePaths::getCxxCompilerHeaderPath();
- if (utility::getOsType() == OS_WINDOWS)
+ for (const FilePath& path : headerSearchPaths)
{
- newHeaderSearchPaths = headerSearchPaths;
- }
- else
- {
- for (const FilePath& path : headerSearchPaths)
+ if (path != cxxCompilerHeaderPath)
{
- if (!path.getConcatenated(L"/stdarg.h").exists())
- {
- newHeaderSearchPaths.push_back(path);
- }
+ newHeaderSearchPaths.push_back(path);
}
}
- newHeaderSearchPaths.push_back(ResourcePaths::getCxxCompilerHeaderPath().getCanonical());
+ newHeaderSearchPaths.push_back(cxxCompilerHeaderPath);
return newHeaderSearchPaths;
}
}
diff --git a/src/lib_cxx/data/indexer/IndexerCommandCxx.cpp b/src/lib_cxx/data/indexer/IndexerCommandCxx.cpp
index a944c3bc..89c890fb 100644
--- a/src/lib_cxx/data/indexer/IndexerCommandCxx.cpp
+++ b/src/lib_cxx/data/indexer/IndexerCommandCxx.cpp
@@ -60,19 +60,33 @@ std::vector IndexerCommandCxx::getCompilerFlagsForSystemHeaderSear
{
std::vector compilerFlags;
compilerFlags.reserve(systemHeaderSearchPaths.size() * 2);
+
+ bool hasCxxCompilerHeaderPath = false;
for (const FilePath& path : systemHeaderSearchPaths)
+ {
+ if (path == ResourcePaths::getCxxCompilerHeaderPath())
+ {
+ hasCxxCompilerHeaderPath = true;
+ }
+ else
+ {
+ compilerFlags.push_back(L"-isystem");
+ compilerFlags.push_back(path.wstr());
+ }
+ }
+
+ if (hasCxxCompilerHeaderPath)
{
#ifdef _WIN32
// prepend clang system includes on windows
- if (path == ResourcePaths::getCxxCompilerHeaderPath())
- {
- compilerFlags = utility::concat({ L"-isystem" , path.wstr() }, compilerFlags);
- continue;
- }
-#endif
+ compilerFlags = utility::concat({ L"-isystem", ResourcePaths::getCxxCompilerHeaderPath().wstr() }, compilerFlags);
+#else
+ // append otherwise
compilerFlags.push_back(L"-isystem");
- compilerFlags.push_back(path.wstr());
+ compilerFlags.push_back(ResourcePaths::getCxxCompilerHeaderPath().wstr());
+#endif
}
+
return compilerFlags;
}
diff --git a/src/lib_gui/qt/element/QtPathListBox.cpp b/src/lib_gui/qt/element/QtPathListBox.cpp
index 43ae1177..581dc0dc 100644
--- a/src/lib_gui/qt/element/QtPathListBox.cpp
+++ b/src/lib_gui/qt/element/QtPathListBox.cpp
@@ -59,7 +59,11 @@ std::vector QtPathListBox::getPathsAsAbsolute() const
void QtPathListBox::setPaths(const std::vector& list, bool readOnly)
{
clear();
+ addPaths(list, readOnly);
+}
+void QtPathListBox::addPaths(const std::vector& list, bool readOnly)
+{
for (FilePath path : list)
{
QtListBoxItem* item = addListBoxItemWithText(QString::fromStdWString(path.wstr()));
diff --git a/src/lib_gui/qt/element/QtPathListBox.h b/src/lib_gui/qt/element/QtPathListBox.h
index 400d3b3d..035b89cd 100644
--- a/src/lib_gui/qt/element/QtPathListBox.h
+++ b/src/lib_gui/qt/element/QtPathListBox.h
@@ -23,7 +23,9 @@ public:
std::vector getPathsAsDisplayed() const;
std::vector getPathsAsAbsolute() const;
+
void setPaths(const std::vector& list, bool readOnly = false);
+ void addPaths(const std::vector& list, bool readOnly = false);
void makeAbsolute(FilePath& path) const;
void makeRelativeIfShorter(FilePath& path) const;
diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.cpp b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.cpp
index fee47ec2..8bf53bf9 100644
--- a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.cpp
+++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.cpp
@@ -15,6 +15,7 @@
#include "SourceGroupCxxEmpty.h"
#include "SourceGroupJavaEmpty.h"
#include "ApplicationSettings.h"
+#include "ResourcePaths.h"
#include "SourceGroupSettingsCustomCommand.h"
#include "SourceGroupSettingsCxx.h"
#include "SourceGroupSettingsCxxCdb.h"
@@ -34,6 +35,7 @@
#include "IncludeProcessing.h"
#include "ScopedFunctor.h"
#include "utility.h"
+#include "utilityApp.h"
#include "utilityCxx.h"
#include "utilityFile.h"
#include "utilityPathDetection.h"
@@ -204,6 +206,11 @@ void QtProjectWizzardContentPaths::detectionClicked()
paths = utility::unique(utility::concat(oldPaths, paths));
+ detectedPaths(paths);
+}
+
+void QtProjectWizzardContentPaths::detectedPaths(const std::vector& paths)
+{
m_list->setPaths(paths);
}
@@ -1011,7 +1018,7 @@ QtProjectWizzardContentPathsHeaderSearchGlobal::QtProjectWizzardContentPathsHead
void QtProjectWizzardContentPathsHeaderSearchGlobal::load()
{
- m_list->setPaths(ApplicationSettings::getInstance()->getHeaderSearchPaths());
+ setPaths(ApplicationSettings::getInstance()->getHeaderSearchPaths());
}
void QtProjectWizzardContentPathsHeaderSearchGlobal::save()
@@ -1020,6 +1027,97 @@ void QtProjectWizzardContentPathsHeaderSearchGlobal::save()
ApplicationSettings::getInstance()->save();
}
+bool QtProjectWizzardContentPathsHeaderSearchGlobal::check()
+{
+ bool hasCompilerHeaderPath = false;
+ bool hasOtherCompilerConfig = false;
+ for (const FilePath& headerPath : m_list->getPathsAsDisplayed())
+ {
+ if (headerPath == ResourcePaths::getCxxCompilerHeaderPath())
+ {
+ hasCompilerHeaderPath = true;
+ }
+ else if (headerPath.getCanonical().getConcatenated(L"/stdarg.h").exists())
+ {
+ hasOtherCompilerConfig = true;
+ }
+ }
+
+ if (!hasCompilerHeaderPath)
+ {
+ QMessageBox msgBox;
+ msgBox.setText("Compiler Header Path missing");
+ msgBox.setInformativeText("Your Global Include Paths do not contain the path to the compiler headers of "
+ "Sourcetrail's C/C++ indexer. This can cause a lot of errors during indexing. Do you want to add the "
+ "path to the list?");
+ msgBox.addButton("Add", QMessageBox::ButtonRole::YesRole);
+ msgBox.addButton("Skip", QMessageBox::ButtonRole::NoRole);
+ msgBox.setIcon(QMessageBox::Icon::Question);
+ int ret = msgBox.exec();
+
+ if (ret == 0) // QMessageBox::Yes
+ {
+ m_list->addPaths({ ResourcePaths::getCxxCompilerHeaderPath() }, true);
+ hasCompilerHeaderPath = true;
+ }
+ }
+
+ if (utility::getOsType() != OS_WINDOWS && hasOtherCompilerConfig && hasCompilerHeaderPath)
+ {
+ QMessageBox msgBox;
+ msgBox.setText("Multiple Compiler Headers");
+ msgBox.setInformativeText("Your Global Include Paths contain another path that holds C/C++ compiler headers, "
+ "probably those of your local C/C++ compiler. They are possibly in conflict with the compiler headers of "
+ "Sourcetrail's C/C++ indexer. This can lead to compatiblity errors during indexing. Do you want to remove "
+ "these paths?");
+ msgBox.addButton("Remove", QMessageBox::ButtonRole::YesRole);
+ msgBox.addButton("Keep", QMessageBox::ButtonRole::NoRole);
+ msgBox.setIcon(QMessageBox::Icon::Question);
+ int ret = msgBox.exec();
+
+ if (ret == 0) // QMessageBox::Yes
+ {
+ std::vector paths;
+ for (const FilePath& headerPath : m_list->getPathsAsDisplayed())
+ {
+ if (headerPath == ResourcePaths::getCxxCompilerHeaderPath() ||
+ !headerPath.getCanonical().getConcatenated(L"/stdarg.h").exists())
+ {
+ paths.push_back(headerPath);
+ }
+ }
+ setPaths(paths);
+ }
+ }
+
+ return QtProjectWizzardContentPaths::check();
+}
+
+void QtProjectWizzardContentPathsHeaderSearchGlobal::detectedPaths(const std::vector& paths)
+{
+ setPaths(paths);
+}
+
+void QtProjectWizzardContentPathsHeaderSearchGlobal::setPaths(const std::vector& paths)
+{
+ m_list->setPaths({});
+
+ std::vector nonCxxCompilerHeaderPaths;
+ for (const FilePath& headerPath : paths)
+ {
+ if (headerPath == ResourcePaths::getCxxCompilerHeaderPath())
+ {
+ m_list->addPaths({ headerPath }, true);
+ }
+ else
+ {
+ nonCxxCompilerHeaderPaths.push_back(headerPath);
+ }
+ }
+
+ m_list->addPaths(nonCxxCompilerHeaderPaths);
+}
+
QtProjectWizzardContentPathsFrameworkSearch::QtProjectWizzardContentPathsFrameworkSearch(
std::shared_ptr settings, QtProjectWizzardWindow* window, bool indicateAsAdditional
diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.h b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.h
index 31c124b0..a020ac0f 100644
--- a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.h
+++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.h
@@ -27,8 +27,8 @@ signals:
public:
QtProjectWizzardContentPaths(
- std::shared_ptr settings,
- QtProjectWizzardWindow* window,
+ std::shared_ptr settings,
+ QtProjectWizzardWindow* window,
QtPathListBox::SelectionPolicyType selectionPolicy,
bool checkMissingPaths = true);
@@ -43,6 +43,8 @@ protected:
void addDetection(QGridLayout* layout, int row);
+ virtual void detectedPaths(const std::vector& paths);
+
std::shared_ptr m_settings;
QtPathListBox* m_list;
@@ -166,6 +168,14 @@ public:
// QtProjectWizzardContent implementation
virtual void load() override;
virtual void save() override;
+
+ virtual bool check() override;
+
+protected:
+ virtual void detectedPaths(const std::vector& paths) override;
+
+private:
+ void setPaths(const std::vector& paths);
};
diff --git a/src/lib_gui/utility/path_detector/cxx_header/CxxHeaderPathDetector.cpp b/src/lib_gui/utility/path_detector/cxx_header/CxxHeaderPathDetector.cpp
index 22b09900..46af08fe 100644
--- a/src/lib_gui/utility/path_detector/cxx_header/CxxHeaderPathDetector.cpp
+++ b/src/lib_gui/utility/path_detector/cxx_header/CxxHeaderPathDetector.cpp
@@ -15,18 +15,15 @@ std::vector CxxHeaderPathDetector::getPaths() const
{
std::vector paths = utility::getCxxHeaderPaths(m_compilerName);
std::vector headerSearchPaths;
+
for (const std::string& path : paths)
{
- if (!utility::isPostfix(" (framework directory)", path))
+ if (!utility::isPostfix(" (framework directory)", path) &&
+ !FilePath(path).getCanonical().getConcatenated(L"/stdarg.h").exists())
{
headerSearchPaths.push_back(FilePath(path).makeCanonical());
}
}
- if (!headerSearchPaths.empty())
- {
- headerSearchPaths = utility::replaceOrAddCxxCompilerHeaderPath(headerSearchPaths);
- }
-
return headerSearchPaths;
}
diff --git a/src/lib_gui/utility/path_detector/cxx_header/CxxVs10To14HeaderPathDetector.cpp b/src/lib_gui/utility/path_detector/cxx_header/CxxVs10To14HeaderPathDetector.cpp
index bf779fa1..9ad94b5d 100644
--- a/src/lib_gui/utility/path_detector/cxx_header/CxxVs10To14HeaderPathDetector.cpp
+++ b/src/lib_gui/utility/path_detector/cxx_header/CxxVs10To14HeaderPathDetector.cpp
@@ -39,7 +39,6 @@ std::vector CxxVs10To14HeaderPathDetector::getPaths() const
if (!headerSearchPaths.empty())
{
utility::append(headerSearchPaths, utility::getWindowsSdkHeaderSearchPaths(m_architecture));
- headerSearchPaths = utility::replaceOrAddCxxCompilerHeaderPath(headerSearchPaths);
}
return headerSearchPaths;
diff --git a/src/lib_gui/utility/path_detector/cxx_header/CxxVs15HeaderPathDetector.cpp b/src/lib_gui/utility/path_detector/cxx_header/CxxVs15HeaderPathDetector.cpp
index 20a5d293..5073c3bd 100644
--- a/src/lib_gui/utility/path_detector/cxx_header/CxxVs15HeaderPathDetector.cpp
+++ b/src/lib_gui/utility/path_detector/cxx_header/CxxVs15HeaderPathDetector.cpp
@@ -51,7 +51,6 @@ std::vector CxxVs15HeaderPathDetector::getPaths() const
windowsSdkHeaderSearchPaths = utility::getWindowsSdkHeaderSearchPaths(APPLICATION_ARCHITECTURE_X86_64);
}
utility::append(headerSearchPaths, windowsSdkHeaderSearchPaths);
- headerSearchPaths = utility::replaceOrAddCxxCompilerHeaderPath(headerSearchPaths);
}
return headerSearchPaths;