This is a follow-up to: Projection using async delegate/lambda
Apparently, the Async CTP has a bug that I've hit into, and I need to use the VS11 compiler. At the command-line, running msbuild even against a project written in VS2010 still compiles with the VS11 compiler because VS11/.NET 4.5 installs in-place in the .NET 4.0 directory.
However, inside Visual Studio 2010, an in-process compiler is used which seems to not have been upgraded to the new VS11 compiler.
Can I (through some hackery / DLL manipulation) change the compiler that Visual Studio 2010 uses? This would just be a hack/workaround until VS11 supports Windows Azure, so that I can upgrade to the beta/release candidate/RTM.
You may run into some success using the little-known property UseHostCompilerIfAvailable. That should cause build within the IDE to use the compiler in the framework directory.
However IDE features such as intellisense will always use the in-proc compiler. If the bug you're hitting is only on the final transformations of async methods though, you may find that the in-proc compiler is good enough for intellisense, and that UseHostCompilerIfAvailable is good enough to allow you to build from VS.
You set it by manually editing your csproj file to include
<UseHostCompilerIfAvailable>false</UseHostCompilerIfAvailable>
in the top property group.
Also - VS11 supports "roundtripping"! In most scenarios you can open your VS10 project using VS11 without forcing an upgrade. Thus if you have a team need to keep your project in the V10 format for the time being, you can at least independently use VS11. However, this is harder if there are addins that you need that have yet to be released for VS11.
Hope this helps! :)
Related
The Context
We'd like to modify Roslyn and be able to debug it while compiling with it. Pre-VS2015 release, doing this was a painful process that didn't flow very well.
Our goal is to develop a C# variant compiler.
The Dream
Pre-VS2015, executing and debugging your modded Roslyn required the opening of a second VS IDE (experimental) set to use your modded Roslyn. This process wasn't straight forward to setup properly, and oftentimes would break your VS2015 installation.
Post-VS2015, is there a better setup and process possible to modify and debug Roslyn?
I have installed Visual Studio 2015 but it looks like I need more required bits. After that I'm unsure how to run the tests and try the changes in VS2015.
We have our current documented process of testing your own versions of Roslyn here. As long as you're on Visual Studio 2015 Update 1 or later (where we did all the work to support this), everything should work.
The executive summary of those instructions is if you now enlist into Roslyn, you can choose the "VisualStudioSetup" project and just hit F5 to run. That builds to .vsix files in your build directory you can also install. If you want to, there's a CompilerExtension project that produces a compiler you can build with.
I've a bit of confusion about roslyn.
What I have done:
I've installed vs 2015 community edition and download in extensibilty > download compiler platform sdk.
So I created a simple console application: hello world example.
Well now I'm expect to choise the c# compiler between the vs2015 default one and roslyn..., but I've not found such option.
So my first question is: how to select version of c# compiler?
Second I've downloaded master-roslyn and I build, then I found csc.exe, well the odd things is that if I lauch the exe
I get c# compiler version 42.42.42.42. ???? Right?
Then I've follow some tutorials, but all purpose me:
to load a source from text file or string vars and analyze or change syntax tree, then compile to var.
Well at this point I'm confused... So:
What is roslyn exactly? A meta compiler? This mean that I can change my code at runtime just like Reflection?
Second: how can compile with vs2015 with default csc or choose roslyn?
third: If I build a custom version of roslyn How can I compile my source using Vs2015 ?
Which know if csc.exe is roslyn? No help or command line print the codename.
Thanks
So it looks like you've got a few questions:
What is Roslyn?
Roslyn is the new default compiler inside of Visual Studio 2015. If you're building and running applications within Visual Studio 2015, they're being compiled with the Roslyn compiler. You'll get to take advantage of all the new C# 6 features that are available only within the new compiler.
If you're using VS2015, Roslyn has replaced the old compiler entirely and as far as I know you can't use the old compiler within VS 2015.
Roslyn is also a platform that allows you to build programs that can modify, interpret and understand other programs. It's not really meant to let you write code that modifies itself (although that's probably possible to a degree).
The common use cases for Roslyn are:
Building Code Analyzers that provide errors and warnings within Visual Studio.
Building extensions for Visual Studio that understand source code.
Building other tools that understand or run source code. Example: ScriptCS - Scripting with C# code.
In order to use Roslyn for these purposes, you pull down the Microsoft.CodeAnalysis packages from NuGet. You can use these packages to parse code, analyze syntax trees, analyze symbols or compile code and emit IL.
If you're interested in learning more about Roslyn, I've started a series called Learn Roslyn Now that you might be interested in.
Can I replace the compiler?
Yes you can, but I'm not convinced this is a great idea outside of testing changes you want to contribute back to Roslyn. You can pull down Roslyn from GitHub and follow these instructions to build and run Roslyn from within Visual Studio.
If you follow those instructions, you'll be able to run the Roslyn project with F5. It will start a new instance of Visual Studio that's using your customized compiler. This is how people outside of Microsoft will contribute features to the compiler from now on. (Previously you couldn't deploy your custom compiler to Visual Studio but they fixed that in Visual Studio Update 1).
Roslyn is two things:
An API that lets you see "compiler things" like syntax trees and symbols.
A new csc.exe that is implemented atop #1.
If you want to make changes to the compiler and use that to build, take a look at these instructions if you haven't already. There's a few different ways you can make your own version of csc.exe and then use that to build something. But there's no "choice" dialog like you're looking for.
Roslyn is the default compiler of Visual Studio 2015. So, if you install VS2015 you´re already using Roslyn.
Roslyn is a codename for .NET Compiler Platform, and it provides open-source C# and Visual Basic compilers. The project is available on github.
When building a project or solution using a specific version of msbuild I can select an earlier .net toolchain by using the /toolsversion or /tv switch:
"C:\Program Files (x86)\MSBuild\14.0\bin\msbuild" /tv:12.0 amazing.sln
This Just Works for all versions of msbuild, and the version of csc.exe etc. is correctly chosen based on the above:
> "C:\Program Files (x86)\MSBuild\14.0\bin\msbuild" /tv:4.0 amazing.sln
...
CoreCompile:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Csc.exe ...
...
> "C:\Program Files (x86)\MSBuild\14.0\bin\msbuild" /tv:12.0 amazing.sln
...
CoreCompile:
C:\Program Files (x86)\MSBuild\12.0\bin\Csc.exe ...
...
If I don't specify /tv, then depending on which version of msbuild I'm using and a number of environment variables, I may get any of:
The ToolsVersion specified in the top-level element in the project file
The ToolsVersion corresponding to the version of msbuild.exe I'm using
A value from msbuild.exe.config
A value from the registry
(See the different versions of the Overriding ToolsVersion Settings page on MSDN).
So, in order to have builds that have consistent results on the build server and on my local machine, I use /tv when running msbuild.exe (in fact, this is enforced in a psake script, which also ensures it uses the corresponding version of msbuild.exe).
However I cannot use the /tv switch when building with Visual Studio. Instead, Visual Studio 2013 and up will use the .net toolchain that shipped with that version of Visual Studio unless:
The environment variable MSBUILDLEGACYDEFAULTTOOLSVERSION is set and...
...all the project files have the ToolsVersion attribute set to the version I want to use.
This is so baroque that I cannot believe anyone is actually doing it. My questions are thus:
Is anyone doing the MSBUILDLEGACYDEFAULTTOOLSVERSION thing?
If not, is there another way to make Visual Studio use a specific ToolsVersion short of using the version of Visual Studio that shipped with that ToolsVersion? Something that could be stored in version control (so in a project or some other settings file) would be ideal.
And lastly:
Should I even care? Given that each successive version of the C# compiler should be able to handle previous versions' input, and I can set the target .net framework and C# language level in the project file, is this enough to ensure repeatable builds?
(My prejudice is that I should care, since:
I want builds in the IDE and on the build server to be the same (of course)
I want to be able to use VS2015 (and future versions) because it's a better IDE than previous versions, but I don't want to be obliged to use the new toolchain until I decide to.
Perhaps I want too much...)
For a concrete example of the problem, please see my msbuild-vs-vs2015-toolsversion repository on github.
Some background: I'm asking this because we recently had a CI build error when one of my colleagues submitted C# 6.0 code that compiled fine with Roslyn on their copy of Visual Studio 2015, but failed in CI because that uses the previous release of the .net toolchain (they'd used an automatic property with no setter, which is fine in Roslyn but not in earlier versions). We will be updating the CI build to Roslyn, but I wanted to see if we could prevent this sort of thing happening in the future.
I solved this by writing a Visual Studio extension that temporarily sets the environment variable MSBUILDDEFAULTTOOLSVERSION for the duration of a build; the value to be used is read from a file .toolsversion in the same directory as the .sln file. The psake script reads the same .toolsversion file and passes the value to the /tv switch.
The code for the extension can be found here: https://github.com/guyboltonking/set-toolsversion-extension. Sadly, I'm not working with C++, or indeed with Visual Studio, at the moment, so I can't provide any support for it (but I can tell you I used it with no issues at all for several months).
Kudos to #efaruk for reminding me about the existence of MSBUILDDEFAULTTOOLSVERSION.
Edit: Thanks to #mbadawi23, it's now possible to use the extension with both VS2015 and VS2017.
To force a specific C# version in Visual Studio 2015, you can go into the project properties -> Build -> Advanced -> Language Version.
If you set this to 5, the compiler will complain about C# 6 features with: Feature '...' is not available in C# 5. Please use language version 6 or greater.
Alternativly ReSharper also has some tools for this.
Note: You can always create an msbuild file to build your project from using it or changing your project it self and you can decide your tool version conditionally (https://msdn.microsoft.com/en-us/library/7z253716.aspx) (.csproj is also a structured msbuild script with different extension and it will be also compatible with VS).
Regards...
Edit:
https://msdn.microsoft.com/en-us/library/bb383985.aspx
by setting the $(ProjectToolsVersion) property on a project within a solution. This lets you build a project in a solution with a Toolset version that differs from that of the other projects.
So, I think you have got your answer ;)
What you see within Visual Studio (the tools etc) and the code behind them are not what is included in the compiled data they are merely a visual/readable representation, when compiling them as an earlier version of VS you are making the executable of that version.
Please keep in mind that if compiling as a previous .NET version you will potentially lose functionality such as async functionality.
I have recently found out that (merely) installing Visual Studio 2012 on my machine, causes Visual Studio 2010 to use the newer C# compiler. This happens even when setting the language version to 4 (http://ericlippert.com/2013/04/04/what-does-the-langversion-switch-do/).
I wanted to know if it were possible to force Visual Studio to use the old compiler anyway. I think it's not possible because it seems that the compiler is installed in the framework folder which is the same for .NET 4 and .NET 4.5, but I was wondering if someone managed to do it anyway somehow.
You can use the command line compiler see here, and run your code on the old compiler in post build actions
As I said in my original question and as some commented, it indeed seems this would be impossible. The new compiler is installed in the same place as the old compiler. One would need to have a clean build environment with the exact compiler needed.
We use Make to compile our product, which includes, C, C++, Java and a bunch of other bits and pieces. As much as possible we have all tools required to compile the whole thing checked into source control, to eliminate local dependencies and to ensure consistency across dev machines.
Recently we've added some components written in C# using Visual Studio and would like to take a similar approach with Visual Studio solutions. Shelling out to devenv isn't a good option. Calling csc.exe directly (as I've done before using Nant) would require keeping track of file dependencies in the build script, which I'd rather just let the Visual Studio solution do.
MSBuild seems like a good bet, though its default location in %windir%\Microsoft.NET\Framework\[version]\ makes me worried about variability between machines, both with the [version] in the path and the fact that you'll see both "Framework" and "Framework64" directories. I wouldn't mind having a requirement that all developers have whatever .NET framework version installed, but I do worry that your v3.5 might not be the same as mine.
Does anyone have a solution to this that they like? Tried anything that you really didn't like?
MSBuild is the lowest-friction option for sure. Different fx versions aren't that big a deal at build-time- if you're using something important from a fx version higher than what's installed, it won't build. The last place I was at, we built a huge multi-environment build system with NAnt as the base, and it hooked out to MSBuild with NAnt's MSBuild tasks. MSBuild is fine on its own if you're just doing MS stuff, but we had a bunch of things that MSBuild didn't natively support, hence the NAnt wrapper.
I agree with everyone else. To make it easy, just make vsvars.bat (the batch file that is the Visual Studio Command prompt) part of your build script, and then MSBuild will just work.
We use Nant to drive msbuild. If you're worried about different versions of the framework, particularly service packs, use FxCop to check that you're not letting unexpected dependencies creep in. Details are in this answer.
MSBuild is the right tool for this job. Just match your framework version to the version of the framework bundled with the Visual Studio you're using.
32-bit versus 64-bit shouldn't matter, I don't think -- I'm pretty sure both the 32-bit and 64-bit editions of Csc.exe can cross-compile to the other platform. The MSBuild project file (*.*proj XML file) should contain everything MSBuild needs to build your application.