ui: Added user interface for auto system header search paths detection

* moved detection files to lib_gui
* added ui to global header search and framework search ui in project wizzard and preferences
* detecting the search paths will add them to the list if not added yet
* only detected compilers are shown in the dropdown list
This commit is contained in:
Eberhard Graether
2016-04-06 11:23:20 +02:00
parent 93f21283f6
commit 5e6714d95a
26 changed files with 345 additions and 243 deletions
@@ -0,0 +1,62 @@
#include "utility/headerSearch/CompilerDetector.h"
#include "utility/utilityApp.h"
#include "utility/utilityString.h"
CompilerDetector::CompilerDetector(const std::string& name)
: DetectorBase(name)
{
}
CompilerDetector::~CompilerDetector()
{
}
std::vector<std::string> CompilerDetector::getHeaderPaths()
{
std::string command = m_name + " -x c++ -v -E /dev/null";
std::string clangOutput = utility::executeProcess(command.c_str());
std::string standardHeaders =
utility::substrBetween(clangOutput, "#include <...> search starts here:\n","\nEnd of search list");
std::vector<std::string> paths;
if (!standardHeaders.empty())
{
for (std::string s : utility::splitToVector(standardHeaders, '\n'))
{
paths.push_back(utility::trim(s));
}
}
return paths;
}
std::vector<FilePath> CompilerDetector::getStandardHeaderPaths()
{
std::vector<std::string> paths = getHeaderPaths();
std::vector<FilePath> headerPaths;
for (const std::string& path : paths)
{
if (!utility::isPostfix(" (framework directory)", path))
{
headerPaths.push_back(FilePath(path).canonical());
}
}
return headerPaths;
}
std::vector<FilePath> CompilerDetector::getStandardFrameworkPaths()
{
std::vector<std::string> paths = getHeaderPaths();
std::vector<FilePath> frameworkPaths;
for (const std::string& path : paths)
{
if (utility::isPostfix(" (framework directory)", path))
{
frameworkPaths.push_back(FilePath(utility::replace(path, " (framework directory)", "")).canonical());
}
}
return frameworkPaths;
}
@@ -0,0 +1,20 @@
#ifndef COMPILER_DETECTOR_H
#define COMPILER_DETECTOR_H
#include "utility/headerSearch/DetectorBase.h"
class CompilerDetector
: public DetectorBase
{
public:
CompilerDetector(const std::string& name);
virtual ~CompilerDetector();
std::vector<std::string> getHeaderPaths();
virtual std::vector<FilePath> getStandardHeaderPaths();
virtual std::vector<FilePath> getStandardFrameworkPaths();
};
#endif // COMPILER_DETECTOR_H
@@ -0,0 +1,29 @@
#include "utility/headerSearch/DetectorBase.h"
DetectorBase::DetectorBase(const std::string name)
{
setName(name);
}
bool DetectorBase::detect()
{
return !getStandardHeaderPaths().empty();
}
std::vector<FilePath> DetectorBase::getStandardFrameworkPaths()
{
return std::vector<FilePath>();
}
std::string DetectorBase::getName() const
{
return m_name;
}
void DetectorBase::setName(const std::string& name)
{
if (!name.empty())
{
m_name = name;
}
}
@@ -0,0 +1,22 @@
#ifndef DETECTOR_BASE_H
#define DETECTOR_BASE_H
#include <vector>
#include "utility/file/FilePath.h"
class DetectorBase
{
public:
DetectorBase(const std::string name);
virtual ~DetectorBase(){};
virtual bool detect();
virtual std::vector<FilePath> getStandardHeaderPaths() = 0;
virtual std::vector<FilePath> getStandardFrameworkPaths();
virtual std::string getName() const;
virtual void setName(const std::string& name);
protected:
std::string m_name;
};
#endif // DETECTOR_BASE_H
@@ -0,0 +1,106 @@
#include "utility/headerSearch/StandardHeaderDetection.h"
#include <cstdlib>
#include <iostream>
#include <map>
#include <string>
#include <utility>
#include <vector>
#include "utility/file/FilePath.h"
#include "utility/headerSearch/CompilerDetector.h"
#include "utility/headerSearch/VisualStudioDetector.h"
#include "utility/logging/logging.h"
#include "utility/utilityApp.h"
#include "utility/utilityString.h"
StandardHeaderDetection::DetectorMap StandardHeaderDetection::s_availableDetectors;
StandardHeaderDetection::DetectorMap StandardHeaderDetection::s_detectedCompilers;
StandardHeaderDetection::StandardHeaderDetection()
{
if (!s_availableDetectors.size())
{
addDetector(std::make_shared<CompilerDetector>("gcc"));
addDetector(std::make_shared<CompilerDetector>("clang"));
addDetector(std::make_shared<VisualStudioDetector>("14"));
addDetector(std::make_shared<VisualStudioDetector>("12"));
addDetector(std::make_shared<VisualStudioDetector>("11"));
addDetector(std::make_shared<VisualStudioDetector>("9"));
detectHeaders();
}
}
StandardHeaderDetection::~StandardHeaderDetection()
{
}
void StandardHeaderDetection::addDetector(std::shared_ptr<DetectorBase> detector)
{
s_availableDetectors.emplace(detector->getName(), detector);
}
void StandardHeaderDetection::detectHeaders()
{
for ( DetectorPair detector : s_availableDetectors)
{
if ( detector.second->detect() )
{
s_detectedCompilers.insert(detector);
}
}
}
std::vector<std::string> StandardHeaderDetection::getDetectedCompilers()
{
std::vector<std::string> v;
for ( DetectorPair detector : s_detectedCompilers)
{
v.push_back(detector.first);
}
return v;
}
std::vector<FilePath> StandardHeaderDetection::getStandardHeaderPaths(std::string compiler)
{
auto it = s_detectedCompilers.find(compiler);
if (it != s_detectedCompilers.end())
{
return it->second->getStandardHeaderPaths();
}
return std::vector<FilePath>();
}
std::vector<FilePath> StandardHeaderDetection::getStandardFrameworkPaths(std::string compiler)
{
auto it = s_detectedCompilers.find(compiler);
if (it != s_detectedCompilers.end())
{
return it->second->getStandardFrameworkPaths();
}
return std::vector<FilePath>();
}
void StandardHeaderDetection::printDetectedCompilers()
{
std::cout << "Detected Compilers: " << std::endl;
std::vector<std::string> compilers = getDetectedCompilers();
for ( std::string compiler : compilers)
{
std::cout << compiler << std::endl;
}
}
void StandardHeaderDetection::printAvailableDetectors()
{
std::cout << "Available Detectors: " << std::endl;
for ( DetectorPair detector : s_availableDetectors)
{
std::cout << detector.first << std::endl;
}
}
@@ -0,0 +1,43 @@
#ifndef STANDARD_HEADER_DETECTION_H
#define STANDARD_HEADER_DETECTION_H
#include <map>
#include <memory>
#include <string>
#include <iostream>
#include "utility/headerSearch/DetectorBase.h"
class FilePath;
class StandardHeaderDetection
{
public:
StandardHeaderDetection();
~StandardHeaderDetection();
void addDetector(std::shared_ptr<DetectorBase> detector);
/// Checks all availabe detectors and saves found Compilers
void detectHeaders();
/// Returns alls found compilers
std::vector<std::string> getDetectedCompilers();
/// Returns the headerpaths from a found compiler
std::vector<FilePath> getStandardHeaderPaths(std::string compiler);
std::vector<FilePath> getStandardFrameworkPaths(std::string compiler);
/// Debugging Output
void printAvailableDetectors();
void printDetectedCompilers();
private:
typedef std::map<std::string, std::shared_ptr<DetectorBase>> DetectorMap;
typedef std::pair<std::string, std::shared_ptr<DetectorBase>> DetectorPair;
static DetectorMap s_availableDetectors;
static DetectorMap s_detectedCompilers;
};
#endif // STANDARD_HEADER_DETECTION_H
@@ -0,0 +1,117 @@
#include "utility/headerSearch/VisualStudioDetector.h"
#include <string>
#include <QSettings>
#include <QSysInfo>
#include <QDir>
#include "utility/file/FilePath.h"
#include "utility/logging/logging.h"
VisualStudioDetector::VisualStudioDetector(const std::string name)
: DetectorBase("")
, m_isExpress(false)
{
setName(name);
}
VisualStudioDetector::~VisualStudioDetector()
{
}
void VisualStudioDetector::setName(const std::string& version)
{
m_versionNumber = std::stoi(version);
if (m_versionNumber > 8 && m_versionNumber < 15)
{
DetectorBase::setName("VS" + version + "0");
}
else
{
// unsupported Visual Studio version
}
}
std::string VisualStudioDetector::getFullName()
{
return "Visual Studio " + std::to_string(m_versionNumber + 1) + (m_isExpress ? " Express" : "");
}
std::vector<FilePath> VisualStudioDetector::getStandardHeaderPaths()
{
std::vector<FilePath> headerPaths;
// vc++ headers
if ( !getStanardHeaderPathsUsingEnvironmentVariable(headerPaths) )
{
if ( !getStanardHeaderPathsUsingRegistry(headerPaths) )
{
if ( !getStanardHeaderPathsUsingRegistry(headerPaths, true) )
{
return headerPaths;
}
}
}
//windows sdk
//TODO
return headerPaths;
}
std::string getInstallDir(const std::string RegistryKey)
{
return "";
}
std::string getWindowsSDKDir()
{
return "";
}
bool VisualStudioDetector::getStanardHeaderPathsUsingEnvironmentVariable(std::vector<FilePath>& paths)
{
std::string VSToolstring = m_name + "comntools";
std::vector<FilePath> path;
if ( const char* vs_env = std::getenv(VSToolstring.c_str()))
{
FilePath VSHeaderpath(vs_env);
VSHeaderpath = VSHeaderpath.concat("../vc/include");
if (VSHeaderpath.exists())
{
LOG_INFO_STREAM(<< getFullName() << " includes detected");
path.push_back(VSHeaderpath.str());
paths = std::move(path);
return true;
}
}
return false;
}
bool VisualStudioDetector::getStanardHeaderPathsUsingRegistry(std::vector<FilePath>& paths, bool lookForExpressVersion)
{
QString key = "HKEY_LOCAL_MACHINE\\SOFTWARE\\";
if (QSysInfo::currentCpuArchitecture() == "x86_64")
{
key += "Wow6432Node\\";
}
key += "Microsoft\\";
key += ( lookForExpressVersion ? "VCExpress" : "VisualStudio" );
key += "\\" + QString::number(m_versionNumber) + ".0";
QSettings expressKey(key, QSettings::NativeFormat);
QString value = expressKey.value("InstallDir").toString() + "../VC/include";
QDir dir(value);
if ( dir.exists())
{
if ( lookForExpressVersion )
{
m_isExpress = true;
}
return true;
}
return false;
}
@@ -0,0 +1,26 @@
#ifndef VISUAL_STUDIO_DETECTOR_H
#define VISUAL_STUDIO_DETECTOR_H
#include <vector>
#include "utility/headerSearch/DetectorBase.h"
class FilePath;
class VisualStudioDetector : public DetectorBase
{
public:
VisualStudioDetector(const std::string name = "14");
virtual ~VisualStudioDetector();
virtual std::vector<FilePath> getStandardHeaderPaths();
private:
std::string getFullName();
bool getStanardHeaderPathsUsingEnvironmentVariable(std::vector<FilePath>& paths);
bool getStanardHeaderPathsUsingRegistry(std::vector<FilePath>& paths, bool lookForExpressVersion = false);
void setName(const std::string& version);
int m_versionNumber;
bool m_isExpress;
};
#endif // VISUAL_STUDIO_DETECTOR_H
+15
View File
@@ -0,0 +1,15 @@
#include "utility/utilityApp.h"
#include <QProcess>
std::string utility::executeProcess(const char *cmd)
{
QProcess process;
process.setProcessChannelMode(QProcess::MergedChannels);
process.start(cmd);
process.waitForFinished();
std::string processoutput = process.readAll().toStdString();
process.close();
return processoutput;
}
+13
View File
@@ -0,0 +1,13 @@
#ifndef UTILITY_APP_H
#define UTILITY_APP_H
#include <QProcess>
namespace utility
{
std::string executeProcess(const char* cmd);
}
#endif // UTILITY_APP_H