Skip to content

feat: add C# support for xmake#7342

Closed
JassJam wants to merge 12 commits intoxmake-io:devfrom
JassJam:feat/charp-lang-cli
Closed

feat: add C# support for xmake#7342
JassJam wants to merge 12 commits intoxmake-io:devfrom
JassJam:feat/charp-lang-cli

Conversation

@JassJam
Copy link
Contributor

@JassJam JassJam commented Feb 23, 2026

Based on #7338.

This is part 1, an implementation using basic xmake cli options with tests.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @JassJam, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces initial support for building C# projects within the xmake build system. It establishes the foundational language definition and build rules for C#, enabling xmake to compile and publish C# applications and libraries using the dotnet CLI. This is the first part of a broader effort to integrate C# fully, laying the groundwork for future enhancements.

Highlights

  • C# Language Integration: A new csharp language definition has been added to xmake, allowing for the recognition and handling of C# source files and project configurations. This includes defining specific API extensions for C# compiler and linker flags.
  • C# Build Rule Implementation: A comprehensive csharp.build rule has been implemented. This rule orchestrates the dotnet CLI for various build operations, including compiling, publishing, cleaning, and installing C# projects. It supports both binary executables and shared libraries, and includes logic for mapping xmake configurations to .NET build modes and handling runtime identifiers.
  • Extensive Test Projects: A suite of diverse C# test projects has been introduced to validate the new xmake C# build capabilities. These projects cover various scenarios, including basic console applications, applications reading runtime configuration, executables linked with local libraries, executables using external NuGet packages, multi-project solutions with dependency chains, and ASP.NET Core web projects.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • tests/projects/csharp/console/.gitignore
    • Added common .NET build output directories to the gitignore file.
  • tests/projects/csharp/console/src/Program.cs
    • Added a basic 'hello xmake!' C# console application.
  • tests/projects/csharp/console/src/test.csproj
    • Added a .NET 8.0 console project file for the test application.
  • tests/projects/csharp/console/test.lua
    • Added a Lua test script to verify the build of the C# console project.
  • tests/projects/csharp/console/xmake.lua
    • Added xmake configuration for the C# console application, defining a binary target with the new csharp rule.
  • tests/projects/csharp/console_with_runtime_json/.gitignore
    • Added common .NET build output directories to the gitignore file.
  • tests/projects/csharp/console_with_runtime_json/src/Program.cs
    • Added a C# console application that reads a runtime.json file.
  • tests/projects/csharp/console_with_runtime_json/src/app.csproj
    • Added a .NET 8.0 console project file, including runtime.json to be copied to the output directory.
  • tests/projects/csharp/console_with_runtime_json/src/runtime.json
    • Added a sample runtime.json configuration file.
  • tests/projects/csharp/console_with_runtime_json/test.lua
    • Added a Lua test script to verify the build of the C# console application with runtime.json.
  • tests/projects/csharp/console_with_runtime_json/xmake.lua
    • Added xmake configuration for the C# console application with runtime.json.
  • tests/projects/csharp/exe_with_library/.gitignore
    • Added common .NET build output directories to the gitignore file.
  • tests/projects/csharp/exe_with_library/src/app/Program.cs
    • Added a C# application that consumes a local library.
  • tests/projects/csharp/exe_with_library/src/app/app.csproj
    • Added a .NET 8.0 console project file with a project reference to a local library.
  • tests/projects/csharp/exe_with_library/src/lib/Greeter.cs
    • Added a C# static library class with a greeting method.
  • tests/projects/csharp/exe_with_library/src/lib/lib.csproj
    • Added a .NET 8.0 class library project file.
  • tests/projects/csharp/exe_with_library/test.lua
    • Added a Lua test script to verify the build of the C# executable with library project.
  • tests/projects/csharp/exe_with_library/xmake.lua
    • Added xmake configuration to build both the C# executable and its dependent library.
  • tests/projects/csharp/exe_with_package/.gitignore
    • Added common .NET build output directories to the gitignore file.
  • tests/projects/csharp/exe_with_package/src/Program.cs
    • Added a C# application that uses an external NuGet package (Humanizer).
  • tests/projects/csharp/exe_with_package/src/app.csproj
    • Added a .NET 8.0 console project file with a NuGet package reference.
  • tests/projects/csharp/exe_with_package/test.lua
    • Added a Lua test script to verify the build of the C# executable with package project.
  • tests/projects/csharp/exe_with_package/xmake.lua
    • Added xmake configuration for the C# executable with a NuGet package dependency.
  • tests/projects/csharp/multiple_library/.gitignore
    • Added common .NET build output directories to the gitignore file.
  • tests/projects/csharp/multiple_library/src/libalpha/Alpha.cs
    • Added a C# library class providing a simple message.
  • tests/projects/csharp/multiple_library/src/libalpha/libalpha.csproj
    • Added a .NET 8.0 class library project file for LibAlpha.
  • tests/projects/csharp/multiple_library/src/libbeta/Beta.cs
    • Added a C# library class dependent on LibAlpha.
  • tests/projects/csharp/multiple_library/src/libbeta/libbeta.csproj
    • Added a .NET 8.0 class library project file for LibBeta with a project reference to LibAlpha.
  • tests/projects/csharp/multiple_library/src/sample/Program.cs
    • Added a C# application dependent on LibBeta.
  • tests/projects/csharp/multiple_library/src/sample/sample.csproj
    • Added a .NET 8.0 console project file with a project reference to LibBeta.
  • tests/projects/csharp/multiple_library/test.lua
    • Added a Lua test script to verify the build of the C# multiple library project.
  • tests/projects/csharp/multiple_library/xmake.lua
    • Added xmake configuration to build the C# application with multiple library dependencies.
  • tests/projects/csharp/web_project/.gitignore
    • Added common .NET build output directories to the gitignore file.
  • tests/projects/csharp/web_project/src/Program.cs
    • Added a basic C# ASP.NET Core web application.
  • tests/projects/csharp/web_project/src/webapp.csproj
    • Added a .NET 8.0 web application project file.
  • tests/projects/csharp/web_project/test.lua
    • Added a Lua test script to verify the build of the C# web project.
  • tests/projects/csharp/web_project/xmake.lua
    • Added xmake configuration for the C# web application.
  • xmake/languages/csharp/load.lua
    • Defined C# specific API extensions for xmake, including add_csflags, add_ldflags, add_shflags, and add_linkdirs.
  • xmake/languages/csharp/xmake.lua
    • Registered the C# language in xmake, configuring its source kinds (.cs, .csproj), target kinds (binary, shared), and build flags. Also defined menu options for C# compiler and linker configurations.
  • xmake/rules/csharp/xmake.lua
    • Implemented the core csharp.build rule, which handles the build lifecycle for C# projects. This includes finding .csproj files, mapping xmake build modes to .NET configurations, determining runtime identifiers, executing dotnet build and dotnet publish commands, and defining clean and install operations.
