diff --git a/.gitignore b/.gitignore
index 1a7e530e494..a4c90c19878 100644
--- a/.gitignore
+++ b/.gitignore
@@ -121,3 +121,6 @@ tests/fsharpqa/testenv/bin/System.ValueTuple.dll
*/.fake
/fcs/packages/
*/paket-files/
+/fcs/TestResult.xml
+/tests/fcs/
+/fcs/.paket/Paket.Restore.targets
diff --git a/build.cmd b/build.cmd
index b24937a8647..7431a36c19e 100644
--- a/build.cmd
+++ b/build.cmd
@@ -538,10 +538,16 @@ set _ngenexe="%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\ngen.exe"
if not exist %_ngenexe% echo Error: Could not find ngen.exe. && goto :failure
echo ---------------- Done with prepare, starting package restore ----------------
+
set _nugetexe="%~dp0.nuget\NuGet.exe"
set _nugetconfig="%~dp0.nuget\NuGet.Config"
if "%RestorePackages%" == "true" (
+ cd fcs
+ .paket\paket.exe restore
+ cd..
+ @if ERRORLEVEL 1 echo Error: Paket restore failed && goto :failure
+
%_ngenexe% install %_nugetexe% /nologo
%_nugetexe% restore packages.config -PackagesDirectory packages -ConfigFile %_nugetconfig%
diff --git a/build.sh b/build.sh
index 6c3323a4f9b..561a129c522 100755
--- a/build.sh
+++ b/build.sh
@@ -412,6 +412,14 @@ _nugetconfig=".nuget/NuGet.Config"
# Restore packages (default to restoring packages if otherwise unspecified).
if [ "${RestorePackages:-true}" = 'true' ]; then
+ cd fcs
+ mono .paket/paket.exe restore
+ cd ..
+ exit_code=$?
+ if [ $exit_code -ne 0 ]; then
+ exit $exit_code
+ fi
+
eval "$_nugetexe restore packages.config -PackagesDirectory packages -ConfigFile $_nugetconfig"
if [ $? -ne 0 ]; then
failwith "Nuget restore failed"
diff --git a/fcs/.paket/Paket.Restore.targets b/fcs/.paket/Paket.Restore.targets
deleted file mode 100644
index 67f745a3671..00000000000
--- a/fcs/.paket/Paket.Restore.targets
+++ /dev/null
@@ -1,225 +0,0 @@
-
-
-
-
-
-
- $(MSBuildAllProjects);$(MSBuildThisFileFullPath)
-
- true
- $(MSBuildThisFileDirectory)
- $(MSBuildThisFileDirectory)..\
- $(PaketRootPath)paket-files\paket.restore.cached
- $(PaketRootPath)paket.lock
- /Library/Frameworks/Mono.framework/Commands/mono
- mono
-
- $(PaketRootPath)paket.exe
- $(PaketToolsPath)paket.exe
- "$(PaketExePath)"
- $(MonoPath) --runtime=v4.0.30319 "$(PaketExePath)"
- $(PaketRootPath)paket.bootstrapper.exe
- $(PaketToolsPath)paket.bootstrapper.exe
- "$(PaketBootStrapperExePath)"
- $(MonoPath) --runtime=v4.0.30319 "$(PaketBootStrapperExePath)"
-
-
-
-
- true
- true
-
-
-
-
-
-
- true
- $(NoWarn);NU1603
-
-
-
- $([System.IO.File]::ReadAllText('$(PaketRestoreCacheFile)'))
- $([System.IO.File]::ReadAllText('$(PaketLockFilePath)'))
- true
- false
- true
-
-
-
-
-
-
-
-
- $(MSBuildProjectDirectory)\obj\$(MSBuildProjectFile).paket.references.cached
-
- $(MSBuildProjectFullPath).paket.references
-
- $(MSBuildProjectDirectory)\$(MSBuildProjectName).paket.references
-
- $(MSBuildProjectDirectory)\paket.references
- $(MSBuildProjectDirectory)\obj\$(MSBuildProjectFile).$(TargetFramework).paket.resolved
- true
- references-file-or-cache-not-found
-
-
-
-
- $([System.IO.File]::ReadAllText('$(PaketReferencesCachedFilePath)'))
- $([System.IO.File]::ReadAllText('$(PaketOriginalReferencesFilePath)'))
- references-file
- false
-
-
-
-
- false
-
-
-
-
- true
- target-framework '$(TargetFramework)'
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[0])
- $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[1])
-
-
- %(PaketReferencesFileLinesInfo.PackageVersion)
-
-
-
-
- $(MSBuildProjectDirectory)/obj/$(MSBuildProjectFile).NuGet.Config
-
-
-
-
-
-
- false
-
-
-
-
-
- $(MSBuildProjectDirectory)/$(MSBuildProjectFile)
- true
- false
- true
-
-
-
- <_NuspecFiles Include="$(BaseIntermediateOutputPath)*.nuspec"/>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/fcs/FSharp.Compiler.Service.MSBuild.v12/FSharp.Compiler.Service.MSBuild.v12.fsproj b/fcs/FSharp.Compiler.Service.MSBuild.v12/FSharp.Compiler.Service.MSBuild.v12.fsproj
index e929138c567..f66cda2f775 100644
--- a/fcs/FSharp.Compiler.Service.MSBuild.v12/FSharp.Compiler.Service.MSBuild.v12.fsproj
+++ b/fcs/FSharp.Compiler.Service.MSBuild.v12/FSharp.Compiler.Service.MSBuild.v12.fsproj
@@ -89,4 +89,4 @@
-
\ No newline at end of file
+
diff --git a/fcs/FSharp.Compiler.Service.ProjectCracker/ProjectCracker.fs b/fcs/FSharp.Compiler.Service.ProjectCracker/ProjectCracker.fs
index 45fab18685b..7a36085de06 100644
--- a/fcs/FSharp.Compiler.Service.ProjectCracker/ProjectCracker.fs
+++ b/fcs/FSharp.Compiler.Service.ProjectCracker/ProjectCracker.fs
@@ -8,18 +8,17 @@ open System.Diagnostics
open System.Text
open System.IO
open System
+open System.Xml
-type ProjectCracker =
- static member GetProjectOptionsFromProjectFileLogged(projectFileName : string, ?properties : (string * string) list, ?loadedTimeStamp, ?enableLogging) =
- let loadedTimeStamp = defaultArg loadedTimeStamp DateTime.MaxValue // Not 'now', we don't want to force reloading
- let properties = defaultArg properties []
- let enableLogging = defaultArg enableLogging true
+module Utils =
+
+ let Convert loadedTimeStamp (originalOpts: ProjectCrackerTool.ProjectOptions) =
let logMap = ref Map.empty
- let rec convert (opts: ProjectCrackerTool.ProjectOptions) : FSharpProjectOptions =
+ let rec convertProject (opts: ProjectCrackerTool.ProjectOptions) =
if not (isNull opts.Error) then failwith opts.Error
- let referencedProjects = Array.map (fun (a, b) -> a, convert b) opts.ReferencedProjectOptions
+ let referencedProjects() = Array.map (fun (a, b) -> a,convertProject b) opts.ReferencedProjectOptions
let sourceFiles, otherOptions =
opts.Options
@@ -41,7 +40,7 @@ type ProjectCracker =
{ ProjectFileName = opts.ProjectFile
SourceFiles = sourceFiles
OtherOptions = otherOptions
- ReferencedProjects = referencedProjects
+ ReferencedProjects = referencedProjects()
IsIncompleteTypeCheckEnvironment = false
UseScriptResolutionRules = false
LoadTime = loadedTimeStamp
@@ -50,6 +49,16 @@ type ProjectCracker =
ExtraProjectInfo = None
Stamp = None }
+ convertProject originalOpts, !logMap
+
+type ProjectCracker =
+
+ static member GetProjectOptionsFromProjectFileLogged(projectFileName : string, ?properties : (string * string) list, ?loadedTimeStamp, ?enableLogging) =
+ let loadedTimeStamp = defaultArg loadedTimeStamp DateTime.MaxValue // Not 'now', we don't want to force reloading
+ let properties = defaultArg properties []
+ let enableLogging = defaultArg enableLogging true
+
+
#if NETSTANDARD1_6
let arguments = [|
yield projectFileName
@@ -70,20 +79,47 @@ type ProjectCracker =
let codebase = Path.GetDirectoryName(Uri(typeof.Assembly.CodeBase).LocalPath)
let crackerFilename = Path.Combine(codebase,"FSharp.Compiler.Service.ProjectCrackerTool.exe")
- if not (File.Exists crackerFilename) then failwithf "ProjectCracker exe not found at: %s it must be next to the ProjectCracker dll." crackerFilename
+ if not (File.Exists crackerFilename) then
+ failwithf "ProjectCracker exe not found at: %s it must be next to the ProjectCracker dll." crackerFilename
+
let p = new System.Diagnostics.Process()
+
p.StartInfo.FileName <- crackerFilename
p.StartInfo.Arguments <- arguments.ToString()
p.StartInfo.UseShellExecute <- false
p.StartInfo.CreateNoWindow <- true
p.StartInfo.RedirectStandardOutput <- true
+ p.StartInfo.RedirectStandardError <- true
+
+ let sbOut = StringBuilder()
+ let sbErr = StringBuilder()
+
+ p.ErrorDataReceived.AddHandler(fun _ a -> sbErr.AppendLine a.Data |> ignore)
+ p.OutputDataReceived.AddHandler(fun _ a -> sbOut.AppendLine a.Data |> ignore)
+
ignore <| p.Start()
- let ser = new DataContractJsonSerializer(typeof)
- let opts = ser.ReadObject(p.StandardOutput.BaseStream) :?> ProjectCrackerTool.ProjectOptions
+ p.EnableRaisingEvents <- true
+ p.BeginOutputReadLine()
+ p.BeginErrorReadLine()
+
+ p.WaitForExit()
+
+ let crackerOut = sbOut.ToString()
+ let crackerErr = sbErr.ToString()
+
+ let opts =
+ try
+ let ser = new DataContractJsonSerializer(typeof)
+ let stringBytes = Encoding.Unicode.GetBytes crackerOut
+ use ms = new MemoryStream(stringBytes)
+ ser.ReadObject(ms) :?> ProjectCrackerTool.ProjectOptions
+ with
+ exn ->
+ raise (Exception(sprintf "error parsing ProjectCrackerTool output, stdoutput was:\n%s\n\nstderr was:\n%s" crackerOut crackerErr, exn))
#endif
- convert opts, !logMap
+ Utils.Convert loadedTimeStamp opts
static member GetProjectOptionsFromProjectFile(projectFileName : string, ?properties : (string * string) list, ?loadedTimeStamp) =
fst (ProjectCracker.GetProjectOptionsFromProjectFileLogged(
diff --git a/fcs/FSharp.Compiler.Service.ProjectCrackerTool/FSharp.Compiler.Service.ProjectCrackerTool.fsproj b/fcs/FSharp.Compiler.Service.ProjectCrackerTool/FSharp.Compiler.Service.ProjectCrackerTool.fsproj
index 07bae7e5765..66d196a1d54 100644
--- a/fcs/FSharp.Compiler.Service.ProjectCrackerTool/FSharp.Compiler.Service.ProjectCrackerTool.fsproj
+++ b/fcs/FSharp.Compiler.Service.ProjectCrackerTool/FSharp.Compiler.Service.ProjectCrackerTool.fsproj
@@ -46,24 +46,9 @@
+
-
- $(FSharpSourcesRoot)/../fcs/dependencies/MSBuild.v14.0/Microsoft.Build.Framework.dll
- false
-
-
- $(FSharpSourcesRoot)/../fcs/dependencies/MSBuild.v14.0/Microsoft.Build.Engine.dll
- false
-
-
- $(FSharpSourcesRoot)/../fcs/dependencies/MSBuild.v14.0/Microsoft.Build.dll
- false
-
-
- $(FSharpSourcesRoot)/../fcs/dependencies/MSBuild.v12.0/Microsoft.Build.Utilities.v12.0.dll
- false
-
@@ -71,13 +56,75 @@
-
$(FSharpSourcesRoot)\..\packages\Microsoft.Portable.FSharp.Core.4.1.20\lib\profiles\net40\FSharp.Core.dll
false
-
+
+
+
+
+ ..\packages\Microsoft.Build\lib\net45\Microsoft.Build.dll
+ True
+ True
+
+
+
+
+
+
+
+
+ ..\packages\Microsoft.Build.Engine\lib\net45\Microsoft.Build.Engine.dll
+ True
+ True
+
+
+
+
+
+
+
+
+ ..\packages\Microsoft.Build.Framework\lib\net45\Microsoft.Build.Framework.dll
+ True
+ True
+
+
+
+
+
+
+
+
+ ..\packages\Microsoft.Build.Utilities.Core\lib\net45\Microsoft.Build.Utilities.Core.dll
+ True
+ True
+
+
+
+
+
+
+
+
+ True
+
+
+
+
+
+
+
+
+ ..\packages\System.Threading.Tasks.Dataflow\lib\portable-net45+win8+wpa81\System.Threading.Tasks.Dataflow.dll
+ True
+ True
+
+
+
+
\ No newline at end of file
diff --git a/fcs/FSharp.Compiler.Service.ProjectCrackerTool/Program.fs b/fcs/FSharp.Compiler.Service.ProjectCrackerTool/Program.fs
index ed8a8b15992..7ce360c312f 100644
--- a/fcs/FSharp.Compiler.Service.ProjectCrackerTool/Program.fs
+++ b/fcs/FSharp.Compiler.Service.ProjectCrackerTool/Program.fs
@@ -1,21 +1,46 @@
namespace Microsoft.FSharp.Compiler.SourceCodeServices.ProjectCrackerTool
open System
-open System.IO
+open System.Reflection
open System.Runtime.Serialization.Json
module Program =
- []
- let main argv =
- let text = Array.exists (fun (s: string) -> s = "--text") argv
- let argv = Array.filter (fun (s: string) -> s <> "--text") argv
+#if !DOTNETCORE
+ let addMSBuildv14BackupResolution () =
+ let onResolveEvent = new ResolveEventHandler(fun sender evArgs ->
+ let requestedAssembly = AssemblyName(evArgs.Name)
+ if requestedAssembly.Name.StartsWith("Microsoft.Build") &&
+ not (requestedAssembly.Name.EndsWith(".resources")) &&
+ not (requestedAssembly.Version.ToString().Contains("12.0.0.0"))
+ then
+ // If the version of MSBuild that we're using wasn't present on the machine, then
+ // just revert back to 12.0.0.0 since that's normally installed as part of the .NET
+ // Framework.
+ requestedAssembly.Version <- Version("12.0.0.0")
+ Assembly.Load requestedAssembly
+ else
+ null)
+ AppDomain.CurrentDomain.add_AssemblyResolve(onResolveEvent)
+#endif
+ let crackAndSendOutput asText argv =
let ret, opts = ProjectCrackerTool.crackOpen argv
- if text then
+ if asText then
printfn "%A" opts
else
let ser = new DataContractJsonSerializer(typeof)
ser.WriteObject(Console.OpenStandardOutput(), opts)
ret
+
+
+ [][]
+ let main argv =
+ let asText = Array.exists (fun (s: string) -> s = "--text") argv
+ let argv = Array.filter (fun (s: string) -> s <> "--text") argv
+
+#if !DOTNETCORE
+ addMSBuildv14BackupResolution ()
+#endif
+ crackAndSendOutput asText argv
diff --git a/fcs/FSharp.Compiler.Service.ProjectCrackerTool/ProjectCrackerTool.fs b/fcs/FSharp.Compiler.Service.ProjectCrackerTool/ProjectCrackerTool.fs
index 9be9c375370..a20c7a33c0e 100644
--- a/fcs/FSharp.Compiler.Service.ProjectCrackerTool/ProjectCrackerTool.fs
+++ b/fcs/FSharp.Compiler.Service.ProjectCrackerTool/ProjectCrackerTool.fs
@@ -2,12 +2,13 @@
open System
open System.IO
-open System.Reflection
open System.Text
open Microsoft.Build.Framework
open Microsoft.Build.Utilities
module internal ProjectCrackerTool =
+ open System.Collections.Generic
+ open Microsoft.Build.Evaluation
let runningOnMono =
#if DOTNETCORE
@@ -36,17 +37,159 @@ module internal ProjectCrackerTool =
member th.Compile(_:obj, _:obj, _:obj) = 0
interface ITaskHost
+ let vs =
+ let programFiles =
+ let getEnv v =
+ let result = System.Environment.GetEnvironmentVariable(v)
+ match result with
+ | null -> None
+ | _ -> Some result
+
+ match List.tryPick getEnv [ "ProgramFiles(x86)"; "ProgramFiles" ] with
+ | Some r -> r
+ | None -> "C:\\Program Files (x86)"
+
+ let vsVersions = ["14.0"; "12.0"]
+ let msbuildBin v = IO.Path.Combine(programFiles, "MSBuild", v, "Bin", "MSBuild.exe")
+ List.tryFind (fun v -> IO.File.Exists(msbuildBin v)) vsVersions
+
+ let mkAbsolute dir v =
+ if Path.IsPathRooted v then v
+ else Path.Combine(dir, v)
+
+ let mkAbsoluteOpt dir v = Option.map (mkAbsolute dir) v
+
+ let CrackProjectUsingNewBuildAPI fsprojFile properties logOpt =
+ let fsprojFullPath = try Path.GetFullPath(fsprojFile) with _ -> fsprojFile
+ let fsprojAbsDirectory = Path.GetDirectoryName fsprojFullPath
+
+ use _pwd =
+ let dir = Directory.GetCurrentDirectory()
+ Directory.SetCurrentDirectory(fsprojAbsDirectory)
+ { new System.IDisposable with
+ member x.Dispose() = Directory.SetCurrentDirectory(dir) }
+ use engine = new Microsoft.Build.Evaluation.ProjectCollection()
+ let host = new HostCompile()
+
+ engine.HostServices.RegisterHostObject(fsprojFullPath, "CoreCompile", "Fsc", host)
+
+ let projectInstanceFromFullPath (fsprojFullPath: string) =
+ use file = new FileStream(fsprojFullPath, FileMode.Open, FileAccess.Read, FileShare.Read)
+ use stream = new StreamReader(file)
+ use xmlReader = System.Xml.XmlReader.Create(stream)
+
+ let project =
+ try
+ engine.LoadProject(xmlReader, FullPath=fsprojFullPath)
+ with
+ | exn ->
+ let tools = engine.Toolsets |> Seq.map (fun x -> x.ToolsPath) |> Seq.toList
+ raise (new Exception(sprintf "Could not load project %s in ProjectCollection. Available tools: %A. Message: %s" fsprojFullPath tools exn.Message))
+
+ project.SetGlobalProperty("BuildingInsideVisualStudio", "true") |> ignore
+ if not (List.exists (fun (p,_) -> p = "VisualStudioVersion") properties) then
+ match vs with
+ | Some version -> project.SetGlobalProperty("VisualStudioVersion", version) |> ignore
+ | None -> ()
+ project.SetGlobalProperty("ShouldUnsetParentConfigurationAndPlatform", "false") |> ignore
+ for (prop, value) in properties do
+ project.SetGlobalProperty(prop, value) |> ignore
+
+ project.CreateProjectInstance()
+
+ let project = projectInstanceFromFullPath fsprojFullPath
+ let directory = project.Directory
+
+ let getprop (p: Microsoft.Build.Execution.ProjectInstance) s =
+ let v = p.GetPropertyValue s
+ if String.IsNullOrWhiteSpace v then None
+ else Some v
+
+ let outFileOpt = getprop project "TargetPath"
+
+ let log = match logOpt with
+ | None -> []
+ | Some l -> [l :> ILogger]
+
+ project.Build([| "Build" |], log) |> ignore
+
+ let getItems s = [ for f in project.GetItems(s) -> mkAbsolute directory f.EvaluatedInclude ]
+
+ let projectReferences =
+ [ for cp in project.GetItems("ProjectReference") do
+ yield cp.GetMetadataValue("FullPath")
+ ]
+
+ let references =
+ [ for i in project.GetItems("ReferencePath") do
+ yield i.EvaluatedInclude
+ for i in project.GetItems("ChildProjectReferences") do
+ yield i.EvaluatedInclude ]
+
+ outFileOpt, directory, getItems, references, projectReferences, getprop project, project.FullPath
+
+#if !DOTNETCORE
+ let CrackProjectUsingOldBuildAPI (fsprojFile:string) properties logOpt =
+ let engine = new Microsoft.Build.BuildEngine.Engine()
+ Option.iter (fun l -> engine.RegisterLogger(l)) logOpt
+
+ let bpg = Microsoft.Build.BuildEngine.BuildPropertyGroup()
+
+ bpg.SetProperty("BuildingInsideVisualStudio", "true")
+ for (prop, value) in properties do
+ bpg.SetProperty(prop, value)
+
+ engine.GlobalProperties <- bpg
+
+ let projectFromFile (fsprojFile:string) =
+ // We seem to need to pass 12.0/4.0 in here for some unknown reason
+ let project = new Microsoft.Build.BuildEngine.Project(engine, engine.DefaultToolsVersion)
+ do project.Load(fsprojFile)
+ project
+
+ let project = projectFromFile fsprojFile
+ project.Build([| "ResolveReferences" |]) |> ignore
+ let directory = Path.GetDirectoryName project.FullFileName
+
+ let getProp (p: Microsoft.Build.BuildEngine.Project) s =
+ let v = p.GetEvaluatedProperty s
+ if String.IsNullOrWhiteSpace v then None
+ else Some v
+
+ let outFileOpt =
+ match mkAbsoluteOpt directory (getProp project "OutDir") with
+ | None -> None
+ | Some d -> mkAbsoluteOpt d (getProp project "TargetFileName")
+
+ let getItems s =
+ let fs = project.GetEvaluatedItemsByName(s)
+ [ for f in fs -> mkAbsolute directory f.FinalItemSpec ]
+
+ let projectReferences =
+ [ for i in project.GetEvaluatedItemsByName("ProjectReference") do
+ yield mkAbsolute directory i.FinalItemSpec
+ ]
+
+ let references =
+ [ for i in project.GetEvaluatedItemsByName("ReferencePath") do
+ yield i.FinalItemSpec
+ for i in project.GetEvaluatedItemsByName("ChildProjectReferences") do
+ yield i.FinalItemSpec ]
+ // Duplicate slashes sometimes appear in the output here, which prevents
+ // them from matching keys used in FSharpProjectOptions.ReferencedProjects
+ |> List.map (fun (s: string) -> s.Replace("//","/"))
+
+ outFileOpt, directory, getItems, references, projectReferences, getProp project, project.FullFileName
+
+#endif
+
//----------------------------------------------------------------------------
// FSharpProjectFileInfo
//
[]
type FSharpProjectFileInfo (fsprojFileName:string, ?properties, ?enableLogging) =
-
let properties = defaultArg properties []
let enableLogging = defaultArg enableLogging false
- let mkAbsolute dir v =
- if Path.IsPathRooted v then v
- else Path.Combine(dir, v)
let logOpt =
if enableLogging then
@@ -55,152 +198,17 @@ module internal ProjectCrackerTool =
Some log
else
None
-
-#if !DOTNETCORE
- let mkAbsoluteOpt dir v = Option.map (mkAbsolute dir) v
-
- let CrackProjectUsingOldBuildAPI(fsprojFile:string) =
- let engine = new Microsoft.Build.BuildEngine.Engine()
- Option.iter (fun l -> engine.RegisterLogger(l)) logOpt
-
- let bpg = Microsoft.Build.BuildEngine.BuildPropertyGroup()
-
- bpg.SetProperty("BuildingInsideVisualStudio", "true")
- for (prop, value) in properties do
- bpg.SetProperty(prop, value)
-
- engine.GlobalProperties <- bpg
-
- let projectFromFile (fsprojFile:string) =
- // We seem to need to pass 12.0/4.0 in here for some unknown reason
- let project = new Microsoft.Build.BuildEngine.Project(engine, engine.DefaultToolsVersion)
- do project.Load(fsprojFile)
- project
-
- let project = projectFromFile fsprojFile
- project.Build([| "ResolveReferences" |]) |> ignore
- let directory = Path.GetDirectoryName project.FullFileName
-
- let getProp (p: Microsoft.Build.BuildEngine.Project) s =
- let v = p.GetEvaluatedProperty s
- if String.IsNullOrWhiteSpace v then None
- else Some v
-
- let outFileOpt =
- match mkAbsoluteOpt directory (getProp project "OutDir") with
- | None -> None
- | Some d -> mkAbsoluteOpt d (getProp project "TargetFileName")
-
- let getItems s =
- let fs = project.GetEvaluatedItemsByName(s)
- [ for f in fs -> mkAbsolute directory f.FinalItemSpec ]
-
- let projectReferences =
- [ for i in project.GetEvaluatedItemsByName("ProjectReference") do
- yield mkAbsolute directory i.FinalItemSpec
- ]
-
- let references =
- [ for i in project.GetEvaluatedItemsByName("ReferencePath") do
- yield i.FinalItemSpec
- for i in project.GetEvaluatedItemsByName("ChildProjectReferences") do
- yield i.FinalItemSpec ]
- // Duplicate slashes sometimes appear in the output here, which prevents
- // them from matching keys used in FSharpProjectOptions.ReferencedProjects
- |> List.map (fun (s: string) -> s.Replace("//","/"))
-
- outFileOpt, directory, getItems, references, projectReferences, getProp project, project.FullFileName
-#endif
-
- let vs =
- let programFiles =
- let getEnv v =
- let result = System.Environment.GetEnvironmentVariable(v)
- match result with
- | null -> None
- | _ -> Some result
-
- match List.tryPick getEnv [ "ProgramFiles(x86)"; "ProgramFiles" ] with
- | Some r -> r
- | None -> "C:\\Program Files (x86)"
-
- let vsVersions = ["14.0"; "12.0"]
- let msbuildBin v = IO.Path.Combine(programFiles, "MSBuild", v, "Bin", "MSBuild.exe")
- List.tryFind (fun v -> IO.File.Exists(msbuildBin v)) vsVersions
-
- let CrackProjectUsingNewBuildAPI(fsprojFile) =
- let fsprojFullPath = try Path.GetFullPath(fsprojFile) with _ -> fsprojFile
- let fsprojAbsDirectory = Path.GetDirectoryName fsprojFullPath
-
- use _pwd =
- let dir = Directory.GetCurrentDirectory()
- Directory.SetCurrentDirectory(fsprojAbsDirectory)
- { new System.IDisposable with
- member x.Dispose() = Directory.SetCurrentDirectory(dir) }
- use engine = new Microsoft.Build.Evaluation.ProjectCollection()
- let host = new HostCompile()
- engine.HostServices.RegisterHostObject(fsprojFullPath, "CoreCompile", "Fsc", host)
-
-
- let projectInstanceFromFullPath (fsprojFullPath: string) =
- use file = new FileStream(fsprojFullPath, FileMode.Open, FileAccess.Read, FileShare.Read)
- use stream = new StreamReader(file)
- use xmlReader = System.Xml.XmlReader.Create(stream)
-
- let project = engine.LoadProject(xmlReader, FullPath=fsprojFullPath)
-
- project.SetGlobalProperty("BuildingInsideVisualStudio", "true") |> ignore
- if not (List.exists (fun (p,_) -> p = "VisualStudioVersion") properties) then
- match vs with
- | Some version -> project.SetGlobalProperty("VisualStudioVersion", version) |> ignore
- | None -> ()
- project.SetGlobalProperty("ShouldUnsetParentConfigurationAndPlatform", "false") |> ignore
- for (prop, value) in properties do
- project.SetGlobalProperty(prop, value) |> ignore
-
- project.CreateProjectInstance()
-
- let project = projectInstanceFromFullPath fsprojFullPath
- let directory = project.Directory
-
- let getprop (p: Microsoft.Build.Execution.ProjectInstance) s =
- let v = p.GetPropertyValue s
- if String.IsNullOrWhiteSpace v then None
- else Some v
-
- let outFileOpt = getprop project "TargetPath"
-
- let log = match logOpt with
- | None -> []
- | Some l -> [l :> ILogger]
-
- project.Build([| "Build" |], log) |> ignore
-
- let getItems s = [ for f in project.GetItems(s) -> mkAbsolute directory f.EvaluatedInclude ]
-
- let projectReferences =
- [ for cp in project.GetItems("ProjectReference") do
- yield cp.GetMetadataValue("FullPath")
- ]
-
- let references =
- [ for i in project.GetItems("ReferencePath") do
- yield i.EvaluatedInclude
- for i in project.GetItems("ChildProjectReferences") do
- yield i.EvaluatedInclude ]
-
- outFileOpt, directory, getItems, references, projectReferences, getprop project, project.FullPath
-
+
let outFileOpt, directory, getItems, references, projectReferences, getProp, fsprojFullPath =
try
#if DOTNETCORE
- CrackProjectUsingNewBuildAPI(fsprojFileName)
+ CrackProjectUsingNewBuildAPI fsprojFileName properties logOpt
with
#else
if runningOnMono then
- CrackProjectUsingOldBuildAPI(fsprojFileName)
+ CrackProjectUsingOldBuildAPI fsprojFileName properties logOpt
else
- CrackProjectUsingNewBuildAPI(fsprojFileName)
+ CrackProjectUsingNewBuildAPI fsprojFileName properties logOpt
with
| :? Microsoft.Build.BuildEngine.InvalidProjectFileException as e ->
raise (Microsoft.Build.Exceptions.InvalidProjectFileException(
@@ -384,66 +392,57 @@ module internal ProjectCrackerTool =
static member Parse(fsprojFileName:string, ?properties, ?enableLogging) = new FSharpProjectFileInfo(fsprojFileName, ?properties=properties, ?enableLogging=enableLogging)
let getOptions file enableLogging properties =
+ let cache = new Dictionary<_,_>()
let rec getOptions file : Option * ProjectOptions =
- let parsedProject = FSharpProjectFileInfo.Parse(file, properties=properties, enableLogging=enableLogging)
- let referencedProjectOptions =
- [| for file in parsedProject.ProjectReferences do
- if Path.GetExtension(file) = ".fsproj" then
- match getOptions file with
- | Some outFile, opts -> yield outFile, opts
- | None, _ -> () |]
-
- // Workaround for Mono 4.2, which doesn't populate the subproject
- // details anymore outside of a solution context. See https://github.com/mono/mono/commit/76c6a08e730393927b6851709cdae1d397cbcc3a#diff-59afd196a55d61d5d1eaaef7bd49d1e5
- // and some explanation from the author at https://github.com/fsharp/FSharp.Compiler.Service/pull/455#issuecomment-154103963
- //
- // In particular we want the output path, which we can get from
- // fully parsing that project itself. We also have to specially parse
- // C# referenced projects, as we don't look at them otherwise.
- let referencedProjectOutputs =
- if runningOnMono then
- [ yield! Array.map (fun (s,_) -> "-r:" + s) referencedProjectOptions
- for file in parsedProject.ProjectReferences do
- let ext = Path.GetExtension(file)
- if ext = ".csproj" || ext = ".vbproj" then
- let parsedProject = FSharpProjectFileInfo.Parse(file, properties=properties, enableLogging=false)
- match parsedProject.OutputFile with
- | None -> ()
- | Some f -> yield "-r:" + f ]
- else
- []
-
- // On some versions of Mono the referenced projects are already
- // correctly included, so we make sure not to introduce duplicates
- |> List.filter (fun r -> not (Set.contains r (set parsedProject.Options)))
-
- let options = { ProjectFile = file
- Options = Array.ofSeq (parsedProject.Options @ referencedProjectOutputs)
- ReferencedProjectOptions = referencedProjectOptions
- LogOutput = parsedProject.LogOutput
- Error = null }
-
- parsedProject.OutputFile, options
+ match cache.TryGetValue file with
+ | true, option -> option
+ | _ ->
+ let parsedProject = FSharpProjectFileInfo.Parse(file, properties=properties, enableLogging=enableLogging)
+
+ let referencedProjectOptions =
+ [| for file in parsedProject.ProjectReferences do
+ if Path.GetExtension(file) = ".fsproj" then
+ match getOptions file with
+ | Some outFile, opts -> yield outFile, opts
+ | None, _ -> () |]
+
+ // Workaround for Mono 4.2, which doesn't populate the subproject
+ // details anymore outside of a solution context. See https://github.com/mono/mono/commit/76c6a08e730393927b6851709cdae1d397cbcc3a#diff-59afd196a55d61d5d1eaaef7bd49d1e5
+ // and some explanation from the author at https://github.com/fsharp/FSharp.Compiler.Service/pull/455#issuecomment-154103963
+ //
+ // In particular we want the output path, which we can get from
+ // fully parsing that project itself. We also have to specially parse
+ // C# referenced projects, as we don't look at them otherwise.
+ let referencedProjectOutputs =
+ if runningOnMono then
+ [ yield! Array.map (fun (s,_) -> "-r:" + s) referencedProjectOptions
+ for file in parsedProject.ProjectReferences do
+ let ext = Path.GetExtension(file)
+ if ext = ".csproj" || ext = ".vbproj" then
+ let parsedProject = FSharpProjectFileInfo.Parse(file, properties=properties, enableLogging=false)
+ match parsedProject.OutputFile with
+ | None -> ()
+ | Some f -> yield "-r:" + f ]
+ else
+ []
+
+ // On some versions of Mono the referenced projects are already
+ // correctly included, so we make sure not to introduce duplicates
+ |> List.filter (fun r -> not (Set.contains r (set parsedProject.Options)))
+
+ let options = { ProjectFile = file
+ Options = Array.ofSeq (parsedProject.Options @ referencedProjectOutputs)
+ ReferencedProjectOptions = referencedProjectOptions
+ LogOutput = parsedProject.LogOutput
+ Error = null }
+
+ let result = parsedProject.OutputFile, options
+ cache.Add(file,result)
+ result
snd (getOptions file)
-#if !DOTNETCORE
- let addMSBuildv14BackupResolution () =
- let onResolveEvent = new ResolveEventHandler(fun sender evArgs ->
- let requestedAssembly = AssemblyName(evArgs.Name)
- if requestedAssembly.Name.StartsWith("Microsoft.Build") &&
- not (requestedAssembly.Name.EndsWith(".resources")) &&
- not (requestedAssembly.Version.ToString().Contains("12.0.0.0")) then
- // If the version of MSBuild that we're using wasn't present on the machine, then
- // just revert back to 12.0.0.0 since that's normally installed as part of the .NET
- // Framework.
- requestedAssembly.Version <- Version("12.0.0.0")
- Assembly.Load (requestedAssembly)
- else
- null)
- AppDomain.CurrentDomain.add_AssemblyResolve(onResolveEvent)
-#endif
-
+
let rec pairs l =
match l with
| [] | [_] -> []
@@ -456,9 +455,6 @@ module internal ProjectCrackerTool =
| true, true -> true
| _ -> false
try
-#if !DOTNETCORE
- addMSBuildv14BackupResolution ()
-#endif
let props = pairs (List.ofArray argv.[2..])
let opts = getOptions argv.[0] enableLogging props
0, opts
@@ -466,8 +462,8 @@ module internal ProjectCrackerTool =
2, { ProjectFile = projectFile;
Options = [||];
ReferencedProjectOptions = [||];
- LogOutput = e.ToString()
- Error = e.Message }
+ LogOutput = e.ToString() + " StackTrace: " + e.StackTrace
+ Error = e.Message + " StackTrace: " + e.StackTrace }
else
1, { ProjectFile = "";
Options = [||];
diff --git a/fcs/FSharp.Compiler.Service.ProjectCrackerTool/paket.references b/fcs/FSharp.Compiler.Service.ProjectCrackerTool/paket.references
new file mode 100644
index 00000000000..3ad1f9662c7
--- /dev/null
+++ b/fcs/FSharp.Compiler.Service.ProjectCrackerTool/paket.references
@@ -0,0 +1,4 @@
+Microsoft.Build.Utilities.Core
+Microsoft.Build.Engine
+Microsoft.Build
+System.Threading.Tasks.Dataflow
\ No newline at end of file
diff --git a/fcs/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj b/fcs/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj
index 98e86a06448..d53494b86f2 100644
--- a/fcs/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj
+++ b/fcs/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj
@@ -80,8 +80,8 @@
PreserveNewest
+
-
@@ -97,7 +97,6 @@
-
$(FSharpSourcesRoot)\..\packages\System.Collections.Immutable.$(SystemCollectionsImmutableVersion)\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll
@@ -112,7 +111,6 @@
$(FSharpSourcesRoot)\..\packages\FSharp.Compiler.Tools.4.1.27\tools\FSharp.Core.dll
true
-
CSharp_Analysis
{887630A3-4B1D-40EA-B8B3-2D842E9C40DB}
@@ -130,4 +128,66 @@
+
+
+
+
+ ..\packages\Microsoft.Build\lib\net45\Microsoft.Build.dll
+ True
+ True
+
+
+
+
+
+
+
+
+ ..\packages\Microsoft.Build.Engine\lib\net45\Microsoft.Build.Engine.dll
+ True
+ True
+
+
+
+
+
+
+
+
+ ..\packages\Microsoft.Build.Framework\lib\net45\Microsoft.Build.Framework.dll
+ True
+ True
+
+
+
+
+
+
+
+
+ ..\packages\Microsoft.Build.Utilities.Core\lib\net45\Microsoft.Build.Utilities.Core.dll
+ True
+ True
+
+
+
+
+
+
+
+
+ True
+
+
+
+
+
+
+
+
+ True
+
+
+
+
\ No newline at end of file
diff --git a/fcs/FSharp.Compiler.Service.Tests/paket.references b/fcs/FSharp.Compiler.Service.Tests/paket.references
new file mode 100644
index 00000000000..c64e284f16b
--- /dev/null
+++ b/fcs/FSharp.Compiler.Service.Tests/paket.references
@@ -0,0 +1,3 @@
+Microsoft.Build.Utilities.Core
+Microsoft.Build.Engine
+Microsoft.Build
\ No newline at end of file
diff --git a/fcs/build.cmd b/fcs/build.cmd
index f7242b03912..c18c0a1f227 100644
--- a/fcs/build.cmd
+++ b/fcs/build.cmd
@@ -1,11 +1,8 @@
@echo off
-dotnet --version
-.nuget\NuGet.exe restore -PackagesDirectory packages
setlocal
cd fcs
-dotnet restore tools.fsproj
if errorlevel 1 (
endlocal
exit /b %errorlevel%
diff --git a/fcs/build.fsx b/fcs/build.fsx
index d3c850757e4..1e39de8bbb9 100644
--- a/fcs/build.fsx
+++ b/fcs/build.fsx
@@ -13,8 +13,22 @@ open Fake.ReleaseNotesHelper
#if MONO
// prevent incorrect output encoding (e.g. https://github.com/fsharp/FAKE/issues/1196)
System.Console.OutputEncoding <- System.Text.Encoding.UTF8
+
+CleanDir (__SOURCE_DIRECTORY__ + "/../tests/TestResults")
+File.WriteAllText(__SOURCE_DIRECTORY__ + "/../tests/TestResults/notestsyet.txt","No tests yet")
#endif
+let dotnetExePath = DotNetCli.InstallDotNetSDK "2.0.2"
+
+let runDotnet workingDir args =
+ let result =
+ ExecProcess (fun info ->
+ info.FileName <- dotnetExePath
+ info.WorkingDirectory <- workingDir
+ info.Arguments <- args) TimeSpan.MaxValue
+
+ if result <> 0 then failwithf "dotnet %s failed" args
+
// --------------------------------------------------------------------------------------
// Utilities
// --------------------------------------------------------------------------------------
@@ -69,6 +83,22 @@ let buildVersion =
else if isAppVeyorBuild then sprintf "%s-b%s" assemblyVersion AppVeyorEnvironment.BuildNumber
else assemblyVersion
+Target "Clean" (fun _ ->
+ CleanDir releaseDir
+)
+
+Target "Restore" (fun _ ->
+ for p in (!! "./../**/packages.config") do
+ let result =
+ ExecProcess (fun info ->
+ info.FileName <- FullName @"./../.nuget/NuGet.exe"
+ info.WorkingDirectory <- FullName @"./.."
+ info.Arguments <- sprintf "restore %s -PackagesDirectory \"%s\" -ConfigFile \"%s\"" (FullName p) (FullName "./../packages") (FullName "./../.nuget/NuGet.Config")) TimeSpan.MaxValue
+ if result <> 0 then failwithf "nuget restore %s failed" p
+
+ runDotnet __SOURCE_DIRECTORY__ "restore tools.fsproj"
+)
+
Target "BuildVersion" (fun _ ->
Shell.Exec("appveyor", sprintf "UpdateBuild -Version \"%s\"" buildVersion) |> ignore
)
@@ -88,11 +118,24 @@ Target "Build.NetFx" (fun _ ->
// Run the unit tests using test runner
Target "Test.NetFx" (fun _ ->
- !! (releaseDir + "/fcs/net45/FSharp.Compiler.Service.Tests.dll")
+ let testDir = __SOURCE_DIRECTORY__ + "/../tests/fcs"
+ CleanDir testDir
+
+ let outDir = releaseDir + "/fcs"
+
+ !! (outDir + "/**/*.*")
+ |> CopyFiles testDir
+
+ let toolPath = __SOURCE_DIRECTORY__ + "/../packages/NUnit.Console.3.0.0/tools"
+ !! (toolPath + "/*.*")
+ |> CopyFiles testDir
+
+ !! (testDir + "/**/FSharp.Compiler.Service.Tests.dll")
|> Fake.Testing.NUnit3.NUnit3 (fun p ->
{ p with
- ToolPath = @"..\packages\NUnit.Console.3.0.0\tools\nunit3-console.exe"
+ ToolPath = testDir + "/nunit3-console.exe"
ShadowCopy = false
+ WorkingDir = FullName testDir
TimeOut = TimeSpan.FromMinutes 20. })
)
@@ -109,26 +152,14 @@ Target "NuGet.NetFx" (fun _ ->
// --------------------------------------------------------------------------------------
// .NET Core and .NET Core SDK
-let isDotnetSDKInstalled =
- match Fake.EnvironmentHelper.environVarOrNone "FCS_DNC" with
- | Some flag ->
- match bool.TryParse flag with
- | true, result -> result
- | _ -> false
- | None ->
- try
- Shell.Exec("dotnet", "--info") = 0
- with
- _ -> false
-
Target "Build.NetStd" (fun _ ->
- runCmdIn __SOURCE_DIRECTORY__ "dotnet" "pack %s -v n -c Release" "FSharp.Compiler.Service.netstandard.sln"
+ runDotnet __SOURCE_DIRECTORY__ (sprintf "pack %s -v n -c Release" "FSharp.Compiler.Service.netstandard.sln")
)
Target "Test.NetStd" (fun _ ->
- runCmdIn __SOURCE_DIRECTORY__ "dotnet" "run -p FSharp.Compiler.Service.Tests.netcore/FSharp.Compiler.Service.Tests.netcore.fsproj -c Release -- --result:TestResults.NetStd.xml;format=nunit3"
+ runDotnet __SOURCE_DIRECTORY__ (sprintf "run -p FSharp.Compiler.Service.Tests.netcore/FSharp.Compiler.Service.Tests.netcore.fsproj -c Release -- --result:TestResults.NetStd.xml;format=nunit3")
)
@@ -136,7 +167,7 @@ Target "Test.NetStd" (fun _ ->
Target "Nuget.AddNetStd" (fun _ ->
let nupkg = sprintf "%s/FSharp.Compiler.Service.%s.nupkg" releaseDir release.AssemblyVersion
let netcoreNupkg = sprintf "FSharp.Compiler.Service.netstandard/bin/Release/FSharp.Compiler.Service.%s.nupkg" release.AssemblyVersion
- runCmdIn __SOURCE_DIRECTORY__ "dotnet" "mergenupkg --source %s --other %s --framework netstandard1.6" nupkg netcoreNupkg
+ runDotnet __SOURCE_DIRECTORY__ (sprintf "mergenupkg --source %s --other %s --framework netstandard1.6" nupkg netcoreNupkg)
)
@@ -168,7 +199,6 @@ Target "PublishNuGet" (fun _ ->
// --------------------------------------------------------------------------------------
// Run all targets by default. Invoke 'build ' to override
-Target "Clean" DoNothing
Target "Release" DoNothing
Target "NuGet" DoNothing
Target "Build" DoNothing
@@ -177,10 +207,12 @@ Target "TestAndNuGet" DoNothing
"Clean"
=?> ("BuildVersion", isAppVeyorBuild)
+ ==> "Restore"
==> "Build.NetStd"
"Clean"
=?> ("BuildVersion", isAppVeyorBuild)
+ ==> "Restore"
==> "Build.NetFx"
"Build.NetFx"
@@ -190,15 +222,15 @@ Target "TestAndNuGet" DoNothing
==> "Test.NetStd"
"Build.NetFx"
- =?> ("Build.NetStd", isDotnetSDKInstalled)
+ ==> "Build.NetStd"
==> "Build"
"Build.NetStd"
- =?> ("Nuget.AddNetStd", isDotnetSDKInstalled)
+ ==> "Nuget.AddNetStd"
"Build.NetFx"
==> "NuGet.NetFx"
- =?> ("Nuget.AddNetStd", isDotnetSDKInstalled)
+ ==> "Nuget.AddNetStd"
==> "NuGet"
"Test.NetFx"
@@ -206,9 +238,7 @@ Target "TestAndNuGet" DoNothing
"NuGet"
==> "TestAndNuGet"
-
-//"Test.NetStd"
-// ==> "TestAndNuGet"
+
"Build"
==> "NuGet"
diff --git a/fcs/build.sh b/fcs/build.sh
index d6559cfaa8b..53e6962df76 100755
--- a/fcs/build.sh
+++ b/fcs/build.sh
@@ -4,10 +4,6 @@ then
# use .Net
cmd fcs/build.cmd $@
else
- dotnet --version
-
- mono .nuget/NuGet.exe restore -PackagesDirectory packages
-
cd fcs
# use mono
@@ -15,8 +11,6 @@ else
mozroots --import --sync --quiet
fi
- dotnet restore tools.fsproj
-
mono .paket/paket.exe restore
exit_code=$?
if [ $exit_code -ne 0 ]; then
@@ -24,4 +18,4 @@ else
fi
mono packages/FAKE/tools/FAKE.exe $@ --fsiargs -d:MONO build.fsx
-fi
\ No newline at end of file
+fi
diff --git a/fcs/dependencies/MSBuild.v14.0/Microsoft.Build.Engine.dll b/fcs/dependencies/MSBuild.v14.0/Microsoft.Build.Engine.dll
deleted file mode 100644
index 06611509976..00000000000
Binary files a/fcs/dependencies/MSBuild.v14.0/Microsoft.Build.Engine.dll and /dev/null differ
diff --git a/fcs/dependencies/MSBuild.v14.0/Microsoft.Build.Framework.dll b/fcs/dependencies/MSBuild.v14.0/Microsoft.Build.Framework.dll
deleted file mode 100644
index 74d6e05b852..00000000000
Binary files a/fcs/dependencies/MSBuild.v14.0/Microsoft.Build.Framework.dll and /dev/null differ
diff --git a/fcs/dependencies/MSBuild.v14.0/Microsoft.Build.dll b/fcs/dependencies/MSBuild.v14.0/Microsoft.Build.dll
deleted file mode 100644
index c702184ec02..00000000000
Binary files a/fcs/dependencies/MSBuild.v14.0/Microsoft.Build.dll and /dev/null differ
diff --git a/fcs/dependencies/README.md b/fcs/dependencies/README.md
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/fcs/paket.dependencies b/fcs/paket.dependencies
index bfd298568f6..39535eedd9d 100644
--- a/fcs/paket.dependencies
+++ b/fcs/paket.dependencies
@@ -1,7 +1,12 @@
-framework: net45
+framework: net45, net46
source https://www.nuget.org/api/v2/
nuget FAKE
nuget FSharp.Formatting
+nuget Microsoft.Build.Utilities.Core 14.3.0
+nuget Microsoft.Build.Framework 14.3.0
+nuget Microsoft.Build.Engine 14.3.0
+nuget Microsoft.Build 14.3.0
+nuget System.Threading.Tasks.Dataflow 4.5.24.0
\ No newline at end of file
diff --git a/fcs/paket.lock b/fcs/paket.lock
index 2e454bee770..947bfc412b7 100644
--- a/fcs/paket.lock
+++ b/fcs/paket.lock
@@ -1,4 +1,4 @@
-RESTRICTION: == net45
+RESTRICTION: || (== net45) (== net46)
NUGET
remote: https://www.nuget.org/api/v2
FAKE (4.63.2)
@@ -8,3 +8,17 @@ NUGET
FSharpVSPowerTools.Core (>= 2.3 < 2.4)
FSharpVSPowerTools.Core (2.3)
FSharp.Compiler.Service (>= 2.0.0.3)
+ Microsoft.Build (14.3)
+ Microsoft.Build.Framework (14.3)
+ Microsoft.Build.Engine (14.3)
+ Microsoft.Build.Framework (14.3)
+ Microsoft.Build.Framework (14.3)
+ System.Collections (>= 4.0.11) - restriction: || (&& (== net45) (>= netstandard1.3)) (== net46)
+ System.Runtime (>= 4.1) - restriction: || (&& (== net45) (>= netstandard1.3)) (== net46)
+ System.Runtime.InteropServices (>= 4.1) - restriction: || (&& (== net45) (>= netstandard1.3)) (== net46)
+ Microsoft.Build.Utilities.Core (14.3)
+ Microsoft.Build.Framework (14.3)
+ System.Collections (4.3) - restriction: || (&& (== net45) (>= netstandard1.3)) (== net46)
+ System.Runtime (4.3) - restriction: || (&& (== net45) (>= netstandard1.3)) (== net46)
+ System.Runtime.InteropServices (4.3) - restriction: || (&& (== net45) (>= netstandard1.3)) (== net46)
+ System.Threading.Tasks.Dataflow (4.5.24)
diff --git a/netci.groovy b/netci.groovy
index 185ea17a197..ddf51e05e7d 100644
--- a/netci.groovy
+++ b/netci.groovy
@@ -105,7 +105,7 @@ ${buildPath}build.cmd ${buildFlavor} ${build_args}""")
Utilities.addArchival(newJob, "tests/TestResults/*.*", "", skipIfNoTestFiles, false)
if (configuration == "Release_fcs") {
- Utilities.addArchival(newJob, "Release/fcs/**")
+ Utilities.addArchival(newJob, "Release/**")
}
else {
Utilities.addArchival(newJob, "${buildFlavor}/**")
diff --git a/tests/service/ProjectOptionsTests.fs b/tests/service/ProjectOptionsTests.fs
index 4fddf734b6a..39ecd5124b4 100644
--- a/tests/service/ProjectOptionsTests.fs
+++ b/tests/service/ProjectOptionsTests.fs
@@ -20,6 +20,10 @@ open FSharp.Compiler.Service.Tests.Common
#if !NO_PROJECTCRACKER
+let hasMSBuild14 =
+ use engine = new Microsoft.Build.Evaluation.ProjectCollection()
+ engine.Toolsets |> Seq.exists (fun x -> x.ToolsPath.Contains "v14.0")
+
let normalizePath s = (new Uri(s)).LocalPath
let checkOption (opts:string[]) s =
@@ -90,7 +94,7 @@ let ``Project file parsing example 1 Default configuration relative path`` () =
[]
let ``Project file parsing VS2013_FSharp_Portable_Library_net45``() =
- if not runningOnMono then // Disabled on Mono due to lack of installed PCL reference libraries - the modern way is to reference the FSHarp.Core nuget package so this is ok
+ if (not hasMSBuild14) || runningOnMono then () else // Disabled on Mono due to lack of installed PCL reference libraries - the modern way is to reference the FSHarp.Core nuget package so this is ok
let projectFile = __SOURCE_DIRECTORY__ + @"/../projects/Sample_VS2013_FSharp_Portable_Library_net45/Sample_VS2013_FSharp_Portable_Library_net45.fsproj"
let options = ProjectCracker.GetProjectOptionsFromProjectFile(projectFile, [])
@@ -106,7 +110,7 @@ let ``Project file parsing VS2013_FSharp_Portable_Library_net45``() =
[]
let ``Project file parsing Sample_VS2013_FSharp_Portable_Library_net451_adjusted_to_profile78``() =
- if not runningOnMono then // Disabled on Mono due to lack of installed PCL reference libraries - the modern way is to reference the FSHarp.Core nuget package so this is ok
+ if (not hasMSBuild14) || runningOnMono then () else // Disabled on Mono due to lack of installed PCL reference libraries - the modern way is to reference the FSHarp.Core nuget package so this is ok
let projectFile = __SOURCE_DIRECTORY__ + @"/../projects/Sample_VS2013_FSharp_Portable_Library_net451_adjusted_to_profile78/Sample_VS2013_FSharp_Portable_Library_net451.fsproj"
Directory.SetCurrentDirectory(__SOURCE_DIRECTORY__ + @"/../projects/Sample_VS2013_FSharp_Portable_Library_net451_adjusted_to_profile78/")
@@ -141,7 +145,8 @@ let ``Project file parsing -- bad project file``() =
ProjectCracker.GetProjectOptionsFromProjectFileLogged(f) |> ignore
failwith "Expected exception"
with e ->
- Assert.That(e.Message, Contains.Substring "The project file could not be loaded.")
+ Assert.That(e.Message, Contains.Substring "Could not load project")
+ Assert.That(e.Message, Contains.Substring "Malformed.fsproj")
[]
let ``Project file parsing -- non-existent project file``() =
@@ -149,7 +154,7 @@ let ``Project file parsing -- non-existent project file``() =
try
ProjectCracker.GetProjectOptionsFromProjectFileLogged(f, enableLogging=true) |> ignore
with e ->
- Assert.That(e.Message, Contains.Substring "Could not find file")
+ Assert.That(e.Message, Contains.Substring "DoesNotExist.fsproj")
[]
let ``Project file parsing -- output file``() =
@@ -175,9 +180,20 @@ let ``Project file parsing -- references``() =
references |> should haveLength 4
p.ReferencedProjects |> should be Empty
+[]
+let ``Project file parsing -- no project references``() =
+ let p = ProjectCracker.GetProjectOptionsFromProjectFile(__SOURCE_DIRECTORY__ + @"/data/Test3.fsproj")
+
+ let references = getReferencedFilenames p.OtherOptions
+ checkOption references "FSharp.Core.dll"
+ checkOption references "mscorlib.dll"
+ checkOption references "System.Core.dll"
+ checkOption references "System.dll"
+ p.ReferencedProjects |> should haveLength 0
+
[]
let ``Project file parsing -- 2nd level references``() =
- let p = ProjectCracker.GetProjectOptionsFromProjectFile(__SOURCE_DIRECTORY__ + @"/data/Test2.fsproj")
+ let p,_ = ProjectCracker.GetProjectOptionsFromProjectFileLogged(__SOURCE_DIRECTORY__ + @"/data/Test2.fsproj", enableLogging=true)
let references = getReferencedFilenames p.OtherOptions
checkOption references "FSharp.Core.dll"
@@ -190,6 +206,7 @@ let ``Project file parsing -- 2nd level references``() =
p.ReferencedProjects |> should haveLength 1
(snd p.ReferencedProjects.[0]).ProjectFileName |> should contain (normalizePath (__SOURCE_DIRECTORY__ + @"/data/Test1.fsproj"))
+
[]
let ``Project file parsing -- reference project output file``() =
let p = ProjectCracker.GetProjectOptionsFromProjectFile(__SOURCE_DIRECTORY__ + @"/data/DifferingOutputDir/Dir2/Test2.fsproj")
@@ -207,20 +224,23 @@ let ``Project file parsing -- reference project output file``() =
[]
let ``Project file parsing -- Tools Version 12``() =
+ if not hasMSBuild14 then () else
let opts = ProjectCracker.GetProjectOptionsFromProjectFile(__SOURCE_DIRECTORY__ + @"/data/ToolsVersion12.fsproj")
checkOption (getReferencedFilenames opts.OtherOptions) "System.Core.dll"
[]
let ``Project file parsing -- Logging``() =
+ if not hasMSBuild14 then () else
let projectFileName = normalizePath (__SOURCE_DIRECTORY__ + @"/data/ToolsVersion12.fsproj")
let _, logMap = ProjectCracker.GetProjectOptionsFromProjectFileLogged(projectFileName, enableLogging=true)
let log = logMap.[projectFileName]
-
+
+ Assert.That(log, Is.StringContaining("ResolveAssemblyReference"))
if runningOnMono then
- Assert.That(log, Is.StringContaining("Reference System.Core resolved"))
- Assert.That(log, Is.StringContaining("Using task ResolveAssemblyReference from Microsoft.Build.Tasks.ResolveAssemblyReference"))
- else
- Assert.That(log, Is.StringContaining("""Using "ResolveAssemblyReference" task from assembly "Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"."""))
+ Assert.That(log, Is.StringContaining("System.Core"))
+ Assert.That(log, Is.StringContaining("Microsoft.Build.Tasks.ResolveAssemblyReference"))
+ else
+ Assert.That(log, Is.StringContaining("Microsoft.Build.Tasks.Core"))
[]
let ``Project file parsing -- FSharpProjectOptions.SourceFiles contains both fs and fsi files``() =
@@ -237,6 +257,7 @@ let ``Project file parsing -- FSharpProjectOptions.SourceFiles contains both fs
[]
let ``Project file parsing -- Full path``() =
+ if not hasMSBuild14 then () else
let f = normalizePath (__SOURCE_DIRECTORY__ + @"/data/ToolsVersion12.fsproj")
let p = ProjectCracker.GetProjectOptionsFromProjectFile(f)
p.ProjectFileName |> should equal f
@@ -253,6 +274,7 @@ let ``Project file parsing -- project references``() =
[]
let ``Project file parsing -- multi language project``() =
+ if not hasMSBuild14 then () else
let f = normalizePath (__SOURCE_DIRECTORY__ + @"/data/MultiLanguageProject/ConsoleApplication1.fsproj")
let options = ProjectCracker.GetProjectOptionsFromProjectFile(f)
@@ -265,8 +287,7 @@ let ``Project file parsing -- multi language project``() =
[]
let ``Project file parsing -- PCL profile7 project``() =
- if not runningOnMono then // Disabled on Mono due to lack of installed PCL reference libraries - the modern way is to reference the FSHarp.Core nuget package so this is ok
-
+ if (not hasMSBuild14) || runningOnMono then () else // Disabled on Mono due to lack of installed PCL reference libraries - the modern way is to reference the FSHarp.Core nuget package so this is ok
let f = normalizePath (__SOURCE_DIRECTORY__ + @"/../projects/Sample_VS2013_FSharp_Portable_Library_net45/Sample_VS2013_FSharp_Portable_Library_net45.fsproj")
@@ -315,8 +336,7 @@ let ``Project file parsing -- PCL profile7 project``() =
[]
let ``Project file parsing -- PCL profile78 project``() =
- if not runningOnMono then // Disabled on Mono due to lack of installed PCL reference libraries - the modern way is to reference the FSHarp.Core nuget package so this is ok
-
+ if (not hasMSBuild14) || runningOnMono then () else // Disabled on Mono due to lack of installed PCL reference libraries - the modern way is to reference the FSHarp.Core nuget package so this is ok
let f = normalizePath (__SOURCE_DIRECTORY__ + @"/../projects/Sample_VS2013_FSharp_Portable_Library_net451_adjusted_to_profile78/Sample_VS2013_FSharp_Portable_Library_net451.fsproj")
@@ -356,7 +376,7 @@ let ``Project file parsing -- PCL profile78 project``() =
[]
let ``Project file parsing -- PCL profile259 project``() =
- if not runningOnMono then // Disabled on Mono due to lack of installed PCL reference libraries - the modern way is to reference the FSHarp.Core nuget package so this is ok
+ if (not hasMSBuild14) || runningOnMono then () else // Disabled on Mono due to lack of installed PCL reference libraries - the modern way is to reference the FSHarp.Core nuget package so this is ok
let f = normalizePath (__SOURCE_DIRECTORY__ + @"/../projects/Sample_VS2013_FSharp_Portable_Library_net451_adjusted_to_profile259/Sample_VS2013_FSharp_Portable_Library_net451.fsproj")
let options = ProjectCracker.GetProjectOptionsFromProjectFile(f)
@@ -468,9 +488,11 @@ let ``Test OtherOptions order for GetProjectOptionsFromScript`` () =
projOpts.OtherOptions
|> Array.map (fun s -> if s.StartsWith "--" then s else Path.GetFileNameWithoutExtension s)
- |> Array.sort
- |> shouldEqual (Array.sort expected2)
- let otherArgs = [|"--noframework"; "--warn:3"; "System.Numerics"; "mscorlib"; "FSharp.Core"; "System"; "System.Xml"; "System.Runtime.Remoting"; "System.Runtime.Serialization.Formatters.Soap"; "System.Data"; "System.Drawing"; "System.Core"; "System.Runtime"; "System.Linq"; "System.Reflection"; "System.Linq.Expressions"; "System.Threading.Tasks"; "System.IO"; "System.Net.Requests"; "System.Collections"; "System.Runtime.Numerics"; "System.Threading"; "System.Web"; "System.Web.Services"; "System.Windows.Forms"; "FSharp.Compiler.Interactive.Settings"|]
+ |> Array.forall (fun s -> Set.contains s expected2)
+ |> shouldEqual true
+
+ let otherArgs = [|"--noframework"; "--warn:3"; "System.Numerics"; "mscorlib"; "FSharp.Core"; "System"; "System.Xml"; "System.Runtime.Remoting"; "System.Runtime.Serialization.Formatters.Soap"; "System.Data"; "System.Drawing"; "System.Core"; "System.Runtime"; "System.Linq"; "System.Reflection"; "System.Linq.Expressions"; "System.Threading.Tasks"; "System.IO"; "System.Net.Requests"; "System.Collections"; "System.Runtime.Numerics"; "System.Threading"; "System.Web"; "System.Web.Services"; "System.Windows.Forms"; "FSharp.Compiler.Interactive.Settings"|] |> Set.ofArray
+
test "Main1" otherArgs
test "Main2" otherArgs
test "Main3" otherArgs
diff --git a/tests/service/data/Test3.fsproj b/tests/service/data/Test3.fsproj
new file mode 100644
index 00000000000..31c2d33c565
--- /dev/null
+++ b/tests/service/data/Test3.fsproj
@@ -0,0 +1,62 @@
+
+
+
+ Debug
+ x86
+ 8.0.30703
+ 2.0
+ {116cc2f9-f987-4b3d-915a-34cac04a73db}
+ ..\..\..\$(Configuration)\net40\bin
+ Exe
+ Test2
+ Test2
+ Test2
+ False
+ 11
+
+
+ True
+ full
+ False
+ False
+ DEBUG;TRACE
+ 3
+ x86
+ bin\Debug\Test2.xml
+
+
+ pdbonly
+ True
+ True
+ TRACE
+ 3
+ x86
+ bin\Release\Test2.xml
+ False
+
+
+
+ ..\..\..\packages\Microsoft.Portable.FSharp.Core.4.1.20\lib\profiles\net40\FSharp.Core.dll
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ..\..\..\packages\NUnit\lib\nunit.framework.dll
+ True
+ True
+
+
+
+
+
\ No newline at end of file