Home > Software design >  Delphi 11: Find correct toolsversion for MSBuild programmatically
Delphi 11: Find correct toolsversion for MSBuild programmatically

Time:07-14

We're upgrading to Delphi 11.1 from 10.4.

We have a few scripts which build and deploy Android projects. They assemble an msbuild command that looked like this:

msbuild someproject.dproj /v:q   /p:Platform=Android /t:Build;Deploy  /p:Config=Release /p:BT_BuildType=AppStore

With 11.1, this throws an error message:

C:\Program Files (x86)\Embarcadero\Studio\22.0\bin\CodeGear.Common.Targets(940,7): error MSB4036: The "XmlPeek" task was not found. Check the following: 1.) The name of the task in the project file is the same as the name of the task class. 2.) The task class is "public" and implements the Microsoft.Build.Framework.ITask interface. 3.) The task is correctly declared with <UsingTask> in the project file, or in the *.tasks files located in the "C:\Windows\Microsoft.NET\Framework\v2.0.50727" directory. [someproject.dproj]

Now, C:\Program Files (x86)\Embarcadero\Studio\22.0\bin\rsvars.bat, which is used by all of our build scripts, explicitly sets the .NET framework as below:

@SET FrameworkDir=C:\Windows\Microsoft.NET\Framework\v4.0.30319
@SET FrameworkVersion=v4.5 

After some research, I hit on the idea of adding a toolsversion parameter to the msbuild command as below, and this worked:

msbuild someproject.dproj /v:q   /p:Platform=Android /t:Build;Deploy  /p:Config=Release /p:BT_BuildType=AppStore  /toolsversion:4.0

This is all well and good, but I would prefer not to hard-code the toolsversion number in the script(s).

Is there a way I can programmatically obtain the correct value of the toolsversion that Delphi itself is using when it generates builds, etc.?

I assume that just finding the highest .NET version installed will not suffice (and even then, one has to "translate" that to a toolsversion). It has to marry up with whatever Delphi is doing (e.g., in the CodeGear.Common.Targets file referenced in the original error message).

CodePudding user response:

Assuming that rsvars.bat has been run,

FOR %%v IN ("%frameworkdir%") DO SET "toolsversion=%%~nv"
ECHO msbuild ...blah...  /toolsversion:%toolsversion:~1%

The variable frameworkdir will be set by rsvars.bat. The for command parses its value (eg. C:\Windows\Microsoft.NET\Framework\v4.0.30319 as though it is a filename, and picks v4.0 as the "filename" (~n modifier [filename] of the metavariable %%v)

Then use the value assigned to toolsversion, starting at character 1 (where the first character is "character 0")

CodePudding user response:

This is a bug in Delphi 11.1 that has at least 3 bug reports: RSP-37855, RSP-38466, and RSP-38467.

You can add /tv:4.0 to your MSBuild command line, or modify the first line in the .dproj file to:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0" DefaultTargets="Build">
  • Related