summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2022-12-17 12:35:53 +0800
committerGitHub <[email protected]>2022-12-17 12:35:53 +0800
commit47f6392bd65c5a6803fdbe9714870928db5d7a1b (patch)
treedaa52b241ce81dd7dfeabd1ae1db11263487cea1
parentf6ce7c17992fa055b2d11260831f7c004784c319 (diff)
parent1ba0ad7cbb139e04ebe29ea4fcede2fa57376433 (diff)
Merge pull request #3168 from Arthapz/cpp23-msvc-stdlib
add support of C++23 standard modules on msvc
-rw-r--r--tests/projects/c++/modules/stdmodules/src/my_module.cpp4
-rw-r--r--tests/projects/c++/modules/stdmodules/src/my_module.mpp4
-rw-r--r--tests/projects/c++/modules/stdmodules/test.lua1
-rw-r--r--tests/projects/c++/modules/stdmodules/test/test.cpp4
-rw-r--r--tests/projects/c++/modules/stdmodules/xmake.lua5
-rw-r--r--tests/projects/c++/modules/test_msvc.lua14
-rw-r--r--xmake/rules/c++/modules/modules_support/clang.lua6
-rw-r--r--xmake/rules/c++/modules/modules_support/common.lua1
-rw-r--r--xmake/rules/c++/modules/modules_support/gcc.lua6
-rw-r--r--xmake/rules/c++/modules/modules_support/msvc.lua97
10 files changed, 94 insertions, 48 deletions
diff --git a/tests/projects/c++/modules/stdmodules/src/my_module.cpp b/tests/projects/c++/modules/stdmodules/src/my_module.cpp
index 5264da821..b87808a6e 100644
--- a/tests/projects/c++/modules/stdmodules/src/my_module.cpp
+++ b/tests/projects/c++/modules/stdmodules/src/my_module.cpp
@@ -1,9 +1,5 @@
module my_module;
-#ifdef _MSC_VER
-import std.core;
-#else
import std;
-#endif
auto my_sum(size_t a, size_t b) -> size_t { return a + b; }
diff --git a/tests/projects/c++/modules/stdmodules/src/my_module.mpp b/tests/projects/c++/modules/stdmodules/src/my_module.mpp
index 5c0e44bc9..bbebb2766 100644
--- a/tests/projects/c++/modules/stdmodules/src/my_module.mpp
+++ b/tests/projects/c++/modules/stdmodules/src/my_module.mpp
@@ -1,9 +1,5 @@
export module my_module;
-#ifdef _MSC_VER
-import std.core;
-#else
import std;
-#endif
export auto my_sum(size_t a, size_t b) -> size_t;
diff --git a/tests/projects/c++/modules/stdmodules/test.lua b/tests/projects/c++/modules/stdmodules/test.lua
new file mode 100644
index 000000000..0657ead56
--- /dev/null
+++ b/tests/projects/c++/modules/stdmodules/test.lua
@@ -0,0 +1 @@
+inherit(".test_msvc")
diff --git a/tests/projects/c++/modules/stdmodules/test/test.cpp b/tests/projects/c++/modules/stdmodules/test/test.cpp
index a12813c24..7c6f7b4df 100644
--- a/tests/projects/c++/modules/stdmodules/test/test.cpp
+++ b/tests/projects/c++/modules/stdmodules/test/test.cpp
@@ -1,8 +1,4 @@
-#ifdef _MSC_VER
-import std.core;
-#else
import std;
-#endif
import my_module;
diff --git a/tests/projects/c++/modules/stdmodules/xmake.lua b/tests/projects/c++/modules/stdmodules/xmake.lua
index ffe2d015b..85e738d14 100644
--- a/tests/projects/c++/modules/stdmodules/xmake.lua
+++ b/tests/projects/c++/modules/stdmodules/xmake.lua
@@ -1,10 +1,11 @@
add_rules("mode.debug", "mode.release")
-set_languages("c++20")
add_cxxflags("clang::-stdlib=libc++")
+set_languages("c++latest")
+
target("mod")
- set_kind("shared")
+ set_kind("static")
add_files("src/*.cpp", "src/*.mpp")
target("test")
diff --git a/tests/projects/c++/modules/test_msvc.lua b/tests/projects/c++/modules/test_msvc.lua
index d51d3e3ef..a436b5814 100644
--- a/tests/projects/c++/modules/test_msvc.lua
+++ b/tests/projects/c++/modules/test_msvc.lua
@@ -1,5 +1,6 @@
import("lib.detect.find_tool")
import("core.base.semver")
+import("core.tool.toolchain")
function _build()
local ci = (os.getenv("CI") or os.getenv("GITHUB_ACTIONS") or ""):lower()
@@ -12,7 +13,16 @@ end
function main(t)
if is_subhost("windows") then
- os.exec("xmake f -c")
- _build()
+ local msvc = toolchain.load("msvc")
+ if msvc and msvc:check() then
+ local vcvars = msvc:config("vcvars")
+ if vcvars and vcvars.VCInstallDir and vcvars.VCToolsVersion and semver.compare(vcvars.VCToolsVersion, "14.35") then
+ local stdmodulesdir = path.join(vcvars.VCInstallDir, "Tools", "MSVC", vcvars.VCToolsVersion, "modules")
+ if os.isdir(stdmodulesdir) then
+ os.exec("xmake f -c")
+ _build()
+ end
+ end
+ end
end
end
diff --git a/xmake/rules/c++/modules/modules_support/clang.lua b/xmake/rules/c++/modules/modules_support/clang.lua
index de71032c7..5fa8845f4 100644
--- a/xmake/rules/c++/modules/modules_support/clang.lua
+++ b/xmake/rules/c++/modules/modules_support/clang.lua
@@ -557,6 +557,12 @@ function build_modules_for_batchcmds(target, batchcmds, objectfiles, modules, op
_flush_mapper(target)
end
+-- not supported atm
+function get_stdmodules(target)
+ local modules = {}
+ return modules
+end
+
function get_bmi_extension()
return ".pcm"
end
diff --git a/xmake/rules/c++/modules/modules_support/common.lua b/xmake/rules/c++/modules/modules_support/common.lua
index ac555f778..01fa1bc88 100644
--- a/xmake/rules/c++/modules/modules_support/common.lua
+++ b/xmake/rules/c++/modules/modules_support/common.lua
@@ -515,6 +515,7 @@ function get_module_dependencies(target, sourcebatch, opt)
if changed or modules == nil then
local moduleinfos = load_moduleinfos(target, sourcebatch)
modules = _parse_dependencies_data(target, moduleinfos)
+ modules = table.join(modules or {}, modules_support(target).get_stdmodules(target))
if modules then
_check_circular_dependencies(modules)
end
diff --git a/xmake/rules/c++/modules/modules_support/gcc.lua b/xmake/rules/c++/modules/modules_support/gcc.lua
index 796b0e033..dfa68de45 100644
--- a/xmake/rules/c++/modules/modules_support/gcc.lua
+++ b/xmake/rules/c++/modules/modules_support/gcc.lua
@@ -514,6 +514,12 @@ function build_modules_for_batchcmds(target, batchcmds, objectfiles, modules, op
batchcmds:set_depmtime(depmtime)
end
+-- not supported atm
+function get_stdmodules(target)
+ local modules = {}
+ return modules
+end
+
function get_bmi_extension()
return ".gcm"
end
diff --git a/xmake/rules/c++/modules/modules_support/msvc.lua b/xmake/rules/c++/modules/modules_support/msvc.lua
index 5e56b1241..e5c37ea38 100644
--- a/xmake/rules/c++/modules/modules_support/msvc.lua
+++ b/xmake/rules/c++/modules/modules_support/msvc.lua
@@ -25,6 +25,7 @@ import("core.project.project")
import("core.project.depend")
import("core.project.config")
import("core.base.hashset")
+import("core.base.semver")
import("utils.progress")
import("private.action.build.object", {alias = "objectbuilder"})
import("common")
@@ -79,7 +80,7 @@ function _add_objectfile_to_link_arguments(target, objectfile)
if table.contains(cache, objectfile) then
return
end
- table.insert(cache, path.translate(objectfile))
+ table.insert(cache, objectfile)
common.localcache():set(cachekey, cache)
common.localcache():save(cachekey)
end
@@ -127,27 +128,29 @@ function load(target)
local modulesflag = get_modulesflag(target)
target:add("cxxflags", modulesflag)
- -- add stdifcdir in case of if the user ask for it
- local stdifcdirflag = get_stdifcdirflag(target)
- if stdifcdirflag then
+ -- enable std modules if c++23 by defaults
+ if target:data("c++.msvc.enable_std_import") == nil then
+ local languages = target:get("languages")
+ local isatleastcpp23 = false
+ for _, language in ipairs(languages) do
+ if language:startswith("c++") or language:startswith("cxx") then
+ isatleastcpp23 = true
+ local version = tonumber(language:match("%d+"))
+ if not version or version <= 20 then
+ isatleastcpp23 = false
+ break
+ end
+ end
+ end
+ local stdmodulesdir
local msvc = target:toolchain("msvc")
if msvc then
local vcvars = msvc:config("vcvars")
- if vcvars.VCInstallDir and vcvars.VCToolsVersion then
- local arch
- if target:is_arch("x64", "x86_64") then
- arch = "x64"
- elseif target:is_arch("x86", "i386") then
- arch = "x86"
- end
- if arch then
- local stdifcdir = path.join(vcvars.VCInstallDir, "Tools", "MSVC", vcvars.VCToolsVersion, "ifc", arch)
- if os.isdir(stdifcdir) then
- target:add("cxxflags", {stdifcdirflag, winos.short_path(stdifcdir)}, {force = true, expand = false})
- end
- end
+ if vcvars.VCInstallDir and vcvars.VCToolsVersion and semver.compare(vcvars.VCToolsVersion, "14.35") then
+ stdmodulesdir = path.join(vcvars.VCInstallDir, "Tools", "MSVC", vcvars.VCToolsVersion, "modules")
end
end
+ target:data_set("c++.msvc.enable_std_import", isatleastcpp23 and os.isdir(stdmodulesdir))
end
end
@@ -441,6 +444,13 @@ function build_modules_for_batchjobs(target, batchjobs, objectfiles, modules, op
_flush_mapper(target)
end, {rootjob = opt.rootjob})
+ if target:data("c++.msvc.enable_std_import") then
+ for objectfile, module in pairs(get_stdmodules(target)) do
+ table.insert(objectfiles, objectfile)
+ modules[objectfile] = module
+ end
+ end
+
local modulesjobs = {}
for _, objectfile in ipairs(objectfiles) do
local module = modules[objectfile]
@@ -490,7 +500,7 @@ function build_modules_for_batchjobs(target, batchjobs, objectfiles, modules, op
name = name or module.cppfile,
flags = _flags,
progress = (index * 100) / total})
- target:add("objectfiles", objectfile)
+ _add_objectfile_to_link_arguments(target, path(objectfile))
elseif requiresflags then
requiresflags = get_requiresflags(target, module.requires)
target:fileconfig_add(cppfile, {force = {cxxflags = table.join(flags, requiresflags)}})
@@ -519,6 +529,13 @@ function build_modules_for_batchcmds(target, batchcmds, objectfiles, modules, op
local referenceflag = get_referenceflag(target)
local internalpartitionflag = get_internalpartitionflag(target)
+ if target:data("c++.msvc.enable_std_import") then
+ for objectfile, module in pairs(get_stdmodules(target)) do
+ table.insert(objectfiles, objectfile)
+ modules[objectfile] = module
+ end
+ end
+
-- build modules
local depmtime = 0
for _, objectfile in ipairs(objectfiles) do
@@ -555,7 +572,7 @@ function build_modules_for_batchcmds(target, batchcmds, objectfiles, modules, op
batchcmds:mkdir(path.directory(objectfile))
batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), table.join(flags, requiresflags or {})), {envs = msvc:runenvs()})
batchcmds:add_depfiles(cppfile)
- target:add("objectfiles", objectfile)
+ _add_objectfile_to_link_arguments(target, path(objectfile))
if provide then
_add_module_to_mapper(target, referenceflag, name, name, objectfile, provide.bmi, requiresflags)
end
@@ -571,6 +588,34 @@ function build_modules_for_batchcmds(target, batchcmds, objectfiles, modules, op
_flush_mapper(target)
end
+function get_stdmodules(target)
+ local modules = {}
+
+ -- build c++23 standard modules if needed
+ if target:data("c++.msvc.enable_std_import") then
+ local msvc = target:toolchain("msvc")
+ if msvc then
+ local vcvars = msvc:config("vcvars")
+ if vcvars.VCInstallDir and vcvars.VCToolsVersion then
+ local stdmodulesdir = path.join(vcvars.VCInstallDir, "Tools", "MSVC", vcvars.VCToolsVersion, "modules")
+ assert(stdmodulesdir, "Can't enable C++23 std modules, directory missing !")
+
+ local stlcachedir = common.stlmodules_cachedir(target)
+ local modulefile = path.join(stdmodulesdir, "std.ixx")
+ local bmifile = path.join(stlcachedir, "std.ixx" .. get_bmi_extension())
+ local objfile = bmifile .. ".obj"
+ modules[objfile] = {provides = {std = {interface = true, sourcefile = modulefile, bmi = bmifile}}}
+ stlcachedir = common.stlmodules_cachedir(target)
+ modulefile = path.join(stdmodulesdir, "std.compat.ixx")
+ bmifile = path.join(stlcachedir, "std.compat.ixx" .. get_bmi_extension())
+ objfile = bmifile .. ".obj"
+ modules[objfile] = {provides = {["std.compat"] = {interface = true, sourcefile = modulefile, bmi = bmifile}}, requires = {std = {unique = false, method = "by-name"}}}
+ end
+ end
+ end
+ return modules
+end
+
function get_bmi_extension()
return ".ifc"
end
@@ -679,18 +724,6 @@ function get_exportheaderflag(target)
return exportheaderflag or nil
end
-function get_stdifcdirflag(target)
- local stdifcdirflag = _g.stdifcdirflag
- if stdifcdirflag == nil then
- local compinst = target:compiler("cxx")
- if compinst:has_flags("-stdIfcDir", "cxxflags", {flagskey = "cl_std_ifc_dir"}) then
- stdifcdirflag = "-stdIfcDir"
- end
- _g.stdifcdirflag = stdifcdirflag or false
- end
- return stdifcdirflag or nil
-end
-
function get_scandependenciesflag(target)
local scandependenciesflag = _g.scandependenciesflag
if scandependenciesflag == nil then
@@ -785,4 +818,4 @@ function get_internalpartitionflag(target)
_g.internalpartitionflag = internalpartitionflag or false
end
return internalpartitionflag or nil
-end \ No newline at end of file
+end