clc: retrieve libclang path at runtime.

LLVM_LIB_DIR is a variable used for runtime compilations.
When cross compiling, LLVM_LIB_DIR must be set to the
libclang path on the target. So, this path should not
be retrieved during compilation but at runtime.

dladdr uses an address to search for a loaded library.
If a library is found, it returns information about it.
The path to the libclang library can therefore be
retrieved using one of its functions. This is useful
because we don't know the name of the libclang library
(libclang.so.X or libclang-cpp.so.X)

v2 (Karol): use clang::CompilerInvocation::CreateFromArgs for dladdr
v3 (Karol): follow symlinks to fix errors on debian

Fixes: e22491c832 ("clc: fetch clang resource dir at runtime")
Signed-off-by: Antoine Coutant <antoine.coutant@smile.fr>
Reviewed-by: Karol Herbst <kherbst@redhat.com>
Reviewed-by (v1): Jesse Natalie <jenatali@microsoft.com>

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25568>
(cherry picked from commit 445aacb421)
This commit is contained in:
Antoine Coutant
2023-11-30 11:10:20 +01:00
committed by Eric Engestrom
parent 613ac7d10e
commit e43a1cd76a
2 changed files with 22 additions and 5 deletions

View File

@@ -174,7 +174,7 @@
"description": "clc: retrieve libclang path at runtime.",
"nominated": true,
"nomination_type": 1,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": "e22491c83265200f518e9fb4deff54e3c2823b68",
"notes": null

View File

@@ -23,6 +23,7 @@
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#include <cstdlib>
#include <filesystem>
#include <sstream>
#include <mutex>
@@ -57,6 +58,10 @@
#include "spirv.h"
#if DETECT_OS_UNIX
#include <dlfcn.h>
#endif
#ifdef USE_STATIC_OPENCL_C_H
#if LLVM_VERSION_MAJOR < 15
#include "opencl-c.h.h"
@@ -876,12 +881,24 @@ clc_compile_to_llvm_module(LLVMContext &llvm_ctx,
#endif
}
#else
Dl_info info;
if (dladdr((void *)clang::CompilerInvocation::CreateFromArgs, &info) == 0) {
clc_error(logger, "Couldn't find libclang path.\n");
return {};
}
char *clang_path = realpath(info.dli_fname, NULL);
if (clang_path == nullptr) {
clc_error(logger, "Couldn't find libclang path.\n");
return {};
}
// GetResourcePath is a way to retrive the actual libclang resource dir based on a given binary
// or library. The path doesn't even need to exist, we just have to put something in there,
// because we might have linked clang statically.
auto libclang_path = fs::path(LLVM_LIB_DIR) / "libclang.so";
// or library.
auto clang_res_path =
fs::path(Driver::GetResourcesPath(libclang_path.string(), CLANG_RESOURCE_DIR)) / "include";
fs::path(Driver::GetResourcesPath(std::string(clang_path), CLANG_RESOURCE_DIR)) / "include";
free(clang_path);
c->getHeaderSearchOpts().UseBuiltinIncludes = true;
c->getHeaderSearchOpts().UseStandardSystemIncludes = true;