Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add naive csharp project support for vsxmake #4510

Draft
wants to merge 14 commits into
base: dev
Choose a base branch
from

Conversation

Kethers
Copy link

@Kethers Kethers commented Dec 16, 2023

Note

This is a very naive and basic support for C# only in windows, and much much far from completely supports C# ecosystem like .Net Core or more advanced topics.

Motivation

I'm learning TheCherno's Game Engine Series courses. In the video Cherno uses premake as build tool. I decide to use xmake since it's getting popular in Chinese game & graphics development community. Everything works fine until the course step into C# Scripting and xmake hasn't supported csharp yet #1539. So I have to modified the xmake to make it work.

How it works in short

When building vsxmake solution, xmake generates .sln and .vcxproj files that uses XML (via customized template). When builds the target project, it uses MSBuild to analyze the .vcxproj. In the .vcxproj template it imports the Xmake.targets and the latter one use <Target> semantic to override the real build actions like config, build, clean, etc.

To support CSharp project, here’s the work that needed:

  1. Frontend: Add languages/rules for csharp (not completely done)
  2. Modified the .sln files to recognize the .csproj
  3. Add .csproj XML templates to generate the .csproj file
  4. Backend: Add cross-platform compiling pipeline. (of course not done since it’s too hard and too much work to make it done)

For step 1, currently set_languages(csharp) and add_files("xx.cs") works fine, and set_kind only supports binary and shared.

For step 2 and 3, currently MSBuild.exe can parse the .sln and .csproj correctly. IntelliSense and Property setting window works fine (tested on VS2022 and Rider 2023.3.1).

For step 4, currently I use the Microsoft.CSharp.targets instead of Xmake.CSharp.targets to build targets, which means it doesn’t override the default build actions. Thus the build actions in the rules/csharp/xmake.lua will not be executed at all.

Optimizations & bug fixes

  1. The project reference in #target#.vcxproj is commented since initial commit. I don’t see why since uncomment it also works fine. For .vcxproj it’s just a slight improvement when using IDE. However for .csproj, it’s a necessary semantic otherwise IntelliSense disfunctions when referencing another C# project via add_deps(...).
  2. set_objectdir("...") doesn’t work correctly on .vcxproj because of hard-coded path, now it works fine.
  3. In project property window, language standard display of c++20 is not correct. (expected: c++20, actually is: c++latest)

Maybe these changes can be extracted as another new pull request.

Test

xmake project -k vsxmake

CSharpTest.zip

Future work

Due to the limitation of time and my ability, there are many things that to be working on, and needs community collaborations:

  1. When writing #target#.csproj, Xmake.Common.props and Xmake.Csharp.targets(this file is not deployed), I take C++ project template files for reference. Thus in these files many C++ settings are left. I didn’t delete them for the reason of compatibility (lol, too noob to fully understood the xmake c++ build pipeline and relevant api mechanics). These legacy code should be cleaned up.

  2. For the similar reason, files in languages/csharp/ and rules/csharp also contain a lot legacy code that copy from c++ corresponding files that should be cleaned up.

  3. Backend compilation override, and cross-platform, more C# ecosystem support and more apis for C# builds.

External reference

  1. Premake implementation of .csproj file
  2. MSDN of MSBulid and .csproj XML


language("csharp")
add_rules("csharp")
set_sourcekinds {cs = {".cs"}}
Copy link
Member

@waruqi waruqi Dec 16, 2023

Choose a reason for hiding this comment

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

add set_sourceflags {cs = {"csflags"}}

-- $(MSBuildToolsPath)\Microsoft.CSharp.targets
-- $(XmakeProgramDir)\scripts\vsxmake\vsproj\Xmake.CSharp.targets
on_build(function(target)

Copy link
Member

Choose a reason for hiding this comment

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

vsxmake project should call xmake to build csharp.

@waruqi
Copy link
Member

waruqi commented Dec 18, 2023

I tried it and it worked, but it didn't call the xmake command to compile the cs project, but directly call vs to build it.

If so, you should implement it in vs project generator (xmake project -k vs) instead of vsxmake.

The vsxmake generator is only used to wrap xmake cli. The xmake command is directly called in the vs project to compile the csharp program.

@Kethers
Copy link
Author

Kethers commented Dec 18, 2023

I tried it and it worked, but it didn't call the xmake command to compile the cs project, but directly call vs to build it.

If so, you should implement it in vs project generator (xmake project -k vs) instead of vsxmake.

The vsxmake generator is only used to wrap xmake cli. The xmake command is directly called in the vs project to compile the csharp program.

Thanks for the reply. I am aware of the fact that it not completely fits in the vsxmake build paradigm. I am trying to figure out a
good way to orchestrate them and there's no doubt that it needs deeper understanding of how xmake build cli functions in the backend and how C# build toolchain works and furthermore to abstract and integrate it into xmake backend. That's a lot of work and it takes time.
Present build backend is definitely more fittable to the vs proj generator. However I will work on vsxmake first since it's more recommendable to use than the old vs in the wiki (although it's easier to implement than vsxmake).
I might be too reckless to pull this unaccomplished request just for helping somebody like me out. At the moment just left it for some time until everything is done:

  • C# build backend integration into xmake
  • Use Xmake.CSharp.targets instead of Microsoft.CSharp.targets in .csproj template.
  • csflags support and LangVersion support

@SirLynix
Copy link
Member

I think it's worth a shot to implement it in for the vs project generator first since it's not going away (vsxmake generator doesn't fully replace it) and it would be great to have C# support in both native vs project and vsxmake/xmake backend.

@waruqi
Copy link
Member

waruqi commented Dec 22, 2023

I think it's worth a shot to implement it in for the vs project generator first since it's not going away (vsxmake generator doesn't fully replace it) and it would be great to have C# support in both native vs project and vsxmake/xmake backend.

right, we can make vs generator to support csharp first.

@Kethers Kethers marked this pull request as draft December 29, 2023 14:14
@kgs233
Copy link

kgs233 commented Jan 5, 2024

I think if you want to use xmake as a build system for C#, you should start with csc (compilation tool), if you simply generate MSbuild project from xmake.lua, then this process may not make much sense, because MSbuild is simple and clear enough (at least in my opinion).

@Kethers
Copy link
Author

Kethers commented Jan 6, 2024

I think if you want to use xmake as a build system for C#, you should start with csc (compilation tool), if you simply generate MSbuild project from xmake.lua, then this process may not make much sense, because MSbuild is simple and clear enough (at least in my opinion).

Thanks for the advice. I know csc.exe. If you check the output log (set detail mode to at least normal) of c# project in vs you will see that it's calling csc.exe with source files plus some compilation options. My initial purpose was to make c# scripting orchestra with xmake and vs2022/rider so I just stopped when msbuild parse .csproj correctly. I haven't go that deep into xmake's compiler backend to see how it works. Furthermore c# ecosystem also have .Net core which might use ''dotnet build'' command. That should be taken into consideration becsuse it's more cross-platform than the old framework one (expired and no more update/newer version), especially when it comes to integrating to a cross-platform build system. Unfortunately at present I am busy doing other stuff and don't have not enough time for this pr. I will accomplish it in the future but I can't make time promise.

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.

4 participants