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_projects>
</user>
<version>5</version>
<version>6</version>
</config>
+2
View File
@@ -137,6 +137,8 @@ void prefillCxxHeaderPaths()
std::shared_ptr<CombinedPathDetector> cxxHeaderDetector = utility::getCxxHeaderPathDetector();
std::vector<FilePath> 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" +
+3 -3
View File
@@ -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> 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)
{
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);
+1 -1
View File
@@ -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();
}
+5 -12
View File
@@ -1,30 +1,23 @@
#include "utilityCxx.h"
#include "ResourcePaths.h"
#include "utilityApp.h"
namespace utility
{
std::vector<FilePath> replaceOrAddCxxCompilerHeaderPath(const std::vector<FilePath>& headerSearchPaths)
{
std::vector<FilePath> 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;
}
}
+21 -7
View File
@@ -60,19 +60,33 @@ std::vector<std::wstring> IndexerCommandCxx::getCompilerFlagsForSystemHeaderSear
{
std::vector<std::wstring> 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;
}
+4
View File
@@ -59,7 +59,11 @@ std::vector<FilePath> QtPathListBox::getPathsAsAbsolute() const
void QtPathListBox::setPaths(const std::vector<FilePath>& list, bool readOnly)
{
clear();
addPaths(list, readOnly);
}
void QtPathListBox::addPaths(const std::vector<FilePath>& list, bool readOnly)
{
for (FilePath path : list)
{
QtListBoxItem* item = addListBoxItemWithText(QString::fromStdWString(path.wstr()));
+2
View File
@@ -23,7 +23,9 @@ public:
std::vector<FilePath> getPathsAsDisplayed() const;
std::vector<FilePath> getPathsAsAbsolute() const;
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 makeRelativeIfShorter(FilePath& path) const;
@@ -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<FilePath>& 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<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(
std::shared_ptr<SourceGroupSettings> settings, QtProjectWizzardWindow* window, bool indicateAsAdditional
@@ -27,8 +27,8 @@ signals:
public:
QtProjectWizzardContentPaths(
std::shared_ptr<SourceGroupSettings> settings,
QtProjectWizzardWindow* window,
std::shared_ptr<SourceGroupSettings> 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<FilePath>& paths);
std::shared_ptr<SourceGroupSettings> 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<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<FilePath> headerSearchPaths;
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());
}
}
if (!headerSearchPaths.empty())
{
headerSearchPaths = utility::replaceOrAddCxxCompilerHeaderPath(headerSearchPaths);
}
return headerSearchPaths;
}
@@ -39,7 +39,6 @@ std::vector<FilePath> CxxVs10To14HeaderPathDetector::getPaths() const
if (!headerSearchPaths.empty())
{
utility::append(headerSearchPaths, utility::getWindowsSdkHeaderSearchPaths(m_architecture));
headerSearchPaths = utility::replaceOrAddCxxCompilerHeaderPath(headerSearchPaths);
}
return headerSearchPaths;
@@ -51,7 +51,6 @@ std::vector<FilePath> CxxVs15HeaderPathDetector::getPaths() const
windowsSdkHeaderSearchPaths = utility::getWindowsSdkHeaderSearchPaths(APPLICATION_ARCHITECTURE_X86_64);
}
utility::append(headerSearchPaths, windowsSdkHeaderSearchPaths);
headerSearchPaths = utility::replaceOrAddCxxCompilerHeaderPath(headerSearchPaths);
}
return headerSearchPaths;