diff options
| author | Arthur LAURENT <[email protected]> | 2024-01-26 18:22:48 +0100 |
|---|---|---|
| committer | Arthur LAURENT <[email protected]> | 2024-01-26 18:22:48 +0100 |
| commit | 300600d704248cc861c0ac50174453fbd27fff61 (patch) | |
| tree | 9db12f399c231fab64e936c645eb14d3ec3a74aa /xmake/rules/c++/modules | |
| parent | 635f106496d545a44cef51134586de17b5594a45 (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.lua | 67 | ||||
| -rw-r--r-- | xmake/rules/c++/modules/modules_support/clang/dependency_scanner.lua | 41 |
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 - |
