Browse Source

Fixes #423: now uses clang++ to find system include paths

pipelines/143601543
eidheim 6 years ago
parent
commit
672108f120
  1. 35
      src/compile_commands.cc
  2. 11
      src/compile_commands.h
  3. 8
      tests/compile_commands_test.cc

35
src/compile_commands.cc

@ -1,9 +1,35 @@
#include "compile_commands.h" #include "compile_commands.h"
#include "clangmm.h" #include "clangmm.h"
#include "terminal.h"
#include <algorithm> #include <algorithm>
#include <boost/property_tree/json_parser.hpp> #include <boost/property_tree/json_parser.hpp>
#include <regex> #include <regex>
CompileCommands::FindSystemIncludePaths::FindSystemIncludePaths() {
std::stringstream stdin_stream, stdout_stream;
stdin_stream << "int main() {}";
exit_status = Terminal::get().process(stdin_stream, stdout_stream, "clang++ -v -x c++ -E 2>&1 -");
if(exit_status != 0)
return;
std::string line;
while(std::getline(stdout_stream, line)) {
if(line == "#include <...> search starts here:") {
while(std::getline(stdout_stream, line)) {
if(!line.empty() && line[0] == ' ') {
auto end = line.find(" (framework directory)", 1);
if(end == std::string::npos)
include_paths.emplace_back(line.substr(1, end));
else
framework_paths.emplace_back(line.substr(1, end));
}
else
return;
}
return;
}
}
}
std::vector<std::string> CompileCommands::Command::parameter_values(const std::string &parameter_name) const { std::vector<std::string> CompileCommands::Command::parameter_values(const std::string &parameter_name) const {
std::vector<std::string> parameter_values; std::vector<std::string> parameter_values;
@ -135,6 +161,14 @@ std::vector<std::string> CompileCommands::get_arguments(const boost::filesystem:
else else
arguments.emplace_back(default_std_argument); arguments.emplace_back(default_std_argument);
static FindSystemIncludePaths system_include_paths;
if(system_include_paths) {
for(auto &path : system_include_paths.include_paths)
arguments.emplace_back("-I" + path);
for(auto &path : system_include_paths.framework_paths)
arguments.emplace_back("-F" + path);
}
else {
auto clang_version_string = clangmm::to_string(clang_getClangVersion()); auto clang_version_string = clangmm::to_string(clang_getClangVersion());
const static std::regex clang_version_regex(R"(^[A-Za-z ]+([0-9.]+).*$)"); const static std::regex clang_version_regex(R"(^[A-Za-z ]+([0-9.]+).*$)");
std::smatch sm; std::smatch sm;
@ -155,6 +189,7 @@ std::vector<std::string> CompileCommands::get_arguments(const boost::filesystem:
arguments.emplace_back("-I" + (boost::filesystem::path(env_msystem_prefix) / "lib/clang" / clang_version / "include").string()); arguments.emplace_back("-I" + (boost::filesystem::path(env_msystem_prefix) / "lib/clang" / clang_version / "include").string());
#endif #endif
} }
}
// Do not add -fretain-comments-from-system-headers if pch is used, since the pch was most likely made without this flag // Do not add -fretain-comments-from-system-headers if pch is used, since the pch was most likely made without this flag
if(std::none_of(arguments.begin(), arguments.end(), [](const std::string &argument) { return argument == "-include-pch"; })) if(std::none_of(arguments.begin(), arguments.end(), [](const std::string &argument) { return argument == "-include-pch"; }))

11
src/compile_commands.h

@ -5,6 +5,17 @@
class CompileCommands { class CompileCommands {
public: public:
class FindSystemIncludePaths {
int exit_status;
public:
std::vector<std::string> include_paths;
std::vector<std::string> framework_paths;
operator bool() const { return exit_status == 0; }
FindSystemIncludePaths();
};
class Command { class Command {
public: public:
boost::filesystem::path directory; boost::filesystem::path directory;

8
tests/compile_commands_test.cc

@ -1,9 +1,17 @@
#include "compile_commands.h" #include "compile_commands.h"
#include <glib.h> #include <glib.h>
#include <gtkmm.h>
int main() { int main() {
auto app = Gtk::Application::create();
auto tests_path = boost::filesystem::canonical(JUCI_TESTS_PATH); auto tests_path = boost::filesystem::canonical(JUCI_TESTS_PATH);
{
CompileCommands::FindSystemIncludePaths system_include_paths;
g_assert(system_include_paths);
g_assert(!system_include_paths.include_paths.empty());
}
{ {
CompileCommands compile_commands(tests_path / "meson_test_files" / "build"); CompileCommands compile_commands(tests_path / "meson_test_files" / "build");

Loading…
Cancel
Save