Skip to content
This repository has been archived by the owner on Apr 16, 2020. It is now read-only.

VisualStudioVersion not passed along in LoadRelease #50

Closed
ctaggart opened this issue Nov 23, 2014 · 11 comments · Fixed by #74
Closed

VisualStudioVersion not passed along in LoadRelease #50

ctaggart opened this issue Nov 23, 2014 · 11 comments · Fixed by #74
Assignees
Milestone

Comments

@ctaggart
Copy link
Owner

When run on AppVeyor, the VsProj.LoadRelease, the VisualStudioVersion ends up evaluating to 10.0 by default. Strangely, it ends up evaluating to 11.0 when I set this in appveyor.yml:

environment:
  VisualStudioVersion: 12.0

My workaround was to pass in the property explicitly:

//        let p = VsProj.LoadRelease proj
        let p = VsProj.Load proj ["Configuration","Release"; "VisualStudioVersion","12.0"]

background:

FSharp.targets for VS 2013 (12.0) and VS 2015 (14.0), this is all that is needed:

<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets" />

VisualStudio will set the VisualStudioVersion property when build from within VisualStudio. When MSBuild is run from the command line, that property get set based on ToolsVersion.

<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />

"C:\Program Files (x86)\MSBuild\12.0\Microsoft.Common.props"

<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.VisualStudioVersion.v*.Common.props" Condition="'$(VisualStudioVersion)' == ''" />

"C:\Program Files (x86)\MSBuild\12.0\Microsoft.VisualStudioVersion.v12.Common.props"
<VisualStudioVersion>12.0</VisualStudioVersion>

@ctaggart ctaggart added the bug label Nov 23, 2014
@ctaggart ctaggart self-assigned this Nov 23, 2014
@ctaggart
Copy link
Owner Author

2012-08-21 Visual Studio project compatibility and VisualStudioVersion

http://blogs.msdn.com/b/webdev/archive/2012/08/22/visual-studio-project-compatability-and-visualstudioversion.aspx

Namespace: Microsoft.Build.Utilities.VisualStudioVersion Enumeration
Assembly: Microsoft.Build.Utilities.Core (in Microsoft.Build.Utilities.Core.dll)

C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.5\Microsoft.Build.dll
image
Meh.

I guess the reason ToolsVersion isn't used in the includes is so that each Visual Studio will use their own templates. I'm not sure this is always wise.
/tv:12.0 $(ProjectToolsVersion)

@ctaggart ctaggart removed the bug label Nov 27, 2014
@ctaggart
Copy link
Owner Author

This isn't a bug. The VisualStudioVersion can be set when load in the project file or defaulted in the project file. I like the idea of defaulting it to the $(ProjectToolsVersion).

@ctaggart
Copy link
Owner Author

ctaggart commented Mar 9, 2015

Closing. This is more of a build issue that was specific to AppVeyor.

@ctaggart ctaggart closed this as completed Mar 9, 2015
@ctaggart
Copy link
Owner Author

I'm reopening this in order to document how it works, if I can figure it out.
AppVeyor recommends setting a VisualStudioVersion environment variable to 12.0 or similar.
http://www.appveyor.com/docs/build-phase#caveats

@ctaggart
Copy link
Owner Author

Now that MSBuild is open source, we can see where VisualStudioVersion is used:
https://github.com/Microsoft/msbuild/search?utf8=%E2%9C%93&q=VisualStudioVersion

I am using Microsoft.Build.Evaluation.Project to load the project files with the constructor to pass in the global properties.

After several hours of troubleshooting on my system, the VisualStudioVersion appears to depend on two things:

  1. the ToolsVersion in the project file
  2. the Microsoft.Common.props if it exists

My PC with VS 2015:
image

AppVeyor:
image

#r "System.Xml"
#r "Microsoft.Build"
#r "Microsoft.Build.Framework"

open Microsoft.Build.Evaluation
open System.Collections.Generic

printfn "%s" typeof<ProjectCollection>.Assembly.Location

let pc = new ProjectCollection()
let d = Dictionary()
d.Add("Configuration", "Release")
let p = Project("vsversion.proj", d, null, pc)

let show = [ "MSBuildToolsVersion"; "MSBuildExtensionsPath"; "VisualStudioVersion" ] |> Set.ofList

