summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2022-12-07 22:56:12 +0800
committerGitHub <[email protected]>2022-12-07 22:56:12 +0800
commitfff1a89bb33b4c5dd99307eca8d12b65452d5806 (patch)
tree5d07c9ad5157e36fde51afd4e1211def01de445d
parent148c595c7b552d08573d8d1c12b7c97951c8498a (diff)
parent911e781d4b2a4aa4260fba1b2c012855c7ee1d9b (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.mpp5
-rw-r--r--tests/projects/c++/modules/link_order/src/foo.mpp5
-rw-r--r--tests/projects/c++/modules/link_order/src/main.cpp5
-rw-r--r--tests/projects/c++/modules/link_order/test.lua1
-rw-r--r--tests/projects/c++/modules/link_order/xmake.lua22
-rw-r--r--xmake/rules/c++/modules/modules_support/clang.lua7
-rw-r--r--xmake/rules/c++/modules/modules_support/gcc.lua66
-rw-r--r--xmake/rules/c++/modules/modules_support/msvc.lua7
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