diff options
| author | Arthur LAURENT <[email protected]> | 2025-11-26 15:29:03 +0100 |
|---|---|---|
| committer | ruki <[email protected]> | 2025-12-18 09:31:44 +0800 |
| commit | c765a2c1cac6ab126efc779eb4c823c5573dd25d (patch) | |
| tree | ce2489bbe8abc8b9cbc807512b641b82d4a506b3 /xmake/modules/private/utils/toolchain.lua | |
| parent | 5dcd669f6e3017d6939af6fd391803c13395406a (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.lua | 111 |
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 |
