Open danmoseley opened 7 years ago
Fyi there was a related question on StackOverflow: https://stackoverflow.com/questions/46065777/is-it-possible-to-compile-a-single-file-with-net-core
While using RunCsc.sh
directly is possible, it would be nice to have a dotnet csc
command that adds all the reference dlls. A problem here is that AFAIK .NET Core doesn’t include its own reference assemblies so there may be differences to a project build
If a command was exposed, I don't think it should automatically add any references, or do anything else "special" -- it should just be equivalent to using csc today where you need to provide such things.
I don't think that dotnet csc
should automatically include required reference assemblies. The point of csc is that you define which assemblies you want to compile against.
csc.exe
adds mscorlib.dll automatically AFAIK.. Would it make sense to add netstandard.dll
on .NET Core?
As I pointed out on SO, the current behaviour is:
$ /usr/local/share/dotnet/sdk/2.0.0/Roslyn/RunCsc.sh Program.cs
Microsoft (R) Visual C# Compiler version 2.3.2.61921 (ad0efbb6)
Copyright (C) Microsoft Corporation. All rights reserved.
Program.cs(1,7): error CS0246: The type or namespace name 'System' could not be found (are you missing a using directive or an assembly reference?)
Program.cs(5,11): error CS0518: Predefined type 'System.Object' is not defined or imported
Program.cs(7,26): error CS0518: Predefined type 'System.String' is not defined or imported
Program.cs(7,16): error CS0518: Predefined type 'System.Void' is not defined or imported
This does not feel like a basic command like build, run, publish, test etc and we have been trying to keep the "native" CLI verbs to a minimum. So, I don't believe we would take building such a command in the CLI. We have been talking quite a bit about global commands and this seems like a good candidate for such a thing.
As you are closing the issue, do you note this request somewhere or can give a timeline for it?
There are currently two command wish lists that I know of: https://github.com/dotnet/cli/issues/4672 https://github.com/dotnet/cli/issues/6223
Probably adding to one wouldn't hurt
yes it wouldn't hurt, it would not at all so - after two years still have to revive python for single file cross-platform scripting instead of beloved C# 🤦♂️
if .NET 5 is considered a replacement for both .NET framework and core, shouldn't it also expose a proper csc
(e.g. via something called dotnet-csc) that allows compiling .cs
from the command line, in a portable fashion?
@jaredpar @MadsTorgersen since the discussion above I believe you have discussed making it easier to get started writing code by allowing global code without Main(). Would it similarly make it easier if I did not need a project file, as proposed here?
We currently don't seem to mention in docs like this that it doesn't work in Core: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-options/command-line-building-with-csc-exe
Reopening for discussion, feel free to close again.
My personal goal is to make it possible to use dotnet build
and dotnet run
for .cs files without needing an explicit project file. That is very different though than allowing direct invocation of the compiler in the form of say dotnet csc hello-world.cs
.
The reason for using dotnet build / run
vs dotnet csc
for a single file application is because at a fundamental level building and running for .NET Framework and .NET Core are very different problem spaces. In .NET Framework there are the following advantages:
csc example.cs
on .NET Desktop we can find all of the default references by using the default csc.rsp file and resolving all of the assemblies in typeof(object).Assembly.Loctation
csc /t:exe example.cs
and then immediately just run example.exe
.That is why for .NET Framework using csc
as the single tool for building is very approachable. For .NET Core though it's really not that generally useful for customers because they need to solve all of the above problems to successfully use csc.
. The logic for those steps are inside dotnet build / run
hence that is what I envision us leveraging for the single *.cs file scenarios.
That being said: I would like to make dotnet csc
as usable on .NET Core as it is on .NET Framework for the act of compiling. If for nothing else than because it's how the Roslyn team does a lot of it's own work :wink:. But I don't think it will be a tool that a ton of customers end up finding that useful.
An implicit project file sounds like a great idea. Is that idea tracked anywhere?
Not in an official proposal yet. Still working on a draft of this. It's been discussed in a few forums though: email, twitter, discord, etc ...
cc @eerhardt since we were just talking about how this could be more approachable.
My personal goal is to make it possible to use dotnet build and dotnet run for .cs files without needing an explicit project file.
@jaredpar - for other languages that allow this, the source files allow for references to external code inside of the source file (both to other files and packages). How do you plan on tackling this problem? The scenario works great for "Hello World", but as soon as you need to use anything that isn't in Microsoft.NETCore.App
, or to include some other class file, now you need a project file.
@eerhardt
By borrowing from existing directive style solutions 😄
#!r Newtonsoft.Json
...
Directives are very easy to scan and easy to ignore by the compiler. This can be parsed out with some ReadLine
calls and a simple string matching code. That can be done by the layer of the build that creates the implicit project file and it can translate them to <PackageReference>
or file references.
Download https://github.com/km-hussain-in/CSharpCore/blob/master/cscc.zip and follow the instructions in readme.txt.
Copy the cscc script from https://github.com/km-hussain-in/CSharpCore/blob/master/cscc.zip into dotnet installation directory and use cscc command. It compiles .cs file to exe which you can run with dotnet command
Good!
Tks so much👍👏
It works for me on Windows as well as Linux.
@km-hussain-in it doesn’t work on Debian; running with bash -x
shows:
[…]
+ dotnet /usr/bin/sdk/5.0.201/Roslyn/bincore/csc.dll -nologo @/tmp/csc-5.0.4.rsp greeter.cs -t:library
Could not execute because the specified command or file was not found.
Possible reasons for this include:
* You misspelled a built-in dotnet command.
* You intended to execute a .NET program, but dotnet-/usr/bin/sdk/5.0.201/Roslyn/bincore/csc.dll does not exist.
* You intended to run a global tool, but a dotnet-prefixed executable with this name could not be found on the PATH.
Though…
$ find /usr/ -name csc.dll
/usr/share/dotnet/sdk/5.0.201/Roslyn/bincore/csc.dll
… probably fixable.
Download https://github.com/km-hussain-in/CSharpCore/blob/master/cscc.zip and follow the instructions in readme.txt.
is HTTP 404 ... someone re-up?
evandrix dixit:
is HTTP 404 ... someone re-up?
Not exactly the same, but I use this:
$ sh csc -nologo NinetyNineBottles.cs
$ sh dotnet-mkrtc NinetyNineBottles.exe
$ dotnet NinetyNineBottles.exe
99 bottles of beer on the wall, 99 bottles of beer.
Take one down and pass it around, 99 bottles of beer on the wall.
98 bottles of beer on the wall, 98 bottles of beer.
[…]
I had to split out the .runtimeconfig.json generation because I also use csc for .dll generation, which don’t need it.
Enjoy, //mirabilos -- FWIW, I'm quite impressed with mksh interactively. I thought it was much much more bare bones. But it turns out it beats the living hell out of ksh93 in that respect. I'd even consider it for my daily use if I hadn't wasted half my life on my zsh setup. :-) -- Frank Terbeck in #!/bin/mksh
DOTNET_CLI_TELEMETRY_OPTOUT=1 export DOTNET_CLI_TELEMETRY_OPTOUT
sdkver=$(LC_ALL=C dotnet --version) fwkver=$(LC_ALL=C dotnet --list-runtimes | \ LC_ALL=C sed --posix -n '/^Microsoft.NETCore.App ([^ ]) .$/{s//\1/p;q;}')
dotnethome=/usr/share/dotnet dotnetlib=$dotnethome/shared/Microsoft.NETCore.App/$fwkver dotnet_cscdll=$dotnethome/sdk/$sdkver/Roslyn/bincore/csc.dll dotnet_csclib='-r:netstandard.dll -r:Microsoft.CSharp.dll -r:System.dll' for x in "$dotnetlib"/System..dll; do dotnet_csclib="$dotnet_csclib -r:${x##/}" done
exec dotnet "$dotnet_cscdll" "-lib:$dotnetlib" $dotnet_csclib "$@"
DOTNET_CLI_TELEMETRY_OPTOUT=1 export DOTNET_CLI_TELEMETRY_OPTOUT
sdkver=$(LC_ALL=C dotnet --version) fwkver=$(LC_ALL=C dotnet --list-runtimes | \ LC_ALL=C sed --posix -n '/^Microsoft.NETCore.App ([^ ]) .$/{s//\1/p;q;}')
exename=$1 case $exename in (.exe|.EXE) ;; (*) echo >&2 "E: $exename is not a .exe file" exit 1 ;; esac
jsonname=${exename%.*}.runtimeconfig.json printf '%s"%s"%s\n' \ '{"runtimeOptions":{"framework":{"name":"Microsoft.NETCore.App","version":' \ "$fwkver" '}}}' >"$jsonname"
Thanks to @mirabilos, I made a script to use as csc
.
Even so, I'm definitely looking forward to using dotnet csc
.
reuploaded dotnet-csc https://github.com/km-hussain-in/CourseSamples/blob/main/CSharp/cscc.zip?raw=true
Not sure whether this belongs in the SDK repo instead.
In the desktop world, most people build with MSBuild on the command line or in VS. But for quick experimentation, learning c#, or custom scripts, one can invoke csc.exe directly. This has the advantage of being very fast, and not needing a project file. In that situation csc adds some default references so you simply run
csc Program.cs
. It is implicit that you are getting no help resolving references, so this is not a good way to make shipping software, unless you really want something custom and know what you're doing. When you are done experimenting, you should make a project file. This scenario has worked well since .NET Framework v1.Can we support this scenario for .NET Core? This would be a supported shortcut for
dotnet C:\Program Files\dotnet\sdk\...version..\Roslyn\csc
that would also add some basic default references.cc @ViktorHofer @stephentoub