Activity
  • This pull request represents the initial implementation for C# support in xmake.
  • It is explicitly noted as 'part 1' of a larger feature, building upon previous discussions or work referenced in issue feat: add C# support for xmake #7338.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

The pull request introduces C# support to xmake, including basic build, clean, and install functionalities for various project types like console applications, libraries, and web projects. The implementation correctly handles .csproj files and integrates with the dotnet CLI. The changes are well-structured and provide a good foundation for C# support.

@waruqi
Copy link
Member

waruqi commented Feb 24, 2026

I've tried it, and the verbose logs should only show detailed build commands and warnings. Other irrelevant logs shouldn't be output.

PS D:\projects\personal\xmake\tests\projects\csharp\console> xmake -rv
checking for platform ... windows (x64)
checking for cl.exe ... C:\Program Files\Microsoft Visual Studio\18\Insiders\VC\Tools\MSVC\14.50.35503\bin\HostX64\x64\cl.exe
checking for Microsoft C/C++ Compiler (x64) ... ok
checking for Microsoft Visual Studio (x64) version ... 2026
checking for nim ... no
[ 31%]: building.csharp.release test
dotnet publish D:\projects\personal\xmake\tests\projects\csharp\console\src\test.csproj --nologo --configuration Release --verbosity minimal --output D:\projects\personal\xmake\tests\projects\csharp\console\build\windows\x64\release\test --runtime win-x64

欢迎使用 .NET 10.0!
---------------------
SDK 版本: 10.0.100-rc.1.25451.107

