From 8913a4a485d1666b0446375ee09f3d04875f8b2f Mon Sep 17 00:00:00 2001 From: eidheim Date: Fri, 9 Jun 2023 18:37:06 +0200 Subject: [PATCH] Fixed clang -resource-dir setting for libclang --- CMakeLists.txt | 4 ++ src/compile_commands.cpp | 116 ++++++++++---------------------- src/compile_commands.hpp | 12 ---- tests/compile_commands_test.cpp | 5 -- 4 files changed, 38 insertions(+), 99 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 32e7c4b..b7ad2a7 100644 --- a/CMakeLists.txt +++ b/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) diff --git a/src/compile_commands.cpp b/src/compile_commands.cpp index 0f3a2ef..32641b0 100644 --- a/src/compile_commands.cpp +++ b/src/compile_commands.cpp @@ -8,40 +8,6 @@ #include #include -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 CompileCommands::Command::parameter_values(const std::string ¶meter_name) const { std::vector parameter_values; @@ -172,57 +138,43 @@ std::vector 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/"; +#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(resource_path); + } +#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; + if(std::regex_match(clang_version_string, sm, clang_version_regex)) { + auto clang_version = sm[1].str(); + 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()); + } #else - const std::string sysroot = ""; -#endif - - static FindSystemIncludePaths system_include_paths; - if(system_include_paths) { - if(!system_include_paths.resource_path.empty()) { - arguments.emplace_back("-resource-dir"); - arguments.emplace_back(system_include_paths.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 - 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(); - 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 + 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"; })) diff --git a/src/compile_commands.hpp b/src/compile_commands.hpp index 77b77fa..54f6424 100644 --- a/src/compile_commands.hpp +++ b/src/compile_commands.hpp @@ -5,18 +5,6 @@ class CompileCommands { public: - class FindSystemIncludePaths { - int exit_status; - - public: - std::string resource_path; - std::vector include_paths; - std::vector framework_paths; - operator bool() const { return exit_status == 0; } - - FindSystemIncludePaths(); - }; - class Command { public: boost::filesystem::path directory; diff --git a/tests/compile_commands_test.cpp b/tests/compile_commands_test.cpp index fa1ebbc..537bf5d 100644 --- a/tests/compile_commands_test.cpp +++ b/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");