summaryrefslogtreecommitdiff
path: root/xmake/modules/private/utils/toolchain.lua
diff options
context:
space:
mode:
authorArthur LAURENT <[email protected]>2025-11-26 15:29:03 +0100
committerruki <[email protected]>2025-12-18 09:31:44 +0800
commitc765a2c1cac6ab126efc779eb4c823c5573dd25d (patch)
treece2489bbe8abc8b9cbc807512b641b82d4a506b3 /xmake/modules/private/utils/toolchain.lua
parent5dcd669f6e3017d6939af6fd391803c13395406a (diff)
(llvm) add runtime dirs to runenvs (for asan and libunwind)
Diffstat (limited to 'xmake/modules/private/utils/toolchain.lua')
-rw-r--r--xmake/modules/private/utils/toolchain.lua111
1 files changed, 69 insertions, 42 deletions
diff --git a/xmake/modules/private/utils/toolchain.lua b/xmake/modules/private/utils/toolchain.lua
index 551209f2d..e1142945a 100644
--- a/xmake/modules/private/utils/toolchain.lua
+++ b/xmake/modules/private/utils/toolchain.lua
@@ -183,25 +183,25 @@ end
-- get llvm sdk resource directory
function _get_llvm_resourcedir(toolchain)
- local llvm_resourcedir = _g._LLVM_resourceDIR
+ local llvm_resourcedir = _g._LLVM_RESOURCE_DIR
if llvm_resourcedir == nil then
- local outdata = try { function() return os.iorunv(toolchain:get("cc"), {"-print-resource-dir"}, {envs = toolchain:runenvs()}) end }
+ local outdata = try { function() return os.iorunv(toolchain:tool("cc"), {"-print-resource-dir"}) end }
if outdata then
llvm_resourcedir = path.normalize(outdata:trim())
if not os.isdir(llvm_resourcedir) then
llvm_resourcedir = nil
end
end
- _g._LLVM_resourceDIR = llvm_resourcedir or false
+ _g._LLVM_RESOURCE_DIR = llvm_resourcedir or false
end
return llvm_resourcedir or nil
end
-- get llvm sdk root directory
-function _get_llvm_rootdir(self)
+function _get_llvm_rootdir(toolchain)
local llvm_rootdir = _g._LLVM_ROOTDIR
if llvm_rootdir == nil then
- local resourcedir = _get_llvm_resourcedir(self)
+ local resourcedir = _get_llvm_resourcedir(toolchain)
if resourcedir then
llvm_rootdir = path.normalize(path.join(resourcedir, "..", "..", ".."))
if not os.isdir(llvm_rootdir) then
@@ -214,40 +214,49 @@ function _get_llvm_rootdir(self)
end
-- find compiler-rt dir
-function _get_llvm_compiler_win_rtdir_and_link(self, target)
+function _get_llvm_compiler_rtdir_and_link(toolchain)
import("lib.detect.find_tool")
- local cc = self:get("cc")
+ local cc = toolchain:tool("cc")
local cc_tool = find_tool(cc, {version = true})
if cc_tool and cc_tool.version then
- local resdir = _get_llvm_resourcedir(self)
+ local resdir = _get_llvm_resourcedir(toolchain)
if resdir then
local res_libdir = path.join(resdir, "lib")
- -- when -DLLVM_ENABLE_TARGET_RUNTIME_DIR=OFF rtdir is windows/ and rtlink is clang_rt.builtinsi_<arch>.lib
+ -- when -DLLVM_ENABLE_TARGET_RUNTIME_DIR=OFF rtdir is windows/ and rtlink is clang_rt.builtins_<arch>.lib
-- when ON rtdir is windows/<target-triple> and rtlink is clang_rt.builtins.lib
- local target_triple = _get_llvm_target_triple(self)
+ local target_triple = _get_llvm_target_triple(toolchain)
local arch = target_triple and target_triple:split("-")[1]
+ local plat
+ if toolchain:is_plat("windows") then
+ plat = "windows"
+ elseif toolchain:is_plat("linux") then
+ plat = "linux"
+ elseif toolchain:is_plat("macosx", "ios", "watchos", "appletvos", "applexros") then
+ plat = "darwin"
+ end
+
local tripletdir = target_triple and path.join(res_libdir, "windows", target_triple)
tripletdir = os.isdir(tripletdir) or nil
- local rtdir = tripletdir and path.join("windows", target_triple) or "windows"
- if os.isdir(path.join(res_libdir, rtdir)) then
+ local rtdir = tripletdir and path.join(plat, target_triple) or plat
+ if os.isdir(path.join(res_libdir, rtdir)) and toolchain:is_plat("windows") then
local rtlink = "clang_rt.builtins" .. (tripletdir and ".lib" or ("-" .. arch .. ".lib"))
if os.isfile(path.join(res_libdir, rtdir, rtlink)) then
- return res_libdir, path.join(rtdir, rtlink)
+ return res_libdir, path.join(rtdir, rtlink), path.join(res_libdir, rtdir)
end
end
- return res_libdir
+ return res_libdir, nil, path.join(res_libdir, rtdir)
end
end
end
-- get llvm target triple
-function _get_llvm_target_triple(self)
+function _get_llvm_target_triple(toolchain)
local llvm_targettriple = _g._LLVM_TARGETTRIPLE
if llvm_targettriple == nil then
- local outdata = try { function() return os.iorunv(self:program(), {"-print-target-triple"}, {envs = self:runenvs()}) end }
+ local outdata = try { function() return os.iorunv(toolchain:tool("cc"), {"-print-target-triple"}) end }
if outdata then
llvm_targettriple = outdata:trim()
end
@@ -268,50 +277,68 @@ function get_llvm_dirs(toolchain)
local bindir, libdir, cxxlibdir, includedir, cxxincludedir, resdir, rtdir, rtlink
if rootdir then
bindir = path.join(rootdir, "bin")
- if bindir then
- bindir = os.isdir(bindir) and bindir or nil
- end
+ bindir = os.isdir(bindir) and bindir or nil
libdir = path.join(rootdir, "lib")
- if libdir then
- libdir = os.isdir(libdir) and libdir or nil
- end
+ libdir = os.isdir(libdir) and libdir or nil
if libdir then
- cxxlibdir = libdir and path.join(libdir, "c++")
- if cxxlibdir then
+ cxxlibdir = path.join(libdir, "c++")
+ cxxlibdir = os.isdir(cxxlibdir) and cxxlibdir or nil
+ if not cxxlibdir then
+ cxxlibdir = path.join(libdir, _get_llvm_target_triple(toolchain))
cxxlibdir = os.isdir(cxxlibdir) and cxxlibdir or nil
end
end
includedir = path.join(rootdir, "include")
- if includedir then
- includedir = os.isdir(includedir) and includedir or nil
- end
+ includedir = os.isdir(includedir) and includedir or nil
if includedir then
- cxxincludedir = includedir and path.join(includedir, "c++", "v1") or nil
- if cxxincludedir then
- cxxincludedir = os.isdir(cxxincludedir) and cxxincludedir or nil
- end
+ cxxincludedir = path.join(includedir, "c++", "v1")
+ cxxincludedir = os.isdir(cxxincludedir) and cxxincludedir or nil
end
resdir = _get_llvm_resourcedir(toolchain)
- if toolchain:is_plat("windows") then
- rtdir, rtlink = _get_llvm_compiler_win_rtdir_and_link(toolchain)
- end
+ rtdir, rtlink, rtlib = _get_llvm_compiler_rtdir_and_link(toolchain)
end
llvm_dirs = {root = rootdir,
- bin = bindir,
- lib = libdir,
- cxxlib = cxxlibdir,
- include = includedir,
- cxxinclude = cxxincludedir,
- res = resdir,
- rt = rtdir,
- rtlink = rtlink }
+ bin = bindir,
+ lib = libdir,
+ cxxlib = cxxlibdir,
+ include = includedir,
+ cxxinclude = cxxincludedir,
+ res = resdir,
+ rt = rtdir,
+ rtlib = rtlib,
+ rtlink = rtlink }
_g.llvm_dirs = llvm_dirs
end
return llvm_dirs
end
+
+-- set runenvs for llvm
+function set_llvm_runenvs(toolchain)
+ local dirs = get_llvm_dirs(toolchain)
+ if dirs then
+ if dirs.bin and toolchain:is_plat("windows") then
+ toolchain:add("runenvs", "PATH", dirs.bin)
+ end
+ for _, dir in ipairs({dirs.lib or false, dirs.cxxlib or false, dirs.rtlib or false}) do
+ if dir then
+ if toolchain:is_plat("windows") then
+ toolchain:add("runenvs", "PATH", dir)
+ elseif toolchain:is_plat("linux", "bsd") then
+ toolchain:add("runenvs", "LD_LIBRARY_PATH", dir)
+ elseif toolchain:is_plat("macosx") then
+ -- using use DYLD_FALLBACK_LIBRARY_PATH instead of DYLD_LIBRARY_PATH to avoid symbols error when running homebrew llvm (which is linked to system libc++)
+ -- e.g dyld[5195]: Symbol not found: __ZnwmSt19__type_descriptor_t
+ -- Referenced from: <378C7CC2-7CD6-3B88-9C66-FE198E30462B> /usr/local/Cellar/llvm/21.1.5/bin/clang-21
+ -- Expected as weak-def export from some loaded dylibSymbol not found: __ZnamSt19__type_descriptor_t
+ toolchain:add("runenvs", "DYLD_FALLBACK_LIBRARY_PATH", dir)
+ end
+ end
+ end
+ end
+end