diff options
| author | ruki <[email protected]> | 2021-11-24 00:56:24 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2021-11-24 00:56:24 +0800 |
| commit | 12ee3ed6eb196f5d9e5cdeb619c40f51b2bec144 (patch) | |
| tree | 15757810c3fb3f7d953d681c803236c770705921 | |
| parent | 499b857f587073a09145c44d4ab9c312afb9a69a (diff) | |
improve c++ modules
| -rw-r--r-- | tests/projects/c++/modules/staticlib/xmake.lua | 2 | ||||
| -rw-r--r-- | xmake/rules/c++/modules/build_modules/clang.lua | 26 | ||||
| -rw-r--r-- | xmake/rules/c++/modules/build_modules/gcc.lua | 14 | ||||
| -rw-r--r-- | xmake/rules/c++/modules/build_modules/msvc.lua | 15 | ||||
| -rw-r--r-- | xmake/rules/c++/modules/xmake.lua | 34 |
5 files changed, 84 insertions, 7 deletions
diff --git a/tests/projects/c++/modules/staticlib/xmake.lua b/tests/projects/c++/modules/staticlib/xmake.lua index 3aa743c64..93045c18f 100644 --- a/tests/projects/c++/modules/staticlib/xmake.lua +++ b/tests/projects/c++/modules/staticlib/xmake.lua @@ -1,7 +1,5 @@ set_languages("c++20") -add_cxxflags("-fmodules-ts") - target("mod") set_kind("static") add_files("src/mod.mpp", "src/mod.cpp") diff --git a/xmake/rules/c++/modules/build_modules/clang.lua b/xmake/rules/c++/modules/build_modules/clang.lua index 06b5aa1db..523c61ad9 100644 --- a/xmake/rules/c++/modules/build_modules/clang.lua +++ b/xmake/rules/c++/modules/build_modules/clang.lua @@ -23,6 +23,32 @@ import("core.tool.compiler") import("private.action.build.object", {alias = "objectbuilder"}) import("module_parser") +-- load parent target with modules files +function load_parent(target, opt) + -- get modules flag + local modulesflag + local compinst = compiler.load("cxx", {target = target}) + if compinst:has_flags("-fmodules") then + modulesflag = "-fmodules" + elseif compinst:has_flags("-fmodules-ts") then + modulesflag = "-fmodules-ts" + end + assert(modulesflag, "compiler(clang): does not support c++ module!") + + -- add module flags + target:add("cxxflags", modulesflag) + + -- the module cache directory + for _, dep in ipairs(target:orderdeps()) do + local sourcebatches = dep:sourcebatches() + if sourcebatches and sourcebatches["c++.build.modules"] then + local cachedir = path.join(dep:autogendir(), "rules", "modules", "cache") + target:add("cxxflags", "-fmodules-cache-path=" .. cachedir, {force = true}) + target:add("cxxflags", "-fimplicit-modules", "-fimplicit-module-maps", "-fprebuilt-module-path=" .. cachedir, {force = true}) + end + end +end + -- build module files function build_with_batchjobs(target, batchjobs, sourcebatch, opt) diff --git a/xmake/rules/c++/modules/build_modules/gcc.lua b/xmake/rules/c++/modules/build_modules/gcc.lua index 1264f29c2..2abaa4f7f 100644 --- a/xmake/rules/c++/modules/build_modules/gcc.lua +++ b/xmake/rules/c++/modules/build_modules/gcc.lua @@ -23,6 +23,20 @@ import("core.tool.compiler") import("private.action.build.object", {alias = "objectbuilder"}) import("module_parser") +-- load parent target with modules files +function load_parent(target, opt) + -- get modules flag + local modulesflag + local compinst = compiler.load("cxx", {target = target}) + if compinst:has_flags("-fmodules-ts") then + modulesflag = "-fmodules-ts" + end + assert(modulesflag, "compiler(gcc): does not support c++ module!") + + -- add module flags + target:add("cxxflags", modulesflag) +end + -- build module files function build_with_batchjobs(target, batchjobs, sourcebatch, opt) diff --git a/xmake/rules/c++/modules/build_modules/msvc.lua b/xmake/rules/c++/modules/build_modules/msvc.lua index 4606edb7e..4cc8500ab 100644 --- a/xmake/rules/c++/modules/build_modules/msvc.lua +++ b/xmake/rules/c++/modules/build_modules/msvc.lua @@ -23,6 +23,21 @@ import("core.tool.compiler") import("private.action.build.object", {alias = "objectbuilder"}) import("module_parser") +-- load parent target with modules files +function load_parent(target, opt) + + -- get modules flag + local modulesflag + local compinst = compiler.load("cxx", {target = target}) + if compinst:has_flags("/experimental:module", "cxxflags") then + modulesflag = "/experimental:module" + end + assert(modulesflag, "compiler(msvc): does not support c++ module!") + + -- add module flags + target:add("cxxflags", modulesflag) +end + -- build module files function build_with_batchjobs(target, batchjobs, sourcebatch, opt) diff --git a/xmake/rules/c++/modules/xmake.lua b/xmake/rules/c++/modules/xmake.lua index 9018f5e2d..78f754521 100644 --- a/xmake/rules/c++/modules/xmake.lua +++ b/xmake/rules/c++/modules/xmake.lua @@ -21,12 +21,36 @@ -- define rule: c++.build.modules rule("c++.build.modules") set_extensions(".mpp", ".mxx", ".cppm", ".ixx") - before_build_files(function (target, batchjobs, sourcebatch, opt) + after_load(function (target) -- we disable to build across targets in parallel, because the source files may depend on other target modules - -- @note we cannot set it in on_load, because it will affect all c++ projects - target:set("policy", "build.across_targets_in_parallel", false) - - -- build module files with batchjobs + -- @see https://github.com/xmake-io/xmake/issues/1858 + local target_with_modules + for _, dep in ipairs(target:orderdeps()) do + local sourcebatches = dep:sourcebatches() + if sourcebatches and sourcebatches["c++.build.modules"] then + target_with_modules = true + break + end + end + if target_with_modules then + -- @note this will cause cross-parallel builds to be disabled for all sub-dependent targets, + -- even if some sub-targets do not contain C++ modules. + -- + -- maybe we will have a more fine-grained configuration strategy to disable it in the future. + target:set("policy", "build.across_targets_in_parallel", false) + local _, toolname = target:tool("cxx") + if toolname:find("clang", 1, true) then + import("build_modules.clang").load_parent(target, opt) + elseif toolname:find("gcc", 1, true) then + import("build_modules.gcc").load_parent(target, opt) + elseif toolname == "cl" then + import("build_modules.msvc").load_parent(target, opt) + else + raise("compiler(%s): does not support c++ module!", toolname) + end + end + end) + before_build_files(function (target, batchjobs, sourcebatch, opt) local _, toolname = target:tool("cxx") if toolname:find("clang", 1, true) then import("build_modules.clang").build_with_batchjobs(target, batchjobs, sourcebatch, opt) |
