1

I have a Windows 2016 server that I am setting up as a build server. It will be setup to use MSBuild to build a .NET 4.6.1 Web API project I am using MSBuild version 15.0, and using TeamCity version 2018.1, however I do not believe TeamCity is really involved in the issue, as I get the issue by doing an MSBuild manually/directly against the code

Windows 2016 has .NET 4.7, so I installed the .NET 4.6.1 targeting pack and .NET 4.6.1 SDK. In the build step in TeamCity, I have a parameter to MSBuild of "/p:TargetFramework=net461" But in the build logs, and when I run MSBuild manually/directly against the code, I get the following error:

HttpExtensions.cs(44, 24): error CS8137: Cannot define a class or member that utilizes tuples because the compiler required type 'System.Runtime.CompilerServices.TupleElementNamesAttribute' cannot be found. Are you missing a reference?

HttpExtensions.cs(44, 24): error CS8179: Predefined type 'System.ValueTuple`2' is not defined or imported

When I am on my development machine with Visual Studio 2017 installed, the project builds without issue. My development machine is Windows 10, but the other major difference is that the Windows 2016 server does not have Visual Studio. My thoughts are this has something to do with Windows 2016 having the primary .NET version as 4.7, and installing Visual Studio would maybe fix the issue. But I really want to avoid installing Visual Studio on the Windows 2016 server

Any ideas/feedback ?

maegus
  • 49
  • 7
  • I have no idea about TeamCity but Team Foundation Server requires Visual Studio installed on the build machine in order to work consistently. Make sure you have same framework sdk versions installed on both machines. – Eldar Nov 11 '19 at 16:41
  • As for @Eldar. Also, I believe if you are building via MS Build, you need to get your dependencies in the right order or it wont build. A Visual Studio build will work it out, but MS Build does not. Even with VS installed, you might need to edit .csproj files to get the build order right via MS Build. Can't add as answer, as it's very hard to work out without seeing the setup. – JsAndDotNet Nov 11 '19 at 16:46
  • If you do not want to install Net, then you need to publish application and run the setup.exe that is created with the setup to get application to run. – jdweng Nov 11 '19 at 17:19
  • Which MSBuild.exe do you use? Consider the fact that there are multiple on the same machine. – Lex Li Nov 11 '19 at 17:50
  • I am using MSBuild version 15.0. When I run MSBuild, i am specifically selecting this version and run directly against the codebase which produces the error – maegus Nov 11 '19 at 18:11
  • I'll also try to look at the build order of dependencies – maegus Nov 11 '19 at 18:18
  • If you have .net framework 4.7 locally and are not specifically targeting 4.6.1 then I believe that System.Value.Tuple is accessible as a nuget reference only in 4.6.1, but is available without a reference in 4.7. It may be that you just need to add a nuget package reference to system.value.tuple to get it to build in 4.6.1. https://stackoverflow.com/questions/42675481/how-can-i-enable-all-features-of-c-sharp-7-in-visual-studio-2017-project/44092985#44092985 – Ross Gurbutt Nov 11 '19 at 19:23
  • @Ross Gurbutt Yeah I saw that...but the funny thing on my development machine where it does compile, there is no reference to the nuget package, and it compiles fine. Target Framework is 4.6.1 in the project properties. – maegus Nov 11 '19 at 20:41
  • Have you tried building from the command line locally using /p:TargetFramework=net461 just to rule out any weird extraneous side effects? – Ross Gurbutt Nov 11 '19 at 21:13
  • @Ross Gurbutt...thanks so much, you are correct, even though on my local it was compiling without a reference to the System.ValueTuple, by adding the reference, the Windows 2016 server without Visual Studio was then able to compile successfully. If you wanted to submit a post, and then i'll mark it as the answer – maegus Nov 12 '19 at 14:49
  • @maegus Thanks, have done, sorry for the delay and glad I could be of assistance and that you have a solution to move forward with. I've tried to explain my thinking behind why it could be happening to help with any future issues, but it's just a best guess, documentation in the area is flaky. – Ross Gurbutt Nov 14 '19 at 01:44

2 Answers2

1

Either or both of the following errors implies that you are trying to use ValueTuples without having either a reference to System.ValueTuple or having a version of mscorlib.dll from NET 4.7 or higher.

error CS8137: Cannot define a class or member that utilizes tuples because the compiler required type 'System.Runtime.CompilerServices.TupleElementNamesAttribute' cannot be found. Are you missing a reference?  
error CS8179: Predefined type 'System.ValueTuple`2' is not defined or imported  

The simple solution is to add a nuget reference to the most up to date version of System.ValueTuple and your project will then build in NET 4.6.1. See here for more details.

The reason why this works locally for you, but doesn't on your build machine is slightly more complex (and entirely theoretical, since I don't have machines of those specs to test it out).

See this question for an explanation of how MSBuild works when it doesn't have the correct targeting pack available.

Your build machine was building your project as requested. MSBuild 15.0 saw that it needed to build a project to target NET 4.6.1, found the correct targeting pack / SDK and pulled in a reference to the NET 4.6.1 mscorlib.dll, and correctly found that with this dll it had no reference to ValueTuples and couldn't build your project.

My guess is (and I'm happy to be wrong here) that you don't have the targeting pack / SDK for Net 4.6.1 installed on you local machine and as such msbuild defaults to the NET framework associated with 15.0 which is (I think) NET 4.7. This means that the mscorlib.dll that gets used is the NET 4.7 one which does contain an in-built ValueTuple type.

Ordinarily adding the nuget reference would cause a conflict for your local build (you have 2 structs from different sources with the same name (ValueTuple)), but Microsoft appear to have done something clever so that the version from the Nuget package is ignored if ValueTuple is contained in the mscorlib.dll. See comments here.

This all feels very nasty, and I personally would prefer if MSBuild threw a hard error if it couldn't find the correct targeting pack, but that's not how it works currently.

Ross Gurbutt
  • 969
  • 1
  • 8
  • 15
0

Thanks to @Ross Gurbutt for pointing in me the right direction. While it's easy to find through googling about the issue related to referencing System.ValueTuple when it's .NET 4.6.1 versus 4.7, what was confusing was that it was compiling successfully on my local without a reference. Nonetheless, I added a reference to the nuget package, and the Windows 2016 server with MSBuild v15.0 was able to build the Web API project successfully

maegus
  • 49
  • 7