遥测
---------
.NET 工具会收集用法数据,帮助我们改善你的体验。它由 Microsoft 收集并与社区共享。你可通过使用喜欢的 shell 将 DOTNET_CLI_TELEMETRY_OPTOUT 环境变量设置为 "1" 或 "true" 来选择退出遥测。

阅读有关 .NET CLI 工具遥测的更多信息: https://aka.ms/dotnet-cli-telemetry

----------------
已安装 ASP.NET Core HTTPS 开发证书。
若要信任该证书,请运行 "dotnet dev-certs https --trust"
了解 HTTPS: https://aka.ms/dotnet-https

----------------
编写第一个应用: https://aka.ms/dotnet-hello-world
了解新增功能: https://aka.ms/dotnet-whats-new
浏览文档: https://aka.ms/dotnet-docs
报告问题并在 GitHub 上查找来源: https://github.com/dotnet/core
使用 "dotnet --help" 查看可用命令或访问: https://aka.ms/dotnet-cli
--------------------------------------------------------------------------------------
还原完成(0.8)
    info NETSDK1057: 你正在使用 .NET 的预览版。请参阅 https://aka.ms/dotnet-support-policy
  test 已成功 (4.3 秒) → D:\projects\personal\xmake\tests\projects\csharp\console\build\windows\x64\release\test\

在 6.0 秒内生成 已成功
checking for cl.exe ... C:\Program Files\Microsoft Visual Studio\18\Insiders\VC\Tools\MSVC\14.50.35503\bin\HostX64\x64\cl.exe
checking for the c compiler (cc) ... cl.exe
[100%]: build ok, spent 8.031s

Expected

PS D:\projects\personal\xmake\tests\projects\csharp\console> xmake -rv
checking for platform ... windows (x64)
checking for cl.exe ... C:\Program Files\Microsoft Visual Studio\18\Insiders\VC\Tools\MSVC\14.50.35503\bin\HostX64\x64\cl.exe
checking for Microsoft C/C++ Compiler (x64) ... ok
checking for Microsoft Visual Studio (x64) version ... 2026
checking for nim ... no
[ 31%]: building.csharp.release test
dotnet publish D:\projects\personal\xmake\tests\projects\csharp\console\src\test.csproj --nologo --configuration Release --verbosity minimal --output D:\projects\personal\xmake\tests\projects\csharp\console\build\windows\x64\release\test --runtime win-x64
checking for cl.exe ... C:\Program Files\Microsoft Visual Studio\18\Insiders\VC\Tools\MSVC\14.50.35503\bin\HostX64\x64\cl.exe
checking for the c compiler (cc) ... cl.exe
[100%]: build ok, spent 8.031s

@waruqi
Copy link
Member

waruqi commented Feb 24, 2026

Incremental compilation doesn't seem to be working.

PS D:\projects\personal\xmake\tests\projects\csharp\exe_with_library> xmake
[ 15%]: building.csharp.release mylib
[ 63%]: building.csharp.release app
[100%]: build ok, spent 4.515s
PS D:\projects\personal\xmake\tests\projects\csharp\exe_with_library> xmake
[ 15%]: building.csharp.release mylib
[ 63%]: building.csharp.release app

<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This requires users to maintain both xmake.lua and csproj. Build support for other languages ​​only requires users to maintain xmake.lua. I believe this can be automatically generated in the rule, eliminating the need for users to maintain it separately.

My initial idea was to completely eliminate the dependency on csproj, directly calling the csc command to compile them. Just like in C++, completely getting rid of msbuild and sln.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see your point, however in my opnion this will be too large and volatile to keep up with .NET sdk changes, there is also the fact that dotnet command that generates templated projects, add packages, restore... etc, touches the csproj file directly.

I don't know if it'll be an easy feat / worth the effort to handle all what dotnet already does.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe it's worthwhile. xmake's initial purpose was to simplify project configuration as much as possible and reduce the maintenance burden on users.

Furthermore, this doesn't conflict with the current implementation; if the user explicitly specifies the add_files("*.csproj") configuration, xmake can still prioritize using it.

What I mean is, it at least provides a default solution. In most basic project configurations, xmake can support builds well even if the user doesn't provide a csproj file.

And for some complex requirements, users can decide whether to provide an external csproj file.

@JassJam
Copy link
Contributor Author

JassJam commented Feb 24, 2026

