How Can I Tell NuGet What MSBuild Executable to Use? - msbuild

NuGet apparently has some logic to determine what MSBuild Executable to use. Is there a way to override this behavior? Or at least a way to tell it to use the x86 MSBuild instead of x64?
MSBuild auto-detection: using msbuild version '14.0' from 'C:\Program Files (x86)\MSBuild\14.0\bin\amd64'.

From the command-line documentation, you can specify -MSBuildPath or -MSBuildVersion on the command line.
MSBuildPath (4.0+) Specifies the path of MSBuild to use with the
command, taking precedence over -MSBuildVersion.
MSBuildVersion (3.2+)
Specifies the version of MSBuild to be used with this command.
Supported values are 4, 12, 14, 15. By default the MSBuild in your
path is picked, otherwise it defaults to the highest installed version
of MSBuild.

The msbuild version used by nuget command line on mono is hard coded:
Cf source code https://github.com/NuGet/NuGet.Client/blob/f24bad0668193ce21a1db8cabd1ce95ba509c7f0/src/NuGet.Clients/NuGet.CommandLine/MsBuildUtility.cs
The offending method is GetMsBuildFromMonoPaths(...)
There is no env var to override it. It's called "auto detection" lol.
A solution is to move away the /Library/Frameworks/Mono.framework/Versions/6.12.0/lib/mono/msbuild/15.0 folder, install msbuild 16.0 using dotnet-install.sh method (use version 5.0.402 for msbuild 16), and create a symbolic link from dotnet/sdk/$netcoreversion to the hard coded path /Library/Frameworks/Mono.framework/Versions/6.12.0/lib/mono/msbuild/15.0

Related

How to specify environment variables in .csproj file

How can I, through the .csproj file, specify environment variables to apply during the build, such as when building with Rider?
Specifically, I want to set DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1 so that I can build from within the IDE, without resorting to the command line (see below).
Adding <InvariantGlobalization>true</InvariantGlobalization> to the project file did not work, since that does not affect the underlying/imported build target, but executing export DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1 before dotnet build NAME.csproj worked.
Background: A recent distro upgrade on openSuse Tumbleweed bricked MonoGame project builds with the following error message when invoking mgcb (re-installing ICU with Zypper did not fix the issue):
Couldn't find a valid ICU package installed on the system. Set the configuration flag System.Globalization.Invariant to true if you want to run with no globalization support.
(...)
error MSB3073: The command "dotnet (...) exited with code 134
Edit: I have finally gotten a Target to run before the Nopipeline target using InitialTargets. The problem now is the Exec task runs in a discarded scope.
Depending on which task fails, you can hope that the target author added an option to set the environment variables.
E.g. for C# compilation, you could set:
<PropertyGroup>
<CscEnvironment>$(CscEnvironment);DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1</CscEnvironment>
</PropertyGroup>
If the tool is run by a custom target, you would need to author a replacement target that allows setting the environment variable.

MSBuild /t:Pack with a .nuspec file - does it support token replacement? [duplicate]

I know Since the release of msbuild 15 (vs 2017) that NuGet is now fully integrated into MSBuild.
I have a nuspec file with defining variables of package properties like:
<metadata>
<id>$id$</id>
<version>$version$</version>
<authors>$authors$</authors>
...
</metadata>
The nuspec file is located in the same folder of the project.
When using nuget tool to create the package , it works fine.
nuget pack
When using msbuild v15, it raise an exception.
run the command:
msbuild -version
Microsoft (R) Build Engine version 15.8.168+ga8fba1ebd7 for .NET Framework
15.8.168.64424
msbuild /t:pack /p:configuration=release /p:NuspecFile=mylib.nuspec
raise exception:
C:\Program Files\dotnet\sdk\2.1.402\Sdks\NuGet.Build.Tasks.Pack\build\NuGet.Build.Tasks.Pack.targets(199,5): error : Value cannot be null or an empty string.
The strange is that dotnet sdk version 2.1.402 raises the exception.
I tried msbuild installed with vs2017 with its path and also it raises the same exception.
When i substitute the variables with its values, msbuild is working fine.
The question
Is this a bug in msbuild version 15.8.168.64424 or i missed something ?
In other words, Can msbuild support using the metadata variables of the package?.
As has been mentioned in the comments, you no longer need a Nuspec file as most aspects can be controlled via properties in the csproj file or additional metadata on items (e.g. if you need additional content).
If you do need a nuspec file for some reason, you need to provide the variables for substitution yourself. You can do this in a target inside the csproj file like this:
<Target Name="SetNuspecProperties" BeforeTargets="GenerateNuspec">
<PropertyGroup>
<NuspecProperties>$(NuspecProperties);id=$(AssemblyName)</NuspecProperties>
<NuspecProperties>$(NuspecProperties);config=$(Configuration)</NuspecProperties>
<NuspecProperties>$(NuspecProperties);version=$(PackageVersion)</NuspecProperties>
<NuspecProperties>$(NuspecProperties);description=$(Description)</NuspecProperties>
<NuspecProperties>$(NuspecProperties);authors=$(Authors)</NuspecProperties>
</PropertyGroup>
</Target>

