diff options
| author | ruki <[email protected]> | 2026-06-23 23:25:42 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2026-07-07 23:04:45 +0800 |
| commit | 65ee93162232d0399a1b9f08701c42bc04f3f9ab (patch) | |
| tree | 0f53d3877124e44ea58da8d2ff2fc0ea97cbb46e | |
| parent | 147fdfa379133d0d7d7f075ac9b4905401ff7126 (diff) | |
add vstudio support for nonetype
| -rw-r--r-- | xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua | 10 | ||||
| -rw-r--r-- | xmake/plugins/project/vstudio/impl/vs201x_vcxproj_filters.lua | 12 | ||||
| -rw-r--r-- | xmake/plugins/project/vstudio/impl/vsutils.lua | 41 | ||||
| -rw-r--r-- | xmake/plugins/project/vsxmake/vsxmake.lua | 58 |
4 files changed, 103 insertions, 18 deletions
diff --git a/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua b/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua index f1f44c3a8..24e1a70ac 100644 --- a/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua +++ b/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua @@ -1438,6 +1438,16 @@ function _make_source_files(vcxprojfile, vsinfo, target) end end vcxprojfile:leave("</ItemGroup>") + + -- add other files (e.g. files added by add_files but handled by a custom rule), for display only + local otherfiles = vsutils.otherfiles(target) + if #otherfiles > 0 then + vcxprojfile:enter("<ItemGroup>") + for _, otherfile in ipairs(otherfiles) do + vcxprojfile:print("<None Include=\"%s\" />", path.relative(path.absolute(otherfile), target.project_dir)) + end + vcxprojfile:leave("</ItemGroup>") + end end -- make vcxproj diff --git a/xmake/plugins/project/vstudio/impl/vs201x_vcxproj_filters.lua b/xmake/plugins/project/vstudio/impl/vs201x_vcxproj_filters.lua index ed9002662..6c4c0ea8d 100644 --- a/xmake/plugins/project/vstudio/impl/vs201x_vcxproj_filters.lua +++ b/xmake/plugins/project/vstudio/impl/vs201x_vcxproj_filters.lua @@ -23,8 +23,10 @@ -- -- imports +import("core.base.hashset") import("core.tool.compiler") import("vsfile") +import("vsutils") -- make header function _make_header(filtersfile, vsinfo) @@ -147,14 +149,20 @@ end -- make sources function _make_sources(filtersfile, vsinfo, target, vcxprojdir) + -- the source files that are not natively built by VS, list them as <None> for display only + local otherfiles = hashset.from(vsutils.otherfiles(target)) + -- the files displayed as include files (e.g. also added by add_extrafiles), skip them to avoid duplicate + local includefiles = hashset.from(table.join(target.headerfiles or {}, target.extrafiles or {})) + -- and sources filtersfile:enter("<ItemGroup>") for _, sourcefile in ipairs(target.sourcefiles) do local filter = _make_filter(sourcefile, target, vcxprojdir) - if filter then + if filter and not includefiles:has(sourcefile) then local nodename local ext = path.extension(sourcefile) - if ext == "asm" then nodename = "CustomBuild" + if otherfiles:has(sourcefile) then nodename = "None" + elseif ext == "asm" then nodename = "CustomBuild" elseif ext == "cu" then nodename = "CudaCompile" else nodename = "ClCompile" end diff --git a/xmake/plugins/project/vstudio/impl/vsutils.lua b/xmake/plugins/project/vstudio/impl/vsutils.lua index 30832ae3f..2cf5e7bdb 100644 --- a/xmake/plugins/project/vstudio/impl/vsutils.lua +++ b/xmake/plugins/project/vstudio/impl/vsutils.lua @@ -20,6 +20,7 @@ -- imports import("core.base.option") +import("core.base.hashset") import("core.project.config") import("core.project.project") import("core.cache.memcache") @@ -64,6 +65,46 @@ function translate_path(filepath) return (filepath:gsub("::", "#")) end +-- get the source files that are not natively built by VS, e.g. files added by add_files but handled +-- by a custom rule. we list them as <None> in the project for display only (like add_extrafiles). +-- this must be consistent with vs201x_vcxproj._make_source_files. +-- @see https://github.com/xmake-io/xmake/issues/7619 +function otherfiles(target) + + -- collect the source files that are natively built by VS + local builtfiles = hashset.new() + for _, targetinfo in ipairs(target.info or {}) do + for _, sourcebatch in pairs(targetinfo.sourcebatches or {}) do + local sourcekind = sourcebatch.sourcekind + local rulename = sourcebatch.rulename + if rulename == "c.build" or rulename == "c++.build" or rulename == "c++.build.modules" + or sourcekind == "as" or sourcekind == "mrc" or sourcekind == "cu" then + for _, sourcefile in ipairs(sourcebatch.sourcefiles) do + builtfiles:insert(sourcefile) + end + end + end + end + + -- exclude the header/extra files and the precompiled header to avoid duplicate display + local excludefiles = hashset.from(table.join(target.headerfiles or {}, target.extrafiles or {})) + if target.pcheader then + excludefiles:insert(target.pcheader) + end + if target.pcxxheader then + excludefiles:insert(target.pcxxheader) + end + + -- the remaining source files are the custom files + local results = {} + for _, sourcefile in ipairs(target.sourcefiles or {}) do + if not builtfiles:has(sourcefile) and not excludefiles:has(sourcefile) then + table.insert(results, sourcefile) + end + end + return results +end + function reset_config_and_caches(mode, arch) -- reload config, project and platform -- modify config diff --git a/xmake/plugins/project/vsxmake/vsxmake.lua b/xmake/plugins/project/vsxmake/vsxmake.lua index 6084d6b84..5cab05c54 100644 --- a/xmake/plugins/project/vsxmake/vsxmake.lua +++ b/xmake/plugins/project/vsxmake/vsxmake.lua @@ -53,6 +53,22 @@ function _filter_files(files, includeexts, excludeexts) return f end +-- the source file extensions natively supported by the vsxmake project, keyed by the template import name +-- the `filenone` group collects everything else (e.g. files added by add_files but handled by a custom rule) +local _source_exts = +{ + filec = {".c"} +, filecxx = {".cpp", ".cc", ".cxx"} +, filempp = {".mpp", ".mxx", ".cppm", ".ixx"} +, filecu = {".cu"} +, fileobj = {".obj", ".o"} +, filerc = {".rc"} +, fileui = {".ui"} +, fileqrc = {".qrc"} +, filets = {".ts"} +, filecs = {".cs"} +} + function _buildparams(info, target, default) local function getprop(match, opt) @@ -122,40 +138,50 @@ function _buildparams(info, target, default) end if args.filec then local files = info._targets[target].sourcefiles - table.insert(r, _filter_files(files, {".c"})) + table.insert(r, _filter_files(files, _source_exts.filec)) elseif args.filecxx then local files = info._targets[target].sourcefiles - table.insert(r, _filter_files(files, {".cpp", ".cc", ".cxx"})) + table.insert(r, _filter_files(files, _source_exts.filecxx)) elseif args.filempp then local files = info._targets[target].sourcefiles - table.insert(r, _filter_files(files, {".mpp", ".mxx", ".cppm", ".ixx"})) + table.insert(r, _filter_files(files, _source_exts.filempp)) elseif args.filecu then local files = info._targets[target].sourcefiles - table.insert(r, _filter_files(files, {".cu"})) + table.insert(r, _filter_files(files, _source_exts.filecu)) elseif args.fileobj then local files = info._targets[target].sourcefiles - table.insert(r, _filter_files(files, {".obj", ".o"})) + table.insert(r, _filter_files(files, _source_exts.fileobj)) elseif args.filerc then local files = info._targets[target].sourcefiles - table.insert(r, _filter_files(files, {".rc"})) + table.insert(r, _filter_files(files, _source_exts.filerc)) elseif args.fileui then -- for qt/.ui local files = info._targets[target].sourcefiles - table.insert(r, _filter_files(files, {".ui"})) + table.insert(r, _filter_files(files, _source_exts.fileui)) elseif args.fileqrc then -- for qt/.qrc local files = info._targets[target].sourcefiles - table.insert(r, _filter_files(files, {".qrc"})) + table.insert(r, _filter_files(files, _source_exts.fileqrc)) elseif args.filets then -- for qt/.ts local files = info._targets[target].sourcefiles - table.insert(r, _filter_files(files, {".ts"})) + table.insert(r, _filter_files(files, _source_exts.filets)) elseif args.filecs then -- for c# local files = info._targets[target].sourcefiles - table.insert(r, _filter_files(files, {".cs"})) - elseif args.filenone then -- for custom build steps - local files = info._targets[target].sourcefiles - table.insert(r, _filter_files(files, nil, { - ".c", ".cpp", ".cc", ".cxx", ".mpp", ".mxx", ".cppm", ".ixx", - ".cu", ".obj", ".o", ".rc", ".ui", ".qrc", ".ts", ".cs" - })) + table.insert(r, _filter_files(files, _source_exts.filecs)) + elseif args.filenone then -- for custom build steps, e.g. files added by add_files but handled by a custom rule + -- collect the source files not natively supported by vsxmake, and exclude the header/extra files + -- to avoid duplicate display with the include group (add_extrafiles) + local _target = info._targets[target] + local excludeexts = {} + for _, exts in table.orderpairs(_source_exts) do + table.join2(excludeexts, exts) + end + local excludefiles = hashset.from(table.join(_target.headerfiles or {}, _target.extrafiles or {})) + local files = {} + for _, file in ipairs(_target.sourcefiles) do + if not excludefiles:has(file) then + table.insert(files, file) + end + end + table.insert(r, _filter_files(files, nil, excludeexts)) elseif args.incc then local files = table.join(info._targets[target].headerfiles or {}, info._targets[target].extrafiles) table.insert(r, _filter_files(files, nil, {".natvis"})) |
