diff options
| author | ruki <[email protected]> | 2024-02-20 09:10:29 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-02-20 09:10:29 +0800 |
| commit | 81508df559b98f20f066a8ebb3049db47bdf907b (patch) | |
| tree | fdaa01942ced262411fc35e1bb0fc0134c6a9203 | |
| parent | 73535cd8d8033272b5a6f759e4fab55c486c445a (diff) | |
| parent | 5faa0b4adbdc647073bb5d6cf3471b2ca2feb47d (diff) | |
Merge pull request #4748 from xmake-io/modules
Improve vs201x generator to support c++ modules
| -rw-r--r-- | xmake/plugins/project/vstudio/impl/vs201x.lua | 128 | ||||
| -rw-r--r-- | xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua | 16 |
2 files changed, 45 insertions, 99 deletions
diff --git a/xmake/plugins/project/vstudio/impl/vs201x.lua b/xmake/plugins/project/vstudio/impl/vs201x.lua index b3c6f84c2..8715f4e33 100644 --- a/xmake/plugins/project/vstudio/impl/vs201x.lua +++ b/xmake/plugins/project/vstudio/impl/vs201x.lua @@ -39,6 +39,8 @@ import("private.action.require.install", {alias = "install_requires"}) import("private.action.run.runenvs") import("actions.config.configfiles", {alias = "generate_configfiles", rootdir = os.programdir()}) import("private.utils.batchcmds") +import("private.utils.rule_groups") +import("plugins.project.utils.target_cmds", {rootdir = os.programdir()}) function _translate_path(dir, vcxprojdir) if dir == nil then @@ -79,6 +81,11 @@ function _clear_cache() localcache.save() end +-- get c++ modules rules +function _get_cxxmodules_rules() + return {"c++.build.modules", "c++.build.modules.builder"} +end + -- get command string function _get_command_string(cmd, vcxprojdir) local kind = cmd.kind @@ -116,93 +123,6 @@ function _get_command_string(cmd, vcxprojdir) end end --- add target custom commands for target -function _make_custom_commands_for_target(commands, target, vcxprojdir, suffix) - for _, ruleinst in ipairs(target:orderules()) do - local scriptname = "buildcmd" .. (suffix and ("_" .. suffix) or "") - local script = ruleinst:script(scriptname) - if script then - local batchcmds_ = batchcmds.new({target = target}) - script(target, batchcmds_, {}) - if not batchcmds_:empty() then - for _, cmd in ipairs(batchcmds_:cmds()) do - local command = _get_command_string(cmd, vcxprojdir) - if command then - local key = suffix and suffix or "before" - commands[key] = commands[key] or {} - table.insert(commands[key], command) - end - end - end - end - - scriptname = "linkcmd" .. (suffix and ("_" .. suffix) or "") - script = ruleinst:script(scriptname) - if script then - local batchcmds_ = batchcmds.new({target = target}) - script(target, batchcmds_, {}) - if not batchcmds_:empty() then - for _, cmd in ipairs(batchcmds_:cmds()) do - local command = _get_command_string(cmd, vcxprojdir) - if command then - local key = (suffix and suffix or "before") .. "_link" - commands[key] = commands[key] or {} - table.insert(commands[key], command) - end - end - end - end - end -end - --- add target custom commands for object rules -function _make_custom_commands_for_objectrules(commands, target, sourcebatch, vcxprojdir, suffix) - - -- get rule - local rulename = assert(sourcebatch.rulename, "unknown rule for sourcebatch!") - local ruleinst = assert(target:rule(rulename) or project.rule(rulename) or rule.rule(rulename), "unknown rule: %s", rulename) - - -- generate commands for xx_buildcmd_files - local scriptname = "buildcmd_files" .. (suffix and ("_" .. suffix) or "") - local script = ruleinst:script(scriptname) - if script then - local batchcmds_ = batchcmds.new({target = target}) - script(target, batchcmds_, sourcebatch, {}) - if not batchcmds_:empty() then - for _, cmd in ipairs(batchcmds_:cmds()) do - local command = _get_command_string(cmd, vcxprojdir) - if command then - local key = suffix and suffix or "before" - commands[key] = commands[key] or {} - table.insert(commands[key], command) - end - end - end - end - - -- generate commands for xx_buildcmd_file - if not script then - scriptname = "buildcmd_file" .. (suffix and ("_" .. suffix) or "") - script = ruleinst:script(scriptname) - if script then - for _, sourcefile in ipairs(sourcebatch.sourcefiles) do - local batchcmds_ = batchcmds.new({target = target}) - script(target, batchcmds_, sourcefile, {}) - if not batchcmds_:empty() then - for _, cmd in ipairs(batchcmds_:cmds()) do - local command = _get_command_string(cmd, vcxprojdir) - if command then - local key = suffix and suffix or "before" - commands[key] = commands[key] or {} - table.insert(commands[key], command) - end - end - end - end - end - end -end - -- make custom commands function _make_custom_commands(target, vcxprojdir) -- https://github.com/xmake-io/xmake/issues/2337 @@ -211,20 +131,30 @@ function _make_custom_commands(target, vcxprojdir) target:data_set("plugin.project.translate_path", function (p) return _translate_path(p, vcxprojdir) end) + + -- build sourcebatch groups first + local sourcegroups = rule_groups.build_sourcebatch_groups(target, target:sourcebatches()) + + -- ignore c++ modules rules + local ignored_rules = _get_cxxmodules_rules() + + -- add before commands + -- we use irpairs(groups), because the last group that should be given the highest priority. + local cmds_before = {} + target_cmds.get_target_buildcmd(target, cmds_before, {suffix = "before", ignored_rules = ignored_rules}) + target_cmds.get_target_buildcmd_sourcegroups(target, cmds_before, sourcegroups, {suffix = "before", ignored_rules = ignored_rules}) + -- rule.on_buildcmd_files should also be executed before building the target, as cmake PRE_BUILD does not work. + target_cmds.get_target_buildcmd_sourcegroups(target, cmds_before, sourcegroups, {ignored_rules = ignored_rules}) + + -- add after commands + local cmds_after = {} + target_cmds.get_target_buildcmd_sourcegroups(target, cmds_after, sourcegroups, {suffix = "after", ignored_rules = ignored_rules}) + target_cmds.get_target_buildcmd(target, cmds_after, {suffix = "after", ignored_rules = ignored_rules}) + local commands = {} - _make_custom_commands_for_target(commands, target, vcxprojdir, "before") - _make_custom_commands_for_target(commands, target, vcxprojdir) - local sourcebatches = target:sourcebatches() - for _, sourcebatch in table.orderpairs(sourcebatches) do - local rulename = sourcebatch.rulename - local sourcekind = sourcebatch.sourcekind - 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") - end + for _, cmd in ipairs(table.join(cmds_before, cmds_after)) do + table.insert(commands, _get_command_string(cmd, vcxprojdir)) end - _make_custom_commands_for_target(commands, target, vcxprojdir, "after") return commands end diff --git a/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua b/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua index ee21e88b1..0ae5e78be 100644 --- a/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua +++ b/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua @@ -138,6 +138,12 @@ function _split_gpucodes(flag) return flag:split(",") end +-- is module file? +function _is_modulefile(sourcefile) + local extension = path.extension(sourcefile) + return extension == ".mpp" or extension == ".mxx" or extension == ".cppm" or extension == ".ixx" +end + -- make compiling command function _make_compcmd(compargv, sourcefile, objectfile, vcxprojdir) local argv = {} @@ -1131,6 +1137,11 @@ function _make_source_file_forall(vcxprojfile, vsinfo, target, sourcefile, sourc -- for *.c/cpp/cu files else + -- compile as c++ modules + if _is_modulefile(sourcefile) then + vcxprojfile:print("<CompileAs>CompileAsCppModule</CompileAs>") + end + -- we need to use different object directory and allow parallel building -- -- @see https://github.com/xmake-io/xmake/issues/2016 @@ -1263,6 +1274,11 @@ function _make_source_file_forspec(vcxprojfile, vsinfo, target, sourcefile, sour -- for *.c/cpp/cu files else + -- compile as c++ modules + if _is_modulefile(sourcefile) then + vcxprojfile:print("<CompileAs>CompileAsCppModule</CompileAs>") + end + -- we need to use different object directory and allow parallel building -- -- @see https://github.com/xmake-io/xmake/issues/2016 |
