logic: Fixes and improvements for C/C++ compiler header path handling

* Always add compiler header path when prefilling on first start, regardless of successful detection
* Show compiler header path in path list box on top and readonly
* Prepend compiler header path on Windows in system header path compiler flags, append otherwise
* Show warning when saving ApplicationSettings if compiler header path is not in global include paths
* Show warning when saving ApplicationSettings if there is another path containing compiler headers
This commit is contained in:
Eberhard Graether
2019-01-21 15:18:31 +01:00
parent 3eb9211520
commit 7d30709306
13 changed files with 153 additions and 35 deletions
@@ -14,5 +14,5 @@
<recent_project>./projects/javaparser/javaparser.srctrlprj</recent_project> <recent_project>./projects/javaparser/javaparser.srctrlprj</recent_project>
</recent_projects> </recent_projects>
</user> </user>
<version>5</version> <version>6</version>
</config> </config>
+2
View File
@@ -137,6 +137,8 @@ void prefillCxxHeaderPaths()
std::shared_ptr<CombinedPathDetector> cxxHeaderDetector = utility::getCxxHeaderPathDetector(); std::shared_ptr<CombinedPathDetector> cxxHeaderDetector = utility::getCxxHeaderPathDetector();
std::vector<FilePath> paths = cxxHeaderDetector->getPaths(); std::vector<FilePath> paths = cxxHeaderDetector->getPaths();
paths = utility::replaceOrAddCxxCompilerHeaderPath(paths);
if (!paths.empty()) if (!paths.empty())
{ {
MessageStatus(L"Ran C/C++ header path detection, found " + std::to_wstring(paths.size()) + L" path" + MessageStatus(L"Ran C/C++ header path detection, found " + std::to_wstring(paths.size()) + L" path" +
+3 -3
View File
@@ -13,7 +13,7 @@
#include "UserPaths.h" #include "UserPaths.h"
#include "Version.h" #include "Version.h"
const size_t ApplicationSettings::VERSION = 5; const size_t ApplicationSettings::VERSION = 6;
std::shared_ptr<ApplicationSettings> ApplicationSettings::s_instance; std::shared_ptr<ApplicationSettings> ApplicationSettings::s_instance;
@@ -78,11 +78,11 @@ bool ApplicationSettings::load(const FilePath& filePath, bool readOnly)
} }
} }
)); ));
migrator.addMigration(5, std::make_shared<SettingsMigrationLambda>( migrator.addMigration(6, std::make_shared<SettingsMigrationLambda>(
[](const SettingsMigration* migration, Settings* settings) [](const SettingsMigration* migration, Settings* settings)
{ {
std::vector<FilePath> cxxHeaderSearchPaths = migration->getValuesFromSettings( std::vector<FilePath> cxxHeaderSearchPaths = migration->getValuesFromSettings(
settings, "indexing/cxx/header_search_paths/header_search_path", std::vector<FilePath>()); settings, "indexing/cxx/header_search_paths/header_search_path", std::vector<FilePath>());
cxxHeaderSearchPaths = utility::replaceOrAddCxxCompilerHeaderPath(cxxHeaderSearchPaths); cxxHeaderSearchPaths = utility::replaceOrAddCxxCompilerHeaderPath(cxxHeaderSearchPaths);
+1 -1
View File
@@ -34,5 +34,5 @@ FilePath ResourcePaths::getJavaPath()
FilePath ResourcePaths::getCxxCompilerHeaderPath() FilePath ResourcePaths::getCxxCompilerHeaderPath()
{ {
return AppPath::getAppPath().concatenate(L"data/cxx/include/"); return AppPath::getAppPath().concatenate(L"data/cxx/include/").getCanonical();
} }
+5 -12
View File
@@ -1,30 +1,23 @@
#include "utilityCxx.h" #include "utilityCxx.h"
#include "ResourcePaths.h" #include "ResourcePaths.h"
#include "utilityApp.h"
namespace utility namespace utility
{ {
std::vector<FilePath> replaceOrAddCxxCompilerHeaderPath(const std::vector<FilePath>& headerSearchPaths) std::vector<FilePath> replaceOrAddCxxCompilerHeaderPath(const std::vector<FilePath>& headerSearchPaths)
{ {
std::vector<FilePath> newHeaderSearchPaths; std::vector<FilePath> newHeaderSearchPaths;
const FilePath cxxCompilerHeaderPath = ResourcePaths::getCxxCompilerHeaderPath();
if (utility::getOsType() == OS_WINDOWS) for (const FilePath& path : headerSearchPaths)
{ {
newHeaderSearchPaths = headerSearchPaths; if (path != cxxCompilerHeaderPath)
}
else
{
for (const FilePath& path : headerSearchPaths)
{ {
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; return newHeaderSearchPaths;
} }
} }
+21 -7
View File
@@ -60,19 +60,33 @@ std::vector<std::wstring> IndexerCommandCxx::getCompilerFlagsForSystemHeaderSear
{ {
std::vector<std::wstring> compilerFlags; std::vector<std::wstring> compilerFlags;
compilerFlags.reserve(systemHeaderSearchPaths.size() * 2); compilerFlags.reserve(systemHeaderSearchPaths.size() * 2);
bool hasCxxCompilerHeaderPath = false;
for (const FilePath& path : systemHeaderSearchPaths) 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 #ifdef _WIN32
// prepend clang system includes on windows // prepend clang system includes on windows
if (path == ResourcePaths::getCxxCompilerHeaderPath()) compilerFlags = utility::concat({ L"-isystem", ResourcePaths::getCxxCompilerHeaderPath().wstr() }, compilerFlags);
{ #else
compilerFlags = utility::concat({ L"-isystem" , path.wstr() }, compilerFlags); // append otherwise
continue;
}
#endif
compilerFlags.push_back(L"-isystem"); compilerFlags.push_back(L"-isystem");
compilerFlags.push_back(path.wstr()); compilerFlags.push_back(ResourcePaths::getCxxCompilerHeaderPath().wstr());
#endif
} }
return compilerFlags; return compilerFlags;
} }
+4
View File
@@ -59,7 +59,11 @@ std::vector<FilePath> QtPathListBox::getPathsAsAbsolute() const
void QtPathListBox::setPaths(const std::vector<FilePath>& list, bool readOnly) void QtPathListBox::setPaths(const std::vector<FilePath>& list, bool readOnly)
{ {
clear(); clear();
addPaths(list, readOnly);
}
void QtPathListBox::addPaths(const std::vector<FilePath>& list, bool readOnly)
{
for (FilePath path : list) for (FilePath path : list)
{ {
QtListBoxItem* item = addListBoxItemWithText(QString::fromStdWString(path.wstr())); QtListBoxItem* item = addListBoxItemWithText(QString::fromStdWString(path.wstr()));
+2
View File
@@ -23,7 +23,9 @@ public:
std::vector<FilePath> getPathsAsDisplayed() const; std::vector<FilePath> getPathsAsDisplayed() const;
std::vector<FilePath> getPathsAsAbsolute() const; std::vector<FilePath> getPathsAsAbsolute() const;
void setPaths(const std::vector<FilePath>& list, bool readOnly = false); void setPaths(const std::vector<FilePath>& list, bool readOnly = false);
void addPaths(const std::vector<FilePath>& list, bool readOnly = false);
void makeAbsolute(FilePath& path) const; void makeAbsolute(FilePath& path) const;
void makeRelativeIfShorter(FilePath& path) const; void makeRelativeIfShorter(FilePath& path) const;
@@ -15,6 +15,7 @@
#include "SourceGroupCxxEmpty.h" #include "SourceGroupCxxEmpty.h"
#include "SourceGroupJavaEmpty.h" #include "SourceGroupJavaEmpty.h"
#include "ApplicationSettings.h" #include "ApplicationSettings.h"
#include "ResourcePaths.h"
#include "SourceGroupSettingsCustomCommand.h" #include "SourceGroupSettingsCustomCommand.h"
#include "SourceGroupSettingsCxx.h" #include "SourceGroupSettingsCxx.h"
#include "SourceGroupSettingsCxxCdb.h" #include "SourceGroupSettingsCxxCdb.h"
@@ -34,6 +35,7 @@
#include "IncludeProcessing.h" #include "IncludeProcessing.h"
#include "ScopedFunctor.h" #include "ScopedFunctor.h"
#include "utility.h" #include "utility.h"
#include "utilityApp.h"
#include "utilityCxx.h" #include "utilityCxx.h"
#include "utilityFile.h" #include "utilityFile.h"
#include "utilityPathDetection.h" #include "utilityPathDetection.h"
@@ -204,6 +206,11 @@ void QtProjectWizzardContentPaths::detectionClicked()
paths = utility::unique(utility::concat(oldPaths, paths)); paths = utility::unique(utility::concat(oldPaths, paths));
detectedPaths(paths);
}
void QtProjectWizzardContentPaths::detectedPaths(const std::vector<FilePath>& paths)
{
m_list->setPaths(paths); m_list->setPaths(paths);
} }
@@ -1011,7 +1018,7 @@ QtProjectWizzardContentPathsHeaderSearchGlobal::QtProjectWizzardContentPathsHead
void QtProjectWizzardContentPathsHeaderSearchGlobal::load() void QtProjectWizzardContentPathsHeaderSearchGlobal::load()
{ {
m_list->setPaths(ApplicationSettings::getInstance()->getHeaderSearchPaths()); setPaths(ApplicationSettings::getInstance()->getHeaderSearchPaths());
} }
void QtProjectWizzardContentPathsHeaderSearchGlobal::save() void QtProjectWizzardContentPathsHeaderSearchGlobal::save()
@@ -1020,6 +1027,97 @@ void QtProjectWizzardContentPathsHeaderSearchGlobal::save()
ApplicationSettings::getInstance()->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<FilePath> 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<FilePath>& paths)
{
setPaths(paths);
}
void QtProjectWizzardContentPathsHeaderSearchGlobal::setPaths(const std::vector<FilePath>& paths)
{
m_list->setPaths({});
std::vector<FilePath> 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( QtProjectWizzardContentPathsFrameworkSearch::QtProjectWizzardContentPathsFrameworkSearch(
std::shared_ptr<SourceGroupSettings> settings, QtProjectWizzardWindow* window, bool indicateAsAdditional std::shared_ptr<SourceGroupSettings> settings, QtProjectWizzardWindow* window, bool indicateAsAdditional
@@ -27,8 +27,8 @@ signals:
public: public:
QtProjectWizzardContentPaths( QtProjectWizzardContentPaths(
std::shared_ptr<SourceGroupSettings> settings, std::shared_ptr<SourceGroupSettings> settings,
QtProjectWizzardWindow* window, QtProjectWizzardWindow* window,
QtPathListBox::SelectionPolicyType selectionPolicy, QtPathListBox::SelectionPolicyType selectionPolicy,
bool checkMissingPaths = true); bool checkMissingPaths = true);
@@ -43,6 +43,8 @@ protected:
void addDetection(QGridLayout* layout, int row); void addDetection(QGridLayout* layout, int row);
virtual void detectedPaths(const std::vector<FilePath>& paths);
std::shared_ptr<SourceGroupSettings> m_settings; std::shared_ptr<SourceGroupSettings> m_settings;
QtPathListBox* m_list; QtPathListBox* m_list;
@@ -166,6 +168,14 @@ public:
// QtProjectWizzardContent implementation // QtProjectWizzardContent implementation
virtual void load() override; virtual void load() override;
virtual void save() override; virtual void save() override;
virtual bool check() override;
protected:
virtual void detectedPaths(const std::vector<FilePath>& paths) override;
private:
void setPaths(const std::vector<FilePath>& paths);
}; };
@@ -15,18 +15,15 @@ std::vector<FilePath> CxxHeaderPathDetector::getPaths() const
{ {
std::vector<std::string> paths = utility::getCxxHeaderPaths(m_compilerName); std::vector<std::string> paths = utility::getCxxHeaderPaths(m_compilerName);
std::vector<FilePath> headerSearchPaths; std::vector<FilePath> headerSearchPaths;
for (const std::string& path : paths) for (const std::string& path : paths)
{ {
if (!utility::isPostfix<std::string>(" (framework directory)", path)) if (!utility::isPostfix<std::string>(" (framework directory)", path) &&
!FilePath(path).getCanonical().getConcatenated(L"/stdarg.h").exists())
{ {
headerSearchPaths.push_back(FilePath(path).makeCanonical()); headerSearchPaths.push_back(FilePath(path).makeCanonical());
} }
} }
if (!headerSearchPaths.empty())
{
headerSearchPaths = utility::replaceOrAddCxxCompilerHeaderPath(headerSearchPaths);
}
return headerSearchPaths; return headerSearchPaths;
} }
@@ -39,7 +39,6 @@ std::vector<FilePath> CxxVs10To14HeaderPathDetector::getPaths() const
if (!headerSearchPaths.empty()) if (!headerSearchPaths.empty())
{ {
utility::append(headerSearchPaths, utility::getWindowsSdkHeaderSearchPaths(m_architecture)); utility::append(headerSearchPaths, utility::getWindowsSdkHeaderSearchPaths(m_architecture));
headerSearchPaths = utility::replaceOrAddCxxCompilerHeaderPath(headerSearchPaths);
} }
return headerSearchPaths; return headerSearchPaths;
@@ -51,7 +51,6 @@ std::vector<FilePath> CxxVs15HeaderPathDetector::getPaths() const
windowsSdkHeaderSearchPaths = utility::getWindowsSdkHeaderSearchPaths(APPLICATION_ARCHITECTURE_X86_64); windowsSdkHeaderSearchPaths = utility::getWindowsSdkHeaderSearchPaths(APPLICATION_ARCHITECTURE_X86_64);
} }
utility::append(headerSearchPaths, windowsSdkHeaderSearchPaths); utility::append(headerSearchPaths, windowsSdkHeaderSearchPaths);
headerSearchPaths = utility::replaceOrAddCxxCompilerHeaderPath(headerSearchPaths);
} }
return headerSearchPaths; return headerSearchPaths;