summaryrefslogtreecommitdiff
path: root/xmake/rules/c++/modules
diff options
context:
space:
mode:
authorArthur LAURENT <[email protected]>2024-01-26 18:22:48 +0100
committerArthur LAURENT <[email protected]>2024-01-26 18:22:48 +0100
commit300600d704248cc861c0ac50174453fbd27fff61 (patch)
tree9db12f399c231fab64e936c645eb14d3ec3a74aa /xmake/rules/c++/modules
parent635f106496d545a44cef51134586de17b5594a45 (diff)
take advantage of XMake runtimes support
Diffstat (limited to 'xmake/rules/c++/modules')
-rw-r--r--xmake/rules/c++/modules/modules_support/clang/compiler_support.lua67
-rw-r--r--xmake/rules/c++/modules/modules_support/clang/dependency_scanner.lua41
2 files changed, 32 insertions, 76 deletions
diff --git a/xmake/rules/c++/modules/modules_support/clang/compiler_support.lua b/xmake/rules/c++/modules/modules_support/clang/compiler_support.lua
index a1f10b5ae..95578acee 100644
--- a/xmake/rules/c++/modules/modules_support/clang/compiler_support.lua
+++ b/xmake/rules/c++/modules/modules_support/clang/compiler_support.lua
@@ -34,8 +34,11 @@ function _get_toolchain_includedirs_for_stlheaders(target, includedirs, clang)
local tmpfile = os.tmpfile() .. ".cc"
io.writefile(tmpfile, "#include <vector>")
local argv = {"-E", "-x", "c++", tmpfile}
- if _use_stdlib(target, "libc++") then
+ local runtime = get_cpplibrary_name(target)
+ if runtime:startswith("c++") then
table.insert(argv, 1, "-stdlib=libc++")
+ elseif runtime:startswith("stdc++") then
+ table.insert(argv, 1, "-stdlib=libstdc++")
end
local result = try {function () return os.iorunv(clang, argv) end}
if result then
@@ -53,16 +56,20 @@ function _get_toolchain_includedirs_for_stlheaders(target, includedirs, clang)
os.tryrm(tmpfile)
end
--- use the given stdlib? e.g. libc++ or libstdc++
-function _use_stdlib(target, name)
- local default = "libstdc++"
- if is_plat("windows") then
- default = "msstl"
- elseif is_plat("macos") then
- default = "libc++"
+function get_cpplibrary_name(target)
+ local runtime = target:runtimes()
+
+ if not runtime then
+ if is_plat("windows") then
+ runtime = "msstl"
+ elseif is_plat("linux") or is_plat("android") then
+ runtime = "stdc++_shared"
+ elseif is_plat("macosx") or is_plat("iphoneos") or is_plat("watchos") then
+ runtime = "c++_shared"
+ end
end
- local stdlib = target:data("cxx.modules.stdlib") or default
- return stdlib == name
+
+ return runtime
end
-- load module support for the current target
@@ -93,19 +100,6 @@ function load(target)
target:set("symbols", dep_symbols and dep_symbols or "none")
end
- -- if use libc++, we need to install libc++ and libc++abi
- --
- -- on ubuntu:
- -- sudo apt install libc++-dev libc++abi-15-dev
- --
- local flags = table.join(target:get("cxxflags") or {}, get_config("cxxflags") or {})
- if table.contains(flags, "-stdlib=libc++", "clang::-stdlib=libc++") then
- target:data_set("cxx.modules.stdlib", "libc++")
- elseif table.contains(flags, "-stdlib=libstdc++", "clang::-stdlib=libstdc++") then
- target:data_set("cxx.modules.stdlib", "libstdc++")
- end
- set_stdlib_flags(target)
-
-- on Windows before llvm18 we need to disable delayed-template-parsing because it's incompatible with modules, from llvm >= 18, it's disabled by default
local clang_version = get_clang_version(target)
if semver.compare(clang_version, "18") < 0 then
@@ -121,7 +115,14 @@ function toolchain_includedirs(target)
local clang, toolname = target:tool("cxx")
assert(toolname:startswith("clang"))
_get_toolchain_includedirs_for_stlheaders(target, includedirs, clang)
- local _, result = try {function () return os.iorunv(clang, {"-E", "-stdlib=libc++", "-Wp,-v", "-xc", os.nuldev()}) end}
+ local runtime = get_cpplibrary_name(target)
+ local runtime_flag
+ if runtime:startswith("c++") then
+ runtime_flag = "-stdlib=libc++"
+ elseif runtime:startswith("stdc++") then
+ runtime_flag = "-stdlib=libstdc++"
+ end
+ local _, result = try {function () return os.iorunv(clang, {"-E", runtime_flag, "-Wp,-v", "-xc", os.nuldev()}) end}
if result then
for _, line in ipairs(result:split("\n", {plain = true})) do
line = line:trim()
@@ -195,24 +196,16 @@ function get_clang_scan_deps(target)
return clang_scan_deps or nil
end
--- set stdlib flags, it will use libstdc++ if we do not set `-stdlib=`
-function set_stdlib_flags(target)
- if _use_stdlib(target, "libc++") then
- target:add("cxxflags", "-stdlib=libc++")
- target:add("ldflags", "-stdlib=libc++")
- target:add("shflags", "-stdlib=libc++")
- end
-end
-
-- not supported atm
function get_stdmodules(target)
if target:policy("build.c++.modules.std") then
- if _use_stdlib(target, "libc++") then
+ local runtime = get_cpplibrary_name(target)
+
+ if runtime:startswith("libc++") then
-- TODO support libc++ std module file when https://github.com/xmake-io/xmake/pull/4630
- return {}
- elseif _use_stdlib(target, "libstdc++") then
+ elseif runtime:startswith("stdc++") then
-- libstdc++ doesn't have a std module file atm
- elseif _use_stdlib(target, "msstl") then
+ elseif runtime:startswith("msstl") then
-- msstl std module file is not compatible with llvm <= 18
-- local toolchain = target:toolchain("clang")
-- local msvc = import("core.tool.toolchain", {anonymous = true}).load("msvc", {plat = toolchain:plat(), arch = toolchain:arch()})
diff --git a/xmake/rules/c++/modules/modules_support/clang/dependency_scanner.lua b/xmake/rules/c++/modules/modules_support/clang/dependency_scanner.lua
index 7ad037f99..71ccabb72 100644
--- a/xmake/rules/c++/modules/modules_support/clang/dependency_scanner.lua
+++ b/xmake/rules/c++/modules/modules_support/clang/dependency_scanner.lua
@@ -47,10 +47,9 @@ function generate_dependencies(target, sourcebatch, opt)
clang_path = compiler_support.get_clang_path(target) or compinst:program()
end
local clangscandeps = compiler_support.get_clang_scan_deps(target)
- local compinst = target:compiler("cxx")
local compflags = compinst:compflags({sourcefile = sourcefile, target = target})
local flags = table.join({"--format=p1689", "--",
- clang_path, "-x", "c++", "-c", sourcefile, "-o", target:objectfile(sourcefile)}, compflags or {})
+ clang_path, "-x", "c++", runtime_flag, "-c", sourcefile, "-o", target:objectfile(sourcefile)}, compflags or {})
vprint(table.concat(table.join(clangscandeps, flags), " "))
local outdata, errdata = os.iorunv(clangscandeps, flags)
assert(errdata, errdata)
@@ -65,7 +64,7 @@ function generate_dependencies(target, sourcebatch, opt)
return flag:startswith("-fmodule") or flag:startswith("-std=c++") or flag:startswith("-std=gnu++")
end)
local ifile = path.translate(path.join(outputdir, path.filename(file) .. ".i"))
- local flags = table.join(compflags or {}, {"-E", "-fkeep-system-includes", "-x", "c++", file, "-o", ifile})
+ local flags = table.join(compflags or {}, {"-E", runtime_flag, "-fkeep-system-includes", "-x", "c++", file, "-o", ifile})
os.vrunv(compinst:program(), flags)
local content = io.readfile(ifile)
os.rm(ifile)
@@ -75,44 +74,8 @@ function generate_dependencies(target, sourcebatch, opt)
changed = true
local rawdependinfo = io.readfile(jsonfile)
- if rawdependinfo then
- local dependinfo = json.decode(rawdependinfo)
- if target:data("cxx.modules.stdlib") == nil then
- local has_std_modules = false
- for _, r in ipairs(dependinfo.rules) do
- for _, required in ipairs(r.requires) do
- -- it may be `std:utility`, ..
- -- @see https://github.com/xmake-io/xmake/issues/3373
- local logical_name = required["logical-name"]
- if logical_name and (logical_name == "std" or logical_name:startswith("std.") or logical_name:startswith("std:")) then
- has_std_modules = true
- break
- end
- end
-
- if has_std_modules then
- break
- end
- end
- if has_std_modules then
-
- -- we need clang >= 17.0 or use clang stdmodules if the current target contains std module
- local clang_version = compiler_support.get_clang_version(target)
- assert((clang_version and semver.compare(clang_version, "17.0") >= 0) or target:policy("build.c++.clang.stdmodules"),
- [[On llvm <= 16 standard C++ modules are not supported ;
- they can be emulated through clang modules and supported only on libc++ ;
- please add -stdlib=libc++ cxx flag or disable strict mode]])
-
- -- we use libc++ by default if we do not explicitly specify -stdlib:libstdc++
- target:data_set("cxx.modules.stdlib", "libc++")
- compiler_support.set_stdlib_flags(target)
- end
- end
- end
-
return {moduleinfo = rawdependinfo}
end, {dependfile = dependfile, files = {sourcefile}, changed = target:is_rebuilt()})
end
return changed
end
-