summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2026-02-26 10:14:31 +0800
committerGitHub <[email protected]>2026-02-26 10:14:31 +0800
commitac2563555fffdf2ce28baa6dab7c488574054f05 (patch)
tree9da4072bc13bb9bae9826868746c3cbfa0f5c147
parent27f49cd4de23014a3e3d9f17740517ab8771f24f (diff)
parent5336c965f443320c5fc13edf83a4b9d88c5b106d (diff)
Merge pull request #7345 from xmake-io/llvm
fix check clang info
-rw-r--r--xmake/modules/private/utils/toolchain.lua87
-rw-r--r--xmake/toolchains/clang-cl/check.lua2
-rw-r--r--xmake/toolchains/clang/check.lua8
-rw-r--r--xmake/toolchains/llvm/check.lua2
-rw-r--r--xmake/toolchains/llvm/xmake.lua2
-rw-r--r--xmake/toolchains/swift/xmake.lua2
6 files changed, 56 insertions, 47 deletions
diff --git a/xmake/modules/private/utils/toolchain.lua b/xmake/modules/private/utils/toolchain.lua
index d6f320a05..f694c23c9 100644
--- a/xmake/modules/private/utils/toolchain.lua
+++ b/xmake/modules/private/utils/toolchain.lua
@@ -343,34 +343,47 @@ function map_linkflags_for_package(package, targetkind, sourcekinds, name, value
return flags
end
--- get llvm sdk resource directory
-function get_llvm_resourcedir(toolchain)
- local memcache = toolchain:memcache()
- local cachekey = "get_llvm_resourcedir"
- local llvm_resourcedir = memcache:get(cachekey)
- if llvm_resourcedir == nil then
- local cc = toolchain:tool("cc")
- if cc then
- local outdata = try { function() return os.iorunv(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
+-- Check and cache llvm/clang driver info (e.g. -print-resource-dir/-print-target-triple) in toolchain:config().
+-- It must be collected during toolchain on_check so that toolchain on_load can use it without running clang again.
+-- @see https://github.com/xmake-io/xmake/issues/7337#issuecomment-3942499208
+function check_llvm_info(toolchain, clang, opt)
+ opt = opt or {}
+ if not clang then
+ return
+ end
+
+ local envs = opt.envs
+ local resourcedir = try {function () return os.iorunv(clang, {"-print-resource-dir"}, {envs = envs}) end}
+ if resourcedir then
+ resourcedir = path.normalize(resourcedir:trim())
+ dprint("checking for llvm resource dir ... %s", resourcedir)
+ if #resourcedir > 0 and os.isdir(resourcedir) then
+ toolchain:config_set("llvm_resourcedir", resourcedir)
+ end
+ end
+
+ local target_triple = try {function () return os.iorunv(clang, {"-print-target-triple"}, {envs = envs}) end}
+ if target_triple then
+ target_triple = target_triple:trim()
+ dprint("checking for llvm target triple ... %s", target_triple)
+ if #target_triple > 0 then
+ toolchain:config_set("llvm_target_triple", target_triple)
end
- memcache:set(cachekey, llvm_resourcedir or false)
end
- return llvm_resourcedir or nil
+end
+
+-- get llvm sdk resource directory
+function _get_llvm_resourcedir(toolchain)
+ return toolchain:config("llvm_resourcedir") or nil
end
-- get llvm sdk root directory
-function get_llvm_rootdir(toolchain)
+function _get_llvm_rootdir(toolchain)
local memcache = toolchain:memcache()
local cachekey = "get_llvm_rootdir"
local llvm_rootdir = memcache:get(cachekey)
if llvm_rootdir == nil then
- local resourcedir = get_llvm_resourcedir(toolchain)
+ local resourcedir = _get_llvm_resourcedir(toolchain)
if resourcedir then
llvm_rootdir = path.normalize(path.join(resourcedir, "..", "..", ".."))
if not os.isdir(llvm_rootdir) then
@@ -383,17 +396,17 @@ function get_llvm_rootdir(toolchain)
end
-- get compiler-rt info
-function get_llvm_compiler_rtinfo(toolchain)
+function _get_llvm_compiler_rtinfo(toolchain)
local memcache = toolchain:memcache()
local cachekey = "get_llvm_compiler_rtinfo"
local rtinfo = memcache:get(cachekey)
if rtinfo == nil then
- local resourcedir = get_llvm_resourcedir(toolchain)
+ local resourcedir = _get_llvm_resourcedir(toolchain)
if resourcedir then
local res_libdir = path.join(resourcedir, "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(toolchain)
+ local target_triple = _get_llvm_target_triple(toolchain)
local arch = target_triple and target_triple:split("-")[1]
local plat
@@ -428,21 +441,8 @@ function get_llvm_compiler_rtinfo(toolchain)
end
-- get llvm target triple
-function get_llvm_target_triple(toolchain)
- local memcache = toolchain:memcache()
- local cachekey = "get_llvm_target_triple"
- local llvm_targettriple = memcache:get(cachekey)
- if llvm_targettriple == nil then
- local cc = toolchain:tool("cc")
- if cc then
- local outdata = try { function() return os.iorunv(cc, {"-print-target-triple"}) end }
- if outdata then
- llvm_targettriple = outdata:trim()
- end
- end
- memcache:set(cachekey, llvm_targettriple or false)
- end
- return llvm_targettriple or nil
+function _get_llvm_target_triple(toolchain)
+ return toolchain:config("llvm_target_triple") or nil
end
-- get llvm toolchain dirs
@@ -453,7 +453,7 @@ function get_llvm_dirs(toolchain)
if llvm_dirs == nil then
local rootdir = toolchain:sdkdir()
if not rootdir and (toolchain:is_plat("windows") or is_host("windows")) then
- rootdir = get_llvm_rootdir(toolchain)
+ rootdir = _get_llvm_rootdir(toolchain)
end
local bindir, libdir, cxxlibdir, includedir, cxxincludedir, resourcedir, rtdir, rtlink, rtlibdir
@@ -468,8 +468,11 @@ function get_llvm_dirs(toolchain)
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
+ local target_triple = _get_llvm_target_triple(toolchain)
+ if target_triple then
+ cxxlibdir = path.join(libdir, target_triple)
+ cxxlibdir = os.isdir(cxxlibdir) and cxxlibdir or nil
+ end
end
end
@@ -481,8 +484,8 @@ function get_llvm_dirs(toolchain)
cxxincludedir = os.isdir(cxxincludedir) and cxxincludedir or nil
end
- resourcedir = get_llvm_resourcedir(toolchain)
- local rtinfo = get_llvm_compiler_rtinfo(toolchain)
+ resourcedir = _get_llvm_resourcedir(toolchain)
+ local rtinfo = _get_llvm_compiler_rtinfo(toolchain)
if rtinfo then
rtdir = rtinfo.rtdir
rtlink = rtinfo.rtlink
diff --git a/xmake/toolchains/clang-cl/check.lua b/xmake/toolchains/clang-cl/check.lua
index b7e417d69..2710700a2 100644
--- a/xmake/toolchains/clang-cl/check.lua
+++ b/xmake/toolchains/clang-cl/check.lua
@@ -33,6 +33,7 @@ function _check_clang_cl(toolchain, vcvars)
local result = find_tool("clang-cl", {force = true, paths = paths, envs = vcvars})
if result then
cprint("checking for LLVM Clang C/C++ Compiler (%s) ... ${color.success}${text.success}", toolchain:arch())
+ toolchain_utils.check_llvm_info(toolchain, result.program, {envs = vcvars})
end
return result
end
@@ -66,4 +67,3 @@ function main(toolchain)
end
end
end
-
diff --git a/xmake/toolchains/clang/check.lua b/xmake/toolchains/clang/check.lua
index 145805547..a6e820125 100644
--- a/xmake/toolchains/clang/check.lua
+++ b/xmake/toolchains/clang/check.lua
@@ -32,6 +32,7 @@ function _check_clang(toolchain, vcvars, suffix)
local result = find_tool("clang" .. suffix, {force = true, paths = paths, envs = vcvars})
if result then
cprint("checking for LLVM Clang C/C++ Compiler (%s) ... ${color.success}${text.success}", toolchain:arch())
+ toolchain_utils.check_llvm_info(toolchain, result.program, {envs = vcvars})
end
return result
end
@@ -72,6 +73,9 @@ function main(toolchain, suffix)
if toolchain:is_plat("windows") then
return _check_for_windows(toolchain, suffix)
end
- return find_tool("clang", {program = "clang" .. suffix})
+ local result = find_tool("clang", {program = "clang" .. suffix})
+ if result then
+ toolchain_utils.check_llvm_info(toolchain, result.program)
+ end
+ return result
end
-
diff --git a/xmake/toolchains/llvm/check.lua b/xmake/toolchains/llvm/check.lua
index b34e66e98..6e67513b3 100644
--- a/xmake/toolchains/llvm/check.lua
+++ b/xmake/toolchains/llvm/check.lua
@@ -140,6 +140,8 @@ function main(toolchain)
toolchain:config_set("cross", cross)
toolchain:config_set("bindir", cross_toolchain.bindir)
toolchain:config_set("sdkdir", cross_toolchain.sdkdir)
+ local clang = path.join(cross_toolchain.bindir, is_host("windows") and "clang.exe" or "clang")
+ toolchain_utils.check_llvm_info(toolchain, os.isfile(clang) and clang or nil)
else
wprint("llvm toolchain not found!")
return false
diff --git a/xmake/toolchains/llvm/xmake.lua b/xmake/toolchains/llvm/xmake.lua
index fb18f280f..eee8ae51a 100644
--- a/xmake/toolchains/llvm/xmake.lua
+++ b/xmake/toolchains/llvm/xmake.lua
@@ -113,7 +113,7 @@ toolchain("llvm")
toolchain:config_set("xcode_sysroot", sdkdir)
end
-- load configurations
- import(".xcode.load_" .. toolchain:plat())(toolchain)
+ import(".xcode.load")(toolchain)
elseif toolchain:is_plat("cross") then
local sysroot
local sdkdir = toolchain:sdkdir()
diff --git a/xmake/toolchains/swift/xmake.lua b/xmake/toolchains/swift/xmake.lua
index ff433b04c..5c3db489e 100644
--- a/xmake/toolchains/swift/xmake.lua
+++ b/xmake/toolchains/swift/xmake.lua
@@ -43,6 +43,6 @@ toolchain("swift")
end
end
-- load configurations
- import(".xcode.load_" .. toolchain:plat())(toolchain)
+ import(".xcode.load")(toolchain)
end
end)