I've tried it, and the verbose logs should only show detailed build commands and warnings. Other irrelevant logs shouldn't be output.

PS D:\projects\personal\xmake\tests\projects\csharp\console> xmake -rv
checking for platform ... windows (x64)
checking for cl.exe ... C:\Program Files\Microsoft Visual Studio\18\Insiders\VC\Tools\MSVC\14.50.35503\bin\HostX64\x64\cl.exe
checking for Microsoft C/C++ Compiler (x64) ... ok
checking for Microsoft Visual Studio (x64) version ... 2026
checking for nim ... no
[ 31%]: building.csharp.release test
dotnet publish D:\projects\personal\xmake\tests\projects\csharp\console\src\test.csproj --nologo --configuration Release --verbosity minimal --output D:\projects\personal\xmake\tests\projects\csharp\console\build\windows\x64\release\test --runtime win-x64

欢迎使用 .NET 10.0!
---------------------
SDK 版本: 10.0.100-rc.1.25451.107

遥测
---------
.NET 工具会收集用法数据,帮助我们改善你的体验。它由 Microsoft 收集并与社区共享。你可通过使用喜欢的 shell 将 DOTNET_CLI_TELEMETRY_OPTOUT 环境变量设置为 "1" 或 "true" 来选择退出遥测。

阅读有关 .NET CLI 工具遥测的更多信息: https://aka.ms/dotnet-cli-telemetry

----------------
已安装 ASP.NET Core HTTPS 开发证书。
若要信任该证书,请运行 "dotnet dev-certs https --trust"
了解 HTTPS: https://aka.ms/dotnet-https

----------------
编写第一个应用: https://aka.ms/dotnet-hello-world
了解新增功能: https://aka.ms/dotnet-whats-new
浏览文档: https://aka.ms/dotnet-docs
报告问题并在 GitHub 上查找来源: https://github.com/dotnet/core
使用 "dotnet --help" 查看可用命令或访问: https://aka.ms/dotnet-cli
--------------------------------------------------------------------------------------
还原完成(0.8)
    info NETSDK1057: 你正在使用 .NET 的预览版。请参阅 https://aka.ms/dotnet-support-policy
  test 已成功 (4.3 秒) → D:\projects\personal\xmake\tests\projects\csharp\console\build\windows\x64\release\test\

在 6.0 秒内生成 已成功
checking for cl.exe ... C:\Program Files\Microsoft Visual Studio\18\Insiders\VC\Tools\MSVC\14.50.35503\bin\HostX64\x64\cl.exe
checking for the c compiler (cc) ... cl.exe
[100%]: build ok, spent 8.031s

Expected

PS D:\projects\personal\xmake\tests\projects\csharp\console> xmake -rv
checking for platform ... windows (x64)
checking for cl.exe ... C:\Program Files\Microsoft Visual Studio\18\Insiders\VC\Tools\MSVC\14.50.35503\bin\HostX64\x64\cl.exe
checking for Microsoft C/C++ Compiler (x64) ... ok
checking for Microsoft Visual Studio (x64) version ... 2026
checking for nim ... no
[ 31%]: building.csharp.release test
dotnet publish D:\projects\personal\xmake\tests\projects\csharp\console\src\test.csproj --nologo --configuration Release --verbosity minimal --output D:\projects\personal\xmake\tests\projects\csharp\console\build\windows\x64\release\test --runtime win-x64
checking for cl.exe ... C:\Program Files\Microsoft Visual Studio\18\Insiders\VC\Tools\MSVC\14.50.35503\bin\HostX64\x64\cl.exe
checking for the c compiler (cc) ... cl.exe
[100%]: build ok, spent 8.031s

Incremental compilation doesn't seem to be working.

PS D:\projects\personal\xmake\tests\projects\csharp\exe_with_library> xmake
[ 15%]: building.csharp.release mylib
[ 63%]: building.csharp.release app
[100%]: build ok, spent 4.515s
PS D:\projects\personal\xmake\tests\projects\csharp\exe_with_library> xmake
[ 15%]: building.csharp.release mylib
[ 63%]: building.csharp.release app

Updated, can you test it again?

@waruqi
Copy link
Member

waruqi commented Feb 25, 2026

Updated, can you test it again?

There seems to be some additional output.

