Commit bc13f955 authored by Milian Wolff's avatar Milian Wolff

Also find clang include path based on runtime libclang library path

My KDevelop was compiled against my system libclang v7.0.1, thus
KDEV_CLANG_BUILTIN_DIR points to /usr/lib/clang/7.0.1/include. Now
I compiled clang 8 from sources and put it in a different folder
in my home path and adapted LD_LIBRARY_PATH to make KDevelop pick it
up. This then fails to find the builtin include path, since it tries
to find `/usr/lib/clang/8.0.1/include` which doesn't exit.

This patch adds another fallback to fix the above scneario: We now
lookup the path of libclang at runtime through dlfcn.h's dladdr,
which we pass a libclang function address, here clang_getClangVersion.
Then on success we deduce the include path by removing the library
name and then instead appending `clang/$version/include`, which makes
it use /home/milian/projects/compiled/other/lib/clang/8.0.1/include
as required.
parent c88bf19b
Pipeline #2529 failed with stage
in 60 minutes
......@@ -2,6 +2,11 @@ add_definitions(-DTRANSLATION_DOMAIN=\"kdevclang\")
add_definitions(${LLVM_CFLAGS})
include_directories(${CLANG_INCLUDE_DIRS})
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_DL_LIBS})
check_cxx_source_compiles(
"#include <dlfcn.h>\nint main() { Dl_info info; return dladdr(nullptr, &info); }"
HAVE_DLFCN)
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/libclang_include_path.h.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/libclang_include_path.h"
......@@ -116,6 +121,10 @@ LINK_PUBLIC
Clang::clang
)
if (HAVE_DLFCN)
target_link_libraries(KDevClangPrivate LINK_PRIVATE ${CMAKE_DL_LIBS})
endif()
install(DIRECTORY duchain/wrappedQtHeaders DESTINATION ${KDE_INSTALL_DATADIR}/kdevclangsupport
DIRECTORY_PERMISSIONS
OWNER_READ OWNER_WRITE OWNER_EXECUTE
......
......@@ -44,6 +44,10 @@
#include <algorithm>
#if HAVE_DLFCN
#include <dlfcn.h>
#endif
using namespace KDevelop;
namespace {
......@@ -408,6 +412,20 @@ QString ClangHelpers::clangBuiltinIncludePath()
}
#endif
#if HAVE_DLFCN
// maybe the location of clang changed, try to use the library path instead
// we find it by pass any symbol in libclang to dladdr
Dl_info info;
if (dladdr(reinterpret_cast<void*>(&clang_getClangVersion), &info)) {
dir = QDir::cleanPath(QStringLiteral("%1/../clang/%2/include")
.arg(QString::fromUtf8(info.dli_fname), clangVersion()));
if (isValidClangBuiltingIncludePath(dir)) {
clangDebug() << "Using builtin dir:" << dir;
return dir;
}
}
#endif
clangDebug() << "Using builtin dir:" << KDEV_CLANG_BUILTIN_DIR;
return QString::fromUtf8(KDEV_CLANG_BUILTIN_DIR);
}();
......
......@@ -20,3 +20,5 @@
*/
#define KDEV_CLANG_BUILTIN_DIR "@CLANG_BUILTIN_DIR@"
#cmakedefine01 HAVE_DLFCN
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment