summaryrefslogtreecommitdiff
path: root/xmake/plugins/project
diff options
context:
space:
mode:
authorArthur Vasseur <[email protected]>2026-04-15 20:21:52 +0200
committerArthur Vasseur <[email protected]>2026-04-16 14:33:56 +0200
commita0fd08ab27edb0bf518a409b8aae9ce6f1aaf51b (patch)
tree8667148350438173eba3959e5da389fa4afbc221 /xmake/plugins/project
parentfabb25749492d6b26887da0217486bfbfd104bdd (diff)
vsxmake: generate .csproj for C# targets
Detect targets whose source kinds are entirely "cs" and emit a .csproj
Diffstat (limited to 'xmake/plugins/project')
-rw-r--r--xmake/plugins/project/vsxmake/getinfo.lua26
-rw-r--r--xmake/plugins/project/vsxmake/vsxmake.lua21
2 files changed, 42 insertions, 5 deletions
diff --git a/xmake/plugins/project/vsxmake/getinfo.lua b/xmake/plugins/project/vsxmake/getinfo.lua
index 9395657fd..60b20b9c4 100644
--- a/xmake/plugins/project/vsxmake/getinfo.lua
+++ b/xmake/plugins/project/vsxmake/getinfo.lua
@@ -89,6 +89,20 @@ function _make_arrs(arr, sep)
return table.concat(r, sep or ";")
end
+-- detect project kind (csharp vs cxx) so vsxmake emits .csproj for C# targets
+function _get_projkind(target)
+ local sourcekinds = table.wrap(target:sourcekinds())
+ if #sourcekinds == 0 then
+ return "cxx"
+ end
+ for _, sk in ipairs(sourcekinds) do
+ if sk ~= "cs" then
+ return "cxx"
+ end
+ end
+ return "csharp"
+end
+
-- get values from target
function _get_values_from_target(target, name)
local values = {}
@@ -122,6 +136,7 @@ function _make_targetinfo(mode, arch, target)
-- save target kind
targetinfo.kind = target:kind()
+ targetinfo.projkind = _get_projkind(target)
-- is default?
targetinfo.default = tostring(target:is_default())
@@ -497,6 +512,17 @@ function main(outputdir, vsinfo)
_target.vcxprojdir_relative_sln = vsutils.translate_path(path.relative(_target.vcxprojdir, vsinfo.solution_dir))
_target.target_id = hash.uuid4(targetname)
_target.kind = target:kind()
+ if not _target.projkind then
+ _target.projkind = _get_projkind(target)
+ if _target.projkind == "csharp" then
+ -- C# project type GUID, see https://www.codeproject.com/Reference/720512/List-of-Visual-Studio-Project-Type-GUIDs
+ _target.projtypeguid = "FAE04EC0-301F-11D3-BF4B-00C04F79EFBC"
+ _target.projext = "csproj"
+ else
+ _target.projtypeguid = "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942"
+ _target.projext = "vcxproj"
+ end
+ end
_target.absscriptdir = target:scriptdir()
_target.scriptdir = path.relative(target:scriptdir(), _target.vcxprojdir)
_target.projectdir = path.relative(project.directory(), _target.vcxprojdir)
diff --git a/xmake/plugins/project/vsxmake/vsxmake.lua b/xmake/plugins/project/vsxmake/vsxmake.lua
index b52b160a9..cd61dfcbf 100644
--- a/xmake/plugins/project/vsxmake/vsxmake.lua
+++ b/xmake/plugins/project/vsxmake/vsxmake.lua
@@ -31,6 +31,7 @@ import("vstudio.impl.vsutils", {rootdir = path.join(os.programdir(), "plugins",
local template_root = path.join(os.programdir(), "scripts", "vsxmake", "vsproj", "templates")
local template_sln = path.join(template_root, "sln", "vsxmake.sln")
local template_vcx = path.join(template_root, "vcxproj", "#target#.vcxproj")
+local template_csproj = path.join(template_root, "csproj", "#target#.csproj")
local template_fil = path.join(template_root, "vcxproj.filters", "#target#.vcxproj.filters")
local template_props = path.join(template_root, "Xmake.Custom.props")
@@ -146,6 +147,9 @@ function _buildparams(info, target, default)
elseif args.filets then -- for qt/.ts
local files = info._targets[target].sourcefiles
table.insert(r, _filter_files(files, {".ts"}))
+ elseif args.filecs then -- for c#
+ local files = info._targets[target].sourcefiles
+ table.insert(r, _filter_files(files, {".cs"}))
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"}))
@@ -239,14 +243,21 @@ function make(version)
for _, target in ipairs(info.targets) do
local paramsprovidertarget = _buildparams(info, target, "<!-- nil -->")
- local vcxproj_dir = info._targets[target].vcxprojdir
+ local _target = info._targets[target]
+ local vcxproj_dir = _target.vcxprojdir
+ local projkind = _target.projkind or "cxx"
+ local projext = _target.projext or "vcxproj"
-- write project file
- local vcxproj_file = path.join(vcxproj_dir, target .. ".vcxproj")
- _writefileifneeded(vcxproj_file, render(template_vcx, "#([A-Za-z0-9_,%.%*%(%)]+)#", "@([^@]+)@", paramsprovidertarget))
+ local proj_file = path.join(vcxproj_dir, target .. "." .. projext)
+ local proj_template = (projkind == "csharp") and template_csproj or template_vcx
+ _writefileifneeded(proj_file, render(proj_template, "#([A-Za-z0-9_,%.%*%(%)]+)#", "@([^@]+)@", paramsprovidertarget))
- local vcxproj_filters = path.join(vcxproj_dir, target .. ".vcxproj.filters")
- _writefileifneeded(vcxproj_filters, render(template_fil, "#([A-Za-z0-9_,%.%*%(%)]+)#", "@([^@]+)@", paramsprovidertarget))
+ -- .csproj does not use a .filters sidecar (legacy .vcxproj-only mechanism)
+ if projkind ~= "csharp" then
+ local vcxproj_filters = path.join(vcxproj_dir, target .. ".vcxproj.filters")
+ _writefileifneeded(vcxproj_filters, render(template_fil, "#([A-Za-z0-9_,%.%*%(%)]+)#", "@([^@]+)@", paramsprovidertarget))
+ end
-- add project custom file
_trycp(template_props, vcxproj_dir)