PS D:\projects\personal\xmake\tests\projects\csharp\web_project> xmake -rv
[ 31%]: building.csharp.release webapp
dotnet publish D:\projects\personal\xmake\tests\projects\csharp\web_project\src\webapp.csproj --nologo --configuration Release --verbosity minimal --output D:\projects\personal\xmake\tests\projects\csharp\web_project\build\windows\x64\release\webapp --runtime win-x64
还原完成(0.7)
    info NETSDK1057: 你正在使用 .NET 的预览版。请参阅 https://aka.ms/dotnet-support-policy
  webapp 已成功 (6.0 秒) → D:\projects\personal\xmake\tests\projects\csharp\web_project\build\windows\x64\release\webapp\

在 7.8 秒内生成 已成功
[100%]: build ok, spent 9.719s
PS D:\projects\personal\xmake\tests\projects\csharp\web_project>

-- Set the build progress output style, e.g. scroll (default), singlerow, multirow
["build.progress_style"] = {description = "Set the build progress output style.", type = "string", values = {"scroll", "singlerow", "multirow"}},
-- Set dotnet verbosity for csharp rule, e.g. quiet|minimal|normal|detailed|diagnostic
["build.csharp.dotnet_verbosity"] = {description = "Set dotnet verbosity for csharp rule.", type = "string", values = {"quiet", "minimal", "normal", "detailed", "diagnostic"}},
Copy link
Member

@waruqi waruqi Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do not add any additional strategies to control log output. xmake has its own log output levels, verbose, and diagnosis. Additional log levels will only confuse users.

We can use diagnosis to control the extra logs output of dotnet. xmake f -D

import("core.base.option")

if option.get("diagnosis") then
end

or use dprint

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hopefully this fixes the xmake -rv, i wasn't getting similar result.

PS C:\Users\Jam\Desktop\projects\xmake\tests\projects\csharp\web_project> xmake -rv
checking for platform ... windows (x64)
checking for cl.exe ... C:\Program Files\Microsoft Visual Studio\18\Enterprise\VC\Tools\MSVC\14.50.35717\bin\HostX64\x64\cl.exe
checking for Microsoft C/C++ Compiler (x64) ... ok
checking for Microsoft Visual Studio (x64) version ... 2026
checking for nim ... no
[ 31%]: building.csharp.release webapp
dotnet publish C:\Users\Jam\Desktop\projects\xmake\tests\projects\csharp\web_project\src\webapp.csproj --nologo --configuration Release --verbosity quiet --output C:\Users\Jam\Desktop\projects\xmake\tests\projects\csharp\web_project\build\windows\x64\release\webapp --runtime win-x64
checking for cl.exe ... C:\Program Files\Microsoft Visual Studio\18\Enterprise\VC\Tools\MSVC\14.50.35717\bin\HostX64\x64\cl.exe
checking for the c compiler (cc) ... cl.exe
[100%]: build ok, spent 1.25s
PS C:\Users\Jam\Desktop\projects\xmake\tests\projects\csharp\web_project>

@waruqi
Copy link
Member

waruqi commented Feb 25, 2026

Additionally, I think it's entirely possible to remove the csproj files and have them automatically generated within the rules.

@JassJam
Copy link
Contributor Author

JassJam commented Feb 25, 2026

Additionally, I think it's entirely possible to remove the csproj files and have them automatically generated within the rules.

I agree that it's possible, but I don't think that'll be a good idea. This will add alot of overhead in generating the csproj and maintaining/keeping up with the dotnet ecosystem, are we sure we want to go with it, or should we make it a seperate PR/TODO for later?

@waruqi
Copy link
Member

waruqi commented Feb 25, 2026

I agree that it's possible, but I don't think that'll be a good idea.

This is absolutely necessary. Otherwise, if support for other language projects like Swift requires users to provide additional .xcodeproj files, then using xmake becomes completely pointless. It would be better to let users directly use xcode or msbuild to build them.

Similarly, if building a CSharp project requires additional maintenance of the csproj file, then using xmake to build it is pointless. Users can simply use Visual Studio to build it directly.

This will add alot of overhead in generating the csproj and maintaining/keeping up with the dotnet ecosystem

Since we already support the vsproj generator, generating project files inherently relies heavily on the Visual Studio and .NET ecosystem. This is unavoidable.

are we sure we want to go with it, or should we make it a seperate PR/TODO for later?

