summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2026-03-17 22:37:53 +0800
committerruki <[email protected]>2026-03-17 22:37:53 +0800
commit701014b37d30227f2fa38ebe6ce344ab766513a2 (patch)
tree88abd3323847e6bbb7e1b8a5ade94883312e2ec2
parentf8723406844fa8b2f2fe9904e67e69e6cd99a9d2 (diff)
improve csharp generator
-rw-r--r--xmake/rules/csharp/config.lua9
-rw-r--r--xmake/rules/csharp/modules/csproj_generator.lua58
-rw-r--r--xmake/rules/csharp/modules/itemgroups.lua2
-rw-r--r--xmake/rules/csharp/modules/properties.lua7
4 files changed, 30 insertions, 46 deletions
diff --git a/xmake/rules/csharp/config.lua b/xmake/rules/csharp/config.lua
index 97b3a4303..8b7186888 100644
--- a/xmake/rules/csharp/config.lua
+++ b/xmake/rules/csharp/config.lua
@@ -19,16 +19,13 @@
--
-- imports
-import("core.project.config")
import("core.project.depend")
-import("modules.csproj_generator", {rootdir = os.scriptdir()})
+import("modules.csproj_generator", {rootdir = os.scriptdir(), alias = "generate_csproj"})
function main(target)
-- compute csproj path
- local targetkey = target:fullname():replace("::", path.sep())
- local csprojdir = path.join(config.directory(), "rules", "csharp", targetkey, target:plat(), target:arch())
- local csprojfile = path.join(csprojdir, target:name() .. ".csproj")
+ local csprojfile = path.join(target:autogendir(), "rules", "csharp", target:name() .. ".csproj")
local dependfile = target:dependfile(csprojfile)
-- collect source files and dep csproj paths as depend values
@@ -43,7 +40,7 @@ function main(target)
-- generate csproj incrementally
depend.on_changed(function ()
- csproj_generator(target, csprojfile)
+ generate_csproj(target, csprojfile)
end, {dependfile = dependfile, files = sourcefiles, values = depcsproj})
target:data_set("csharp.csproj", csprojfile)
diff --git a/xmake/rules/csharp/modules/csproj_generator.lua b/xmake/rules/csharp/modules/csproj_generator.lua
index 8972b5550..6ee9cf152 100644
--- a/xmake/rules/csharp/modules/csproj_generator.lua
+++ b/xmake/rules/csharp/modules/csproj_generator.lua
@@ -37,7 +37,7 @@ function _format_attributes(attrs)
return ""
end
local keys = {}
- for key, value in pairs(attrs) do
+ for key, value in table.orderpairs(attrs) do
if value ~= nil and value ~= "" then
table.insert(keys, key)
end
@@ -132,7 +132,7 @@ function _normalize_item_entry(item, default_xml)
local attrs = item.attrs
if type(attrs) ~= "table" then
attrs = {}
- for key, value in pairs(item) do
+ for key, value in table.orderpairs(item) do
if type(key) == "string" and key ~= "xml" and key ~= "value" and key ~= "attrs" then
attrs[key] = value
end
@@ -214,15 +214,8 @@ function _add_custom_properties_from_item(entries, item)
_add_custom_property(entries, tostring(item.name), item.value)
return
end
- local keys = {}
- for k in pairs(item) do
- if type(k) == "string" then
- table.insert(keys, k)
- end
- end
- table.sort(keys)
- for _, key in ipairs(keys) do
- _add_custom_property(entries, key, item[key])
+ for k, v in table.orderpairs(item) do
+ _add_custom_property(entries, k, v)
end
end
@@ -234,37 +227,37 @@ function _collect_custom_property_entries(target)
return entries
end
-function _render_property_group(lines, entries)
+function _render_property_group(file, entries)
if #entries == 0 then
return
end
- table.insert(lines, " <PropertyGroup>")
+ file:print(" <PropertyGroup>")
for _, entry in ipairs(entries) do
- table.insert(lines, string.format(" <%s>%s</%s>", entry.xml, _xml_escape(entry.value), entry.xml))
+ file:print(" <%s>%s</%s>", entry.xml, _xml_escape(entry.value), entry.xml)
end
- table.insert(lines, " </PropertyGroup>")
+ file:print(" </PropertyGroup>")
end
-function _render_item_groups(lines, item_groups)
+function _render_item_groups(file, item_groups)
for _, group in ipairs(item_groups) do
if #group.items > 0 then
- table.insert(lines, " <ItemGroup>")
+ file:print(" <ItemGroup>")
for _, item in ipairs(group.items) do
local attrs = _format_attributes(item.attrs)
if item.value ~= nil and item.value ~= "" then
- table.insert(lines, string.format(" <%s%s>%s</%s>", item.xml, attrs, _xml_escape(item.value), item.xml))
+ file:print(" <%s%s>%s</%s>", item.xml, attrs, _xml_escape(item.value), item.xml)
else
- table.insert(lines, string.format(" <%s%s />", item.xml, attrs))
+ file:print(" <%s%s />", item.xml, attrs)
end
end
- table.insert(lines, " </ItemGroup>")
+ file:print(" </ItemGroup>")
end
end
end
function main(target, csprojfile, opt)
opt = opt or {}
-
+
local csprojdir = path.directory(csprojfile)
local context = {
target = target,
@@ -282,21 +275,16 @@ function main(target, csprojfile, opt)
table.join2(property_entries, custom_property_entries)
local item_groups = _collect_item_groups(context, item_registry_entries)
- local lines = {}
-
- table.insert(lines, string.format("<Project%s>", _format_attributes(project_attributes)))
- _render_property_group(lines, property_entries)
- _render_item_groups(lines, item_groups)
- table.insert(lines, "</Project>")
- local content = table.concat(lines, "\n") .. "\n"
+ local tmpfile = os.tmpfile() .. ".csproj"
+ local file = io.open(tmpfile, "w")
+ file:print("<Project%s>", _format_attributes(project_attributes))
+ _render_property_group(file, property_entries)
+ _render_item_groups(file, item_groups)
+ file:print("</Project>")
+ file:close()
os.mkdir(csprojdir)
- local oldcontent = nil
- if os.isfile(csprojfile) then
- oldcontent = io.readfile(csprojfile)
- end
- if oldcontent ~= content then
- io.writefile(csprojfile, content)
- end
+ os.cp(tmpfile, csprojfile, {copy_if_different = true})
+ os.rm(tmpfile)
end
diff --git a/xmake/rules/csharp/modules/itemgroups.lua b/xmake/rules/csharp/modules/itemgroups.lua
index e9367f96f..785858024 100644
--- a/xmake/rules/csharp/modules/itemgroups.lua
+++ b/xmake/rules/csharp/modules/itemgroups.lua
@@ -100,7 +100,7 @@ function _collect_nuget_references(context)
end
local references = {}
- for pkgname, version in pairs(versions) do
+ for pkgname, version in table.orderpairs(versions) do
table.insert(references, {name = pkgname, version = version or nil})
end
table.sort(references, function (a, b) return a.name < b.name end)
diff --git a/xmake/rules/csharp/modules/properties.lua b/xmake/rules/csharp/modules/properties.lua
index 10606b357..6d392dbd8 100644
--- a/xmake/rules/csharp/modules/properties.lua
+++ b/xmake/rules/csharp/modules/properties.lua
@@ -22,8 +22,6 @@ function _has_target_frameworks(context)
return #table.wrap(context.target:values("csharp.target_frameworks")) > 0
end
-local _default_target_framework_cached = {}
-
function _first(value)
if type(value) == "table" then
return value[1]
@@ -39,7 +37,8 @@ end
function _get_default_target_framework(context)
local dotnet = _first(context.target:get("toolset.cs")) or "dotnet"
dotnet = tostring(dotnet)
- local cached = _default_target_framework_cached[dotnet]
+ _g.default_target_frameworks = _g.default_target_frameworks or {}
+ local cached = _g.default_target_frameworks[dotnet]
if cached ~= nil then
return cached
end
@@ -66,7 +65,7 @@ function _get_default_target_framework(context)
end
local target_framework = major and ("net" .. tostring(major) .. ".0") or "net8.0"
- _default_target_framework_cached[dotnet] = target_framework
+ _g.default_target_frameworks[dotnet] = target_framework
return target_framework
end