From 315ddb090acfb4cac9737ac60efce7d79d8bc261 Mon Sep 17 00:00:00 2001 From: SnowinterCat Date: Fri, 28 Nov 2025 14:16:56 +0800 Subject: fix_libc++_cannot_find_stdmodule --- xmake/rules/c++/modules/clang/support.lua | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/xmake/rules/c++/modules/clang/support.lua b/xmake/rules/c++/modules/clang/support.lua index ad8d008aa..e0d3792b7 100644 --- a/xmake/rules/c++/modules/clang/support.lua +++ b/xmake/rules/c++/modules/clang/support.lua @@ -243,6 +243,17 @@ function get_clang_scan_deps(target) return clang_scan_deps or nil end +function parse_link_files(filepath) + if not os.islink(filepath) then + return filepath + end + local target = os.readlink(filepath) + if path.is_absolute(target) then + return target + end + return path.join(path.directory(filepath), target) +end + function get_stdmodules(target) local cpplib = get_cpplibrary_name(target) @@ -255,7 +266,8 @@ function get_stdmodules(target) if modules_json and modules_json.modules and #modules_json.modules > 0 then local std_module_directory = path.directory(modules_json.modules[1]["source-path"]) if not path.is_absolute(std_module_directory) then - std_module_directory = path.join(path.directory(modules_json_path), std_module_directory) + local clang_dir = path.directory(parse_link_files(get_clang_path(target))) + std_module_directory = path.join(clang_dir, std_module_directory) end if os.isdir(std_module_directory) then return {path.normalize(path.join(std_module_directory, "std.cppm")), path.normalize(path.join(std_module_directory, "std.compat.cppm"))} -- cgit v1.3.1 From 4d1579d05f0b59be3f70a258603e34da4131373a Mon Sep 17 00:00:00 2001 From: SnowinterCat Date: Sat, 29 Nov 2025 10:31:22 +0800 Subject: try_two_methods --- xmake/rules/c++/modules/clang/support.lua | 41 ++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/xmake/rules/c++/modules/clang/support.lua b/xmake/rules/c++/modules/clang/support.lua index e0d3792b7..90225f632 100644 --- a/xmake/rules/c++/modules/clang/support.lua +++ b/xmake/rules/c++/modules/clang/support.lua @@ -255,25 +255,42 @@ function parse_link_files(filepath) end function get_stdmodules(target) - local cpplib = get_cpplibrary_name(target) if cpplib then if cpplib == "c++" then -- libc++ module is found by parsing libc++.modules.json local modules_json_path = _get_std_module_manifest_path(target) - if modules_json_path then - local modules_json = json.decode(io.readfile(modules_json_path)) - if modules_json and modules_json.modules and #modules_json.modules > 0 then - local std_module_directory = path.directory(modules_json.modules[1]["source-path"]) - if not path.is_absolute(std_module_directory) then - local clang_dir = path.directory(parse_link_files(get_clang_path(target))) - std_module_directory = path.join(clang_dir, std_module_directory) - end - if os.isdir(std_module_directory) then - return {path.normalize(path.join(std_module_directory, "std.cppm")), path.normalize(path.join(std_module_directory, "std.compat.cppm"))} - end + if not modules_json_path then + wprint("libc++.modules.json not found! maybe try to add --sdk= or install libc++") + return + end + local modules_json = json.decode(io.readfile(modules_json_path)) + if not (modules_json and modules_json.modules and #modules_json.modules > 0) then + wprint("libc++.modules.json is invalid! path: %s", path.normalize(modules_json_path)) + return + end + local std_module_directory = path.directory(modules_json.modules[1]["source-path"]) + -- check absolute path first + if path.is_absolute(std_module_directory) then + if os.isdir(std_module_directory) then + return {path.normalize(path.join(std_module_directory, "std.cppm")), path.normalize(path.join(std_module_directory, "std.compat.cppm"))} + else + wprint("std module directory not found: %s which defined in %s", path.normalize(std_module_directory), path.normalize(modules_json_path)) + return end end + -- otherwise try to resolve relative path + local try_std_module_directory + -- first try the directory relative to libc++.modules.json + try_std_module_directory = path.join(path.directory(modules_json_path), std_module_directory) + if os.isdir(try_std_module_directory) then + return {path.normalize(path.join(try_std_module_directory, "std.cppm")), path.normalize(path.join(try_std_module_directory, "std.compat.cppm"))} + end + -- then try the directory relative to clang bin directory + try_std_module_directory = path.join(path.directory(parse_link_files(get_clang_path(target))), std_module_directory) + if os.isdir(try_std_module_directory) then + return {path.normalize(path.join(try_std_module_directory, "std.cppm")), path.normalize(path.join(try_std_module_directory, "std.compat.cppm"))} + end elseif cpplib == "stdc++" then -- dont be greedy and don't enable stdc++ std module support for llvm < 19 local clang_version = get_clang_version(target) -- cgit v1.3.1 From 5a88ba3eb9e992af78a1c52dbeed19e46378e82a Mon Sep 17 00:00:00 2001 From: SnowinterCat Date: Sat, 29 Nov 2025 10:37:38 +0800 Subject: parse_chain_of_symbolic_link --- xmake/rules/c++/modules/clang/support.lua | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/xmake/rules/c++/modules/clang/support.lua b/xmake/rules/c++/modules/clang/support.lua index 90225f632..9447d9c97 100644 --- a/xmake/rules/c++/modules/clang/support.lua +++ b/xmake/rules/c++/modules/clang/support.lua @@ -254,6 +254,13 @@ function parse_link_files(filepath) return path.join(path.directory(filepath), target) end +function get_original_file(filepath) + while os.islink(filepath) do + filepath = parse_link_files(filepath) + end + return filepath +end + function get_stdmodules(target) local cpplib = get_cpplibrary_name(target) if cpplib then @@ -287,7 +294,7 @@ function get_stdmodules(target) return {path.normalize(path.join(try_std_module_directory, "std.cppm")), path.normalize(path.join(try_std_module_directory, "std.compat.cppm"))} end -- then try the directory relative to clang bin directory - try_std_module_directory = path.join(path.directory(parse_link_files(get_clang_path(target))), std_module_directory) + try_std_module_directory = path.join(path.directory(get_original_file(get_clang_path(target))), std_module_directory) if os.isdir(try_std_module_directory) then return {path.normalize(path.join(try_std_module_directory, "std.cppm")), path.normalize(path.join(try_std_module_directory, "std.compat.cppm"))} end -- cgit v1.3.1