summaryrefslogtreecommitdiff
path: root/xmake/modules/detect
diff options
context:
space:
mode:
authorruki <[email protected]>2026-03-14 00:04:01 +0800
committerruki <[email protected]>2026-03-14 00:11:43 +0800
commita86bde866d5f65d5fbd31f1474190dcc40aa2876 (patch)
treea043c2be4830b300a59543f8d10bcfddced70f4f /xmake/modules/detect
parent4b56123d797578f1abec0c3d507282d9e5bc8f3b (diff)
improve csharp support
Diffstat (limited to 'xmake/modules/detect')
-rw-r--r--xmake/modules/detect/sdks/find_dotnet.lua134
-rw-r--r--xmake/modules/detect/tools/find_dotnet.lua53
2 files changed, 144 insertions, 43 deletions
diff --git a/xmake/modules/detect/sdks/find_dotnet.lua b/xmake/modules/detect/sdks/find_dotnet.lua
index 2dfd2a916..3430d2626 100644
--- a/xmake/modules/detect/sdks/find_dotnet.lua
+++ b/xmake/modules/detect/sdks/find_dotnet.lua
@@ -20,16 +20,60 @@
-- imports
import("lib.detect.find_file")
+import("lib.detect.find_tool")
import("core.tool.toolchain")
import("core.base.option")
import("core.base.global")
import("core.project.config")
import("core.cache.detectcache")
--- find dotnet directory
-function _find_sdkdir(sdkdir)
+-- find dotnet sdk info from dotnet cli
+function _find_dotnet_cli()
+ local dotnet = find_tool("dotnet", {version = true})
+ if not dotnet then
+ return nil
+ end
+
+ local result = {program = dotnet.program, version = dotnet.version}
+
+ -- get sdk list, e.g. "8.0.100 [/usr/share/dotnet/sdk]"
+ local sdklist = try { function () return os.iorunv(dotnet.program, {"--list-sdks"}) end }
+ if sdklist then
+ local sdks = {}
+ for _, line in ipairs(sdklist:split("\n", {plain = true})) do
+ line = line:trim()
+ local ver, dir = line:match("^(%S+)%s+%[(.-)%]")
+ if ver and dir then
+ table.insert(sdks, {version = ver, directory = path.join(dir, ver)})
+ end
+ end
+ if #sdks > 0 then
+ result.sdks = sdks
+ result.sdkdir = sdks[#sdks].directory
+ result.sdkver = sdks[#sdks].version
+ end
+ end
+
+ -- get runtime list, e.g. "Microsoft.NETCore.App 8.0.0 [/usr/share/dotnet/shared/Microsoft.NETCore.App]"
+ local runtimelist = try { function () return os.iorunv(dotnet.program, {"--list-runtimes"}) end }
+ if runtimelist then
+ local runtimes = {}
+ for _, line in ipairs(runtimelist:split("\n", {plain = true})) do
+ line = line:trim()
+ local name, ver = line:match("^(%S+)%s+(%S+)%s+%[")
+ if name and ver then
+ table.insert(runtimes, {name = name, version = ver})
+ end
+ end
+ if #runtimes > 0 then
+ result.runtimes = runtimes
+ end
+ end
+ return result
+end
- -- get sdk directory from vcvars
+-- find .NET Framework SDK directory from MSVC (Windows only)
+function _find_netfxsdk(sdkdir)
if not sdkdir then
local msvc = toolchain.load("msvc")
if msvc and msvc:check() then
@@ -42,55 +86,40 @@ function _find_sdkdir(sdkdir)
end
end
end
- return sdkdir
-end
-
--- find dotnet toolchains
-function _find_dotnet(sdkdir, sdkver)
-
- -- find dotnet directory
- sdkdir = _find_sdkdir(sdkdir)
if not sdkdir or not os.isdir(sdkdir) then
return nil
end
-- get sdk version
- if not sdkver then
- local vers = {}
- for _, dir in ipairs(os.dirs(path.join(sdkdir, "*", "Include"))) do
- table.insert(vers, path.filename(path.directory(dir)))
- end
- for _, ver in ipairs(vers) do
- if os.isdir(path.join(sdkdir, ver, "Lib", "um")) and os.isdir(path.join(sdkdir, ver, "Include", "um")) then
- sdkver = ver
- break
- end
+ local sdkver
+ local vers = {}
+ for _, dir in ipairs(os.dirs(path.join(sdkdir, "*", "Include"))) do
+ table.insert(vers, path.filename(path.directory(dir)))
+ end
+ for _, ver in ipairs(vers) do
+ if os.isdir(path.join(sdkdir, ver, "Lib", "um")) and os.isdir(path.join(sdkdir, ver, "Include", "um")) then
+ sdkver = ver
+ break
end
end
if not sdkver then
return nil
end
-
- -- get the lib directory
- local libdir = path.join(sdkdir, sdkver, "Lib")
-
- -- get the include directory
- local includedir = path.join(sdkdir, sdkver, "Include")
-
- -- get toolchains
- return {sdkdir = sdkdir, libdir = libdir, includedir = includedir, sdkver = sdkver}
+ return {sdkdir = sdkdir, sdkver = sdkver,
+ libdir = path.join(sdkdir, sdkver, "Lib"),
+ includedir = path.join(sdkdir, sdkver, "Include")}
end
--- find dotnet toolchains
+-- find dotnet sdk
--
-- @param sdkdir the dotnet directory
--- @param opt the argument options, e.g. {verbose = true, force = false, version = "5.9.1"}
+-- @param opt the argument options, e.g. {verbose = true, force = false}
--
--- @return the dotnet toolchains. e.g. {sdkver = ..., sdkdir = ..., bindir = .., libdir = ..., includedir = ..., .. }
+-- @return the dotnet sdk info, e.g. {program = ..., version = ..., sdkver = ..., sdkdir = ..., sdks = {...}, runtimes = {...}}
--
-- @code
--
--- local toolchains = find_dotnet("~/dotnet")
+-- local dotnet = find_dotnet()
--
-- @endcode
--
@@ -106,24 +135,43 @@ function main(sdkdir, opt)
return cacheinfo.dotnet
end
- -- find dotnet
- local dotnet = _find_dotnet(sdkdir or config.get("dotnet") or global.get("dotnet"), opt.version or config.get("dotnet_sdkver"))
- if dotnet then
+ -- find dotnet cli sdk
+ local dotnet = _find_dotnet_cli()
+ -- find .NET Framework SDK on Windows
+ if is_host("windows") then
+ local netfxsdk = _find_netfxsdk(sdkdir or config.get("dotnet") or global.get("dotnet"))
+ if netfxsdk then
+ if dotnet then
+ dotnet.netfxsdk = netfxsdk
+ else
+ dotnet = netfxsdk
+ end
+ end
+ end
+
+ if dotnet then
-- save to config
- config.set("dotnet", dotnet.sdkdir, {force = true, readonly = true})
- config.set("dotnet_sdkver", dotnet.sdkver, {force = true, readonly = true})
+ if dotnet.sdkdir then
+ config.set("dotnet", dotnet.sdkdir, {force = true, readonly = true})
+ end
+ if dotnet.sdkver then
+ config.set("dotnet_sdkver", dotnet.sdkver, {force = true, readonly = true})
+ end
-- trace
if opt.verbose or option.get("verbose") then
- cprint("checking for .Net SDK directory ... ${color.success}%s", dotnet.sdkdir)
- cprint("checking for .Net SDK version ... ${color.success}%s", dotnet.sdkver)
+ if dotnet.version then
+ cprint("checking for .NET SDK version ... ${color.success}%s", dotnet.version)
+ end
+ if dotnet.sdkdir then
+ cprint("checking for .NET SDK directory ... ${color.success}%s", dotnet.sdkdir)
+ end
end
else
-
-- trace
if opt.verbose or option.get("verbose") then
- cprint("checking for .Net SDK directory ... ${color.nothing}${text.nothing}")
+ cprint("checking for .NET SDK directory ... ${color.nothing}${text.nothing}")
end
end
diff --git a/xmake/modules/detect/tools/find_dotnet.lua b/xmake/modules/detect/tools/find_dotnet.lua
new file mode 100644
index 000000000..ac17979ec
--- /dev/null
+++ b/xmake/modules/detect/tools/find_dotnet.lua
@@ -0,0 +1,53 @@
+--!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, Xmake Open Source Community.
+--
+-- @author ruki
+-- @file find_dotnet.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+
+-- find dotnet
+--
+-- @param opt the argument options, e.g. {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local dotnet = find_dotnet()
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+ opt.check = opt.check or "--version"
+ opt.command = opt.command or "--version"
+
+ -- find program
+ local program = find_program(opt.program or "dotnet", opt)
+
+ -- find program version
+ local version = nil
+ if program and opt and opt.version then
+ version = find_programver(program, opt)
+ end
+ return program, version
+end