@@ -45,39 +45,56 @@ let toDict items =
45
45
let getAllKnownPaths =
46
46
( knownMsBuildEntries |> List.collect ( fun m -> m.Paths) |> List.rev) @ oldMsBuildLocations
47
47
48
+ /// Versions of Mono prior to this one have faulty implementations of MSBuild
49
+ let monoVersionToUseMSBuildOn = System.Version( " 5.0.0.0" )
48
50
49
51
/// Tries to detect the right version of MSBuild.
50
52
/// - On all OS's, we check a `MSBuild` environment variable which is either
51
53
/// * a direct path to a file to use, or
52
- /// * a directory that contains a file called `msbuild` on non-Windows systems, or `MSBuild.exe` on Windows systems
54
+ /// * a directory that contains a file called
55
+ /// * `msbuild` on non-Windows systems with mono >= 5.0.0.0, or
56
+ /// * `xbuild` on non-Windows systems with mono < 5.0.0.0,
57
+ /// * `MSBuild.exe` on Windows systems, or
58
+ /// * a tool that exists on the current PATH
53
59
/// - In addition, on non-Windows systems we check the current PATH for the following binaries, in this order:
54
- /// * `msbuild`
55
- /// * `xbuild`
60
+ /// * Mono >= 5.0.0.0: `msbuild`, `xbuild`
61
+ /// * Mono < 5.0.0.0: `xbuild`, `msbuild`
62
+ /// * This is due to several known issues in the Mono < 5.0 implementation of MSBuild.
56
63
/// - In addition, on Windows systems we
57
64
/// * try to read the MSBuild tool location from the AppSettings file using a parameter named `MSBuild`, and finally
58
65
/// * if a `VisualStudioVersion` environment variable is specified, we try to use the specific MSBuild version, matching that Visual Studio version.
59
66
let msBuildExe =
60
- /// the value we're given can be a full path to a file or just a directory.
67
+ /// the value we're given can be a:
68
+ /// * full path to a file or
69
+ /// * just a directory
61
70
/// if just a directory we can make it the path to a file by Path-Combining the tool name to the directory.
62
71
let exactPathOrBinaryOnPath tool input =
63
72
if FileSystemHelper.isDirectory input && Directory.Exists input
64
73
then input </> tool
65
74
else input
66
75
67
76
let which tool = ProcessHelper.tryFindFileOnPath tool
68
- let environVarDir = EnvironmentHelper.environVarOrNone " MSBuild"
77
+ let msbuildEnvironVar = EnvironmentHelper.environVarOrNone " MSBuild"
69
78
70
- if isUnix
71
- then
72
- let unixSources = [
73
- environVarDir |> Option.map ( exactPathOrBinaryOnPath " msbuild" )
79
+ match isUnix, EnvironmentHelper.monoVersion with
80
+ | true , Some(_, Some( version)) when version >= monoVersionToUseMSBuildOn ->
81
+ let sources = [
82
+ msbuildEnvironVar |> Option.map ( exactPathOrBinaryOnPath " msbuild" )
83
+ msbuildEnvironVar |> Option.bind which
74
84
which " msbuild"
75
85
which " xbuild"
76
86
]
77
- defaultArg ( unixSources |> List.choose id |> List.tryHead) " xbuild"
78
- else
87
+ defaultArg ( sources |> List.choose id |> List.tryHead) " msbuild"
88
+ | true , _ ->
89
+ let sources = [
90
+ msbuildEnvironVar |> Option.map ( exactPathOrBinaryOnPath " xbuild" )
91
+ msbuildEnvironVar |> Option.bind which
92
+ which " xbuild"
93
+ which " msbuild"
94
+ ]
95
+ defaultArg ( sources |> List.choose id |> List.tryHead) " xbuild"
96
+ | false , _ ->
79
97
80
- let envVarPath = environVarDir |> Option.map ( exactPathOrBinaryOnPath " MSBuild.exe" )
81
98
let configIgnoreMSBuild =
82
99
if " true" .Equals( ConfigurationManager.AppSettings.[ " IgnoreMSBuild" ], StringComparison.OrdinalIgnoreCase)
83
100
then Some " "
@@ -90,12 +107,13 @@ let msBuildExe =
90
107
91
108
ProcessHelper.tryFindFileInDirsThenPath vsVersionPaths " MSBuild.exe"
92
109
93
- let windowsSources = [
94
- envVarPath
110
+ let sources = [
111
+ msbuildEnvironVar |> Option.map ( exactPathOrBinaryOnPath " MSBuild.exe" )
112
+ msbuildEnvironVar |> Option.bind which
95
113
configIgnoreMSBuild
96
114
findOnVSPathsThenSystemPath
97
115
]
98
- defaultArg ( windowsSources |> List.choose id |> List.tryHead) " MSBuild.exe"
116
+ defaultArg ( sources |> List.choose id |> List.tryHead) " MSBuild.exe"
99
117
100
118
101
119
/// [omit]
@@ -446,7 +464,9 @@ let MSBuildWithProjectProperties outputPath (targets : string) (properties : (st
446
464
|> Set.unionMany
447
465
448
466
let setBuildParam project projectParams =
449
- { projectParams with Targets = targets |> split ';' |> List.filter ((<>) " " ); Properties = projectParams.Properties @ properties project }
467
+ { projectParams with
468
+ Targets = targets |> split ';' |> List.filter ((<>) " " )
469
+ Properties = projectParams.Properties @ properties project }
450
470
451
471
projects
452
472
|> List.filter ( fun project -> not <| Set.contains project dependencies)
0 commit comments