diff options
| author | ruki <[email protected]> | 2022-12-07 22:56:12 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2022-12-07 22:56:12 +0800 |
| commit | fff1a89bb33b4c5dd99307eca8d12b65452d5806 (patch) | |
| tree | 5d07c9ad5157e36fde51afd4e1211def01de445d | |
| parent | 148c595c7b552d08573d8d1c12b7c97951c8498a (diff) | |
| parent | 911e781d4b2a4aa4260fba1b2c012855c7ee1d9b (diff) | |
Merge pull request #3141 from Arthapz/fix-gcc-link-module-order
Fix import order on GCC and force it on clang and msvc
| -rw-r--r-- | tests/projects/c++/modules/link_order/src/bar.mpp | 5 | ||||
| -rw-r--r-- | tests/projects/c++/modules/link_order/src/foo.mpp | 5 | ||||
| -rw-r--r-- | tests/projects/c++/modules/link_order/src/main.cpp | 5 | ||||
| -rw-r--r-- | tests/projects/c++/modules/link_order/test.lua | 1 | ||||
| -rw-r--r-- | tests/projects/c++/modules/link_order/xmake.lua | 22 | ||||
| -rw-r--r-- | xmake/rules/c++/modules/modules_support/clang.lua | 7 | ||||
| -rw-r--r-- | xmake/rules/c++/modules/modules_support/gcc.lua | 66 | ||||
| -rw-r--r-- | xmake/rules/c++/modules/modules_support/msvc.lua | 7 |
8 files changed, 104 insertions, 14 deletions
diff --git a/tests/projects/c++/modules/link_order/src/bar.mpp b/tests/projects/c++/modules/link_order/src/bar.mpp new file mode 100644 index 000000000..dc7c14ec8 --- /dev/null +++ b/tests/projects/c++/modules/link_order/src/bar.mpp @@ -0,0 +1,5 @@ +export module duplicate; + +export int value() { + return 1; +} diff --git a/tests/projects/c++/modules/link_order/src/foo.mpp b/tests/projects/c++/modules/link_order/src/foo.mpp new file mode 100644 index 000000000..eba3a4223 --- /dev/null +++ b/tests/projects/c++/modules/link_order/src/foo.mpp @@ -0,0 +1,5 @@ +export module duplicate; + +export int value() { + return 0; +} diff --git a/tests/projects/c++/modules/link_order/src/main.cpp b/tests/projects/c++/modules/link_order/src/main.cpp new file mode 100644 index 000000000..cd9524d8b --- /dev/null +++ b/tests/projects/c++/modules/link_order/src/main.cpp @@ -0,0 +1,5 @@ +import duplicate; + +int main() { + return value(); +} diff --git a/tests/projects/c++/modules/link_order/test.lua b/tests/projects/c++/modules/link_order/test.lua new file mode 100644 index 000000000..7717f8049 --- /dev/null +++ b/tests/projects/c++/modules/link_order/test.lua @@ -0,0 +1 @@ +inherit(".test_base") diff --git a/tests/projects/c++/modules/link_order/xmake.lua b/tests/projects/c++/modules/link_order/xmake.lua new file mode 100644 index 000000000..6a11418ac --- /dev/null +++ b/tests/projects/c++/modules/link_order/xmake.lua @@ -0,0 +1,22 @@ +add_rules("mode.release", "mode.debug") +set_languages("c++20") + +target("foo") + add_rules("c++") + set_kind("static") + add_files("src/foo.mpp") + +target("bar") + add_rules("c++") + set_kind("static") + add_files("src/bar.mpp") + +target("link_order_1") + set_kind("binary") + add_deps("foo", "bar") + add_files("src/main.cpp") + +target("link_order_2") + set_kind("binary") + add_deps("bar", "foo") + add_files("src/main.cpp") diff --git a/xmake/rules/c++/modules/modules_support/clang.lua b/xmake/rules/c++/modules/modules_support/clang.lua index 9cad5f2ff..adef57a4f 100644 --- a/xmake/rules/c++/modules/modules_support/clang.lua +++ b/xmake/rules/c++/modules/modules_support/clang.lua @@ -714,9 +714,16 @@ function get_requiresflags(target, requires) local flags = {} local modulemap = _get_modulemap_from_mapper(target) -- add deps required module flags + local already_mapped_modules = {} for name, _ in pairs(requires) do + -- if already in flags, continue + if already_mapped_modules[name] then + goto continue + end + for _, dep in ipairs(target:orderdeps()) do local modulemap_ = _get_modulemap_from_mapper(dep) + already_mapped_modules[name] = true if modulemap_[name] then table.join2(flags, modulemap_[name].flag) table.join2(flags, modulemap_[name].deps or {}) diff --git a/xmake/rules/c++/modules/modules_support/gcc.lua b/xmake/rules/c++/modules/modules_support/gcc.lua index 1f9a85f70..8912bb60e 100644 --- a/xmake/rules/c++/modules/modules_support/gcc.lua +++ b/xmake/rules/c++/modules/modules_support/gcc.lua @@ -29,8 +29,8 @@ import("private.action.build.object", {alias = "objectbuilder"}) import("common") -- get and create the path of module mapper -function _get_module_mapper() - local mapper_file = path.join(config.buildir(), "mapper.txt") +function _get_module_mapper(target) + local mapper_file = path.join(config.buildir(), target:name(), "mapper.txt") if not os.isfile(mapper_file) then io.writefile(mapper_file, "") end @@ -55,15 +55,23 @@ function _add_module_to_mapper(file, module, bmi) return true end +function _get_module_from_mapper(file, module) + for line in io.lines(file) do + if line:startswith(module .. " ") then + return line:split(" ", {plain = true}) + end + end + return nil +end + -- load module support for the current target function load(target) local modulesflag = get_modulesflag(target) local modulemapperflag = get_modulemapperflag(target) - target:add("cxxflags", modulesflag) - if os.isfile(_get_module_mapper()) then - os.rm(_get_module_mapper()) + if os.isfile(_get_module_mapper(target)) then + os.rm(_get_module_mapper(target)) end - target:add("cxxflags", modulemapperflag .. _get_module_mapper(), {force = true, expand = false}) + target:add("cxxflags", {modulesflag, modulemapperflag .. path.translate(_get_module_mapper(target))}, {force = true, expand = false}) -- fix cxxabi issue, @see https://github.com/xmake-io/xmake/issues/2716#issuecomment-1225057760 target:add("cxxflags", "-D_GLIBCXX_USE_CXX11_ABI=0") end @@ -99,7 +107,8 @@ function _build_modulefile(target, sourcefile, opt) local objectfile = opt.objectfile local dependfile = opt.dependfile local compinst = compiler.load("cxx", {target = target}) - local compflags = table.join("-x", "c++", compinst:compflags({target = target})) + local modulemapperflag = get_modulemapperflag(target) + local compflags = table.join("-x", "c++", modulemapperflag .. path.translate(_get_module_mapper(target)), compinst:compflags({target = target})) local dependinfo = option.get("rebuild") and {} or (depend.load(dependfile) or {}) -- need build this object? @@ -220,7 +229,7 @@ end -- generate target stl header units for batchjobs function generate_stl_headerunits_for_batchjobs(target, batchjobs, headerunits, opt) local compinst = target:compiler("cxx") - local mapper_file = _get_module_mapper() + local mapper_file = _get_module_mapper(target) local stlcachedir = common.stlmodules_cachedir(target) local modulemapperflag = get_modulemapperflag(target) @@ -259,7 +268,7 @@ end -- generate target stl header units for batchcmds function generate_stl_headerunits_for_batchcmds(target, batchcmds, headerunits, opt) local compinst = target:compiler("cxx") - local mapper_file = _get_module_mapper() + local mapper_file = _get_module_mapper(target) local stlcachedir = common.stlmodules_cachedir(target) -- build headerunits @@ -282,7 +291,7 @@ end -- generate target user header units for batchjobs function generate_user_headerunits_for_batchjobs(target, batchjobs, headerunits, opt) local compinst = target:compiler("cxx") - local mapper_file = _get_module_mapper() + local mapper_file = _get_module_mapper(target) local cachedir = common.modules_cachedir(target) -- build headerunits @@ -334,7 +343,7 @@ end -- generate target user header units for batchcmds function generate_user_headerunits_for_batchcmds(target, batchcmds, headerunits, opt) local compinst = target:compiler("cxx") - local mapper_file = _get_module_mapper() + local mapper_file = _get_module_mapper(target) local cachedir = common.modules_cachedir(target) -- build headerunits @@ -378,7 +387,7 @@ end -- build module files for batchjobs function build_modules_for_batchjobs(target, batchjobs, objectfiles, modules, opt) - local mapper_file = _get_module_mapper() + local mapper_file = _get_module_mapper(target) -- build modules local projectdir = os.projectdir() @@ -409,6 +418,20 @@ function build_modules_for_batchjobs(target, batchjobs, objectfiles, modules, op deps = table.keys(module.requires or {}), sourcefile = cppfile, job = batchjobs:newjob(name or cppfile, function(index, total) + -- append dependencies module now to ensures deps modulemap is filled + for required, _ in pairs(module.requires) do + local m + for _, dep in ipairs(target:orderdeps()) do + m = _get_module_from_mapper(_get_module_mapper(dep), required) + if m then + break + end + end + if m then + _add_module_to_mapper(mapper_file, m[1], m[2]) + break + end + end if provide or common.has_module_extension(cppfile) then _build_modulefile(target, cppfile, { @@ -433,7 +456,8 @@ end -- build module files for batchcmds function build_modules_for_batchcmds(target, batchcmds, objectfiles, modules, opt) local compinst = target:compiler("cxx") - local mapper_file = _get_module_mapper() + local modulemapperflag = get_modulemapperflag(target) + local mapper_file = _get_module_mapper(target) -- build modules local projectdir = os.projectdir() @@ -456,7 +480,21 @@ function build_modules_for_batchcmds(target, batchcmds, objectfiles, modules, op break end end - local flags = {"-x", "c++","-c", path(cppfile), "-o", path(objectfile)} + -- append dependencies module now to ensures deps modulemap is filled + for required, _ in pairs(module.requires) do + local m + for _, dep in ipairs(target:orderdeps()) do + m = _get_module_from_mapper(_get_module_mapper(dep), required) + if m then + break + end + end + if m then + _add_module_to_mapper(mapper_file, m[1], m[2]) + break + end + end + local flags = {"-x", "c++", "-c", path(cppfile), "-o", path(objectfile)} batchcmds:show_progress(opt.progress, "${color.build.object}compiling.module.$(mode) %s", name or cppfile) batchcmds:mkdir(path.directory(objectfile)) batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), flags)) diff --git a/xmake/rules/c++/modules/modules_support/msvc.lua b/xmake/rules/c++/modules/modules_support/msvc.lua index c360cb2eb..756f19703 100644 --- a/xmake/rules/c++/modules/modules_support/msvc.lua +++ b/xmake/rules/c++/modules/modules_support/msvc.lua @@ -719,12 +719,19 @@ function get_requiresflags(target, requires, opt) local flags = {} local modulemap = _get_modulemap_from_mapper(target) -- add deps required module flags + local already_mapped_modules = {} for name, _ in table.orderpairs(requires) do + -- if already in flags, continue + if already_mapped_modules[name] then + goto continue + end + for _, dep in ipairs(target:orderdeps()) do local modulemap_ = _get_modulemap_from_mapper(dep) if modulemap_[name] then table.join2(flags, modulemap_[name].flag) table.join2(flags, modulemap_[name].deps or {}) + already_mapped_modules[name] = true if os.isfile(modulemap_[name].objectfile) then _add_objectfile_to_link_arguments(target, modulemap_[name].objectfile) end |