p.Properties
|> Seq.filter (fun pr -> show.Contains pr.Name)
|> Seq.iter (fun pr ->
    printfn "%s %s" pr.Name pr.UnevaluatedValue
)
  1. no ToolsVersion and no common.props has no VisualStudioVersion
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</Project>
PS C:\Projects\SourceLink1> Fsi.exe .\vsversion.fsx
C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.Build\v4.0_4.0.0.0__b03f5f7f11d50a3a\Microsoft.Build.dll
MSBuildToolsVersion 2.0
  1. ToolsVersion 4.0 ends up with VisualStudioVersion 11.0
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</Project>
MSBuildToolsVersion 4.0
VisualStudioVersion 11.0
  1. ToolsVersion 12.0 ends up with VisualStudioVersion 12.0
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</Project>
MSBuildToolsVersion 12.0
VisualStudioVersion 12.0
  1. ToolsVersion 14 ends up with VisualStudio 14.0
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</Project>
MSBuildToolsVersion 14.0
VisualStudioVersion 14.0
    1. no ToolsVersion and with common.props has no VisualStudioVersion
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="C:\Projects\msbuild\src\XMakeTasks\Microsoft.Common.props" />
</Project>
MSBuildToolsVersion 2.0
  1. ToolsVersion 4.0 ends up with VisualStudioVersion 11.0
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="C:\Projects\msbuild\src\XMakeTasks\Microsoft.Common.props" />
</Project>
MSBuildToolsVersion 11.0
  1. ToolsVersion 12.0 ends up with VisualStudioVersion 10.0
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="C:\Projects\msbuild\src\XMakeTasks\Microsoft.Common.props" />
</Project>
MSBuildToolsVersion 10.0
  1. ToolsVersion 14.0 ends up with VisualStudioVersion 10.0
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="C:\Projects\msbuild\src\XMakeTasks\Microsoft.Common.props" />
</Project>
MSBuildToolsVersion 10.0

I consider 7 & 8 to be bugs. I think this is the cause:
https://github.com/Microsoft/msbuild/blob/master/src/XMakeTasks/Microsoft.Common.props#L38

Looking at the current SourceLink.fsproj:
image
There may be a couple of options. To solve for VS 2013 and higher, may be just set:

<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">$(MSBuildToolsVersion )</VisualStudioVersion>

That would have to be done before Microsoft.Common.props is included. May be see if Microsoft.Common.props can be removed.

@ctaggart
Copy link
Owner Author

If there was an open source binary of the required MSBuild library, I would bundle it. Switching to this is sometimes a pain and Microsoft.Common.props is often included.

VsProj.Load proj ["Configuration","Release"; "VisualStudioVersion","12.0"]

May be I can build my own source indexed MSBuild library to bundle. :-)

@ctaggart ctaggart reopened this Apr 13, 2015
@ctaggart ctaggart added this to the 0.6.0 milestone Apr 13, 2015
@ctaggart
Copy link
Owner Author

ctaggart commented May 3, 2015

The problem is that just doing a #r "Microsoft.Build" leads to 4.0.0 being used instead of the latest, 12.0.0 or 14.0.0.

image

image

#r "Microsoft.Build"
open Microsoft.Build.Evaluation
printfn "%s" typeof<ProjectCollection>.Assembly.Location

image

$env:path = "C:\Program Files (x86)\Microsoft SDKs\F#\3.1\Framework\v4.0;$env:path"

image

How do I reference the latest Microsoft.Build on a system?

@ctaggart
Copy link
Owner Author

ctaggart commented May 3, 2015

@ctaggart
Copy link
Owner Author

ctaggart commented May 5, 2015

image

@ctaggart ctaggart reopened this May 5, 2015
@ctaggart
Copy link
Owner Author

ctaggart commented May 5, 2015

Looks like Microsoft.Build.Utilities.Core assembly is a runtime dependency.
.
image

https://github.com/Microsoft/msbuild/blob/db88c6ee0902fc86298d34b80047de9aaf57e5be/src/XMakeBuildEngine/Resources/Constants.cs#L345

"C:\Program Files (x86)\MSBuild\14.0\Bin\Microsoft.Build.Utilities.Core.dll"

ctaggart pushed a commit that referenced this issue May 6, 2015
@ctaggart
Copy link
Owner Author

ctaggart commented May 7, 2015

Fixed! The SourceLink.MSBuild used to publish it is here:
https://www.nuget.org/packages/SourceLink.MSBuild/

Code is here:
https://github.com/ctaggart/msbuild

Blog post is in progress.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant