Browse Source

Fixed clang -resource-dir setting for libclang

merge-requests/413/head
eidheim 3 years ago
parent
commit
8913a4a485
  1. 4
      CMakeLists.txt
  2. 96
      src/compile_commands.cpp
  3. 12
      src/compile_commands.hpp
  4. 5
      tests/compile_commands_test.cpp

4
CMakeLists.txt

@ -100,6 +100,10 @@ else()
find_package(LibClang REQUIRED)
endif()
if(APPLE)
add_definitions(-DJUCI_LIBCLANG_LIBRARY="${LIBCLANG_LIBRARIES}")
endif()
set(BUILD_TESTING_SAVED ${BUILD_TESTING})
set(BUILD_TESTING OFF CACHE BOOL "Disable sub-project tests" FORCE)
add_subdirectory(lib/tiny-process-library)

96
src/compile_commands.cpp

@ -8,40 +8,6 @@
#include <algorithm>
#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(starts_with(line, "#include <...> search starts here:")) {
while(std::getline(stdout_stream, line)) {
if(!line.empty() && line[0] == ' ') {
#ifdef _WIN32
if(line.back() == '\r')
line.pop_back();
#endif
if(ends_with(line, " (framework directory)"))
framework_paths.emplace_back(line.substr(1, line.size() - 22 - 1));
else {
#ifdef __APPLE__
// Workaround for missing resource-dir
if(line == " /Library/Developer/CommandLineTools/usr/lib/clang/14.0.3/include")
resource_path = "/Library/Developer/CommandLineTools/usr/lib/clang/14.0.3";
#endif
include_paths.emplace_back(line.substr(1));
}
}
else
return;
}
return;
}
}
}
std::vector<std::string> CompileCommands::Command::parameter_values(const std::string &parameter_name) const {
std::vector<std::string> parameter_values;
@ -172,24 +138,18 @@ std::vector<std::string> CompileCommands::get_arguments(const boost::filesystem:
else
arguments.emplace_back(default_std_argument);
#ifdef JUCI_FLATPAK_SANDBOX
// The host file system is mounted here, need to add this as prefix to access host system headers
const std::string sysroot = "/var/run/host/";
#else
const std::string sysroot = "";
#endif
static FindSystemIncludePaths system_include_paths;
if(system_include_paths) {
if(!system_include_paths.resource_path.empty()) {
#if defined(__APPLE__)
static auto resource_path = []() -> std::string {
boost::system::error_code ec;
for(boost::filesystem::directory_iterator it(boost::filesystem::path(JUCI_LIBCLANG_LIBRARY).parent_path() / "clang", ec), end; it != end; ++it)
return it->path().string();
return {};
}();
if(!resource_path.empty()) {
arguments.emplace_back("-resource-dir");
arguments.emplace_back(system_include_paths.resource_path);
arguments.emplace_back(resource_path);
}
for(auto &path : system_include_paths.include_paths)
arguments.emplace_back("-I" + sysroot + path);
for(auto &path : system_include_paths.framework_paths)
arguments.emplace_back("-F" + path);
#ifdef _WIN32
#elif defined(_WIN32)
auto clang_version_string = clangmm::to_string(clang_getClangVersion());
const static std::regex clang_version_regex(R"(^[A-Za-z ]+([0-9.]+).*$)", std::regex::optimize);
std::smatch sm;
@ -199,30 +159,22 @@ std::vector<std::string> CompileCommands::get_arguments(const boost::filesystem:
if(env_msystem_prefix)
arguments.emplace_back("-I" + (boost::filesystem::path(env_msystem_prefix) / "lib/clang" / clang_version / "include").string());
}
#endif
#else
static auto resource_path = []() -> std::string {
std::stringstream stdin_stream, stdout_stream;
auto exit_status = Terminal::get().process(stdin_stream, stdout_stream, "clang++ -print-resource-dir");
if(exit_status != 0)
return {};
auto path = stdout_stream.str();
if(!path.empty())
path.pop_back();
return path;
}();
if(!resource_path.empty()) {
arguments.emplace_back("-resource-dir");
arguments.emplace_back(resource_path);
}
else {
auto clang_version_string = clangmm::to_string(clang_getClangVersion());
const static std::regex clang_version_regex(R"(^[A-Za-z ]+([0-9.]+).*$)", std::regex::optimize);
std::smatch sm;
if(std::regex_match(clang_version_string, sm, clang_version_regex)) {
auto clang_version = sm[1].str();
arguments.emplace_back("-I" + sysroot + "/usr/lib/clang/" + clang_version + "/include");
arguments.emplace_back("-I" + sysroot + "/usr/lib64/clang/" + clang_version + "/include"); // For Fedora
#if defined(__APPLE__)
// Missing include and framework folders for MacOS:
arguments.emplace_back("-I/usr/local/opt/llvm/include/c++/v1");
arguments.emplace_back("-I/usr/local/opt/llvm/lib/clang/" + clang_version + "/include");
arguments.emplace_back("-I/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include");
arguments.emplace_back("-F/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks");
#endif
#ifdef _WIN32
auto env_msystem_prefix = std::getenv("MSYSTEM_PREFIX");
if(env_msystem_prefix)
arguments.emplace_back("-I" + (boost::filesystem::path(env_msystem_prefix) / "lib/clang" / clang_version / "include").string());
#endif
}
}
// 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"; }))

12
src/compile_commands.hpp

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

5
tests/compile_commands_test.cpp

@ -9,11 +9,6 @@ int main() {
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_old_test_files" / "build");

Loading…
Cancel
Save