From dc486e5bc120ae2b972f2173a9dcd06c7836ee42 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 4 Feb 2024 17:50:55 +0100 Subject: [PATCH] fix objectfile handling --- .../c++/modules/modules_support/builder.lua | 6 ------ .../modules/modules_support/clang/builder.lua | 16 +++++++--------- .../modules/modules_support/compiler_support.lua | 16 +++++++++++----- .../modules_support/dependency_scanner.lua | 5 +++-- .../c++/modules/modules_support/msvc/builder.lua | 14 ++++++-------- xmake/rules/c++/modules/xmake.lua | 4 ++-- 6 files changed, 29 insertions(+), 32 deletions(-) diff --git a/xmake/rules/c++/modules/modules_support/builder.lua b/xmake/rules/c++/modules/modules_support/builder.lua index 741009af545..993f1bcc508 100644 --- a/xmake/rules/c++/modules/modules_support/builder.lua +++ b/xmake/rules/c++/modules/modules_support/builder.lua @@ -32,7 +32,6 @@ import("dependency_scanner") -- build target modules function _build_modules(target, sourcebatch, modules, opt) local objectfiles = dependency_scanner.sort_modules_by_dependencies(sourcebatch.objectfiles, modules) - _builder(target).populate_module_map(target, modules) -- build modules @@ -49,11 +48,6 @@ function _build_modules(target, sourcebatch, modules, opt) local bmifile = provide and compiler_support.get_bmi_path(provide.bmi) local build = _should_build(target, cppfile, bmifile, {objectfile = objectfile, requires = module.requires}) - -- add objectfile if module is not from external dep - if not (fileconfig and fileconfig.external) then - target:add("objectfiles", objectfile) - end - -- needed to detect rebuild of dependencies if provide and build then _mark_build(target, name) diff --git a/xmake/rules/c++/modules/modules_support/clang/builder.lua b/xmake/rules/c++/modules/modules_support/clang/builder.lua index 86b3d1a37de..bf8ba67bf0d 100644 --- a/xmake/rules/c++/modules/modules_support/clang/builder.lua +++ b/xmake/rules/c++/modules/modules_support/clang/builder.lua @@ -38,12 +38,12 @@ function _make_modulebuildflags(target, provide, bmifile, opt) local flags local precompile = false - if module_outputflag and provide and not opt.external then -- one step compilation of named module, clang >= 16 + if module_outputflag and provide and opt.build_objectfile then -- one step compilation of named module, clang >= 16 flags = {{"-x", "c++-module", module_outputflag .. bmifile}} elseif provide then -- two step compilation of named module precompile = true flags = {{"-x", "c++-module", "--precompile"}} - if not opt.external then + if opt.build_objectfile then table.insert(flags, {}) end else -- internal module, no bmi needed @@ -199,7 +199,7 @@ function make_module_buildjobs(target, batchjobs, job_name, deps, opt) return { name = job_name, deps = deps, - sourcefile = cppfile, + sourcefile = opt.cppfile, job = batchjobs:newjob(name or opt.cppfile, function(index, total) local compinst = compiler.load("cxx", {target = target}) @@ -226,10 +226,9 @@ function make_module_buildjobs(target, batchjobs, job_name, deps, opt) end end - local fileconfig = target:fileconfig(opt.cppfile) - local external = fileconfig and fileconfig.external + local build_objectfile = target:kind() == "binary" - local precompile, first_step, second_step = _make_modulebuildflags(target, provide, bmifile, {sourcefile = opt.cppfile, external = external, name = name}) + local precompile, first_step, second_step = _make_modulebuildflags(target, provide, bmifile, {sourcefile = opt.cppfile, build_objectfile = build_objectfile, name = name}) _compile(target, first_step, opt.cppfile, precompile and bmifile or opt.objectfile) @@ -260,10 +259,9 @@ function make_module_buildcmds(target, batchcmds, opt) batchcmds:show_progress(opt.progress, "${color.build.target}<%s> ${clear}${color.build.object}compiling.module.$(mode) %s", target:name(), name or opt.cppfile) batchcmds:mkdir(path.directory(opt.objectfile)) - local fileconfig = target:fileconfig(opt.cppfile) - local external = fileconfig and fileconfig.external + local build_objectfile = target:kind() == "binary" - local precompile, first_step, second_step = _make_modulebuildflags(target, provide, bmifile, {batchcmds = true, sourcefile = opt.cppfile, external = external, name = name}) + local precompile, first_step, second_step = _make_modulebuildflags(target, provide, bmifile, {batchcmds = true, sourcefile = opt.cppfile, build_objectfile = build_objectfile, name = name}) _batchcmds_compile(batchcmds, target, first_step, opt.cppfile, precompile and bmifile or opt.objectfile) if second_step then diff --git a/xmake/rules/c++/modules/modules_support/compiler_support.lua b/xmake/rules/c++/modules/modules_support/compiler_support.lua index 52ee86a57e5..8c03c9dba2e 100644 --- a/xmake/rules/c++/modules/modules_support/compiler_support.lua +++ b/xmake/rules/c++/modules/modules_support/compiler_support.lua @@ -64,14 +64,20 @@ function patch_sourcebatch(target, sourcebatch) end -- cull sourcebatch objectfiles -function cull_objectfiles(target, sourcebatch) +function cull_objectfiles(target, modules, sourcebatch) + + -- don't cull for executables + if target:kind() == "binary" then + return + end - sourcebatch.sourcekind = "cxx" sourcebatch.objectfiles = {} for _, sourcefile in ipairs(sourcebatch.sourcefiles) do - local fileconfig = target:fileconfig(sourcefile) - if not (fileconfig and fileconfig.external) then - local objectfile = target:objectfile(sourcefile) + local objectfile = target:objectfile(sourcefile) + local module = modules[objectfile] + local _, provide, _ = get_provided_module(module) + + if not provide then table.insert(sourcebatch.objectfiles, objectfile) end end diff --git a/xmake/rules/c++/modules/modules_support/dependency_scanner.lua b/xmake/rules/c++/modules/modules_support/dependency_scanner.lua index 7ad34475006..82e960827af 100644 --- a/xmake/rules/c++/modules/modules_support/dependency_scanner.lua +++ b/xmake/rules/c++/modules/modules_support/dependency_scanner.lua @@ -182,7 +182,7 @@ function _get_edges(nodes, modules) for _, required_node in ipairs(nodes) do local name, _, _ = compiler_support.get_provided_module(modules[required_node]) if name and name == required_name then - table.insert(edges, {node, required_node}) + table.insert(edges, {required_node, node}) break end end @@ -398,7 +398,7 @@ end -- topological sort function sort_modules_by_dependencies(objectfiles, modules) local result = {} - local edges, nodeps_nodes = _get_edges(objectfiles, modules) + local edges = _get_edges(objectfiles, modules) local dag = graph.new(true) for _, e in ipairs(edges) do dag:add_edge(e[1], e[2]) @@ -418,6 +418,7 @@ function sort_modules_by_dependencies(objectfiles, modules) for _, objectfile in ipairs(objectfiles_sorted) do table.insert(result, objectfile) end + local objectfiles_sorted_set = hashset.from(objectfiles_sorted) for _, objectfile in ipairs(objectfiles) do if not objectfiles_sorted_set:has(objectfile) then diff --git a/xmake/rules/c++/modules/modules_support/msvc/builder.lua b/xmake/rules/c++/modules/modules_support/msvc/builder.lua index 019235837b0..7ccaaa9a2f9 100644 --- a/xmake/rules/c++/modules/modules_support/msvc/builder.lua +++ b/xmake/rules/c++/modules/modules_support/msvc/builder.lua @@ -37,7 +37,7 @@ function _make_modulebuildflags(target, provide, bmifile, opt) local ifconlyflag = compiler_support.get_ifconlyflag(target) local interfaceflag = compiler_support.get_interfaceflag(target) local internalpartitionflag = compiler_support.get_internalpartitionflag(target) - local ifconly = (opt.external and ifconlyflag) + local ifconly = (not opt.build_objectfile and ifconlyflag) local flags if provide then -- named module @@ -243,9 +243,8 @@ function make_module_buildjobs(target, batchjobs, job_name, deps, opt) end end - local fileconfig = target:fileconfig(opt.cppfile) - local external = fileconfig and fileconfig.external - local flags = _make_modulebuildflags(target, provide, bmifile, {external = external}) + local build_objectfile = target:kind() == "binary" + local flags = _make_modulebuildflags(target, provide, bmifile, {build_objectfile = build_objectfile}) _compile(target, flags, opt.cppfile, opt.objectfile) end @@ -272,10 +271,9 @@ function make_module_buildcmds(target, batchcmds, opt) batchcmds:show_progress(opt.progress, "${color.build.target}<%s> ${clear}${color.build.object}compiling.module.$(mode) %s", target:name(), name or opt.cppfile) batchcmds:mkdir(path.directory(opt.objectfile)) - local fileconfig = target:fileconfig(opt.cppfile) - local external = fileconfig and fileconfig.external - local flags = _make_modulebuildflags(target, provide, bmifile, opt.cppfile, opt.objectfile, {batchcmds = true, external = external}) - _batchcmds_compile(batchcmds, target, flags, opt.cppfile, objectfile) + local build_objectfile = target:kind() == "binary" + local flags = _make_modulebuildflags(target, provide, bmifile, opt.cppfile, {batchcmds = true, build_objectfile = build_objectfile}) + _batchcmds_compile(batchcmds, target, flags, opt.cppfile, opt.objectfile) end end batchcmds:add_depfiles(opt.cppfile) diff --git a/xmake/rules/c++/modules/xmake.lua b/xmake/rules/c++/modules/xmake.lua index ecb79f65b7c..d9e26e41f81 100644 --- a/xmake/rules/c++/modules/xmake.lua +++ b/xmake/rules/c++/modules/xmake.lua @@ -100,7 +100,7 @@ rule("c++.build.modules.builder") builder.build_headerunits_for_batchjobs(target, batchjobs, sourcebatch, modules, opt) -- cull external modules objectfile - compiler_support.cull_objectfiles(target, sourcebatch) + compiler_support.cull_objectfiles(target, modules, sourcebatch) else -- avoid duplicate linking of object files of non-module programs sourcebatch.objectfiles = {} @@ -147,7 +147,7 @@ rule("c++.build.modules.builder") builder.build_modules_for_batchcmds(target, batchcmds, sourcebatch, modules, opt) -- cull external modules objectfile - compiler_support.cull_objectfiles(target, sourcebatch) + compiler_support.cull_objectfiles(target, modules, sourcebatch) else -- avoid duplicate linking of object files of non-module programs sourcebatch.objectfiles = {}