TFS 2013 using VS2015 MSBuild with TfvcTemplate.12.xaml template

After adding MSBuild arguments:
/tv:14.0 /p:VisualStudioVersion=14
I get the following error message:
C:\Builds\10\IW_*****\Dev\src\Sites\******\Properties\CompileLicxFiles_Patched.targets (98): The "LC" task was not given a value for the required parameter "TargetFrameworkVersion".
I'm trying to build using VS2015 (TFS2013 server)
Found this: https://connect.microsoft.com/VisualStudio/feedback/details/1406942/new-required-lc-task-parameter-targetframeworkversion
However, I've checked and all projects in the solution have 4.5.2 version assigned.
Log (it seems it's still using VS2013):
Added package 'NEST.1.9.1' to folder ...
Added package 'FluentAssertions.4.17.0'....
...
C:\Program Files (x86)\MSBuild\12.0\bin\amd64\MSBuild.exe /nologo /noconsolelogger "C:\Builds\10\IW_****\Dev\src\Solution123.All.sln" /nr:False /fl
To use VS 2015, the argument should be /p:VisualStudioVersion=14.0.
First thing first.
I was using VS2015 to edit TfvcTemplate.12.xaml build template which cased issues. For some reason, when using VS2015 - it was modifying the xaml document incorrectly. To make any type of changes to TfvcTemplate.12.xaml template you have to use VS2013!
TfvcTemplate.12.xaml does not contain "ToolPath" variable. To make this work I simply added "14.0" (quotes necessary) under "ToolVersion"
TFS2013 will use VS2015 MSBuild to run the build. No need for MSBuild command line switches. Works without them.
Output log:
Run MSBuild00:13:39 C:\Program Files\Microsoft Team Foundation Server
12.0\Tools\nuget.exe restore "C:\Builds\9************\packageRestore.proj" -NonInteractive MSBuild
auto-detection: using msbuild version '14.0' from 'C:\Program Files
(x86)\MSBuild\14.0\bin'.
You could also just modify your build definition with Visual Studio. On the process tab of the build definition that uses TfvcTemplate.12.xaml expand 2.5 section to see the MSBuild arguments. Add the below arguments to the build definition and save it. I assume your problem was you had /p:VisualStudioVersion=14 instead of /p:VisualStudioVersion=14.0.
/p:VisualStudioVersion=14.0 /tv:14.0

MSBUILDEMITSOLUTION not working with .NET 4?

In prior versions of MSBuild, you could set an environment variable named MSBUILDEMITSOLUTION to 1 to get an XML version of a solution (.sln) file that could be parsed. According to the MSBuild Team Blog, that's still in the version that ships with Visual Studio 2010, but it does not seem to be working.
Has anyone managed to get this working with MSBuild 4.0? If so, what is required?
(We use this to find and run convention-based unit tests with an NAnt script.)
Set MSBuildEmitSolution=1 and then build from the command line. You should then see a MySolution.sln.metaproj file near MySolution.sln.
Notes:
If you open a command prompt window, then set the env var via System Settings, you will have to open a new command prompt.
You'd think you could also use msbuild /p:MSBuildEmitSolution=1, but you can't.

Nant msbuild task with .net 4.0 rc

How do I need to indicate to the msbuild task in my nant script that it should use .net 4.0 rc?
I think the latest NAnt/NAntContrib defaults to .NET 3.5, so you'll have to change that to 4.0. There is a NAnt property to handle that (<property name="nant.settings.currentframework" value="net-4.0" />), which should go near the top of your NAnt build file.
Next, you'll need to go into your NAnt's configuration file and add the 4.0 node, so that NAnt (and by extension NantContrib) are aware of the new CLR version.
The first option is to change the executable that MSBuild task uses. According to the doco this is a framework property so you would need to change it in the main nant config file rather than in you're individual script, and you would have to do it on every machine you plan on building the script on.
The other option is to use the exec task instead. This question and answer should help with that.
EDIT: Forgot to mention the directories MSBuild is in. To change versions just use a different MSBuild.
2.0: %windir%\Microsoft.NET\Framework\v2.0.50727\MSBuild.exe
3.5: %windir%\Microsoft.NET\Framework\v3.5\MSBuild.exe
4.0b2: %windir%\Microsoft.NET\Framework\v4.0.21006\MSBuild.exe