From 4a6acafb07f5af250c51604c731dba7fafdd8547 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 4 Feb 2024 17:50:55 +0100 Subject: [PATCH 01/40] fix objectfile handling --- .../c++/modules/modules_support/builder.lua | 1 - .../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, 30 insertions(+), 26 deletions(-) diff --git a/xmake/rules/c++/modules/modules_support/builder.lua b/xmake/rules/c++/modules/modules_support/builder.lua index 4ceb67b0baa..ca7a3cbb81c 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 diff --git a/xmake/rules/c++/modules/modules_support/clang/builder.lua b/xmake/rules/c++/modules/modules_support/clang/builder.lua index 15a53c00ba5..6a7237eb2f7 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}) @@ -242,10 +242,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) @@ -289,14 +288,15 @@ function make_module_buildcmds(target, batchcmds, opt) build = should_build(target, opt.cppfile, bmifile, {objectfile = opt.objectfile, requires = opt.module.requires}) end + local build_objectfile = target:kind() == "binary" if build then -- compile if it's a named module if provide or compiler_support.has_module_extension(opt.cppfile) then 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 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) local precompile, first_step, second_step = _make_modulebuildflags(target, provide, bmifile, {batchcmds = true, sourcefile = opt.cppfile, external = external, name = name}) _batchcmds_compile(batchcmds, target, first_step, opt.cppfile, precompile and bmifile or opt.objectfile) 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 10a0ad409c7..e7b2c854309 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 @@ -259,9 +259,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) else @@ -307,10 +306,9 @@ function make_module_buildcmds(target, batchcmds, should_build, mark_build, 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) else batchcmds:rm(opt.objectfile) -- force rebuild for .cpp files end 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 = {} From 2328ca4f94c6a7680c72fc92f43a39c4f753d7a3 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 4 Feb 2024 20:24:24 +0100 Subject: [PATCH 02/40] fix missing objectfiles for private modules --- .../c++/modules/modules_support/builder.lua | 5 ----- .../modules/modules_support/clang/builder.lua | 14 +++++++++++--- .../modules_support/compiler_support.lua | 9 ++++++++- .../modules/modules_support/msvc/builder.lua | 10 ++++++++-- xmake/rules/c++/modules/xmake.lua | 18 ++++++++++++++---- 5 files changed, 41 insertions(+), 15 deletions(-) diff --git a/xmake/rules/c++/modules/modules_support/builder.lua b/xmake/rules/c++/modules/modules_support/builder.lua index ca7a3cbb81c..62b874bfb0a 100644 --- a/xmake/rules/c++/modules/modules_support/builder.lua +++ b/xmake/rules/c++/modules/modules_support/builder.lua @@ -45,11 +45,6 @@ function _build_modules(target, sourcebatch, modules, opt) cppfile = cppfile or module.cppfile local fileconfig = target:fileconfig(cppfile) - local bmifile = provide and compiler_support.get_bmi_path(provide.bmi) - -- add objectfile if module is not from external dep - if not (fileconfig and fileconfig.external) then - target:add("objectfiles", objectfile) - end local deps = {} for _, dep in ipairs(table.keys(module.requires or {})) do diff --git a/xmake/rules/c++/modules/modules_support/clang/builder.lua b/xmake/rules/c++/modules/modules_support/clang/builder.lua index 6a7237eb2f7..5050be7cfbb 100644 --- a/xmake/rules/c++/modules/modules_support/clang/builder.lua +++ b/xmake/rules/c++/modules/modules_support/clang/builder.lua @@ -242,7 +242,10 @@ function make_module_buildjobs(target, batchjobs, job_name, deps, opt) end end - local build_objectfile = target:kind() == "binary" + local fileconfig = target:fileconfig(opt.cppfile) + local public = fileconfig and fileconfig.public + local external = fileconfig and fileconfig.external + local build_objectfile = target:kind() == "binary" or (not public and not external) local precompile, first_step, second_step = _make_modulebuildflags(target, provide, bmifile, {sourcefile = opt.cppfile, build_objectfile = build_objectfile, name = name}) @@ -295,8 +298,13 @@ 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 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) + local fileconfig = target:fileconfig(opt.cppfile) + local public = fileconfig and fileconfig.public + local external = fileconfig and fileconfig.external + local build_objectfile = target:kind() == "binary" or (not public and not external) + + 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) local precompile, first_step, second_step = _make_modulebuildflags(target, provide, bmifile, {batchcmds = true, sourcefile = opt.cppfile, external = external, name = name}) _batchcmds_compile(batchcmds, target, first_step, opt.cppfile, precompile and bmifile or opt.objectfile) diff --git a/xmake/rules/c++/modules/modules_support/compiler_support.lua b/xmake/rules/c++/modules/modules_support/compiler_support.lua index 8c03c9dba2e..d9d849454f1 100644 --- a/xmake/rules/c++/modules/modules_support/compiler_support.lua +++ b/xmake/rules/c++/modules/modules_support/compiler_support.lua @@ -77,7 +77,14 @@ function cull_objectfiles(target, modules, sourcebatch) local module = modules[objectfile] local _, provide, _ = get_provided_module(module) - if not provide then + if provide then + local fileconfig = target:fileconfig(sourcefile) + local public = fileconfig and fileconfig.public + local external = fileconfig and fileconfig.external + if not public and not external then + table.insert(sourcebatch.objectfiles, objectfile) + end + else table.insert(sourcebatch.objectfiles, objectfile) end end diff --git a/xmake/rules/c++/modules/modules_support/msvc/builder.lua b/xmake/rules/c++/modules/modules_support/msvc/builder.lua index e7b2c854309..702f3f2f2c8 100644 --- a/xmake/rules/c++/modules/modules_support/msvc/builder.lua +++ b/xmake/rules/c++/modules/modules_support/msvc/builder.lua @@ -259,7 +259,10 @@ function make_module_buildjobs(target, batchjobs, job_name, deps, opt) end end - local build_objectfile = target:kind() == "binary" + local fileconfig = target:fileconfig(opt.cppfile) + local public = fileconfig and fileconfig.public + local external = fileconfig and fileconfig.external + local build_objectfile = target:kind() == "binary" or (not public and not external) local flags = _make_modulebuildflags(target, provide, bmifile, {build_objectfile = build_objectfile}) _compile(target, flags, opt.cppfile, opt.objectfile) @@ -306,7 +309,10 @@ function make_module_buildcmds(target, batchcmds, should_build, mark_build, 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 build_objectfile = target:kind() == "binary" + local fileconfig = target:fileconfig(opt.cppfile) + local public = fileconfig and fileconfig.public + local external = fileconfig and fileconfig.external + local build_objectfile = target:kind() == "binary" or (not public and not external) local flags = _make_modulebuildflags(target, provide, bmifile, opt.cppfile, {batchcmds = true, build_objectfile = build_objectfile}) _batchcmds_compile(batchcmds, target, flags, opt.cppfile, opt.objectfile) else diff --git a/xmake/rules/c++/modules/xmake.lua b/xmake/rules/c++/modules/xmake.lua index d9e26e41f81..96446e2ec8f 100644 --- a/xmake/rules/c++/modules/xmake.lua +++ b/xmake/rules/c++/modules/xmake.lua @@ -76,7 +76,12 @@ rule("c++.build.modules.builder") end -- append std module - table.join2(sourcebatch.sourcefiles, compiler_support.get_stdmodules(target) or {}) + local std_modules = compiler_support.get_stdmodules(target) + if std_modules then + table.join2(sourcebatch.sourcefiles, std_modules) + target:fileconfig_set(std_modules[1], {external = true}) + target:fileconfig_set(std_modules[2], {external = true}) + end -- extract packages modules dependencies local package_modules_data = dependency_scanner.get_all_packages_modules(target, opt) @@ -84,7 +89,7 @@ rule("c++.build.modules.builder") -- append to sourcebatch for _, package_module_data in table.orderpairs(package_modules_data) do table.insert(sourcebatch.sourcefiles, package_module_data.file) - target:fileconfig_add(package_module_data.file, {external = true, defines = package_module_data.metadata.defines}) + target:fileconfig_set(package_module_data.file, {external = true, defines = package_module_data.metadata.defines}) end end @@ -123,7 +128,12 @@ rule("c++.build.modules.builder") end -- append std module - table.join2(sourcebatch.sourcefiles, compiler_support.get_stdmodules(target) or {}) + local std_modules = compiler_support.get_stdmodules(target) + if std_modules then + table.join2(sourcebatch.sourcefiles, std_modules) + target:fileconfig_set(std_modules[1], {external = true}) + target:fileconfig_set(std_modules[2], {external = true}) + end -- extract packages modules dependencies local package_modules_data = dependency_scanner.get_all_packages_modules(target, opt) @@ -131,7 +141,7 @@ rule("c++.build.modules.builder") -- append to sourcebatch for _, package_module_data in table.orderpairs(package_modules_data) do table.insert(sourcebatch.sourcefiles, package_module_data.file) - target:fileconfig_add(package_module_data.file, {external = true, defines = package_module_data.metadata.defines}) + target:fileconfig_set(package_module_data.file, {external = true, defines = package_module_data.metadata.defines}) end end From 538cf30fe70c7e90a82f8a509d9e5875d0a3a665 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 5 Feb 2024 13:59:24 +0100 Subject: [PATCH 03/40] fix merge --- xmake/rules/c++/modules/modules_support/clang/builder.lua | 3 --- 1 file changed, 3 deletions(-) diff --git a/xmake/rules/c++/modules/modules_support/clang/builder.lua b/xmake/rules/c++/modules/modules_support/clang/builder.lua index 5050be7cfbb..0e5f0b5bd43 100644 --- a/xmake/rules/c++/modules/modules_support/clang/builder.lua +++ b/xmake/rules/c++/modules/modules_support/clang/builder.lua @@ -306,9 +306,6 @@ function make_module_buildcmds(target, batchcmds, opt) 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) - local precompile, first_step, second_step = _make_modulebuildflags(target, provide, bmifile, {batchcmds = true, sourcefile = opt.cppfile, external = external, name = name}) - _batchcmds_compile(batchcmds, target, first_step, opt.cppfile, precompile and bmifile or opt.objectfile) - if second_step then _batchcmds_compile(batchcmds, target, second_step, opt.cppfile, opt.objectfile, {bmifile = bmifile}) end From 4d3ad3f3176ffefd1253e3e64f8149606ee85c00 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 5 Feb 2024 14:18:10 +0100 Subject: [PATCH 04/40] fix format --- .../rules/c++/modules/modules_support/msvc/builder.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/xmake/rules/c++/modules/modules_support/msvc/builder.lua b/xmake/rules/c++/modules/modules_support/msvc/builder.lua index 702f3f2f2c8..8c451f69912 100644 --- a/xmake/rules/c++/modules/modules_support/msvc/builder.lua +++ b/xmake/rules/c++/modules/modules_support/msvc/builder.lua @@ -259,11 +259,11 @@ function make_module_buildjobs(target, batchjobs, job_name, deps, opt) end end - local fileconfig = target:fileconfig(opt.cppfile) - local public = fileconfig and fileconfig.public - local external = fileconfig and fileconfig.external - local build_objectfile = target:kind() == "binary" or (not public and not external) - local flags = _make_modulebuildflags(target, provide, bmifile, {build_objectfile = build_objectfile}) + local fileconfig = target:fileconfig(opt.cppfile) + local public = fileconfig and fileconfig.public + local external = fileconfig and fileconfig.external + local build_objectfile = target:kind() == "binary" or (not public and not external) + local flags = _make_modulebuildflags(target, provide, bmifile, {build_objectfile = build_objectfile}) _compile(target, flags, opt.cppfile, opt.objectfile) else From 750aa4ca36eb7189ac810e9c4bd9b468dfc1af08 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 5 Feb 2024 14:58:58 +0100 Subject: [PATCH 05/40] fix gcc --- xmake/rules/c++/modules/modules_support/gcc/compiler_support.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/xmake/rules/c++/modules/modules_support/gcc/compiler_support.lua b/xmake/rules/c++/modules/modules_support/gcc/compiler_support.lua index a598f39f582..c365a107a27 100644 --- a/xmake/rules/c++/modules/modules_support/gcc/compiler_support.lua +++ b/xmake/rules/c++/modules/modules_support/gcc/compiler_support.lua @@ -99,7 +99,6 @@ end -- not supported atm function get_stdmodules(target) - return {} end function get_bmi_extension() From 0b8ea930d1d9cc7dbb38fa62d1331f2addbbdc66 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 5 Feb 2024 16:18:41 +0100 Subject: [PATCH 06/40] cull unreferenced modules and fix gcc module mapper --- .../c++/modules/modules_support/builder.lua | 2 +- .../modules_support/dependency_scanner.lua | 6 +++++- .../c++/modules/modules_support/gcc/builder.lua | 17 ----------------- xmake/rules/c++/modules/xmake.lua | 6 ++++++ 4 files changed, 12 insertions(+), 19 deletions(-) diff --git a/xmake/rules/c++/modules/modules_support/builder.lua b/xmake/rules/c++/modules/modules_support/builder.lua index 62b874bfb0a..af0a0539f94 100644 --- a/xmake/rules/c++/modules/modules_support/builder.lua +++ b/xmake/rules/c++/modules/modules_support/builder.lua @@ -31,7 +31,7 @@ import("dependency_scanner") -- build target modules function _build_modules(target, sourcebatch, modules, opt) - local objectfiles = dependency_scanner.sort_modules_by_dependencies(sourcebatch.objectfiles, modules) + local objectfiles = sourcebatch.objectfiles _builder(target).populate_module_map(target, modules) -- build modules diff --git a/xmake/rules/c++/modules/modules_support/dependency_scanner.lua b/xmake/rules/c++/modules/modules_support/dependency_scanner.lua index 82e960827af..b5b3fcf5f8e 100644 --- a/xmake/rules/c++/modules/modules_support/dependency_scanner.lua +++ b/xmake/rules/c++/modules/modules_support/dependency_scanner.lua @@ -422,7 +422,11 @@ function sort_modules_by_dependencies(objectfiles, modules) local objectfiles_sorted_set = hashset.from(objectfiles_sorted) for _, objectfile in ipairs(objectfiles) do if not objectfiles_sorted_set:has(objectfile) then - table.insert(result, objectfile) + -- cull unreferenced named module but add non-module files + local _, provide, _ = compiler_support.get_provided_module(modules[objectfile]) + if not provide then + table.insert(result, objectfile) + end end end return result diff --git a/xmake/rules/c++/modules/modules_support/gcc/builder.lua b/xmake/rules/c++/modules/modules_support/gcc/builder.lua index 7e96c3fcc59..17b3aabc580 100644 --- a/xmake/rules/c++/modules/modules_support/gcc/builder.lua +++ b/xmake/rules/c++/modules/modules_support/gcc/builder.lua @@ -107,13 +107,6 @@ function _get_maplines(target, module) for required, _ in table.orderpairs(module.requires) do local dep_module local dep_target - for _, dep in ipairs(target:orderdeps()) do - dep_module = get_from_target_mapper(dep, required) - if dep_module then - dep_target = dep - break - end - end -- if not in target dep if not dep_module then @@ -173,16 +166,6 @@ end -- populate module map function populate_module_map(target, modules) - - -- append all modules - for _, module in pairs(modules) do - local name, provide = compiler_support.get_provided_module(module) - if provide then - add_module_to_target_mapper(target, name, provide.sourcefile, compiler_support.get_bmi_path(provide.bmi)) - end - end - - -- then update their deps for _, module in pairs(modules) do local name, provide = compiler_support.get_provided_module(module) if provide then diff --git a/xmake/rules/c++/modules/xmake.lua b/xmake/rules/c++/modules/xmake.lua index 96446e2ec8f..c8385da03ce 100644 --- a/xmake/rules/c++/modules/xmake.lua +++ b/xmake/rules/c++/modules/xmake.lua @@ -98,6 +98,9 @@ rule("c++.build.modules.builder") compiler_support.patch_sourcebatch(target, sourcebatch, opt) local modules = dependency_scanner.get_module_dependencies(target, sourcebatch, opt) + -- avoid linking culled objectfiles + sourcebatch.objectfiles = dependency_scanner.sort_modules_by_dependencies(sourcebatch.objectfiles, modules) + -- build modules builder.build_modules_for_batchjobs(target, batchjobs, sourcebatch, modules, opt) @@ -150,6 +153,9 @@ rule("c++.build.modules.builder") compiler_support.patch_sourcebatch(target, sourcebatch, opt) local modules = dependency_scanner.get_module_dependencies(target, sourcebatch, opt) + -- avoid linking culled objectfiles + sourcebatch.objectfiles = dependency_scanner.sort_modules_by_dependencies(sourcebatch.objectfiles, modules) + -- build headerunits builder.build_headerunits_for_batchcmds(target, batchcmds, sourcebatch, modules, opt) From cf0e793a7cee0e1225c307473794245529cbc302 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 5 Feb 2024 17:30:02 +0100 Subject: [PATCH 07/40] fix tests --- tests/projects/c++/modules/staticlib/xmake.lua | 3 ++- tests/projects/c++/modules/staticlib_without_cpp/xmake.lua | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/projects/c++/modules/staticlib/xmake.lua b/tests/projects/c++/modules/staticlib/xmake.lua index d353774e455..9e1cf422174 100644 --- a/tests/projects/c++/modules/staticlib/xmake.lua +++ b/tests/projects/c++/modules/staticlib/xmake.lua @@ -3,7 +3,8 @@ set_languages("c++20") target("mod") set_kind("static") - add_files("src/mod.mpp", "src/mod.cpp", {public = true}) + add_files("src/mod.mpp", {public = true}) + add_files("src/mod.cpp") target("hello") set_kind("binary") diff --git a/tests/projects/c++/modules/staticlib_without_cpp/xmake.lua b/tests/projects/c++/modules/staticlib_without_cpp/xmake.lua index a0609141429..bff9c5d132f 100644 --- a/tests/projects/c++/modules/staticlib_without_cpp/xmake.lua +++ b/tests/projects/c++/modules/staticlib_without_cpp/xmake.lua @@ -3,4 +3,4 @@ set_languages("c++20") target("mod") set_kind("static") - add_files("src/mod.mpp") + add_files("src/mod.mpp", {public = true}) From 6739478d0bf6a4aaf0d1a1caf1c6b60532fa07f8 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 5 Feb 2024 17:30:32 +0100 Subject: [PATCH 08/40] fix gcc --- .../c++/modules/modules_support/builder.lua | 3 +-- .../modules_support/dependency_scanner.lua | 10 ++++++---- .../modules/modules_support/gcc/builder.lua | 18 ++++-------------- xmake/rules/c++/modules/xmake.lua | 10 +++++----- 4 files changed, 16 insertions(+), 25 deletions(-) diff --git a/xmake/rules/c++/modules/modules_support/builder.lua b/xmake/rules/c++/modules/modules_support/builder.lua index af0a0539f94..1f014abdeca 100644 --- a/xmake/rules/c++/modules/modules_support/builder.lua +++ b/xmake/rules/c++/modules/modules_support/builder.lua @@ -44,13 +44,12 @@ function _build_modules(target, sourcebatch, modules, opt) local name, provide, cppfile = compiler_support.get_provided_module(module) cppfile = cppfile or module.cppfile - local fileconfig = target:fileconfig(cppfile) - local deps = {} for _, dep in ipairs(table.keys(module.requires or {})) do table.insert(deps, opt.batchjobs and target:name() .. dep or dep) end + local fileconfig = target:fileconfig(cppfile) opt.build_module(deps, module, name, provide, objectfile, cppfile, fileconfig) ::CONTINUE:: diff --git a/xmake/rules/c++/modules/modules_support/dependency_scanner.lua b/xmake/rules/c++/modules/modules_support/dependency_scanner.lua index b5b3fcf5f8e..0b02292ef85 100644 --- a/xmake/rules/c++/modules/modules_support/dependency_scanner.lua +++ b/xmake/rules/c++/modules/modules_support/dependency_scanner.lua @@ -396,7 +396,7 @@ function get_all_packages_modules(target, opt) end -- topological sort -function sort_modules_by_dependencies(objectfiles, modules) +function sort_modules_by_dependencies(target, objectfiles, modules) local result = {} local edges = _get_edges(objectfiles, modules) local dag = graph.new(true) @@ -422,9 +422,11 @@ function sort_modules_by_dependencies(objectfiles, modules) local objectfiles_sorted_set = hashset.from(objectfiles_sorted) for _, objectfile in ipairs(objectfiles) do if not objectfiles_sorted_set:has(objectfile) then - -- cull unreferenced named module but add non-module files - local _, provide, _ = compiler_support.get_provided_module(modules[objectfile]) - if not provide then + -- cull unreferenced non-public named module but add non-module files and implementation modules + local _, provide, cppfile = compiler_support.get_provided_module(modules[objectfile]) + local fileconfig = target:fileconfig(cppfile) + local public = fileconfig and fileconfig.public + if not provide or public then table.insert(result, objectfile) end end diff --git a/xmake/rules/c++/modules/modules_support/gcc/builder.lua b/xmake/rules/c++/modules/modules_support/gcc/builder.lua index 17b3aabc580..c4c9871e212 100644 --- a/xmake/rules/c++/modules/modules_support/gcc/builder.lua +++ b/xmake/rules/c++/modules/modules_support/gcc/builder.lua @@ -99,24 +99,14 @@ end function _get_maplines(target, module) local maplines = {} - local m_name, m = compiler_support.get_provided_module(module) + local m_name, m, cppfile = compiler_support.get_provided_module(module) if m then table.insert(maplines, m_name .. " " .. compiler_support.get_bmi_path(m.bmi)) end for required, _ in table.orderpairs(module.requires) do - local dep_module - local dep_target - - -- if not in target dep - if not dep_module then - dep_module = get_from_target_mapper(target, required) - if dep_module then - dep_target = target - end - end - - assert(dep_module, "module dependency %s required for %s not found", required, m_name) + local dep_module = get_from_target_mapper(target, required) + assert(dep_module, "module dependency %s required for %s not found", required, m_name or module.cppfile) local bmifile = dep_module.bmi local mapline @@ -136,7 +126,7 @@ function _get_maplines(target, module) -- append deps if dep_module.opt and dep_module.opt.deps then - local deps = _get_maplines(dep_target, { name = dep_module.name, bmi = bmifile, requires = dep_module.opt.deps }) + local deps = _get_maplines(target, {name = dep_module.name, bmi = bmifile, requires = dep_module.opt.deps}) table.join2(maplines, deps) end end diff --git a/xmake/rules/c++/modules/xmake.lua b/xmake/rules/c++/modules/xmake.lua index c8385da03ce..62fb37205bb 100644 --- a/xmake/rules/c++/modules/xmake.lua +++ b/xmake/rules/c++/modules/xmake.lua @@ -98,8 +98,8 @@ rule("c++.build.modules.builder") compiler_support.patch_sourcebatch(target, sourcebatch, opt) local modules = dependency_scanner.get_module_dependencies(target, sourcebatch, opt) - -- avoid linking culled objectfiles - sourcebatch.objectfiles = dependency_scanner.sort_modules_by_dependencies(sourcebatch.objectfiles, modules) + -- avoid building non referenced modules + sourcebatch.objectfiles = dependency_scanner.sort_modules_by_dependencies(target, sourcebatch.objectfiles, modules) -- build modules builder.build_modules_for_batchjobs(target, batchjobs, sourcebatch, modules, opt) @@ -153,8 +153,8 @@ rule("c++.build.modules.builder") compiler_support.patch_sourcebatch(target, sourcebatch, opt) local modules = dependency_scanner.get_module_dependencies(target, sourcebatch, opt) - -- avoid linking culled objectfiles - sourcebatch.objectfiles = dependency_scanner.sort_modules_by_dependencies(sourcebatch.objectfiles, modules) + -- avoid building non referenced modules + sourcebatch.objectfiles = dependency_scanner.sort_modules_by_dependencies(target, sourcebatch.objectfiles, modules) -- build headerunits builder.build_headerunits_for_batchcmds(target, batchcmds, sourcebatch, modules, opt) @@ -163,7 +163,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, modules, sourcebatch) + -- compiler_support.cull_objectfiles(target, modules, sourcebatch) else -- avoid duplicate linking of object files of non-module programs sourcebatch.objectfiles = {} From 3a7d68de17f19afadc2f7eec698d54861ecd729d Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 5 Feb 2024 18:22:44 +0100 Subject: [PATCH 09/40] update relevent tests to use moduleonly target rule --- tests/projects/c++/modules/link_order/xmake.lua | 10 ++++++---- tests/projects/c++/modules/moduleonly/src/mod.mpp | 2 ++ .../{staticlib_without_cpp => moduleonly}/test.lua | 0 tests/projects/c++/modules/moduleonly/xmake.lua | 7 +++++++ .../packages/my-repo/packages/b/bar2/src/bar.mpp | 8 ++++++++ .../packages/my-repo/packages/b/bar2/src/xmake.lua | 7 +++++++ .../modules/packages/my-repo/packages/b/bar2/xmake.lua | 7 +++++++ tests/projects/c++/modules/packages/src/main.cpp | 2 ++ tests/projects/c++/modules/packages/xmake.lua | 4 ++-- .../c++/modules/staticlib_without_cpp/xmake.lua | 6 ------ tests/projects/c++/modules/test_base.lua | 2 +- tests/projects/c++/modules/test_stdmodules.lua | 2 +- .../projects/c++/modules/user_headerunit2/a/xmake.lua | 6 ++++-- .../projects/c++/modules/user_headerunit2/b/xmake.lua | 5 +++-- 14 files changed, 50 insertions(+), 18 deletions(-) create mode 100644 tests/projects/c++/modules/moduleonly/src/mod.mpp rename tests/projects/c++/modules/{staticlib_without_cpp => moduleonly}/test.lua (100%) create mode 100644 tests/projects/c++/modules/moduleonly/xmake.lua create mode 100644 tests/projects/c++/modules/packages/my-repo/packages/b/bar2/src/bar.mpp create mode 100644 tests/projects/c++/modules/packages/my-repo/packages/b/bar2/src/xmake.lua create mode 100644 tests/projects/c++/modules/packages/my-repo/packages/b/bar2/xmake.lua delete mode 100644 tests/projects/c++/modules/staticlib_without_cpp/xmake.lua diff --git a/tests/projects/c++/modules/link_order/xmake.lua b/tests/projects/c++/modules/link_order/xmake.lua index b062dbe66f4..1ae6639bb40 100644 --- a/tests/projects/c++/modules/link_order/xmake.lua +++ b/tests/projects/c++/modules/link_order/xmake.lua @@ -3,13 +3,15 @@ set_languages("c++20") target("foo") add_rules("c++") - set_kind("static") - add_files("src/foo.mpp", {public = true}) + set_kind("headeronly") + add_rules("c++.moduleonly") + add_files("src/foo.mpp") target("bar") add_rules("c++") - set_kind("static") - add_files("src/bar.mpp", {public = true}) + set_kind("headeronly") + add_rules("c++.moduleonly") + add_files("src/bar.mpp") target("link_order_1") set_kind("binary") diff --git a/tests/projects/c++/modules/moduleonly/src/mod.mpp b/tests/projects/c++/modules/moduleonly/src/mod.mpp new file mode 100644 index 00000000000..b7dd3883c6c --- /dev/null +++ b/tests/projects/c++/modules/moduleonly/src/mod.mpp @@ -0,0 +1,2 @@ +export module hello; +export int foo() { return 0; } diff --git a/tests/projects/c++/modules/staticlib_without_cpp/test.lua b/tests/projects/c++/modules/moduleonly/test.lua similarity index 100% rename from tests/projects/c++/modules/staticlib_without_cpp/test.lua rename to tests/projects/c++/modules/moduleonly/test.lua diff --git a/tests/projects/c++/modules/moduleonly/xmake.lua b/tests/projects/c++/modules/moduleonly/xmake.lua new file mode 100644 index 00000000000..c6cb7cef49e --- /dev/null +++ b/tests/projects/c++/modules/moduleonly/xmake.lua @@ -0,0 +1,7 @@ +add_rules("mode.release", "mode.debug") +set_languages("c++20") + +target("mod") + set_kind("headeronly") + add_rules("c++.moduleonly") + add_files("src/mod.mpp") diff --git a/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/src/bar.mpp b/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/src/bar.mpp new file mode 100644 index 00000000000..2aaf4432e75 --- /dev/null +++ b/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/src/bar.mpp @@ -0,0 +1,8 @@ +export module bar2; + +export namespace bar { +const char *hello2() { + return "Hello world"; +} +} + diff --git a/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/src/xmake.lua b/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/src/xmake.lua new file mode 100644 index 00000000000..ddc3ae31177 --- /dev/null +++ b/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/src/xmake.lua @@ -0,0 +1,7 @@ +add_rules("mode.release", "mode.debug") +set_languages("c++20") + +target("bar") + set_kind("headeonly") + add_rules("moduleonly") + add_files("*.mpp") diff --git a/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/xmake.lua b/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/xmake.lua new file mode 100644 index 00000000000..1f0d5af8275 --- /dev/null +++ b/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/xmake.lua @@ -0,0 +1,7 @@ +package("bar") + set_kind("headeronly") + set_sourcedir(path.join(os.scriptdir(), "src")) + + on_install(function(package) + import("package.tools.xmake").install(package, {}) + end) diff --git a/tests/projects/c++/modules/packages/src/main.cpp b/tests/projects/c++/modules/packages/src/main.cpp index d12361c453a..d6f2218c07d 100644 --- a/tests/projects/c++/modules/packages/src/main.cpp +++ b/tests/projects/c++/modules/packages/src/main.cpp @@ -1,7 +1,9 @@ import foo; import bar; +import bar2; int main() { foo::say(bar::hello()); + foo::say(bar::hello2()); return 0; } diff --git a/tests/projects/c++/modules/packages/xmake.lua b/tests/projects/c++/modules/packages/xmake.lua index f772d666850..62dba119b23 100644 --- a/tests/projects/c++/modules/packages/xmake.lua +++ b/tests/projects/c++/modules/packages/xmake.lua @@ -2,10 +2,10 @@ add_rules("mode.release", "mode.debug") set_languages("c++2b") add_repositories("my-repo my-repo") -add_requires("foo", "bar") +add_requires("foo", "bar", "bar2") target("packages") set_kind("binary") add_files("src/*.cpp") - add_packages("foo", "bar") + add_packages("foo", "bar", "bar2") set_policy("build.c++.modules", true) diff --git a/tests/projects/c++/modules/staticlib_without_cpp/xmake.lua b/tests/projects/c++/modules/staticlib_without_cpp/xmake.lua deleted file mode 100644 index bff9c5d132f..00000000000 --- a/tests/projects/c++/modules/staticlib_without_cpp/xmake.lua +++ /dev/null @@ -1,6 +0,0 @@ -add_rules("mode.release", "mode.debug") -set_languages("c++20") - -target("mod") - set_kind("static") - add_files("src/mod.mpp", {public = true}) diff --git a/tests/projects/c++/modules/test_base.lua b/tests/projects/c++/modules/test_base.lua index 092fbd72f77..f39c31b7551 100644 --- a/tests/projects/c++/modules/test_base.lua +++ b/tests/projects/c++/modules/test_base.lua @@ -56,7 +56,7 @@ function main(t) os.exec("xmake f --toolchain=clang -c --yes") _build() os.exec("xmake clean -a") - os.exec("xmake f --toolchain=clang --runtimes=c++_shared -c --yes") + os.exec("xmake f --toolchain=clang --runtimes=c++_shared --sdk='/opt/llvm-git/usr/' -c --yes") _build() end end diff --git a/tests/projects/c++/modules/test_stdmodules.lua b/tests/projects/c++/modules/test_stdmodules.lua index 68a5922ef3b..c2945736406 100644 --- a/tests/projects/c++/modules/test_stdmodules.lua +++ b/tests/projects/c++/modules/test_stdmodules.lua @@ -51,7 +51,7 @@ function main(t) -- os.exec("xmake f --toolchain=clang -c --yes") -- _build() os.exec("xmake clean -a") - os.exec("xmake f --toolchain=clang --runtimes=c++_shared -c --yes") + os.exec("xmake f --toolchain=clang --runtimes=c++_shared --sdk='/opt/llvm-git/usr/' -c --yes") _build() end end diff --git a/tests/projects/c++/modules/user_headerunit2/a/xmake.lua b/tests/projects/c++/modules/user_headerunit2/a/xmake.lua index 3225b2814cd..26142892103 100644 --- a/tests/projects/c++/modules/user_headerunit2/a/xmake.lua +++ b/tests/projects/c++/modules/user_headerunit2/a/xmake.lua @@ -1,4 +1,6 @@ target("a") set_languages("cxxlatest") - set_kind("object") - add_files("a.mpp", {public = true}) + set_kind("headeronly") + add_rules("c++.moduleonly") + add_headerfiles("*.hpp") + add_files("a.mpp") diff --git a/tests/projects/c++/modules/user_headerunit2/b/xmake.lua b/tests/projects/c++/modules/user_headerunit2/b/xmake.lua index 24f9c9b1ffd..9821fcd6d9b 100644 --- a/tests/projects/c++/modules/user_headerunit2/b/xmake.lua +++ b/tests/projects/c++/modules/user_headerunit2/b/xmake.lua @@ -1,5 +1,6 @@ target("b") add_deps("a") set_languages("cxxlatest") - set_kind("object") - add_files("b.mpp", {public = true}) + set_kind("headeronly") + add_rules("c++.moduleonly") + add_files("b.mpp") From 3280d7f327d762491d36d68a7a0d3ecc89bc7a19 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 5 Feb 2024 18:23:08 +0100 Subject: [PATCH 10/40] add support of moduleonly targets with c++.moduleonly rule --- .../c++/modules/modules_support/builder.lua | 29 +++ .../modules_support/compiler_support.lua | 4 +- .../modules_support/dependency_scanner.lua | 2 +- xmake/rules/c++/modules/xmake.lua | 218 ++++++++++++------ 4 files changed, 174 insertions(+), 79 deletions(-) diff --git a/xmake/rules/c++/modules/modules_support/builder.lua b/xmake/rules/c++/modules/modules_support/builder.lua index 1f014abdeca..b3426736fc1 100644 --- a/xmake/rules/c++/modules/modules_support/builder.lua +++ b/xmake/rules/c++/modules/modules_support/builder.lua @@ -21,6 +21,7 @@ -- imports import("core.base.json") import("core.base.option") +import("async.runjobs") import("private.async.buildjobs") import("core.tool.compiler") import("core.project.config") @@ -305,6 +306,34 @@ function build_headerunits_for_batchcmds(target, batchcmds, sourcebatch, modules end end +function generate_metadata(target, modules) + local public_modules + + for _, module in pairs(modules) do + local _, _, cppfile = compiler_support.get_provided_module(module) + local fileconfig = target:fileconfig(cppfile) + local public = fileconfig and fileconfig.public + if public then + public_modules = public_modules or {} + table.insert(public_modules, module) + end + end + + if not public_modules then + return + end + + local jobs = option.get("jobs") or os.default_njob() + runjobs(target:name() .. "_install_modules", function(index) + local module = public_modules[index] + local name, _, cppfile = compiler_support.get_provided_module(module) + local metafilepath = compiler_support.get_metafile(target, cppfile) + progress.show((index * 100) / #public_modules, "${color.build.target}<%s> generating.module.metadata %s", target:name(), name) + local metadata = _generate_meta_module_info(target, name, cppfile, module.requires) + json.savefile(metafilepath, metadata) + end, {comax = jobs, total = #public_modules}) +end + -- flush target module mapper keys function flush_target_module_mapper_keys(target) local memcache = compiler_support.memcache() diff --git a/xmake/rules/c++/modules/modules_support/compiler_support.lua b/xmake/rules/c++/modules/modules_support/compiler_support.lua index d9d849454f1..d7e8a0bd843 100644 --- a/xmake/rules/c++/modules/modules_support/compiler_support.lua +++ b/xmake/rules/c++/modules/modules_support/compiler_support.lua @@ -116,14 +116,14 @@ end -- this target contains module files? function contains_modules(target) -- we can not use `"c++.build.builder"`, because it contains sourcekind/cxx. - local target_with_modules = target:sourcebatches()["c++.build.modules"] and true or false + local target_with_modules = (target:sourcebatches()["c++.moduleonly"] or target:sourcebatches()["c++.build.modules"]) and true or false if not target_with_modules then target_with_modules = target:policy("build.c++.modules") end if not target_with_modules then for _, dep in ipairs(target:orderdeps()) do local sourcebatches = dep:sourcebatches() - if sourcebatches["c++.build.modules"] then + if sourcebatches["c++.moduleonly"] or sourcebatches["c++.build.modules"] then target_with_modules = true break end diff --git a/xmake/rules/c++/modules/modules_support/dependency_scanner.lua b/xmake/rules/c++/modules/modules_support/dependency_scanner.lua index 0b02292ef85..e4e6783bd79 100644 --- a/xmake/rules/c++/modules/modules_support/dependency_scanner.lua +++ b/xmake/rules/c++/modules/modules_support/dependency_scanner.lua @@ -438,7 +438,7 @@ end function get_targetdeps_modules(target) local sourcefiles for _, dep in ipairs(target:orderdeps()) do - local sourcebatch = dep:sourcebatches()["c++.build.modules.builder"] + local sourcebatch = dep:sourcebatches()["c++.moduleonly"] or dep:sourcebatches()["c++.build.modules.builder"] if sourcebatch and sourcebatch.sourcefiles then for _, sourcefile in ipairs(sourcebatch.sourcefiles) do local fileconfig = dep:fileconfig(sourcefile) diff --git a/xmake/rules/c++/modules/xmake.lua b/xmake/rules/c++/modules/xmake.lua index 62fb37205bb..6db349873a9 100644 --- a/xmake/rules/c++/modules/xmake.lua +++ b/xmake/rules/c++/modules/xmake.lua @@ -52,6 +52,14 @@ rule("c++.build.modules") -- mark this target with modules target:data_set("cxx.has_modules", true) + + -- moduleonly modules are implicitly public + if target:rule("c++.moduleonly") then + local sourcebatch = target:sourcebatches()["c++.moduleonly"] + for _, sourcefile in ipairs(sourcebatch.sourcefiles) do + target:fileconfig_add(sourcefile, {public = true}) + end + end end end) @@ -62,111 +70,123 @@ rule("c++.build.modules.builder") -- parallel build support to accelerate `xmake build` to build modules before_build_files(function(target, batchjobs, sourcebatch, opt) - if target:data("cxx.has_modules") then - import("modules_support.compiler_support") - import("modules_support.dependency_scanner") - import("modules_support.builder") - - -- add target deps modules - if target:orderdeps() then - local deps_sourcefiles = dependency_scanner.get_targetdeps_modules(target) - if deps_sourcefiles then - table.join2(sourcebatch.sourcefiles, deps_sourcefiles) + if not target:rule("c++.moduleonly") then + if target:data("cxx.has_modules") then + import("modules_support.compiler_support") + import("modules_support.dependency_scanner") + import("modules_support.builder") + + -- add target deps modules + if target:orderdeps() then + local deps_sourcefiles = dependency_scanner.get_targetdeps_modules(target) + if deps_sourcefiles then + table.join2(sourcebatch.sourcefiles, deps_sourcefiles) + end end - end - -- append std module - local std_modules = compiler_support.get_stdmodules(target) - if std_modules then - table.join2(sourcebatch.sourcefiles, std_modules) - target:fileconfig_set(std_modules[1], {external = true}) - target:fileconfig_set(std_modules[2], {external = true}) - end + -- append std module + local std_modules = compiler_support.get_stdmodules(target) + if std_modules then + table.join2(sourcebatch.sourcefiles, std_modules) + target:fileconfig_set(std_modules[1], {external = true}) + target:fileconfig_set(std_modules[2], {external = true}) + end - -- extract packages modules dependencies - local package_modules_data = dependency_scanner.get_all_packages_modules(target, opt) - if package_modules_data then - -- append to sourcebatch - for _, package_module_data in table.orderpairs(package_modules_data) do - table.insert(sourcebatch.sourcefiles, package_module_data.file) - target:fileconfig_set(package_module_data.file, {external = true, defines = package_module_data.metadata.defines}) + -- extract packages modules dependencies + local package_modules_data = dependency_scanner.get_all_packages_modules(target, opt) + if package_modules_data then + -- append to sourcebatch + for _, package_module_data in table.orderpairs(package_modules_data) do + table.insert(sourcebatch.sourcefiles, package_module_data.file) + target:fileconfig_set(package_module_data.file, {external = true, defines = package_module_data.metadata.defines}) + end end - end - opt.batchjobs = true + opt.batchjobs = true - compiler_support.patch_sourcebatch(target, sourcebatch, opt) - local modules = dependency_scanner.get_module_dependencies(target, sourcebatch, opt) + compiler_support.patch_sourcebatch(target, sourcebatch, opt) + local modules = dependency_scanner.get_module_dependencies(target, sourcebatch, opt) - -- avoid building non referenced modules - sourcebatch.objectfiles = dependency_scanner.sort_modules_by_dependencies(target, sourcebatch.objectfiles, modules) + -- avoid building non referenced modules + sourcebatch.objectfiles = dependency_scanner.sort_modules_by_dependencies(target, sourcebatch.objectfiles, modules) - -- build modules - builder.build_modules_for_batchjobs(target, batchjobs, sourcebatch, modules, opt) + -- build modules + builder.build_modules_for_batchjobs(target, batchjobs, sourcebatch, modules, opt) - -- build headerunits and we need to do it before building modules - builder.build_headerunits_for_batchjobs(target, batchjobs, sourcebatch, modules, opt) + -- build headerunits and we need to do it before building modules + builder.build_headerunits_for_batchjobs(target, batchjobs, sourcebatch, modules, opt) - -- cull external modules objectfile - compiler_support.cull_objectfiles(target, modules, sourcebatch) + -- cull external modules objectfile + compiler_support.cull_objectfiles(target, modules, sourcebatch) + else + -- avoid duplicate linking of object files of non-module programs + sourcebatch.objectfiles = {} + end else - -- avoid duplicate linking of object files of non-module programs + sourcebatch.sourcefiles = {} sourcebatch.objectfiles = {} + sourcebatch.dependfiles = {} end end, {batch = true}) -- serial compilation only, usually used to support project generator before_buildcmd_files(function(target, batchcmds, sourcebatch, opt) - if target:data("cxx.has_modules") then - import("modules_support.compiler_support") - import("modules_support.dependency_scanner") - import("modules_support.builder") - - -- add target deps modules - if target:orderdeps() then - local deps_sourcefiles = dependency_scanner.get_targetdeps_modules(target) - if deps_sourcefiles then - table.join2(sourcebatch.sourcefiles, deps_sourcefiles) + if not target:rule("c++.moduleonly") then + if target:data("cxx.has_modules") then + import("modules_support.compiler_support") + import("modules_support.dependency_scanner") + import("modules_support.builder") + + -- add target deps modules + if target:orderdeps() then + local deps_sourcefiles = dependency_scanner.get_targetdeps_modules(target) + if deps_sourcefiles then + table.join2(sourcebatch.sourcefiles, deps_sourcefiles) + end end - end - -- append std module - local std_modules = compiler_support.get_stdmodules(target) - if std_modules then - table.join2(sourcebatch.sourcefiles, std_modules) - target:fileconfig_set(std_modules[1], {external = true}) - target:fileconfig_set(std_modules[2], {external = true}) - end + -- append std module + local std_modules = compiler_support.get_stdmodules(target) + if std_modules then + table.join2(sourcebatch.sourcefiles, std_modules) + target:fileconfig_set(std_modules[1], {external = true}) + target:fileconfig_set(std_modules[2], {external = true}) + end - -- extract packages modules dependencies - local package_modules_data = dependency_scanner.get_all_packages_modules(target, opt) - if package_modules_data then - -- append to sourcebatch - for _, package_module_data in table.orderpairs(package_modules_data) do - table.insert(sourcebatch.sourcefiles, package_module_data.file) - target:fileconfig_set(package_module_data.file, {external = true, defines = package_module_data.metadata.defines}) + -- extract packages modules dependencies + local package_modules_data = dependency_scanner.get_all_packages_modules(target, opt) + if package_modules_data then + -- append to sourcebatch + for _, package_module_data in table.orderpairs(package_modules_data) do + table.insert(sourcebatch.sourcefiles, package_module_data.file) + target:fileconfig_set(package_module_data.file, {external = true, defines = package_module_data.metadata.defines}) + end end - end - opt.batchjobs = false + opt.batchjobs = false - compiler_support.patch_sourcebatch(target, sourcebatch, opt) - local modules = dependency_scanner.get_module_dependencies(target, sourcebatch, opt) + compiler_support.patch_sourcebatch(target, sourcebatch, opt) + local modules = dependency_scanner.get_module_dependencies(target, sourcebatch, opt) - -- avoid building non referenced modules - sourcebatch.objectfiles = dependency_scanner.sort_modules_by_dependencies(target, sourcebatch.objectfiles, modules) + -- avoid building non referenced modules + sourcebatch.objectfiles = dependency_scanner.sort_modules_by_dependencies(target, sourcebatch.objectfiles, modules) - -- build headerunits - builder.build_headerunits_for_batchcmds(target, batchcmds, sourcebatch, modules, opt) + -- build headerunits + builder.build_headerunits_for_batchcmds(target, batchcmds, sourcebatch, modules, opt) - -- build modules - builder.build_modules_for_batchcmds(target, batchcmds, sourcebatch, modules, opt) + -- build modules + builder.build_modules_for_batchcmds(target, batchcmds, sourcebatch, modules, opt) - -- cull external modules objectfile - -- compiler_support.cull_objectfiles(target, modules, sourcebatch) + -- cull external modules objectfile + -- compiler_support.cull_objectfiles(target, modules, sourcebatch) + else + -- avoid duplicate linking of object files of non-module programs + sourcebatch.objectfiles = {} + end else - -- avoid duplicate linking of object files of non-module programs + sourcebatch.sourcefiles = {} sourcebatch.objectfiles = {} + sourcebatch.dependfiles = {} end end) @@ -187,16 +207,62 @@ rule("c++.build.modules.builder") end end) +-- moduleonly +rule("c++.moduleonly") + add_deps("c++.build.modules.install") + set_extensions(".mpp", ".mxx", ".cppm", ".ixx", ".cpp") + + before_build(function(target) + if target:data("cxx.has_modules") then + import("modules_support.compiler_support") + import("modules_support.dependency_scanner") + + local sourcebatch = target:sourcebatches()["c++.moduleonly"] + + -- add target deps modules + if target:orderdeps() then + local deps_sourcefiles = dependency_scanner.get_targetdeps_modules(target) + if deps_sourcefiles then + table.join2(sourcebatch.sourcefiles, deps_sourcefiles) + end + end + + -- append std module + table.join2(sourcebatch.sourcefiles, compiler_support.get_stdmodules(target) or {}) + + -- extract packages modules dependencies + local package_modules_data = dependency_scanner.get_all_packages_modules(target, opt) + if package_modules_data then + -- append to sourcebatch + for _, package_module_data in table.orderpairs(package_modules_data) do + table.insert(sourcebatch.sourcefiles, package_module_data.file) + target:fileconfig_add(package_module_data.file, {external = true, defines = package_module_data.metadata.defines}) + end + end + + local opt = {batchjobs = true} + + compiler_support.patch_sourcebatch(target, sourcebatch, opt) + local modules = dependency_scanner.get_module_dependencies(target, sourcebatch, opt) + compiler_support.localcache():set2(target:name(), "c++.modules", modules) + compiler_support.localcache():save() + end + end) + -- install modules rule("c++.build.modules.install") set_extensions(".mpp", ".mxx", ".cppm", ".ixx") before_install(function (target) import("modules_support.compiler_support") + import("modules_support.builder") -- we cannot use target:data("cxx.has_modules"), -- because on_config will be not called when installing targets if compiler_support.contains_modules(target) then + local modules = compiler_support.localcache():get2(target:name(), "c++.modules") + builder.generate_metadata(target, modules) + compiler_support.install_module_target(target) end end) From e8b4dafc56fb43af310e9b71c1ead5784949ed74 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 5 Feb 2024 18:26:04 +0100 Subject: [PATCH 11/40] fix packages test --- .../modules/packages/my-repo/packages/b/bar2/src/xmake.lua | 6 +++--- .../c++/modules/packages/my-repo/packages/b/bar2/xmake.lua | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/src/xmake.lua b/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/src/xmake.lua index ddc3ae31177..9312aee2dd6 100644 --- a/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/src/xmake.lua +++ b/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/src/xmake.lua @@ -1,7 +1,7 @@ add_rules("mode.release", "mode.debug") set_languages("c++20") -target("bar") - set_kind("headeonly") - add_rules("moduleonly") +target("bar2") + set_kind("headeronly") + add_rules("c++.moduleonly") add_files("*.mpp") diff --git a/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/xmake.lua b/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/xmake.lua index 1f0d5af8275..e56cdaf438d 100644 --- a/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/xmake.lua +++ b/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/xmake.lua @@ -1,4 +1,4 @@ -package("bar") +package("bar2") set_kind("headeronly") set_sourcedir(path.join(os.scriptdir(), "src")) From effa81f89c816e3b9951c1cac1fad01644b02f22 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 5 Feb 2024 18:26:43 +0100 Subject: [PATCH 12/40] remove old file --- tests/projects/c++/modules/staticlib_without_cpp/src/mod.mpp | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 tests/projects/c++/modules/staticlib_without_cpp/src/mod.mpp diff --git a/tests/projects/c++/modules/staticlib_without_cpp/src/mod.mpp b/tests/projects/c++/modules/staticlib_without_cpp/src/mod.mpp deleted file mode 100644 index b7dd3883c6c..00000000000 --- a/tests/projects/c++/modules/staticlib_without_cpp/src/mod.mpp +++ /dev/null @@ -1,2 +0,0 @@ -export module hello; -export int foo() { return 0; } From 359ad44c2c98b3a42325bb308b0657072edb622c Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 5 Feb 2024 17:33:18 +0100 Subject: [PATCH 13/40] fix msvc --- .../rules/c++/modules/modules_support/msvc/compiler_support.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/xmake/rules/c++/modules/modules_support/msvc/compiler_support.lua b/xmake/rules/c++/modules/modules_support/msvc/compiler_support.lua index 662fd603e8b..e65effa1110 100644 --- a/xmake/rules/c++/modules/modules_support/msvc/compiler_support.lua +++ b/xmake/rules/c++/modules/modules_support/msvc/compiler_support.lua @@ -88,7 +88,6 @@ function get_stdmodules(target) end end end - return {} end function get_bmi_extension() From cf5c45be7013afc766e63f6d756f32d77ae426cc Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 5 Feb 2024 19:20:53 +0100 Subject: [PATCH 14/40] cleanup --- tests/projects/c++/modules/test_base.lua | 2 +- .../projects/c++/modules/test_stdmodules.lua | 2 +- .../c++/modules/modules_support/builder.lua | 29 +++---------------- 3 files changed, 6 insertions(+), 27 deletions(-) diff --git a/tests/projects/c++/modules/test_base.lua b/tests/projects/c++/modules/test_base.lua index f39c31b7551..092fbd72f77 100644 --- a/tests/projects/c++/modules/test_base.lua +++ b/tests/projects/c++/modules/test_base.lua @@ -56,7 +56,7 @@ function main(t) os.exec("xmake f --toolchain=clang -c --yes") _build() os.exec("xmake clean -a") - os.exec("xmake f --toolchain=clang --runtimes=c++_shared --sdk='/opt/llvm-git/usr/' -c --yes") + os.exec("xmake f --toolchain=clang --runtimes=c++_shared -c --yes") _build() end end diff --git a/tests/projects/c++/modules/test_stdmodules.lua b/tests/projects/c++/modules/test_stdmodules.lua index c2945736406..68a5922ef3b 100644 --- a/tests/projects/c++/modules/test_stdmodules.lua +++ b/tests/projects/c++/modules/test_stdmodules.lua @@ -51,7 +51,7 @@ function main(t) -- os.exec("xmake f --toolchain=clang -c --yes") -- _build() os.exec("xmake clean -a") - os.exec("xmake f --toolchain=clang --runtimes=c++_shared --sdk='/opt/llvm-git/usr/' -c --yes") + os.exec("xmake f --toolchain=clang --runtimes=c++_shared -c --yes") _build() end end diff --git a/xmake/rules/c++/modules/modules_support/builder.lua b/xmake/rules/c++/modules/modules_support/builder.lua index b3426736fc1..768c337ce1d 100644 --- a/xmake/rules/c++/modules/modules_support/builder.lua +++ b/xmake/rules/c++/modules/modules_support/builder.lua @@ -42,7 +42,7 @@ function _build_modules(target, sourcebatch, modules, opt) goto CONTINUE end - local name, provide, cppfile = compiler_support.get_provided_module(module) + local name, _, cppfile = compiler_support.get_provided_module(module) cppfile = cppfile or module.cppfile local deps = {} @@ -50,8 +50,7 @@ function _build_modules(target, sourcebatch, modules, opt) table.insert(deps, opt.batchjobs and target:name() .. dep or dep) end - local fileconfig = target:fileconfig(cppfile) - opt.build_module(deps, module, name, provide, objectfile, cppfile, fileconfig) + opt.build_module(deps, module, name, objectfile, cppfile) ::CONTINUE:: end @@ -192,21 +191,10 @@ function build_modules_for_batchjobs(target, batchjobs, sourcebatch, modules, op local modulesjobs = {} _build_modules(target, sourcebatch, modules, table.join(opt, { - build_module = function(deps, module, name, provide, objectfile, cppfile, fileconfig) + build_module = function(deps, module, name, objectfile, cppfile) local job_name = name and target:name() .. name or cppfile modulesjobs[job_name] = _builder(target).make_module_buildjobs(target, batchjobs, job_name, deps, {module = module, objectfile = objectfile, cppfile = cppfile}) - - if provide and fileconfig and fileconfig.public then - batchjobs:addjob(name .. "_metafile", function(index, total) - local metafilepath = compiler_support.get_metafile(target, cppfile) - depend.on_changed(function() - progress.show((index * 100) / total, "${color.build.target}<%s> generating.module.metadata %s", target:name(), name) - local metadata = _generate_meta_module_info(target, name, cppfile, module.requires) - json.savefile(metafilepath, metadata) - end, {dependfile = target:dependfile(metafilepath), files = {cppfile}, changed = target:is_rebuilt()}) - end, {rootjob = opt.rootjob}) - end end })) @@ -222,17 +210,8 @@ function build_modules_for_batchcmds(target, batchcmds, sourcebatch, modules, op -- build modules _build_modules(target, sourcebatch, modules, table.join(opt, { - build_module = function(_, module, name, provide, objectfile, cppfile, fileconfig) + build_module = function(_, module, _, objectfile, cppfile) depmtime = math.max(depmtime, _builder(target).make_module_buildcmds(target, batchcmds, {module = module, cppfile = cppfile, objectfile = objectfile, progress = opt.progress})) - - if provide and fileconfig and fileconfig.public then - local metafilepath = compiler_support.get_metafile(target, cppfile) - depend.on_changed(function() - progress.show(opt.progress, "${color.build.target}<%s> generating.module.metadata %s", target:name(), name) - local metadata = _generate_meta_module_info(target, name, cppfile, module.requires) - json.savefile(metafilepath, metadata) - end, {dependfile = target:dependfile(metafilepath), files = {cppfile}, changed = target:is_rebuilt()}) - end end })) From 3266f5dda184c4d1b1d340ec9e21cc9f299fcb84 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 5 Feb 2024 19:22:13 +0100 Subject: [PATCH 15/40] fixe module installation --- xmake/rules/c++/modules/xmake.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/xmake/rules/c++/modules/xmake.lua b/xmake/rules/c++/modules/xmake.lua index 6db349873a9..34d636ca1d3 100644 --- a/xmake/rules/c++/modules/xmake.lua +++ b/xmake/rules/c++/modules/xmake.lua @@ -118,6 +118,8 @@ rule("c++.build.modules.builder") -- cull external modules objectfile compiler_support.cull_objectfiles(target, modules, sourcebatch) + compiler_support.localcache():set2(target:name(), "c++.modules", modules) + compiler_support.localcache():save() else -- avoid duplicate linking of object files of non-module programs sourcebatch.objectfiles = {} @@ -178,7 +180,9 @@ rule("c++.build.modules.builder") builder.build_modules_for_batchcmds(target, batchcmds, sourcebatch, modules, opt) -- cull external modules objectfile - -- compiler_support.cull_objectfiles(target, modules, sourcebatch) + compiler_support.cull_objectfiles(target, modules, sourcebatch) + compiler_support.localcache():set2(target:name(), "c++.modules", modules) + compiler_support.localcache():save() else -- avoid duplicate linking of object files of non-module programs sourcebatch.objectfiles = {} From 8929c381e0cd70ff804e7c52bb3efc134e056e78 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 6 Feb 2024 18:31:13 +0100 Subject: [PATCH 16/40] implement target kind moduleonly --- .../projects/c++/modules/link_order/xmake.lua | 8 +- .../projects/c++/modules/moduleonly/xmake.lua | 3 +- .../my-repo/packages/b/bar2/src/xmake.lua | 4 +- .../my-repo/packages/b/bar2/xmake.lua | 2 +- .../c++/modules/user_headerunit2/a/xmake.lua | 4 +- .../c++/modules/user_headerunit2/b/xmake.lua | 4 +- xmake/actions/build/build.lua | 2 +- xmake/actions/build/kinds/moduleonly.lua | 257 ++++++++++++++++++ xmake/core/project/target.lua | 9 +- .../check/checkers/api/target/kind.lua | 2 +- xmake/plugins/project/cmake/cmakelists.lua | 2 + .../modules_support/compiler_support.lua | 4 +- .../modules_support/dependency_scanner.lua | 2 +- xmake/rules/c++/modules/xmake.lua | 182 +++++-------- 14 files changed, 353 insertions(+), 132 deletions(-) create mode 100644 xmake/actions/build/kinds/moduleonly.lua diff --git a/tests/projects/c++/modules/link_order/xmake.lua b/tests/projects/c++/modules/link_order/xmake.lua index 1ae6639bb40..5c7b8a236c8 100644 --- a/tests/projects/c++/modules/link_order/xmake.lua +++ b/tests/projects/c++/modules/link_order/xmake.lua @@ -3,14 +3,14 @@ set_languages("c++20") target("foo") add_rules("c++") - set_kind("headeronly") - add_rules("c++.moduleonly") + set_kind("moduleonly") + add_files("src/foo.mpp") target("bar") add_rules("c++") - set_kind("headeronly") - add_rules("c++.moduleonly") + set_kind("moduleonly") + add_files("src/bar.mpp") target("link_order_1") diff --git a/tests/projects/c++/modules/moduleonly/xmake.lua b/tests/projects/c++/modules/moduleonly/xmake.lua index c6cb7cef49e..54c681cc870 100644 --- a/tests/projects/c++/modules/moduleonly/xmake.lua +++ b/tests/projects/c++/modules/moduleonly/xmake.lua @@ -2,6 +2,5 @@ add_rules("mode.release", "mode.debug") set_languages("c++20") target("mod") - set_kind("headeronly") - add_rules("c++.moduleonly") + set_kind("moduleonly") add_files("src/mod.mpp") diff --git a/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/src/xmake.lua b/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/src/xmake.lua index 9312aee2dd6..905c38a02ae 100644 --- a/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/src/xmake.lua +++ b/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/src/xmake.lua @@ -2,6 +2,6 @@ add_rules("mode.release", "mode.debug") set_languages("c++20") target("bar2") - set_kind("headeronly") - add_rules("c++.moduleonly") + set_kind("moduleonly") + add_files("*.mpp") diff --git a/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/xmake.lua b/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/xmake.lua index e56cdaf438d..343a52e0215 100644 --- a/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/xmake.lua +++ b/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/xmake.lua @@ -1,5 +1,5 @@ package("bar2") - set_kind("headeronly") + set_kind("moduleonly") set_sourcedir(path.join(os.scriptdir(), "src")) on_install(function(package) diff --git a/tests/projects/c++/modules/user_headerunit2/a/xmake.lua b/tests/projects/c++/modules/user_headerunit2/a/xmake.lua index 26142892103..8d9a4cb8b1b 100644 --- a/tests/projects/c++/modules/user_headerunit2/a/xmake.lua +++ b/tests/projects/c++/modules/user_headerunit2/a/xmake.lua @@ -1,6 +1,6 @@ target("a") set_languages("cxxlatest") - set_kind("headeronly") - add_rules("c++.moduleonly") + set_kind("moduleonly") + add_headerfiles("*.hpp") add_files("a.mpp") diff --git a/tests/projects/c++/modules/user_headerunit2/b/xmake.lua b/tests/projects/c++/modules/user_headerunit2/b/xmake.lua index 9821fcd6d9b..5be8ae50bb0 100644 --- a/tests/projects/c++/modules/user_headerunit2/b/xmake.lua +++ b/tests/projects/c++/modules/user_headerunit2/b/xmake.lua @@ -1,6 +1,6 @@ target("b") add_deps("a") set_languages("cxxlatest") - set_kind("headeronly") - add_rules("c++.moduleonly") + set_kind("moduleonly") + add_files("b.mpp") diff --git a/xmake/actions/build/build.lua b/xmake/actions/build/build.lua index bb0b61cc149..1db197cd602 100644 --- a/xmake/actions/build/build.lua +++ b/xmake/actions/build/build.lua @@ -65,7 +65,7 @@ function _add_batchjobs_builtin(batchjobs, rootjob, target) end -- uses the builtin target script - if not job and (target:is_static() or target:is_binary() or target:is_shared() or target:is_object()) then + if not job and (target:is_static() or target:is_binary() or target:is_shared() or target:is_object() or target:is_moduleonly()) then job, job_leaf = import("kinds." .. target:kind(), {anonymous = true})(batchjobs, rootjob, target) end job = job or rootjob diff --git a/xmake/actions/build/kinds/moduleonly.lua b/xmake/actions/build/kinds/moduleonly.lua new file mode 100644 index 00000000000..1a5997712ad --- /dev/null +++ b/xmake/actions/build/kinds/moduleonly.lua @@ -0,0 +1,257 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015-present, TBOOX Open Source Group. +-- +-- @author ruki, Arthapz +-- @file modules.lua +-- + +-- imports +import("core.base.option") +import("core.project.rule") +import("core.project.config") +import("core.project.project") +import("async.runjobs") +import("private.utils.batchcmds") +import("private.utils.rule_groups") + +-- has scripts for the custom rule +function _has_scripts_for_rule(ruleinst, suffix) + + -- add batch jobs for xx_build_files + local scriptname = "build_files" .. (suffix and ("_" .. suffix) or "") + local script = ruleinst:script(scriptname) + if script then + return true + end + + -- add batch jobs for xx_build_file + scriptname = "build_file" .. (suffix and ("_" .. suffix) or "") + script = ruleinst:script(scriptname) + if script then + return true + end + + -- add batch jobs for xx_buildcmd_files + scriptname = "buildcmd_files" .. (suffix and ("_" .. suffix) or "") + script = ruleinst:script(scriptname) + if script then + return true + end + + -- add batch jobs for xx_buildcmd_file + scriptname = "buildcmd_file" .. (suffix and ("_" .. suffix) or "") + script = ruleinst:script(scriptname) + if script then + return true + end +end + +-- has scripts for target +function _has_scripts_for_target(target, suffix) + local scriptname = "build_files" .. (suffix and ("_" .. suffix) or "") + local script = target:script(scriptname) + if script then + return true + else + scriptname = "build_file" .. (suffix and ("_" .. suffix) or "") + script = target:script(scriptname) + if script then + return true + end + end +end + +-- has scripts for group +function _has_scripts_for_group(group, suffix) + for _, item in pairs(group) do + if item.target and _has_scripts_for_target(item.target, suffix) then + return true + end + if item.rule and _has_scripts_for_rule(item.rule, suffix) then + return true + end + end +end + +-- add batch jobs for the custom rule +function _add_batchjobs_for_rule(batchjobs, rootjob, target, sourcebatch, suffix) + + -- get rule + local rulename = assert(sourcebatch.rulename, "unknown rule for sourcebatch!") + local ruleinst = rule_groups.get_rule(target, rulename) + + -- add batch jobs for xx_build_files + local scriptname = "build_files" .. (suffix and ("_" .. suffix) or "") + local script = ruleinst:script(scriptname) + if script then + if ruleinst:extraconf(scriptname, "batch") then + script(target, batchjobs, sourcebatch, {rootjob = rootjob, distcc = ruleinst:extraconf(scriptname, "distcc")}) + else + batchjobs:addjob("rule/" .. rulename .. "/" .. scriptname, function (index, total) + script(target, sourcebatch, {progress = (index * 100) / total}) + end, {rootjob = rootjob}) + end + end + + -- add batch jobs for xx_build_file + if not script then + scriptname = "build_file" .. (suffix and ("_" .. suffix) or "") + script = ruleinst:script(scriptname) + if script then + local sourcekind = sourcebatch.sourcekind + for _, sourcefile in ipairs(sourcebatch.sourcefiles) do + batchjobs:addjob(sourcefile, function (index, total) + script(target, sourcefile, {sourcekind = sourcekind, progress = (index * 100) / total}) + end, {rootjob = rootjob, distcc = ruleinst:extraconf(scriptname, "distcc")}) + end + end + end + + -- add batch jobs for xx_buildcmd_files + if not script then + scriptname = "buildcmd_files" .. (suffix and ("_" .. suffix) or "") + script = ruleinst:script(scriptname) + if script then + batchjobs:addjob("rule/" .. rulename .. "/" .. scriptname, function (index, total) + local batchcmds_ = batchcmds.new({target = target}) + local distcc = ruleinst:extraconf(scriptname, "distcc") + script(target, batchcmds_, sourcebatch, {progress = (index * 100) / total, distcc = distcc}) + batchcmds_:runcmds({changed = target:is_rebuilt(), dryrun = option.get("dry-run")}) + end, {rootjob = rootjob}) + end + end + + -- add batch jobs for xx_buildcmd_file + if not script then + scriptname = "buildcmd_file" .. (suffix and ("_" .. suffix) or "") + script = ruleinst:script(scriptname) + if script then + local sourcekind = sourcebatch.sourcekind + for _, sourcefile in ipairs(sourcebatch.sourcefiles) do + batchjobs:addjob(sourcefile, function (index, total) + local batchcmds_ = batchcmds.new({target = target}) + script(target, batchcmds_, sourcefile, {sourcekind = sourcekind, progress = (index * 100) / total}) + batchcmds_:runcmds({changed = target:is_rebuilt(), dryrun = option.get("dry-run")}) + end, {rootjob = rootjob, distcc = ruleinst:extraconf(scriptname, "distcc")}) + end + end + end +end + +-- add batch jobs for target +function _add_batchjobs_for_target(batchjobs, rootjob, target, sourcebatch, suffix) + -- we just build sourcebatch with on_build_files scripts + -- + -- for example, c++.build and c++.build.modules.builder rules have same sourcefiles, + -- but we just build it for c++.build + -- + -- @see https://github.com/xmake-io/xmake/issues/3171 + -- + local rulename = sourcebatch.rulename + if rulename then + local ruleinst = rule_groups.get_rule(target, rulename) + if not ruleinst:script("build_file") and + not ruleinst:script("build_files") then + return + end + end + + -- add batch jobs + local scriptname = "build_files" .. (suffix and ("_" .. suffix) or "") + local script = target:script(scriptname) + if script then + if target:extraconf(scriptname, "batch") then + script(target, batchjobs, sourcebatch, {rootjob = rootjob, distcc = target:extraconf(scriptname, "distcc")}) + else + batchjobs:addjob(target:name() .. "/" .. scriptname, function (index, total) + script(target, sourcebatch, {progress = (index * 100) / total}) + end, {rootjob = rootjob}) + end + return true + else + scriptname = "build_file" .. (suffix and ("_" .. suffix) or "") + script = target:script(scriptname) + if script then + local sourcekind = sourcebatch.sourcekind + for _, sourcefile in ipairs(sourcebatch.sourcefiles) do + batchjobs:addjob(sourcefile, function (index, total) + script(target, sourcefile, {sourcekind = sourcekind, progress = (index * 100) / total}) + end, {rootjob = rootjob, distcc = target:extraconf(scriptname, "distcc")}) + end + return true + end + end +end + +-- add batch jobs for group +function _add_batchjobs_for_group(batchjobs, rootjob, target, group, suffix) + for _, item in pairs(group) do + local sourcebatch = item.sourcebatch + if item.target then + _add_batchjobs_for_target(batchjobs, rootjob, target, sourcebatch, suffix) + end + -- override on_xxx script in target? we need to ignore rule scripts + if item.rule and (suffix or not _has_scripts_for_target(target, suffix)) then + _add_batchjobs_for_rule(batchjobs, rootjob, target, sourcebatch, suffix) + end + end +end + +-- add batch jobs for building source files +function add_batchjobs_for_sourcefiles(batchjobs, rootjob, target, sourcebatches) + + -- build sourcebatch groups first + local groups = rule_groups.build_sourcebatch_groups(target, sourcebatches) + + -- add batch jobs for build_after + local groups_root + local groups_leaf = rootjob + for idx, group in ipairs(groups) do + if _has_scripts_for_group(group, "after") then + batchjobs:group_enter(target:name() .. "/after_build_files" .. idx) + _add_batchjobs_for_group(batchjobs, groups_leaf, target, group, "after") + groups_leaf = batchjobs:group_leave() or groups_leaf + groups_root = groups_root or groups_leaf + end + end + + -- add batch jobs for build + for idx, group in ipairs(groups) do + if _has_scripts_for_group(group) then + batchjobs:group_enter(target:name() .. "/build_files" .. idx) + _add_batchjobs_for_group(batchjobs, groups_leaf, target, group) + groups_leaf = batchjobs:group_leave() or groups_leaf + groups_root = groups_root or groups_leaf + end + end + + -- add batch jobs for build_before + for idx, group in ipairs(groups) do + if _has_scripts_for_group(group, "before") then + batchjobs:group_enter(target:name() .. "/before_build_files" .. idx) + _add_batchjobs_for_group(batchjobs, groups_leaf, target, group, "before") + groups_leaf = batchjobs:group_leave() or groups_leaf + groups_root = groups_root or groups_leaf + end + end + return groups_leaf, groups_root or groups_leaf +end + +-- add batch jobs for generating modules deps files +function main(batchjobs, rootjob, target) + return add_batchjobs_for_sourcefiles(batchjobs, rootjob, target, target:sourcebatches()) +end + diff --git a/xmake/core/project/target.lua b/xmake/core/project/target.lua index 8cc2ff824ca..b6835a277ad 100644 --- a/xmake/core/project/target.lua +++ b/xmake/core/project/target.lua @@ -1201,9 +1201,14 @@ function _instance:is_headeronly() return self:kind() == "headeronly" end +-- is moduleonly target? +function _instance:is_moduleonly() + return self:kind() == "moduleonly" +end + -- is library target? function _instance:is_library() - return self:is_static() or self:is_shared() or self:is_headeronly() + return self:is_static() or self:is_shared() or self:is_headeronly() or self:is_moduleonly() end -- is default target? @@ -1555,7 +1560,7 @@ end function _instance:filename() -- no target file? - if self:is_object() or self:is_phony() or self:is_headeronly() then + if self:is_object() or self:is_phony() or self:is_headeronly() or self:is_moduleonly() then return end diff --git a/xmake/modules/private/check/checkers/api/target/kind.lua b/xmake/modules/private/check/checkers/api/target/kind.lua index 127f78ad5c1..5d716b1295a 100644 --- a/xmake/modules/private/check/checkers/api/target/kind.lua +++ b/xmake/modules/private/check/checkers/api/target/kind.lua @@ -23,5 +23,5 @@ import(".api_checker") function main(opt) opt = opt or {} - api_checker.check_targets("kind", table.join(opt, {values = {"object", "binary", "static", "shared", "headeronly", "phony"}})) + api_checker.check_targets("kind", table.join(opt, {values = {"object", "binary", "static", "shared", "headeronly", "moduleonly", "phony"}})) end diff --git a/xmake/plugins/project/cmake/cmakelists.lua b/xmake/plugins/project/cmake/cmakelists.lua index 6fcf38313bb..a91328d54e1 100644 --- a/xmake/plugins/project/cmake/cmakelists.lua +++ b/xmake/plugins/project/cmake/cmakelists.lua @@ -1003,6 +1003,8 @@ function _add_target(cmakelists, target, outputdir) _add_target_headeronly(cmakelists, target) _add_target_include_directories(cmakelists, target, outputdir) return + elseif targetkind == 'moduleonly' then + raise("target kind moduleonly is currently not supported for cmakelists") else raise("unknown target kind %s", target:kind()) end diff --git a/xmake/rules/c++/modules/modules_support/compiler_support.lua b/xmake/rules/c++/modules/modules_support/compiler_support.lua index d7e8a0bd843..d9d849454f1 100644 --- a/xmake/rules/c++/modules/modules_support/compiler_support.lua +++ b/xmake/rules/c++/modules/modules_support/compiler_support.lua @@ -116,14 +116,14 @@ end -- this target contains module files? function contains_modules(target) -- we can not use `"c++.build.builder"`, because it contains sourcekind/cxx. - local target_with_modules = (target:sourcebatches()["c++.moduleonly"] or target:sourcebatches()["c++.build.modules"]) and true or false + local target_with_modules = target:sourcebatches()["c++.build.modules"] and true or false if not target_with_modules then target_with_modules = target:policy("build.c++.modules") end if not target_with_modules then for _, dep in ipairs(target:orderdeps()) do local sourcebatches = dep:sourcebatches() - if sourcebatches["c++.moduleonly"] or sourcebatches["c++.build.modules"] then + if sourcebatches["c++.build.modules"] then target_with_modules = true break end diff --git a/xmake/rules/c++/modules/modules_support/dependency_scanner.lua b/xmake/rules/c++/modules/modules_support/dependency_scanner.lua index e4e6783bd79..0b02292ef85 100644 --- a/xmake/rules/c++/modules/modules_support/dependency_scanner.lua +++ b/xmake/rules/c++/modules/modules_support/dependency_scanner.lua @@ -438,7 +438,7 @@ end function get_targetdeps_modules(target) local sourcefiles for _, dep in ipairs(target:orderdeps()) do - local sourcebatch = dep:sourcebatches()["c++.moduleonly"] or dep:sourcebatches()["c++.build.modules.builder"] + local sourcebatch = dep:sourcebatches()["c++.build.modules.builder"] if sourcebatch and sourcebatch.sourcefiles then for _, sourcefile in ipairs(sourcebatch.sourcefiles) do local fileconfig = dep:fileconfig(sourcefile) diff --git a/xmake/rules/c++/modules/xmake.lua b/xmake/rules/c++/modules/xmake.lua index 34d636ca1d3..13fb405d854 100644 --- a/xmake/rules/c++/modules/xmake.lua +++ b/xmake/rules/c++/modules/xmake.lua @@ -54,8 +54,8 @@ rule("c++.build.modules") target:data_set("cxx.has_modules", true) -- moduleonly modules are implicitly public - if target:rule("c++.moduleonly") then - local sourcebatch = target:sourcebatches()["c++.moduleonly"] + if target:is_moduleonly() then + local sourcebatch = target:sourcebatches()["c++.build.modules.builder"] for _, sourcefile in ipairs(sourcebatch.sourcefiles) do target:fileconfig_add(sourcefile, {public = true}) end @@ -70,43 +70,43 @@ rule("c++.build.modules.builder") -- parallel build support to accelerate `xmake build` to build modules before_build_files(function(target, batchjobs, sourcebatch, opt) - if not target:rule("c++.moduleonly") then - if target:data("cxx.has_modules") then - import("modules_support.compiler_support") - import("modules_support.dependency_scanner") - import("modules_support.builder") - - -- add target deps modules - if target:orderdeps() then - local deps_sourcefiles = dependency_scanner.get_targetdeps_modules(target) - if deps_sourcefiles then - table.join2(sourcebatch.sourcefiles, deps_sourcefiles) - end - end + if target:data("cxx.has_modules") then + import("modules_support.compiler_support") + import("modules_support.dependency_scanner") + import("modules_support.builder") - -- append std module - local std_modules = compiler_support.get_stdmodules(target) - if std_modules then - table.join2(sourcebatch.sourcefiles, std_modules) - target:fileconfig_set(std_modules[1], {external = true}) - target:fileconfig_set(std_modules[2], {external = true}) + -- add target deps modules + if target:orderdeps() then + local deps_sourcefiles = dependency_scanner.get_targetdeps_modules(target) + if deps_sourcefiles then + table.join2(sourcebatch.sourcefiles, deps_sourcefiles) end + end - -- extract packages modules dependencies - local package_modules_data = dependency_scanner.get_all_packages_modules(target, opt) - if package_modules_data then - -- append to sourcebatch - for _, package_module_data in table.orderpairs(package_modules_data) do - table.insert(sourcebatch.sourcefiles, package_module_data.file) - target:fileconfig_set(package_module_data.file, {external = true, defines = package_module_data.metadata.defines}) - end + -- append std module + local std_modules = compiler_support.get_stdmodules(target) + if std_modules then + table.join2(sourcebatch.sourcefiles, std_modules) + target:fileconfig_set(std_modules[1], {external = true}) + target:fileconfig_set(std_modules[2], {external = true}) + end + + -- extract packages modules dependencies + local package_modules_data = dependency_scanner.get_all_packages_modules(target, opt) + if package_modules_data then + -- append to sourcebatch + for _, package_module_data in table.orderpairs(package_modules_data) do + table.insert(sourcebatch.sourcefiles, package_module_data.file) + target:fileconfig_set(package_module_data.file, {external = true, defines = package_module_data.metadata.defines}) end + end - opt.batchjobs = true + opt.batchjobs = true - compiler_support.patch_sourcebatch(target, sourcebatch, opt) - local modules = dependency_scanner.get_module_dependencies(target, sourcebatch, opt) + compiler_support.patch_sourcebatch(target, sourcebatch, opt) + local modules = dependency_scanner.get_module_dependencies(target, sourcebatch, opt) + if not target:is_moduleonly() then -- avoid building non referenced modules sourcebatch.objectfiles = dependency_scanner.sort_modules_by_dependencies(target, sourcebatch.objectfiles, modules) @@ -118,58 +118,57 @@ rule("c++.build.modules.builder") -- cull external modules objectfile compiler_support.cull_objectfiles(target, modules, sourcebatch) - compiler_support.localcache():set2(target:name(), "c++.modules", modules) - compiler_support.localcache():save() else - -- avoid duplicate linking of object files of non-module programs sourcebatch.objectfiles = {} end + + compiler_support.localcache():set2(target:name(), "c++.modules", modules) + compiler_support.localcache():save() else - sourcebatch.sourcefiles = {} + -- avoid duplicate linking of object files of non-module programs sourcebatch.objectfiles = {} - sourcebatch.dependfiles = {} end end, {batch = true}) -- serial compilation only, usually used to support project generator before_buildcmd_files(function(target, batchcmds, sourcebatch, opt) - if not target:rule("c++.moduleonly") then - if target:data("cxx.has_modules") then - import("modules_support.compiler_support") - import("modules_support.dependency_scanner") - import("modules_support.builder") - - -- add target deps modules - if target:orderdeps() then - local deps_sourcefiles = dependency_scanner.get_targetdeps_modules(target) - if deps_sourcefiles then - table.join2(sourcebatch.sourcefiles, deps_sourcefiles) - end - end + if target:data("cxx.has_modules") then + import("modules_support.compiler_support") + import("modules_support.dependency_scanner") + import("modules_support.builder") - -- append std module - local std_modules = compiler_support.get_stdmodules(target) - if std_modules then - table.join2(sourcebatch.sourcefiles, std_modules) - target:fileconfig_set(std_modules[1], {external = true}) - target:fileconfig_set(std_modules[2], {external = true}) + -- add target deps modules + if target:orderdeps() then + local deps_sourcefiles = dependency_scanner.get_targetdeps_modules(target) + if deps_sourcefiles then + table.join2(sourcebatch.sourcefiles, deps_sourcefiles) end + end - -- extract packages modules dependencies - local package_modules_data = dependency_scanner.get_all_packages_modules(target, opt) - if package_modules_data then - -- append to sourcebatch - for _, package_module_data in table.orderpairs(package_modules_data) do - table.insert(sourcebatch.sourcefiles, package_module_data.file) - target:fileconfig_set(package_module_data.file, {external = true, defines = package_module_data.metadata.defines}) - end + -- append std module + local std_modules = compiler_support.get_stdmodules(target) + if std_modules then + table.join2(sourcebatch.sourcefiles, std_modules) + target:fileconfig_set(std_modules[1], {external = true}) + target:fileconfig_set(std_modules[2], {external = true}) + end + + -- extract packages modules dependencies + local package_modules_data = dependency_scanner.get_all_packages_modules(target, opt) + if package_modules_data then + -- append to sourcebatch + for _, package_module_data in table.orderpairs(package_modules_data) do + table.insert(sourcebatch.sourcefiles, package_module_data.file) + target:fileconfig_set(package_module_data.file, {external = true, defines = package_module_data.metadata.defines}) end + end - opt.batchjobs = false + opt.batchjobs = false - compiler_support.patch_sourcebatch(target, sourcebatch, opt) - local modules = dependency_scanner.get_module_dependencies(target, sourcebatch, opt) + compiler_support.patch_sourcebatch(target, sourcebatch, opt) + local modules = dependency_scanner.get_module_dependencies(target, sourcebatch, opt) + if not target:is_moduleonly() then -- avoid building non referenced modules sourcebatch.objectfiles = dependency_scanner.sort_modules_by_dependencies(target, sourcebatch.objectfiles, modules) @@ -181,12 +180,13 @@ rule("c++.build.modules.builder") -- cull external modules objectfile compiler_support.cull_objectfiles(target, modules, sourcebatch) - compiler_support.localcache():set2(target:name(), "c++.modules", modules) - compiler_support.localcache():save() else -- avoid duplicate linking of object files of non-module programs sourcebatch.objectfiles = {} end + + compiler_support.localcache():set2(target:name(), "c++.modules", modules) + compiler_support.localcache():save() else sourcebatch.sourcefiles = {} sourcebatch.objectfiles = {} @@ -211,48 +211,6 @@ rule("c++.build.modules.builder") end end) --- moduleonly -rule("c++.moduleonly") - add_deps("c++.build.modules.install") - set_extensions(".mpp", ".mxx", ".cppm", ".ixx", ".cpp") - - before_build(function(target) - if target:data("cxx.has_modules") then - import("modules_support.compiler_support") - import("modules_support.dependency_scanner") - - local sourcebatch = target:sourcebatches()["c++.moduleonly"] - - -- add target deps modules - if target:orderdeps() then - local deps_sourcefiles = dependency_scanner.get_targetdeps_modules(target) - if deps_sourcefiles then - table.join2(sourcebatch.sourcefiles, deps_sourcefiles) - end - end - - -- append std module - table.join2(sourcebatch.sourcefiles, compiler_support.get_stdmodules(target) or {}) - - -- extract packages modules dependencies - local package_modules_data = dependency_scanner.get_all_packages_modules(target, opt) - if package_modules_data then - -- append to sourcebatch - for _, package_module_data in table.orderpairs(package_modules_data) do - table.insert(sourcebatch.sourcefiles, package_module_data.file) - target:fileconfig_add(package_module_data.file, {external = true, defines = package_module_data.metadata.defines}) - end - end - - local opt = {batchjobs = true} - - compiler_support.patch_sourcebatch(target, sourcebatch, opt) - local modules = dependency_scanner.get_module_dependencies(target, sourcebatch, opt) - compiler_support.localcache():set2(target:name(), "c++.modules", modules) - compiler_support.localcache():save() - end - end) - -- install modules rule("c++.build.modules.install") set_extensions(".mpp", ".mxx", ".cppm", ".ixx") @@ -266,7 +224,7 @@ rule("c++.build.modules.install") if compiler_support.contains_modules(target) then local modules = compiler_support.localcache():get2(target:name(), "c++.modules") builder.generate_metadata(target, modules) - + compiler_support.install_module_target(target) end end) From eb1fd6ff416d62865fe34667284b79b780c1dfac Mon Sep 17 00:00:00 2001 From: ruki Date: Wed, 7 Feb 2024 11:20:10 +0800 Subject: [PATCH 17/40] Update xmake.lua --- tests/projects/c++/modules/link_order/xmake.lua | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/projects/c++/modules/link_order/xmake.lua b/tests/projects/c++/modules/link_order/xmake.lua index 5c7b8a236c8..4cb2af87f45 100644 --- a/tests/projects/c++/modules/link_order/xmake.lua +++ b/tests/projects/c++/modules/link_order/xmake.lua @@ -2,15 +2,11 @@ add_rules("mode.release", "mode.debug") set_languages("c++20") target("foo") - add_rules("c++") set_kind("moduleonly") - add_files("src/foo.mpp") target("bar") - add_rules("c++") set_kind("moduleonly") - add_files("src/bar.mpp") target("link_order_1") From 50ecef532fbd1e24845656b6422e6b65c85bd421 Mon Sep 17 00:00:00 2001 From: ruki Date: Wed, 7 Feb 2024 11:21:10 +0800 Subject: [PATCH 18/40] Update bar.mpp --- .../modules/packages/my-repo/packages/b/bar2/src/bar.mpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/src/bar.mpp b/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/src/bar.mpp index 2aaf4432e75..ee9fb2c7805 100644 --- a/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/src/bar.mpp +++ b/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/src/bar.mpp @@ -1,8 +1,8 @@ export module bar2; export namespace bar { -const char *hello2() { - return "Hello world"; -} + const char *hello2() { + return "Hello world"; + } } From 660d40f8344289caedd5273d6a00558b575110b0 Mon Sep 17 00:00:00 2001 From: ruki Date: Wed, 7 Feb 2024 11:21:40 +0800 Subject: [PATCH 19/40] Update xmake.lua --- .../c++/modules/packages/my-repo/packages/b/bar2/src/xmake.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/src/xmake.lua b/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/src/xmake.lua index 905c38a02ae..0324fa93188 100644 --- a/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/src/xmake.lua +++ b/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/src/xmake.lua @@ -3,5 +3,4 @@ set_languages("c++20") target("bar2") set_kind("moduleonly") - add_files("*.mpp") From ec17990db4b9c01d040d9c86c1518c7529380f3b Mon Sep 17 00:00:00 2001 From: ruki Date: Wed, 7 Feb 2024 11:22:40 +0800 Subject: [PATCH 20/40] Update xmake.lua --- tests/projects/c++/modules/user_headerunit2/a/xmake.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/projects/c++/modules/user_headerunit2/a/xmake.lua b/tests/projects/c++/modules/user_headerunit2/a/xmake.lua index 8d9a4cb8b1b..a3c5906fcef 100644 --- a/tests/projects/c++/modules/user_headerunit2/a/xmake.lua +++ b/tests/projects/c++/modules/user_headerunit2/a/xmake.lua @@ -1,6 +1,5 @@ target("a") - set_languages("cxxlatest") set_kind("moduleonly") - add_headerfiles("*.hpp") add_files("a.mpp") + set_languages("cxxlatest") From c732c99ed56183243230f555d775a2eac78ec3ca Mon Sep 17 00:00:00 2001 From: ruki Date: Wed, 7 Feb 2024 11:23:00 +0800 Subject: [PATCH 21/40] Update xmake.lua --- tests/projects/c++/modules/user_headerunit2/b/xmake.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/projects/c++/modules/user_headerunit2/b/xmake.lua b/tests/projects/c++/modules/user_headerunit2/b/xmake.lua index 5be8ae50bb0..7a353ec26a3 100644 --- a/tests/projects/c++/modules/user_headerunit2/b/xmake.lua +++ b/tests/projects/c++/modules/user_headerunit2/b/xmake.lua @@ -1,6 +1,5 @@ target("b") add_deps("a") - set_languages("cxxlatest") set_kind("moduleonly") - add_files("b.mpp") + set_languages("cxxlatest") From 384256cb7e9624cfe6af6055b0f1a55988c4f5f9 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 7 Feb 2024 11:52:40 +0100 Subject: [PATCH 22/40] improve moduleonly.lua --- xmake/actions/build/kinds/moduleonly.lua | 239 +---------------------- 1 file changed, 2 insertions(+), 237 deletions(-) diff --git a/xmake/actions/build/kinds/moduleonly.lua b/xmake/actions/build/kinds/moduleonly.lua index 1a5997712ad..d177b8b97d6 100644 --- a/xmake/actions/build/kinds/moduleonly.lua +++ b/xmake/actions/build/kinds/moduleonly.lua @@ -15,243 +15,8 @@ -- Copyright (C) 2015-present, TBOOX Open Source Group. -- -- @author ruki, Arthapz --- @file modules.lua +-- @file moduleonly.lua -- -- imports -import("core.base.option") -import("core.project.rule") -import("core.project.config") -import("core.project.project") -import("async.runjobs") -import("private.utils.batchcmds") -import("private.utils.rule_groups") - --- has scripts for the custom rule -function _has_scripts_for_rule(ruleinst, suffix) - - -- add batch jobs for xx_build_files - local scriptname = "build_files" .. (suffix and ("_" .. suffix) or "") - local script = ruleinst:script(scriptname) - if script then - return true - end - - -- add batch jobs for xx_build_file - scriptname = "build_file" .. (suffix and ("_" .. suffix) or "") - script = ruleinst:script(scriptname) - if script then - return true - end - - -- add batch jobs for xx_buildcmd_files - scriptname = "buildcmd_files" .. (suffix and ("_" .. suffix) or "") - script = ruleinst:script(scriptname) - if script then - return true - end - - -- add batch jobs for xx_buildcmd_file - scriptname = "buildcmd_file" .. (suffix and ("_" .. suffix) or "") - script = ruleinst:script(scriptname) - if script then - return true - end -end - --- has scripts for target -function _has_scripts_for_target(target, suffix) - local scriptname = "build_files" .. (suffix and ("_" .. suffix) or "") - local script = target:script(scriptname) - if script then - return true - else - scriptname = "build_file" .. (suffix and ("_" .. suffix) or "") - script = target:script(scriptname) - if script then - return true - end - end -end - --- has scripts for group -function _has_scripts_for_group(group, suffix) - for _, item in pairs(group) do - if item.target and _has_scripts_for_target(item.target, suffix) then - return true - end - if item.rule and _has_scripts_for_rule(item.rule, suffix) then - return true - end - end -end - --- add batch jobs for the custom rule -function _add_batchjobs_for_rule(batchjobs, rootjob, target, sourcebatch, suffix) - - -- get rule - local rulename = assert(sourcebatch.rulename, "unknown rule for sourcebatch!") - local ruleinst = rule_groups.get_rule(target, rulename) - - -- add batch jobs for xx_build_files - local scriptname = "build_files" .. (suffix and ("_" .. suffix) or "") - local script = ruleinst:script(scriptname) - if script then - if ruleinst:extraconf(scriptname, "batch") then - script(target, batchjobs, sourcebatch, {rootjob = rootjob, distcc = ruleinst:extraconf(scriptname, "distcc")}) - else - batchjobs:addjob("rule/" .. rulename .. "/" .. scriptname, function (index, total) - script(target, sourcebatch, {progress = (index * 100) / total}) - end, {rootjob = rootjob}) - end - end - - -- add batch jobs for xx_build_file - if not script then - scriptname = "build_file" .. (suffix and ("_" .. suffix) or "") - script = ruleinst:script(scriptname) - if script then - local sourcekind = sourcebatch.sourcekind - for _, sourcefile in ipairs(sourcebatch.sourcefiles) do - batchjobs:addjob(sourcefile, function (index, total) - script(target, sourcefile, {sourcekind = sourcekind, progress = (index * 100) / total}) - end, {rootjob = rootjob, distcc = ruleinst:extraconf(scriptname, "distcc")}) - end - end - end - - -- add batch jobs for xx_buildcmd_files - if not script then - scriptname = "buildcmd_files" .. (suffix and ("_" .. suffix) or "") - script = ruleinst:script(scriptname) - if script then - batchjobs:addjob("rule/" .. rulename .. "/" .. scriptname, function (index, total) - local batchcmds_ = batchcmds.new({target = target}) - local distcc = ruleinst:extraconf(scriptname, "distcc") - script(target, batchcmds_, sourcebatch, {progress = (index * 100) / total, distcc = distcc}) - batchcmds_:runcmds({changed = target:is_rebuilt(), dryrun = option.get("dry-run")}) - end, {rootjob = rootjob}) - end - end - - -- add batch jobs for xx_buildcmd_file - if not script then - scriptname = "buildcmd_file" .. (suffix and ("_" .. suffix) or "") - script = ruleinst:script(scriptname) - if script then - local sourcekind = sourcebatch.sourcekind - for _, sourcefile in ipairs(sourcebatch.sourcefiles) do - batchjobs:addjob(sourcefile, function (index, total) - local batchcmds_ = batchcmds.new({target = target}) - script(target, batchcmds_, sourcefile, {sourcekind = sourcekind, progress = (index * 100) / total}) - batchcmds_:runcmds({changed = target:is_rebuilt(), dryrun = option.get("dry-run")}) - end, {rootjob = rootjob, distcc = ruleinst:extraconf(scriptname, "distcc")}) - end - end - end -end - --- add batch jobs for target -function _add_batchjobs_for_target(batchjobs, rootjob, target, sourcebatch, suffix) - -- we just build sourcebatch with on_build_files scripts - -- - -- for example, c++.build and c++.build.modules.builder rules have same sourcefiles, - -- but we just build it for c++.build - -- - -- @see https://github.com/xmake-io/xmake/issues/3171 - -- - local rulename = sourcebatch.rulename - if rulename then - local ruleinst = rule_groups.get_rule(target, rulename) - if not ruleinst:script("build_file") and - not ruleinst:script("build_files") then - return - end - end - - -- add batch jobs - local scriptname = "build_files" .. (suffix and ("_" .. suffix) or "") - local script = target:script(scriptname) - if script then - if target:extraconf(scriptname, "batch") then - script(target, batchjobs, sourcebatch, {rootjob = rootjob, distcc = target:extraconf(scriptname, "distcc")}) - else - batchjobs:addjob(target:name() .. "/" .. scriptname, function (index, total) - script(target, sourcebatch, {progress = (index * 100) / total}) - end, {rootjob = rootjob}) - end - return true - else - scriptname = "build_file" .. (suffix and ("_" .. suffix) or "") - script = target:script(scriptname) - if script then - local sourcekind = sourcebatch.sourcekind - for _, sourcefile in ipairs(sourcebatch.sourcefiles) do - batchjobs:addjob(sourcefile, function (index, total) - script(target, sourcefile, {sourcekind = sourcekind, progress = (index * 100) / total}) - end, {rootjob = rootjob, distcc = target:extraconf(scriptname, "distcc")}) - end - return true - end - end -end - --- add batch jobs for group -function _add_batchjobs_for_group(batchjobs, rootjob, target, group, suffix) - for _, item in pairs(group) do - local sourcebatch = item.sourcebatch - if item.target then - _add_batchjobs_for_target(batchjobs, rootjob, target, sourcebatch, suffix) - end - -- override on_xxx script in target? we need to ignore rule scripts - if item.rule and (suffix or not _has_scripts_for_target(target, suffix)) then - _add_batchjobs_for_rule(batchjobs, rootjob, target, sourcebatch, suffix) - end - end -end - --- add batch jobs for building source files -function add_batchjobs_for_sourcefiles(batchjobs, rootjob, target, sourcebatches) - - -- build sourcebatch groups first - local groups = rule_groups.build_sourcebatch_groups(target, sourcebatches) - - -- add batch jobs for build_after - local groups_root - local groups_leaf = rootjob - for idx, group in ipairs(groups) do - if _has_scripts_for_group(group, "after") then - batchjobs:group_enter(target:name() .. "/after_build_files" .. idx) - _add_batchjobs_for_group(batchjobs, groups_leaf, target, group, "after") - groups_leaf = batchjobs:group_leave() or groups_leaf - groups_root = groups_root or groups_leaf - end - end - - -- add batch jobs for build - for idx, group in ipairs(groups) do - if _has_scripts_for_group(group) then - batchjobs:group_enter(target:name() .. "/build_files" .. idx) - _add_batchjobs_for_group(batchjobs, groups_leaf, target, group) - groups_leaf = batchjobs:group_leave() or groups_leaf - groups_root = groups_root or groups_leaf - end - end - - -- add batch jobs for build_before - for idx, group in ipairs(groups) do - if _has_scripts_for_group(group, "before") then - batchjobs:group_enter(target:name() .. "/before_build_files" .. idx) - _add_batchjobs_for_group(batchjobs, groups_leaf, target, group, "before") - groups_leaf = batchjobs:group_leave() or groups_leaf - groups_root = groups_root or groups_leaf - end - end - return groups_leaf, groups_root or groups_leaf -end - --- add batch jobs for generating modules deps files -function main(batchjobs, rootjob, target) - return add_batchjobs_for_sourcefiles(batchjobs, rootjob, target, target:sourcebatches()) -end - +inherit("object") From d98db4c10802a503dd824d0dcb15bacb76d29749 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 7 Feb 2024 11:53:34 +0100 Subject: [PATCH 23/40] use table.orderpairs for generate_metadata --- xmake/rules/c++/modules/modules_support/builder.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/xmake/rules/c++/modules/modules_support/builder.lua b/xmake/rules/c++/modules/modules_support/builder.lua index 768c337ce1d..936f904142e 100644 --- a/xmake/rules/c++/modules/modules_support/builder.lua +++ b/xmake/rules/c++/modules/modules_support/builder.lua @@ -287,8 +287,7 @@ end function generate_metadata(target, modules) local public_modules - - for _, module in pairs(modules) do + for _, module in table.orderpairs(modules) do local _, _, cppfile = compiler_support.get_provided_module(module) local fileconfig = target:fileconfig(cppfile) local public = fileconfig and fileconfig.public From 618f75184179eafa6ae8bcd4c9e81acaeebc6b53 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 7 Feb 2024 11:54:53 +0100 Subject: [PATCH 24/40] use target:is_binary instead of target:kind() == "binary" --- xmake/rules/c++/modules/modules_support/compiler_support.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/xmake/rules/c++/modules/modules_support/compiler_support.lua b/xmake/rules/c++/modules/modules_support/compiler_support.lua index d9d849454f1..d11e833fd83 100644 --- a/xmake/rules/c++/modules/modules_support/compiler_support.lua +++ b/xmake/rules/c++/modules/modules_support/compiler_support.lua @@ -67,7 +67,7 @@ end function cull_objectfiles(target, modules, sourcebatch) -- don't cull for executables - if target:kind() == "binary" then + if target:is_binary() then return end @@ -76,7 +76,6 @@ function cull_objectfiles(target, modules, sourcebatch) local objectfile = target:objectfile(sourcefile) local module = modules[objectfile] local _, provide, _ = get_provided_module(module) - if provide then local fileconfig = target:fileconfig(sourcefile) local public = fileconfig and fileconfig.public From dee7608d9e53e040803fdaff4e87561ac3932943 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 7 Feb 2024 11:55:43 +0100 Subject: [PATCH 25/40] fix test --- .../c++/modules/packages/my-repo/packages/b/bar2/xmake.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/xmake.lua b/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/xmake.lua index 343a52e0215..ffa208234fb 100644 --- a/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/xmake.lua +++ b/tests/projects/c++/modules/packages/my-repo/packages/b/bar2/xmake.lua @@ -1,5 +1,5 @@ package("bar2") - set_kind("moduleonly") + set_kind("library") set_sourcedir(path.join(os.scriptdir(), "src")) on_install(function(package) From 348a74ac9d4eeb464e8f890c453e39cb77ab2446 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 7 Feb 2024 12:09:32 +0100 Subject: [PATCH 26/40] update vsxmake to handle moduleonly target kind --- xmake/plugins/project/vsxmake/getinfo.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xmake/plugins/project/vsxmake/getinfo.lua b/xmake/plugins/project/vsxmake/getinfo.lua index e992c1bd488..af88b51f6c7 100644 --- a/xmake/plugins/project/vsxmake/getinfo.lua +++ b/xmake/plugins/project/vsxmake/getinfo.lua @@ -154,7 +154,7 @@ function _make_targetinfo(mode, arch, target) -- fix c++17 to cxx17 for Xmake.props targetinfo.languages = targetinfo.languages:replace("c++", "cxx", {plain = true}) end - if target:is_phony() or target:is_headeronly() then + if target:is_phony() or target:is_headeronly() or target:is_moduleonly() then return targetinfo end From 56ba14af708baf74759e825052d2b41024360ea1 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 7 Feb 2024 13:12:40 +0100 Subject: [PATCH 27/40] fix msvc batchcmds --- xmake/rules/c++/modules/modules_support/msvc/builder.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xmake/rules/c++/modules/modules_support/msvc/builder.lua b/xmake/rules/c++/modules/modules_support/msvc/builder.lua index 8c451f69912..fad85357701 100644 --- a/xmake/rules/c++/modules/modules_support/msvc/builder.lua +++ b/xmake/rules/c++/modules/modules_support/msvc/builder.lua @@ -278,7 +278,7 @@ function make_module_buildjobs(target, batchjobs, job_name, deps, opt) end -- build module file for batchcmds -function make_module_buildcmds(target, batchcmds, should_build, mark_build, opt) +function make_module_buildcmds(target, batchcmds, opt) local name, provide, _ = compiler_support.get_provided_module(opt.module) local bmifile = provide and compiler_support.get_bmi_path(provide.bmi) From 6f520cf8320ddb4424560b9094fb74844dd8e40b Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 7 Feb 2024 13:13:15 +0100 Subject: [PATCH 28/40] improve moduleonly vsxmake --- xmake/scripts/vsxmake/vsproj/Xmake.props | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/xmake/scripts/vsxmake/vsproj/Xmake.props b/xmake/scripts/vsxmake/vsproj/Xmake.props index 3e3a3329825..990a9505684 100644 --- a/xmake/scripts/vsxmake/vsproj/Xmake.props +++ b/xmake/scripts/vsxmake/vsproj/Xmake.props @@ -94,6 +94,11 @@ Unknown + + + Unknown + + From 6e3d6c4cf7166e093ba77fac1d221ff6daef1792 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 7 Feb 2024 16:56:02 +0100 Subject: [PATCH 29/40] update vs project generator to support moduleonly target kind --- xmake/plugins/project/vstudio/impl/vs201x.lua | 20 ++++++----- .../project/vstudio/impl/vs201x_vcxproj.lua | 35 ++++++++++++++----- .../modules_support/dependency_scanner.lua | 1 + .../modules/modules_support/msvc/builder.lua | 6 ++-- xmake/rules/c++/modules/xmake.lua | 2 ++ 5 files changed, 44 insertions(+), 20 deletions(-) diff --git a/xmake/plugins/project/vstudio/impl/vs201x.lua b/xmake/plugins/project/vstudio/impl/vs201x.lua index a8b48dada5f..d67a3f7a393 100644 --- a/xmake/plugins/project/vstudio/impl/vs201x.lua +++ b/xmake/plugins/project/vstudio/impl/vs201x.lua @@ -185,7 +185,6 @@ function _make_custom_commands_for_objectrules(commands, target, sourcebatch, vc scriptname = "buildcmd_file" .. (suffix and ("_" .. suffix) or "") script = ruleinst:script(scriptname) if script then - local sourcekind = sourcebatch.sourcekind for _, sourcefile in ipairs(sourcebatch.sourcefiles) do local batchcmds_ = batchcmds.new({target = target}) script(target, batchcmds_, sourcefile, {}) @@ -219,7 +218,7 @@ function _make_custom_commands(target, vcxprojdir) for _, sourcebatch in table.orderpairs(sourcebatches) do local rulename = sourcebatch.rulename local sourcekind = sourcebatch.sourcekind - if rulename ~= "c.build" and rulename ~= "c++.build" and rulename ~= "asm.build" and rulename ~= "cuda.build" and sourcekind ~= "mrc" then + if rulename ~= "c.build" and rulename ~= "c++.build" and not rulename:startswith("c++.build.modules") and rulename ~= "asm.build" and rulename ~= "cuda.build" and sourcekind ~= "mrc" then _make_custom_commands_for_objectrules(commands, target, sourcebatch, vcxprojdir, "before") _make_custom_commands_for_objectrules(commands, target, sourcebatch, vcxprojdir, nil) _make_custom_commands_for_objectrules(commands, target, sourcebatch, vcxprojdir, "after") @@ -256,6 +255,9 @@ function _make_targetinfo(mode, arch, target, vcxprojdir) -- save symbols targetinfo.symbols = target:get("symbols") + -- has modules + targetinfo.has_modules = target:data("cxx.has_modules") + -- save target kind targetinfo.targetkind = target:kind() if target:is_phony() or target:is_headeronly() then @@ -268,9 +270,6 @@ function _make_targetinfo(mode, arch, target, vcxprojdir) -- save symbol file targetinfo.symbolfile = target:symbolfile() - -- save sourcebatches - targetinfo.sourcebatches = target:sourcebatches() - -- save sourcekinds targetinfo.sourcekinds = target:sourcekinds() @@ -289,9 +288,9 @@ function _make_targetinfo(mode, arch, target, vcxprojdir) local sourcekind = sourcebatch.sourcekind local rulename = sourcebatch.rulename if sourcekind then - for idx, sourcefile in ipairs(sourcebatch.sourcefiles) do + for _, sourcefile in ipairs(sourcebatch.sourcefiles) do local compflags = compiler.compflags(sourcefile, {target = target, sourcekind = sourcekind}) - if not firstcompflags and (rulename == "c.build" or rulename == "c++.build" or rulename == "cuda.build") then + if not firstcompflags and (rulename == "c.build" or rulename == "c++.build" or rulename == "c++.build.modules" or rulename == "cuda.build") then firstcompflags = compflags end targetinfo.compflags[sourcefile] = compflags @@ -309,8 +308,11 @@ function _make_targetinfo(mode, arch, target, vcxprojdir) end end + -- save sourcebatches + targetinfo.sourcebatches = target:sourcebatches() + -- save linker flags - local linkflags = linker.linkflags(target:kind(), target:sourcekinds(), {target = target}) + local linkflags = linker.linkflags(target:is_moduleonly() and 'static' or target:kind(), target:sourcekinds(), {target = target}) targetinfo.linkflags = linkflags if table.contains(target:sourcekinds(), "cu") then @@ -323,7 +325,7 @@ function _make_targetinfo(mode, arch, target, vcxprojdir) end -- save execution dir (when executed from VS) - targetinfo.rundir = target:rundir() + targetinfo.rundir = target:is_moduleonly() and "" or target:rundir() -- save runenvs local targetrunenvs = {} diff --git a/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua b/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua index f5bb88d738c..56850bbe3cf 100644 --- a/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua +++ b/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua @@ -242,6 +242,7 @@ function _make_configurations(vcxprojfile, vsinfo, target) binary = "Application" , shared = "DynamicLibrary" , static = "StaticLibrary" + , moduleonly = "StaticLibrary" -- emulate moduleonly with staticlib } -- make ProjectConfigurations @@ -307,8 +308,10 @@ function _make_configurations(vcxprojfile, vsinfo, target) vcxprojfile:enter("", targetinfo.mode, targetinfo.arch) vcxprojfile:print("%s\\", _make_dirs(targetinfo.targetdir, target.project_dir)) vcxprojfile:print("%s\\", _make_dirs(targetinfo.objectdir, target.project_dir)) - vcxprojfile:print("%s", path.basename(targetinfo.targetfile)) - vcxprojfile:print("%s", path.extension(targetinfo.targetfile)) + if targetinfo.targetfile then + vcxprojfile:print("%s", path.basename(targetinfo.targetfile)) + vcxprojfile:print("%s", path.extension(targetinfo.targetfile)) + end if target.kind == "binary" then vcxprojfile:print("true") @@ -723,7 +726,7 @@ endlocal & call :xmErrorLevel %errorlevel% & goto :xmDone exit /b %1 :xmDone if %errorlevel% neq 0 goto :VCEnd]] - vcxprojfile:print("%s", cmdstr) + vcxprojfile:print("%s", cmdstr:replace("<", " <"):replace(">", ">"):replace("/Fo ", "/Fo")) if suffix == "after" or suffix == "after_link" then vcxprojfile:print("") elseif suffix == "before" then @@ -742,12 +745,12 @@ end -- make common item function _make_common_item(vcxprojfile, vsinfo, target, targetinfo) - -- init the linker kinds local linkerkinds = { binary = "Link" , static = "Lib" + , moduleonly = "Lib" -- emulate moduleonly with staticlib , shared = "Link" } if not linkerkinds[targetinfo.targetkind] then @@ -892,6 +895,10 @@ function _make_common_item(vcxprojfile, vsinfo, target, targetinfo) vcxprojfile:print("%s", cstandard) end + if targetinfo.has_modules then + vcxprojfile:enter("true") + end + -- use c or c++ precompiled header local pcheader = target.pcxxheader or target.pcheader if pcheader then @@ -959,9 +966,8 @@ function _build_common_items(vsinfo, target) for _, sourcebatch in pairs(targetinfo.sourcebatches) do local sourcekind = sourcebatch.sourcekind local rulename = sourcebatch.rulename - if (rulename == "c.build" or rulename == "c++.build" or rulename == "asm.build" or sourcekind == "mrc") then + if (rulename == "c.build" or rulename == "c++.build" or rulename == "c++.build.modules" or rulename == "asm.build" or sourcekind == "mrc") then for _, sourcefile in ipairs(sourcebatch.sourcefiles) do - -- make compiler flags local flags = _make_compflags(sourcefile, targetinfo, target.project_dir) @@ -1028,7 +1034,7 @@ function _build_common_items(vsinfo, target) for _, sourcefile in ipairs(sourcebatch.sourcefiles) do sourceflags[sourcefile] = targetinfo.sourceflags[sourcefile] end - elseif rulename == "c.build" or rulename == "c++.build" then -- sourcekind maybe bind multiple rules, e.g. c++modules + elseif rulename == "c.build" or rulename == "c++.build" or rulename == "c++.build.modules" then -- sourcekind maybe bind multiple rules, e.g. c++modules for _, sourcefile in ipairs(sourcebatch.sourcefiles) do local flags = targetinfo.sourceflags[sourcefile] local otherflags = {} @@ -1062,7 +1068,7 @@ function _make_common_items(vcxprojfile, vsinfo, target) -- for each mode and arch for _, targetinfo in ipairs(target.info) do -- make common item - _make_common_item(vcxprojfile, vsinfo, target, targetinfo, target.project_dir) + _make_common_item(vcxprojfile, vsinfo, target, targetinfo) end end @@ -1325,6 +1331,19 @@ function _make_source_files(vcxprojfile, vsinfo, target) sourceinfos[sourcefile] = sourceinfos[sourcefile] or {} table.insert(sourceinfos[sourcefile], {targetinfo = targetinfo, mode = targetinfo.mode, arch = targetinfo.arch, sourcekind = sourcekind, objectfile = objectfile, flags = flags, compargv = targetinfo.compargvs[sourcefile]}) end + elseif rulename == "c++.build.modules" then + local builder_batch = targetinfo.sourcebatches["c++.build.modules.builder"] + table.sort(builder_batch.objectfiles) + local objectfiles = builder_batch.objectfiles + for idx, sourcefile in ipairs(sourcebatch.sourcefiles) do + local is_named_module = table.contains(builder_batch.sourcefiles, sourcefile) + if is_named_module then + local objectfile = objectfiles[idx] + local flags = targetinfo.sourceflags[sourcefile] + sourceinfos[sourcefile] = sourceinfos[sourcefile] or {} + table.insert(sourceinfos[sourcefile], {targetinfo = targetinfo, mode = targetinfo.mode, arch = targetinfo.arch, sourcekind = "cxx", objectfile = objectfile, flags = flags, compargv = targetinfo.compargvs[sourcefile]}) + end + end end 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 0b02292ef85..1dc55bcb8e6 100644 --- a/xmake/rules/c++/modules/modules_support/dependency_scanner.lua +++ b/xmake/rules/c++/modules/modules_support/dependency_scanner.lua @@ -224,6 +224,7 @@ function _generate_dependencies(target, sourcebatch, opt) end -- get module dependencies function get_module_dependencies(target, sourcebatch, opt) + print(sourcebatch) local cachekey = target:name() .. "/" .. sourcebatch.rulename local modules = compiler_support.memcache():get2("modules", cachekey) if modules == nil or opt.regenerate then diff --git a/xmake/rules/c++/modules/modules_support/msvc/builder.lua b/xmake/rules/c++/modules/modules_support/msvc/builder.lua index fad85357701..015e04db5fb 100644 --- a/xmake/rules/c++/modules/modules_support/msvc/builder.lua +++ b/xmake/rules/c++/modules/modules_support/msvc/builder.lua @@ -41,7 +41,7 @@ function _make_modulebuildflags(target, provide, bmifile, opt) local flags if provide then -- named module - flags = table.join({"-TP", ifcoutputflag, bmifile, provide.interface and interfaceflag or internalpartitionflag}, ifconly or {}) + flags = table.join({"-TP", ifcoutputflag, path(bmifile), provide.interface and interfaceflag or internalpartitionflag}, ifconly or {}) else flags = {"-TP"} end @@ -102,8 +102,8 @@ function _batchcmds_compile(batchcmds, target, flags, sourcefile, outputfile) opt = opt or {} local compinst = target:compiler("cxx") local compflags = compinst:compflags({sourcefile = sourcefile, target = target}) - flags = table.join("-c", compflags or {}, flags, {"/Fo", outputfile, sourcefile}) - batchcmds:compilev(flags, {compiler = compinst, sourcekind = "cxx"}) + flags = table.join(compflags or {}, flags) + batchcmds:compile(sourcefile, outputfile, {sourcekind = "cxx", compflags = flags}) end -- get module requires flags diff --git a/xmake/rules/c++/modules/xmake.lua b/xmake/rules/c++/modules/xmake.lua index 13fb405d854..922841cd1d0 100644 --- a/xmake/rules/c++/modules/xmake.lua +++ b/xmake/rules/c++/modules/xmake.lua @@ -101,6 +101,7 @@ rule("c++.build.modules.builder") end end + opt = opt or {} opt.batchjobs = true compiler_support.patch_sourcebatch(target, sourcebatch, opt) @@ -163,6 +164,7 @@ rule("c++.build.modules.builder") end end + opt = opt or {} opt.batchjobs = false compiler_support.patch_sourcebatch(target, sourcebatch, opt) From 5d088711452a880de0a101e1d1759207eac1cf68 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 7 Feb 2024 18:35:11 +0100 Subject: [PATCH 30/40] cleanup --- xmake/rules/c++/modules/modules_support/dependency_scanner.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/xmake/rules/c++/modules/modules_support/dependency_scanner.lua b/xmake/rules/c++/modules/modules_support/dependency_scanner.lua index 1dc55bcb8e6..0b02292ef85 100644 --- a/xmake/rules/c++/modules/modules_support/dependency_scanner.lua +++ b/xmake/rules/c++/modules/modules_support/dependency_scanner.lua @@ -224,7 +224,6 @@ function _generate_dependencies(target, sourcebatch, opt) end -- get module dependencies function get_module_dependencies(target, sourcebatch, opt) - print(sourcebatch) local cachekey = target:name() .. "/" .. sourcebatch.rulename local modules = compiler_support.memcache():get2("modules", cachekey) if modules == nil or opt.regenerate then From e721aae44e6b8fbfd8b6434bffbdf5279259af96 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 7 Feb 2024 18:34:46 +0100 Subject: [PATCH 31/40] implement basic cmake support for moduleonly --- xmake/plugins/project/cmake/cmakelists.lua | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/xmake/plugins/project/cmake/cmakelists.lua b/xmake/plugins/project/cmake/cmakelists.lua index a91328d54e1..723b80b33ec 100644 --- a/xmake/plugins/project/cmake/cmakelists.lua +++ b/xmake/plugins/project/cmake/cmakelists.lua @@ -323,6 +323,11 @@ function _add_target_headeronly(cmakelists, target) cmakelists:print("add_library(%s INTERFACE)", target:name()) end +-- add target: headeronly +function _add_target_moduleonly(cmakelists, target) + cmakelists:print("add_library(%s INTERFACE)", target:name()) +end + -- add target dependencies function _add_target_dependencies(cmakelists, target) local deps = target:get("deps") @@ -1003,8 +1008,8 @@ function _add_target(cmakelists, target, outputdir) _add_target_headeronly(cmakelists, target) _add_target_include_directories(cmakelists, target, outputdir) return - elseif targetkind == 'moduleonly' then - raise("target kind moduleonly is currently not supported for cmakelists") + elseif targetkind == 'headeronly' then + _add_target_moduleonly(cmakelists, target) else raise("unknown target kind %s", target:kind()) end From 955f2bb283e338e10cb3616c25ed41db9103d6f2 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 8 Feb 2024 14:30:37 +0100 Subject: [PATCH 32/40] support ProjectReferences for VS project generator --- xmake/plugins/project/vstudio/impl/vs201x.lua | 7 +++++++ .../project/vstudio/impl/vs201x_vcxproj.lua | 14 ++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/xmake/plugins/project/vstudio/impl/vs201x.lua b/xmake/plugins/project/vstudio/impl/vs201x.lua index d67a3f7a393..b3c6f84c251 100644 --- a/xmake/plugins/project/vstudio/impl/vs201x.lua +++ b/xmake/plugins/project/vstudio/impl/vs201x.lua @@ -546,6 +546,13 @@ function make(outputdir, vsinfo) -- save file groups _target.filegroups = table.unique(table.join(_target.filegroups or {}, target:get("filegroups"))) + -- save references to deps + for _, dep in ipairs(target:orderdeps()) do + _target.deps = _target.deps or {} + local dep_name = dep:name() + _target.deps[dep_name] = path.relative(path.join(vsinfo.solution_dir, dep_name, dep_name .. ".vcxproj"), _target.project_dir) + end + for filegroup, groupconf in pairs(target:extraconf("filegroups")) do _target.filegroups_extraconf = _target.filegroups_extraconf or {} local mergedconf = _target.filegroups_extraconf[filegroup] diff --git a/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua b/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua index 56850bbe3cf..ee21e88b193 100644 --- a/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua +++ b/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua @@ -218,6 +218,17 @@ function _make_header(vcxprojfile, vsinfo) vcxprojfile:enter("", assert(vsinfo.project_version)) end +-- make references +function _make_references(vcxprojfile, vsinfo, target) + vcxprojfile:print("") + for dep_name, dep_vcxprojfile in pairs(target.deps) do + vcxprojfile:print("", dep_vcxprojfile) + vcxprojfile:print("{%s}", hash.uuid4(dep_name)) + vcxprojfile:print("") + end + vcxprojfile:print("") +end + -- make tailer function _make_tailer(vcxprojfile, vsinfo, target) vcxprojfile:print("") @@ -1405,6 +1416,9 @@ function make(vsinfo, target) -- make source files _make_source_files(vcxprojfile, vsinfo, target) + -- make deps references + _make_references(vcxprojfile, vsinfo, target) + -- make tailer _make_tailer(vcxprojfile, vsinfo, target) From b23959e2e56181f021f4f41dd7aaedc3bd8197f3 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 8 Feb 2024 14:47:39 +0100 Subject: [PATCH 33/40] fix msvc batchcmds --- xmake/rules/c++/modules/modules_support/msvc/builder.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xmake/rules/c++/modules/modules_support/msvc/builder.lua b/xmake/rules/c++/modules/modules_support/msvc/builder.lua index 015e04db5fb..c703de47827 100644 --- a/xmake/rules/c++/modules/modules_support/msvc/builder.lua +++ b/xmake/rules/c++/modules/modules_support/msvc/builder.lua @@ -38,6 +38,7 @@ function _make_modulebuildflags(target, provide, bmifile, opt) local interfaceflag = compiler_support.get_interfaceflag(target) local internalpartitionflag = compiler_support.get_internalpartitionflag(target) local ifconly = (not opt.build_objectfile and ifconlyflag) + print("AAAAAAAAAAAAAAAA", bmifile, opt.build_objectfile) local flags if provide then -- named module @@ -313,7 +314,7 @@ function make_module_buildcmds(target, batchcmds, opt) local public = fileconfig and fileconfig.public local external = fileconfig and fileconfig.external local build_objectfile = target:kind() == "binary" or (not public and not external) - local flags = _make_modulebuildflags(target, provide, bmifile, opt.cppfile, {batchcmds = true, build_objectfile = build_objectfile}) + local flags = _make_modulebuildflags(target, provide, bmifile, {build_objectfile = build_objectfile}) _batchcmds_compile(batchcmds, target, flags, opt.cppfile, opt.objectfile) else batchcmds:rm(opt.objectfile) -- force rebuild for .cpp files From 93545500fa6f1ac8bb9980d3837ca5b6847b0ebb Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 8 Feb 2024 14:48:08 +0100 Subject: [PATCH 34/40] fix module compilation for CMake --- xmake/plugins/project/cmake/cmakelists.lua | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/xmake/plugins/project/cmake/cmakelists.lua b/xmake/plugins/project/cmake/cmakelists.lua index 723b80b33ec..30ba57d660f 100644 --- a/xmake/plugins/project/cmake/cmakelists.lua +++ b/xmake/plugins/project/cmake/cmakelists.lua @@ -68,6 +68,7 @@ end function _escape_path(filepath) if is_host("windows") then filepath = filepath:gsub('\\', '/') + filepath = filepath:gsub(' ', '\\ ') end return filepath end @@ -345,8 +346,8 @@ function _add_target_sources(cmakelists, target, outputdir) local has_cuda = false cmakelists:print("target_sources(%s PRIVATE", target:name()) local sourcebatches = target:sourcebatches() - for _, sourcebatch in table.orderpairs(sourcebatches) do - if _sourcebatch_is_built(sourcebatch) then + for name, sourcebatch in table.orderpairs(sourcebatches) do + if _sourcebatch_is_built(sourcebatch) and not name:startswith("c++.build.modules") then for _, sourcefile in ipairs(sourcebatch.sourcefiles) do cmakelists:print(" " .. _get_relative_unix_path(sourcefile, outputdir)) end @@ -899,6 +900,7 @@ function _get_command_string(cmd, outputdir) table.insert(argv, _translate_flag(v, outputdir)) end local command = _escape_path(cmd.program) .. " " .. os.args(argv) + print(cmd.program, _escape_path(cmd.program)) if opt and opt.curdir then command = "${CMAKE_COMMAND} -E chdir " .. _get_relative_unix_path_to_cmake(opt.curdir, outputdir) .. " " .. command end @@ -1008,7 +1010,7 @@ function _add_target(cmakelists, target, outputdir) _add_target_headeronly(cmakelists, target) _add_target_include_directories(cmakelists, target, outputdir) return - elseif targetkind == 'headeronly' then + elseif targetkind == 'moduleonly' then _add_target_moduleonly(cmakelists, target) else raise("unknown target kind %s", target:kind()) From 14a186c9a2ee9df85621361af610fcf4dc96befe Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 8 Feb 2024 14:50:18 +0100 Subject: [PATCH 35/40] fix CMake moduleonly support --- xmake/plugins/project/cmake/cmakelists.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xmake/plugins/project/cmake/cmakelists.lua b/xmake/plugins/project/cmake/cmakelists.lua index 30ba57d660f..2fd0eb57a84 100644 --- a/xmake/plugins/project/cmake/cmakelists.lua +++ b/xmake/plugins/project/cmake/cmakelists.lua @@ -326,7 +326,7 @@ end -- add target: headeronly function _add_target_moduleonly(cmakelists, target) - cmakelists:print("add_library(%s INTERFACE)", target:name()) + cmakelists:print("add_custom_target(%s)", target:name()) end -- add target dependencies @@ -1012,6 +1012,7 @@ function _add_target(cmakelists, target, outputdir) return elseif targetkind == 'moduleonly' then _add_target_moduleonly(cmakelists, target) + return else raise("unknown target kind %s", target:kind()) end From 7b6d069488f8d7418f01e7f8f87dc34d0b502cd6 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 8 Feb 2024 14:50:44 +0100 Subject: [PATCH 36/40] cleanup --- xmake/rules/c++/modules/modules_support/msvc/builder.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/xmake/rules/c++/modules/modules_support/msvc/builder.lua b/xmake/rules/c++/modules/modules_support/msvc/builder.lua index c703de47827..3fc86b36975 100644 --- a/xmake/rules/c++/modules/modules_support/msvc/builder.lua +++ b/xmake/rules/c++/modules/modules_support/msvc/builder.lua @@ -38,7 +38,6 @@ function _make_modulebuildflags(target, provide, bmifile, opt) local interfaceflag = compiler_support.get_interfaceflag(target) local internalpartitionflag = compiler_support.get_internalpartitionflag(target) local ifconly = (not opt.build_objectfile and ifconlyflag) - print("AAAAAAAAAAAAAAAA", bmifile, opt.build_objectfile) local flags if provide then -- named module From b0819c9bc05ed539d6f84f07eb8bf2ee89b1e40c Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 8 Feb 2024 15:17:48 +0100 Subject: [PATCH 37/40] support uninstalling modules --- xmake/modules/target/action/uninstall/main.lua | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/xmake/modules/target/action/uninstall/main.lua b/xmake/modules/target/action/uninstall/main.lua index cc5feb3ac6c..daa23917cf8 100644 --- a/xmake/modules/target/action/uninstall/main.lua +++ b/xmake/modules/target/action/uninstall/main.lua @@ -26,6 +26,12 @@ function _uninstall_files(target) end end +-- uninstall modules +function _uninstall_modules(target, opt) + local moduledir = path.join(target:installdir(), opt and opt.moduledir or "modules") + os.vrm(moduledir) +end + -- the builtin uninstall main entry function main(target, opt) @@ -47,6 +53,9 @@ function main(target, opt) end end + -- remove modules + _uninstall_modules(target, opt) + -- uninstall the other files _uninstall_files(target) end From 3af5f89b0c56d83e31a645c5a9ff440f900d6a58 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 8 Feb 2024 16:24:35 +0100 Subject: [PATCH 38/40] add support of xmake package for modules --- xmake/actions/package/local/main.lua | 102 +++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/xmake/actions/package/local/main.lua b/xmake/actions/package/local/main.lua index 90495dae484..858059ac1d6 100644 --- a/xmake/actions/package/local/main.lua +++ b/xmake/actions/package/local/main.lua @@ -95,6 +95,7 @@ function _package_library(target) local binarydir = path.join(packagedir, target:plat(), target:arch(), config.mode(), "bin") local librarydir = path.join(packagedir, target:plat(), target:arch(), config.mode(), "lib") local headerdir = path.join(packagedir, target:plat(), target:arch(), config.mode(), "include") + local modulesdir = path.join(packagedir, target:plat(), target:arch(), config.mode(), "modules") -- copy the library file to the output directory local targetfile = target:targetfile() @@ -142,6 +143,32 @@ function _package_library(target) end end + -- copy modules + if target:data("cxx.has_modules") then + import(".rules.c++.modules.modules_support.compiler_support") + import(".rules.c++.modules.modules_support.builder") + + local modules = compiler_support.localcache():get2(target:name(), "c++.modules") + builder.generate_metadata(target, modules) + + local sourcebatch = target:sourcebatches()["c++.build.modules.install"] + if sourcebatch and sourcebatch.sourcefiles then + for _, sourcefile in ipairs(sourcebatch.sourcefiles) do + local fileconfig = target:fileconfig(sourcefile) + local install = fileconfig and fileconfig.public or false + if install then + local modulehash = compiler_support.get_modulehash(target, sourcefile) + local prefixdir = path.join(modulesdir, modulehash) + os.vcp(sourcefile, path.join(prefixdir, path.filename(sourcefile))) + local metafile = compiler_support.get_metafile(target, sourcefile) + if os.exists(metafile) then + os.vcp(metafile, path.join(prefixdir, path.filename(metafile))) + end + end + end + end + end + -- generate xmake.lua local file = io.open(path.join(packagedir, "xmake.lua"), "w") if file then @@ -261,6 +288,80 @@ function _package_headeronly(target) print("package(%s): %s generated", packagename, packagedir) end +function _package_moduleonly(target) + import(".rules.c++.modules.modules_support.compiler_support") + import(".rules.c++.modules.modules_support.builder") + + -- get the output directory + local packagedir = target:packagedir() + local packagename = target:name():lower() + local headerdir = path.join(packagedir, target:plat(), target:arch(), config.mode(), "include") + local modulesdir = path.join(packagedir, target:plat(), target:arch(), config.mode(), "modules") + + local modules = compiler_support.localcache():get2(target:name(), "c++.modules") + builder.generate_metadata(target, modules) + + -- copy headers + local srcheaders, dstheaders = target:headerfiles(headerdir) + if srcheaders and dstheaders then + local i = 1 + for _, srcheader in ipairs(srcheaders) do + local dstheader = dstheaders[i] + if dstheader then + os.vcp(srcheader, dstheader) + end + i = i + 1 + end + end + + -- copy modules + local sourcebatch = target:sourcebatches()["c++.build.modules.install"] + if sourcebatch and sourcebatch.sourcefiles then + for _, sourcefile in ipairs(sourcebatch.sourcefiles) do + local modulehash = compiler_support.get_modulehash(target, sourcefile) + local prefixdir = path.join(modulesdir, modulehash) + os.vcp(sourcefile, path.join(prefixdir, path.filename(sourcefile))) + local metafile = compiler_support.get_metafile(target, sourcefile) + if os.exists(metafile) then + os.vcp(metafile, path.join(prefixdir, path.filename(metafile))) + end + end + end + + -- generate xmake.lua + local file = io.open(path.join(packagedir, "xmake.lua"), "w") + if file then + local deps = _get_librarydeps(target) + file:print("package(\"%s\")", packagename) + local homepage = option.get("homepage") + if homepage then + file:print(" set_homepage(\"%s\")", homepage) + end + local description = option.get("description") or ("The " .. packagename .. " package") + file:print(" set_description(\"%s\")", description) + if target:license() then + file:print(" set_license(\"%s\")", target:license()) + end + if #deps > 0 then + file:print(" add_deps(\"%s\")", table.concat(deps, "\", \"")) + end + file:print("") + file:print([[ + on_load(function (package) + package:set("installdir", path.join(os.scriptdir(), package:plat(), package:arch(), package:mode())) + end) + + on_fetch(function (package) + local result = {} + result.includedirs = package:installdir("include") + return result + end)]]) + file:close() + end + + -- show tips + print("package(%s): %s generated", packagename, packagedir) +end -- do package target function _do_package_target(target) if not target:is_phony() then @@ -269,6 +370,7 @@ function _do_package_target(target) binary = _package_binary , static = _package_library , shared = _package_library + , moduleonly = _package_moduleonly , headeronly = _package_headeronly } local kind = target:kind() From 0550446f4dc00728801f233f0e815aafbe521ac8 Mon Sep 17 00:00:00 2001 From: ruki Date: Sun, 11 Feb 2024 12:40:01 +0800 Subject: [PATCH 39/40] Update cmakelists.lua --- xmake/plugins/project/cmake/cmakelists.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/xmake/plugins/project/cmake/cmakelists.lua b/xmake/plugins/project/cmake/cmakelists.lua index 2fd0eb57a84..4402f080fd7 100644 --- a/xmake/plugins/project/cmake/cmakelists.lua +++ b/xmake/plugins/project/cmake/cmakelists.lua @@ -900,7 +900,6 @@ function _get_command_string(cmd, outputdir) table.insert(argv, _translate_flag(v, outputdir)) end local command = _escape_path(cmd.program) .. " " .. os.args(argv) - print(cmd.program, _escape_path(cmd.program)) if opt and opt.curdir then command = "${CMAKE_COMMAND} -E chdir " .. _get_relative_unix_path_to_cmake(opt.curdir, outputdir) .. " " .. command end From b6983ac3373a704f0f63c514655221473383e46d Mon Sep 17 00:00:00 2001 From: ruki Date: Sun, 11 Feb 2024 12:44:32 +0800 Subject: [PATCH 40/40] Update main.lua --- xmake/actions/package/local/main.lua | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/xmake/actions/package/local/main.lua b/xmake/actions/package/local/main.lua index 858059ac1d6..f27cbd0911c 100644 --- a/xmake/actions/package/local/main.lua +++ b/xmake/actions/package/local/main.lua @@ -25,6 +25,8 @@ import("core.project.rule") import("core.project.config") import("core.project.project") import("core.base.bit") +import("rules.c++.modules.modules_support.compiler_support", {alias = "module_compiler_support", rootdir = os.programdir()}) +import("rules.c++.modules.modules_support.builder", {alias = "module_builder", rootdir = os.programdir()}) -- get library deps function _get_librarydeps(target) @@ -145,11 +147,9 @@ function _package_library(target) -- copy modules if target:data("cxx.has_modules") then - import(".rules.c++.modules.modules_support.compiler_support") - import(".rules.c++.modules.modules_support.builder") - local modules = compiler_support.localcache():get2(target:name(), "c++.modules") - builder.generate_metadata(target, modules) + local modules = module_compiler_support.localcache():get2(target:name(), "c++.modules") + module_builder.generate_metadata(target, modules) local sourcebatch = target:sourcebatches()["c++.build.modules.install"] if sourcebatch and sourcebatch.sourcefiles then @@ -157,10 +157,10 @@ function _package_library(target) local fileconfig = target:fileconfig(sourcefile) local install = fileconfig and fileconfig.public or false if install then - local modulehash = compiler_support.get_modulehash(target, sourcefile) + local modulehash = module_compiler_support.get_modulehash(target, sourcefile) local prefixdir = path.join(modulesdir, modulehash) os.vcp(sourcefile, path.join(prefixdir, path.filename(sourcefile))) - local metafile = compiler_support.get_metafile(target, sourcefile) + local metafile = module_compiler_support.get_metafile(target, sourcefile) if os.exists(metafile) then os.vcp(metafile, path.join(prefixdir, path.filename(metafile))) end @@ -289,8 +289,6 @@ function _package_headeronly(target) end function _package_moduleonly(target) - import(".rules.c++.modules.modules_support.compiler_support") - import(".rules.c++.modules.modules_support.builder") -- get the output directory local packagedir = target:packagedir() @@ -298,8 +296,8 @@ function _package_moduleonly(target) local headerdir = path.join(packagedir, target:plat(), target:arch(), config.mode(), "include") local modulesdir = path.join(packagedir, target:plat(), target:arch(), config.mode(), "modules") - local modules = compiler_support.localcache():get2(target:name(), "c++.modules") - builder.generate_metadata(target, modules) + local modules = module_compiler_support.localcache():get2(target:name(), "c++.modules") + module_builder.generate_metadata(target, modules) -- copy headers local srcheaders, dstheaders = target:headerfiles(headerdir) @@ -318,10 +316,10 @@ function _package_moduleonly(target) local sourcebatch = target:sourcebatches()["c++.build.modules.install"] if sourcebatch and sourcebatch.sourcefiles then for _, sourcefile in ipairs(sourcebatch.sourcefiles) do - local modulehash = compiler_support.get_modulehash(target, sourcefile) + local modulehash = module_compiler_support.get_modulehash(target, sourcefile) local prefixdir = path.join(modulesdir, modulehash) os.vcp(sourcefile, path.join(prefixdir, path.filename(sourcefile))) - local metafile = compiler_support.get_metafile(target, sourcefile) + local metafile = module_compiler_support.get_metafile(target, sourcefile) if os.exists(metafile) then os.vcp(metafile, path.join(prefixdir, path.filename(metafile))) end