Supporting it in the current pull request is the most basic requirement. Then, the test examples provide both examples with and without the csproj file.

@JassJam
Copy link
Contributor Author

JassJam commented Feb 28, 2026

The new commits added csproj lookup if it was provided with fallback to csproj generation if it wasnt provided.

Added various commonly used csproj properties add_values("csharp.<prop>", <value>) with possibility to declare your own custom property add_values("csharp.properties", "AnotherProperty=Value").

nuget's find_package had to be updated, I added _find_target_root, _find_library_root and _get_packagesdir_from_manifest to load packages and their path. Please revise it and let me know if there should be any other way to handle it.

The nuget's refactor was done because i was getting the following error:

PS C:\Users\Jam\Desktop\projects\xmake> xmake l tests/run.lua projects/csharp -vD
...
>> [4/7]: testing tests\projects\csharp\exe_with_package ...
checking for platform ... windows (x64)
checking for Microsoft C/C++ Compiler (x64) ... ok
checking for Microsoft Visual Studio (x64) version ... 2026
finding Humanizer.Core from nuget ..
installing Humanizer.Core from nuget ..
  => installing nuget::Humanizer.Core .. (1/dotnet.exe) finding Humanizer.Core from nuget ..

error: ...\modules\private\action\require\impl\actions\install.lua:509: fetch nuget::Humanizer.Core 2.14.1 failed!
stack traceback:
    [C]: in function 'error'
    [@programdir\core\base\os.lua:1148]: in function 'raiselevel'
    [@programdir\core\sandbox\modules\utils.lua:144]: in function 'assert'
    [...\modules\private\action\require\impl\actions\install.lua:509]:

  => install nuget::Humanizer.Core 2.14.1 .. failed
error: @programdir\core\main.lua:274: @programdir\modules\async\runjobs.lua:261: ...\modules\private\action\require\impl\actions\install.lua:592: install failed!
stack traceback:
    [C]: in function 'error'
    [@programdir\core\base\os.lua:1148]:
    [...\modules\private\action\require\impl\actions\install.lua:592]: in function 'catch'
    [@programdir\core\sandbox\modules\try.lua:123]: in function 'try'
    [...\modules\private\action\require\impl\actions\install.lua:447]:
    [...modules\private\action\require\impl\install_packages.lua:514]: in function 'job_func'
    [@programdir\modules\async\runjobs.lua:441]:

stack traceback:
        [C]: in function 'error'
        @programdir\core\base\os.lua:1148: in function 'base/os.raiselevel'
        (...tail calls...)
        @programdir\core\main.lua:274: in upvalue 'cotask'
        @programdir\core\base\scheduler.lua:514: in function <@programdir\core\base\scheduler.lua:507>
>>     test failed: exec(xmake f -c -D -y) failed(-1), unknown reason
>>       function test_build tests\projects\csharp\exe_with_package\test.lua:3
error: aborting because of unhandled error ...
PS C:\Users\Jam\Desktop\projects\xmake>

@waruqi
Copy link
Member

waruqi commented Mar 1, 2026

Thanks, I need some time to review.

@waruqi
Copy link
Member

waruqi commented Mar 2, 2026

When csproj exists, the source code directory will generate an out/bin/obj directory instead of the build directory.

It should use the paths specified by target:objectdir, target:targetdir, and target:targetfile.

目录: D:\projects\personal\xmake\tests\projects\csharp\existing_csproj

Mode LastWriteTime Length Name


d----- 2026/3/2 12:33 .xmake
d----- 2026/3/2 12:34 bin <----------------------------
d----- 2026/3/2 12:34 build
d----- 2026/3/2 12:34 obj. <----------------------------
-a---- 2026/3/2 12:31 40 .gitignore
-a---- 2026/3/2 12:31 243 existing_csproj.csproj
-a---- 2026/3/2 12:31 103 Program.cs
-a---- 2026/3/2 12:31 194 test.lua
-a---- 2026/3/2 12:31 143 xmake.lua


target("test")
set_kind("binary")
add_rules("csharp")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have already defined the .cs language, and this rule will be applied automatically; we don't need to set it.


var runtimeFile = Path.Combine(AppContext.BaseDirectory, "runtime.json");
if (!File.Exists(runtimeFile))
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure your coding style is consistent with xmake/core/c code.

