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:
@@ -14,5 +14,5 @@
|
||||
<recent_project>./projects/javaparser/javaparser.srctrlprj</recent_project>
|
||||
</recent_projects>
|
||||
</user>
|
||||
<version>5</version>
|
||||
<version>6</version>
|
||||
</config>
|
||||
|
||||
@@ -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" +
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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()));
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user