Add support for c sharp (dotnet core, etc)
Problem Description
C# .cs files (for dotnet core or other C# tooling) are reported as unrecognised:
[max@hostname example]$ xmake
error: unknown source file: dotnet-project/Program.cs
Solution
.cs files should be recognised as C# and built with whatever installed tooling. dotnet core is likely to be lowest friction for xmake as it can be run directly from the commandline.
Alternative
Currently I build the dotnet project separately and have a script to put all the build artefacts in the right spot. This sucks compared to just running xmake.
Additional context
I'm not totally sure how add_deps etc should be handled. Ideally native dependencies from the same project would be put somewhere that the C# project can find it with [DllImport ("libname")], and similar - this works remarkably well with c/cpp currently :)
I've got a primitive integration working with the following
rule("csharp")
set_extensions(".csproj")
on_build_file(function (target, sourcefile)
os.runv("dotnet", {"build", sourcefile, "-o", target:targetdir()})
end)
on_clean(function (target, sourcefile)
os.runv("dotnet", {"clean", sourcefile, "-o", target:targetdir()})
end)
on_run(function (target, sourcefile)
os.runv("dotnet", {"run", sourcefile, "-o", target:targetdir()})
end)
on_link(function () end)
rule_end()
target("test-cs")
set_kind("binary")
add_rules("csharp")
add_files("dotnet/**.csproj")
This fails to run the program:
[max@hostname example]$ xmake run test-cs
error: please run `$xmake [target]` to build the following targets first:
-> test-cs
but at least builds it in the right place
This fails to run the program:
you need run xmake build and ensure target:targetfile() is generated.
With the run rule above i get a cryptic warning about argv:
error: invalid argv[?
Without the special run rule it works, if the exact name of the final assembly matches the rule name, which i guess makes sense.
I'm not sure how best to handle running the dotnet assembly - it works as above but seems very fragile (the final assembly depends on the name of the .csproj, so they need to match). This is sort of expected, as xmake is just wrapping dotnet's build logic, but is not particularly nice. You can probably comment on what would be the best approach.
(Thanks for the very prompt support! I'm off for tonight but will revisit this tomorrow as if I can get xmake driving everything, that's nicer for me)
I don't know how dotnet builds them, but I think it would be better to use set_extensions(".cs") in rule("cshape") to directly support add_files("src/*.cs") source code compilation. But it may require more work.
Of course, your current rule should also work. but you need ensure target:targetfile() is generated. xmake run will run it.
I think it would be better to use set_extensions(".cs") in rule("cshape") to directly support add_files("src/*.cs") source code compilation.
Yeah i'd love something more analogous to the C/++ compilation but I haven't dug into how dotnet supports that - i think the expectation is that you have a .csproj file akin to a visual studio .sln + .vcxproj and you just point dotnet core at that.
Final rule for the moment to help anyone else who sees this, as I need to get the project done rather than keep working on build stuff :upside_down_face:
rule("csharp")
set_extensions(".csproj")
on_build_file(function (target, sourcefile)
os.execv("dotnet", {"build", sourcefile, "-o", target:targetdir()})
end)
on_clean(function (target, sourcefile)
os.execv("dotnet", {"clean", sourcefile, "-o", target:targetdir()})
end)
on_link(function () end)
rule_end()
target("test")
set_kind("binary")
add_rules("csharp")
add_files("src/dotnet/test.csproj")
note that the name of the target and the name of the csproj file are the same.
I used execv to get all output, so i can see error output when there's a problem, not sure if this is the best way to go about things, but it works well enough. Annoyingly slows down compilation a lot as msbuild seems to take a second or more to realise nothing needs doing, but could be worse.
Yes, in order to quickly build an existing csharp project, you can follow the existing solution to deal with it, there is no problem.
In the future, I will consider further supporting the compilation of the csharp project, but I am not sure when it will be supported. Maybe you need to wait for a while.
If you want to run the executable file you generated through dotnet, you need to tell xmake where your executable file is. By default, target:targetfile() returns the executable file path you compiled.
rule("csharp")
set_extensions(".csproj")
on_build_file(function (target, sourcefile)
os.execv("dotnet", {"build", sourcefile, "-o", target:targetdir()})
-- you need copy executable file to target file path
os.cp(path.join(target:targetdir(), "compiled_execute_filename"), target:targetfile())
end)
xmake run will call os.exec to execute target:targetfile()
I'm passing the arguments "-o", target:targetdir() to let dotnet use that as the output directory - because i'm using the same name (test) for both the .csproj and the xmake target, it ends up in the right place without a copy :slightly_smiling_face: the copy could help if the csproj name is different for sure!
Anything new here? @waruqi It's a nice thought
Anything new here? @waruqi It's a nice thought
Not yet, I haven't had much time to pay attention to it recently.
@waruqi Thanks for reply! Just wondering, does it possible to copy a csharp project with xmake project -k vsxmake -m "debug;release" command, a hook or somthing?
@waruqi Thanks for reply! Just wondering, does it possible to copy a
csharp projectwithxmake project -k vsxmake -m "debug;release"command, a hook or somthing?
you can do anything in on_build()