if () {
}

namespace MyLib;

public static class Greeter
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

xxx {
}


target("app")
set_kind("binary")
add_rules("csharp")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove it


target("app")
set_kind("binary")
add_rules("csharp")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove it


target("test")
set_kind("binary")
add_rules("csharp")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove it

-- @file load.lua
--

import("modules.csharp_common", {rootdir = os.scriptdir(), alias = "csharp_common"})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import("modules.csharp_common")

-- @file installcmd.lua
--

import("modules.csharp_common", {rootdir = os.scriptdir(), alias = "csharp_common"})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import("modules.csharp_common")

batchcmds:mkdir(install_abs)
end
batchcmds:vrunv(dotnet, argv, csharp_common.get_dotnet_runopt(csprojfile))
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

installcmd is for Xpack. Have you tested Xpack? Can it successfully generate a CSharp NSIS installer?

-- @file install.lua
--

import("modules.csharp_common", {rootdir = os.scriptdir(), alias = "csharp_common"})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here

csharp_common.append_target_flags(target, argv)

local runopt = csharp_common.get_dotnet_runopt(csprojfile)
if os.vrunv then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why? They always exist; we only need to call one. os.vrunv

@waruqi
Copy link
Member

waruqi commented Mar 2, 2026

The current build implementation is inconsistent with the current architecture. Please refer to the implementation of Rust rules.

use compiler:build and compiler:buildcmd

vprint(compinst:buildcmd(sourcefiles, targetfile, {target = target, compflags = compflags}))
-- flush io buffer to update progress info
io.flush()
-- compile it
dependinfo.files = {}
assert(compinst:build(sourcefiles, targetfile, {target = target, dependinfo = dependinfo, compflags = compflags}))

then add core/tools/donet.lua to implement build and resolve add_defines, symbols, optimize ...

https://github.com/xmake-io/xmake/blob/dev/xmake/modules/core/tools/rustc.lua

function nf_optimize(self, level)

if rid and target:is_binary() then
table.join2(argv, {"--runtime", rid})
end
csharp_common.append_target_flags(target, argv)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should move build logic to core/tools/donet.lua, Implementations such as nf_optimize will be automatically mapped to build flags when call compiler:build

if targetdirabs then
batchcmds:mkdir(targetdirabs)
end
batchcmds:vrunv(dotnet, argv, csharp_common.get_dotnet_runopt(csprojfile))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can use batchcmds:compile in buildcmd instead of compiler:build.

end
if not major then
local version = try { function ()
return os.iorunv(dotnet, {"--version"})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should implment it in find_dotnet, then use find_tool("dotnet", {version = true}) to get version

end

function _get_default_target_framework(context)
local dotnet = _first(context.target:get("toolset.cs")) or "dotnet"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use find_tool("dotnet")

@waruqi
Copy link
Member

waruqi commented Mar 2, 2026

Additionally, we should define a new toolchain toolchains/dotnet.lua and its corresponding has_flags.lua implementation.

You can refer to https://github.com/xmake-io/xmake/tree/dev/tests/apis/custom_toolchain/xmake

@waruqi
Copy link
Member

waruqi commented Mar 2, 2026

Perhaps I haven't explained it clearly enough, but these things are essential for supporting a new language.

  • languages/csharp (done)
  • toolchains/dotnet (missing)
  • rules/charp (done)
  • core/tools/dotnet.lua (build implemention, missing)
  • core/tools/dotnet/has_flags.lua (missing, it will check add_csflags values)
  • detect/tools/find_dotnet.lua (done, need to find version support)
  • detect/sdks/find_dotnet.lua (missing, find more dotnet sdk infos, toolchain/dotnet/on_check will call it and cache them)

@waruqi waruqi mentioned this pull request Mar 13, 2026
@waruqi
Copy link
Member

waruqi commented Mar 13, 2026

wait for this patch #7398

@waruqi
Copy link
Member

waruqi commented Mar 17, 2026

try it again. #7398

@JassJam

@waruqi waruqi closed this Mar 17, 2026
@JassJam
Copy link
Contributor Author

JassJam commented Mar 17, 2026

Works fine on my windows and linux machine, good work @waruqi !!

@JassJam JassJam deleted the feat/charp-lang-cli branch March 17, 2026 20:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants