From 7538cd1e333fabb6e02bcab0555f947746b01639 Mon Sep 17 00:00:00 2001 From: enricosada Date: Thu, 12 Jan 2017 01:18:39 +0100 Subject: [PATCH] build and package fsc using .NET Core Sdk - add helper script to install .NET Core Sdk (only if needed) - build `Fsc.netcore.fspro with `fsc-proto` - publish Fsc using .NET Core Sdk as framework dependent app - create `Microsoft.FSharp.Compiler.Sdk.netcore` package - add build script using `dotnet msbuild` - run when `netcoresdk` arg is passed to build script (`build.cmd`) - add end to end tests to check created package - add examples of .net core sdk projects (lib/console) --- .gitignore | 3 + DotnetCoreSdkVersion.txt | 1 + build-using-netcore-sdk.proj | 68 +++++++++++ build.cmd | 30 ++++- build/CheckPrereqs.proj | 34 ++++++ build/Compile.proj | 42 +++++++ ...Microsoft.FSharp.Compiler.Sdk.netcore.proj | 57 +++++++++ build/Package.proj | 90 +++++++++++++++ build/Prepare.proj | 37 ++++++ build/Test.E2E.proj | 68 +++++++++++ examples/dotnetcoresdk/NuGet.Config | 8 ++ examples/dotnetcoresdk/simple/README.md | 9 ++ examples/dotnetcoresdk/simple/Simple.sln | 10 ++ .../simple/console/ConsoleApp.fsproj | 22 ++++ .../dotnetcoresdk/simple/console/Program.fs | 16 +++ examples/dotnetcoresdk/simple/lib/Helper.fs | 9 ++ examples/dotnetcoresdk/simple/lib/Helper2.fs | 9 ++ .../dotnetcoresdk/simple/lib/Library1.fsproj | 20 ++++ scripts/use_dotnet_core_sdk.README.md | 30 +++++ scripts/use_dotnet_core_sdk.bat | 25 ++++ scripts/use_dotnet_core_sdk.ps1 | 61 ++++++++++ src/FSharp.nugets.props | 10 ++ src/FSharpSource.UseProtoFsc.net40.props | 9 ++ src/FSharpSource.netcore.props | 60 ++++++++++ ...crosoft.FSharp.Compiler.Sdk.netcore.nuspec | 23 ++++ ...icrosoft.FSharp.Compiler.Sdk.netcore.props | 21 ++++ ...icrosoft.FSharp.Compiler.Sdk.netcore.props | 21 ++++ src/fsharp/Fsc/Fsc.netcore.NuGet.Config | 8 ++ src/fsharp/Fsc/Fsc.netcore.fsproj | 103 +++++++++++++++++ tests/fsharp/test-framework.fs | 66 ++++++++++- .../assets/dotnetcoresdk/console/Program.fs | 8 ++ .../dotnetcoresdk/console/console.fsproj | 26 +++++ .../dotnetcoresdk/dotnetcoresdk.NuGet.Config | 8 ++ .../assets/dotnetcoresdk/lib/Library.fs | 5 + .../assets/dotnetcoresdk/lib/lib.fsproj | 25 ++++ .../dotnetcoresdk/DotnetCoreTestConfig.fs | 109 ++++++++++++++++++ .../FSharp.Tests.DotnetCoreSdk.fsproj | 34 ++++++ tests/projects/dotnetcoresdk/Tests.fs | 91 +++++++++++++++ .../dotnetcoresdk/XunitToNunitShim.fs | 7 ++ 39 files changed, 1281 insertions(+), 2 deletions(-) create mode 100644 DotnetCoreSdkVersion.txt create mode 100644 build-using-netcore-sdk.proj create mode 100644 build/CheckPrereqs.proj create mode 100644 build/Compile.proj create mode 100644 build/Package.Nupkg.Microsoft.FSharp.Compiler.Sdk.netcore.proj create mode 100644 build/Package.proj create mode 100644 build/Prepare.proj create mode 100644 build/Test.E2E.proj create mode 100644 examples/dotnetcoresdk/NuGet.Config create mode 100644 examples/dotnetcoresdk/simple/README.md create mode 100644 examples/dotnetcoresdk/simple/Simple.sln create mode 100644 examples/dotnetcoresdk/simple/console/ConsoleApp.fsproj create mode 100644 examples/dotnetcoresdk/simple/console/Program.fs create mode 100644 examples/dotnetcoresdk/simple/lib/Helper.fs create mode 100644 examples/dotnetcoresdk/simple/lib/Helper2.fs create mode 100644 examples/dotnetcoresdk/simple/lib/Library1.fsproj create mode 100644 scripts/use_dotnet_core_sdk.README.md create mode 100644 scripts/use_dotnet_core_sdk.bat create mode 100644 scripts/use_dotnet_core_sdk.ps1 create mode 100644 src/FSharp.nugets.props create mode 100644 src/FSharpSource.UseProtoFsc.net40.props create mode 100644 src/FSharpSource.netcore.props create mode 100644 src/fsharp/FSharp.Compiler.Sdk.netcore.nuget/Microsoft.FSharp.Compiler.Sdk.netcore.nuspec create mode 100644 src/fsharp/FSharp.Compiler.Sdk.netcore.nuget/build/Microsoft.FSharp.Compiler.Sdk.netcore.props create mode 100644 src/fsharp/FSharp.Compiler.Sdk.netcore.nuget/buildCrossTargeting/Microsoft.FSharp.Compiler.Sdk.netcore.props create mode 100644 src/fsharp/Fsc/Fsc.netcore.NuGet.Config create mode 100644 src/fsharp/Fsc/Fsc.netcore.fsproj create mode 100644 tests/projects/assets/dotnetcoresdk/console/Program.fs create mode 100644 tests/projects/assets/dotnetcoresdk/console/console.fsproj create mode 100644 tests/projects/assets/dotnetcoresdk/dotnetcoresdk.NuGet.Config create mode 100644 tests/projects/assets/dotnetcoresdk/lib/Library.fs create mode 100644 tests/projects/assets/dotnetcoresdk/lib/lib.fsproj create mode 100644 tests/projects/dotnetcoresdk/DotnetCoreTestConfig.fs create mode 100644 tests/projects/dotnetcoresdk/FSharp.Tests.DotnetCoreSdk.fsproj create mode 100644 tests/projects/dotnetcoresdk/Tests.fs create mode 100644 tests/projects/dotnetcoresdk/XunitToNunitShim.fs diff --git a/.gitignore b/.gitignore index bea716942962..5d1568988f5d 100644 --- a/.gitignore +++ b/.gitignore @@ -107,3 +107,6 @@ times source_link.json .vs/ /VSRelease/net40/bin +.dotnetsdk +scripts/dotnet-install.*.ps1 +src/fsharp/FSharp.Compiler.Sdk.netcore.nuget/bin diff --git a/DotnetCoreSdkVersion.txt b/DotnetCoreSdkVersion.txt new file mode 100644 index 000000000000..efbc44c08d13 --- /dev/null +++ b/DotnetCoreSdkVersion.txt @@ -0,0 +1 @@ +1.0.0-preview4-004233 \ No newline at end of file diff --git a/build-using-netcore-sdk.proj b/build-using-netcore-sdk.proj new file mode 100644 index 000000000000..bf0241e9de42 --- /dev/null +++ b/build-using-netcore-sdk.proj @@ -0,0 +1,68 @@ + + + + + + + $(MSBuildThisFileDirectory) + $(RepoRoot)/packages + + + + + + + + + + + + + + + diff --git a/build.cmd b/build.cmd index 7db8c6879d90..75bdd35d316c 100644 --- a/build.cmd +++ b/build.cmd @@ -17,7 +17,7 @@ echo Build and run a subset of test suites echo. echo Usage: echo. -echo build.cmd ^ +echo build.cmd ^ echo ^ echo ^ echo ^ @@ -40,6 +40,7 @@ echo. build.cmd net40 test (build and test net40) echo. build.cmd coreclr test (build and test net40) echo. build.cmd vs test (build and test net40) echo. build.cmd all test (build and test net40) +echo. build.cmd coreclr netcoresdk (build compiler for .NET Core using .NET Core Sdk) echo. build.cmd nobuild test include Conformance (run only tests marked with Conformance category) echo. build.cmd nobuild test include Expensive (run only tests marked with Expensive category) echo. @@ -57,6 +58,7 @@ set BUILD_PROTO=0 set BUILD_PHASE=1 set BUILD_NET40=0 set BUILD_CORECLR=0 +set BUILD_CORECLR_USING_NETCORESDK=0 set BUILD_PORTABLE=0 set BUILD_VS=0 set BUILD_CONFIG=release @@ -231,6 +233,7 @@ if /i '%ARG%' == 'ci_part3' ( set BUILD_PROTO=1 set BUILD_NET40=1 set BUILD_CORECLR=1 + set BUILD_CORECLR_USING_NETCORESDK=1 set TEST_CORECLR_FSHARP_SUITE=1 set TEST_CORECLR_COREUNIT_SUITE=1 @@ -328,6 +331,10 @@ if /i '%ARG%' == 'publicsign' ( set BUILD_PUBLICSIGN=1 ) +if /i '%ARG%' == 'netcoresdk' ( + set BUILD_CORECLR_USING_NETCORESDK=1 +) + goto :EOF :: Note: "goto :EOF" returns from an in-batchfile "call" command :: in preference to returning from the entire batch file. @@ -345,6 +352,7 @@ echo BUILD_PROTO=%BUILD_PROTO% echo BUILD_PROTO_WITH_CORECLR_LKG=%BUILD_PROTO_WITH_CORECLR_LKG% echo BUILD_NET40=%BUILD_NET40% echo BUILD_CORECLR=%BUILD_CORECLR% +echo BUILD_CORECLR_USING_NETCORESDK=%BUILD_CORECLR_USING_NETCORESDK% echo BUILD_PORTABLE=%BUILD_PORTABLE% echo BUILD_VS=%BUILD_VS% echo BUILD_SETUP=%BUILD_SETUP% @@ -542,6 +550,26 @@ if '%BUILD_PHASE%' == '1' ( @if ERRORLEVEL 1 echo Error: '%_msbuildexe% %msbuildflags% build-everything.proj /p:Configuration=%BUILD_CONFIG% %BUILD_DIAG% /p:BUILD_PUBLICSIGN=%BUILD_PUBLICSIGN%' failed && goto :failure ) +echo ---------------- Done with build, building using .net core sdk ----------- + +if '%BUILD_CORECLR_USING_NETCORESDK%' == '1' ( + + setlocal enableDelayedExpansion + + call .\scripts\use_dotnet_core_sdk.bat + @if ERRORLEVEL 1 echo Error: scripts\use_dotnet_core_sdk.bat && endlocal && goto :failure + + echo .NET Core Sdk version: + dotnet --version + @if ERRORLEVEL 1 echo Error: dotnet --version && endlocal && goto :failure + + dotnet msbuild build-using-netcore-sdk.proj /p:Configuration=%BUILD_CONFIG% /t:All /v:n + @if ERRORLEVEL 1 echo Error: dotnet msbuild build-using-netcore-sdk.proj && endlocal && goto :failure + + endlocal + +) + echo ---------------- Done with build, starting update/prepare --------------- if '%BUILD_NET40%' == '1' ( diff --git a/build/CheckPrereqs.proj b/build/CheckPrereqs.proj new file mode 100644 index 000000000000..9e8f8c13c554 --- /dev/null +++ b/build/CheckPrereqs.proj @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + <_ExpectedDotnetCoreSdkBranch>1.0.0-preview4 + + + + + + + + + + + $(RepoRoot)/$(Configuration)/coreclr/bin + + + + + + diff --git a/build/Compile.proj b/build/Compile.proj new file mode 100644 index 000000000000..42bd3775a078 --- /dev/null +++ b/build/Compile.proj @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + $(RepoRoot)/src/fsharp/Fsc/bin/$(Configuration)/netcoreapp1.0/publish + + + + + + + + + + + + + + diff --git a/build/Package.Nupkg.Microsoft.FSharp.Compiler.Sdk.netcore.proj b/build/Package.Nupkg.Microsoft.FSharp.Compiler.Sdk.netcore.proj new file mode 100644 index 000000000000..798b14d4a0c9 --- /dev/null +++ b/build/Package.Nupkg.Microsoft.FSharp.Compiler.Sdk.netcore.proj @@ -0,0 +1,57 @@ + + + + + + + + + <_PackageProjectDir>$(RepoRoot)/src/fsharp/FSharp.Compiler.Sdk.netcore.nuget + <_PackageName>Microsoft.FSharp.Compiler.Sdk.netcore + + + + + + + <_FscPublishOutputFiles Include="$(FscPublishDirectoryNetCoreApp1_0)/**/*" /> + <_FsharpBuildFiles Include="$(CoreclrReleaseDir)/FSharp.Build.*" /> + <_PackageProjectFiles Include="$(_PackageProjectDir)/**/*" + Exclude="$(_PackageProjectDir)/*.nuspec;$(_PackageProjectDir)/bin/**/*" /> + + + + $(_PackageName) + build/netcoreapp1.0/%(RecursiveDir)%(FileName)%(Extension) + + + + + $(_PackageName) + build/netcoreapp1.0/%(RecursiveDir)%(FileName)%(Extension) + + + + + $(_PackageName) + %(RecursiveDir)%(FileName)%(Extension) + + + + + $(NuGetPerBuildPreReleaseVersion) + + + + + + $(_PackageProjectDir)/$(_PackageName).nuspec + $(PackageVersion) + + + + + + diff --git a/build/Package.proj b/build/Package.proj new file mode 100644 index 000000000000..52be07523483 --- /dev/null +++ b/build/Package.proj @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + $(RepoRoot)/$(Configuration)/artifacts + $(RepoRoot)/$(Configuration)/forPackaging + + + + + + + + + + <_PackageName>%(NugetPackageLayout.PackageName) + + + + + + + + + + https://github.com/Microsoft/visualfsharp/blob/master/License.txt + https://github.com/Microsoft/visualfsharp + $(NuGetPerBuildPreReleaseVersion) + Microsoft + Visual F# Compiler FSharp coreclr functional programming + + + + <_CurrentPackageName>%(NugetPackageDef.Identity) + + + + + + <_NuspecProperties Include='licenseUrl="$(PackageLicenceUrl)"' /> + <_NuspecProperties Include='projectUrl="$(PackageProjectUrl)"' /> + <_NuspecProperties Include='version=$(PackageVersion)' /> + <_NuspecProperties Include='authors="$(PackageAuthors)"' /> + <_NuspecProperties Include='tags="$(PackageTags)"' /> + + + + + <_NupkgDirectory>.$([MSBuild]::MakeRelative( $(MSBuildProjectDirectory), "$(NupkgOutputDirectory)/" )) + + + <_NupkgDirectory>$(_NupkgDirectory.TrimEnd('\').TrimEnd('/')) + + + + + + + + + + + diff --git a/build/Prepare.proj b/build/Prepare.proj new file mode 100644 index 000000000000..44429af0f113 --- /dev/null +++ b/build/Prepare.proj @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/Test.E2E.proj b/build/Test.E2E.proj new file mode 100644 index 000000000000..0d58508e08ba --- /dev/null +++ b/build/Test.E2E.proj @@ -0,0 +1,68 @@ + + + + + + + + + + + <_CompilerSdkPackageVersion Condition=" '%(NugetPackageDef.Identity)' == 'Microsoft.FSharp.Compiler.Sdk.netcore' ">%(NugetPackageDef.Version) + <_CommandText> + + + + + + + + + + + + $(RepoRoot)/tests/projects/assets/dotnetcoresdk/dotnetcoresdk.NuGet.Config + + + + + + + + + + + + + + + + + <_TestLockFiles Include="$(RepoRoot)/tests/projects/**/obj/project.assets.json" /> + <_TestLockFiles Include="$(RepoRoot)/tests/projects/**/obj/*.fsproj.nuget.g.props" /> + + + + + + + + + + + diff --git a/examples/dotnetcoresdk/NuGet.Config b/examples/dotnetcoresdk/NuGet.Config new file mode 100644 index 000000000000..e88a9c235d0d --- /dev/null +++ b/examples/dotnetcoresdk/NuGet.Config @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/examples/dotnetcoresdk/simple/README.md b/examples/dotnetcoresdk/simple/README.md new file mode 100644 index 000000000000..9c69c26294b6 --- /dev/null +++ b/examples/dotnetcoresdk/simple/README.md @@ -0,0 +1,9 @@ + +How to run it: + +``` +cd console +dotnet restore +dotnet build +dotnet run +``` diff --git a/examples/dotnetcoresdk/simple/Simple.sln b/examples/dotnetcoresdk/simple/Simple.sln new file mode 100644 index 000000000000..7d3f1263eba5 --- /dev/null +++ b/examples/dotnetcoresdk/simple/Simple.sln @@ -0,0 +1,10 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Global + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/examples/dotnetcoresdk/simple/console/ConsoleApp.fsproj b/examples/dotnetcoresdk/simple/console/ConsoleApp.fsproj new file mode 100644 index 000000000000..6dc80bd604c5 --- /dev/null +++ b/examples/dotnetcoresdk/simple/console/ConsoleApp.fsproj @@ -0,0 +1,22 @@ + + + + Exe + netcoreapp1.0 + + + + + + + + + + + All + + + + + + diff --git a/examples/dotnetcoresdk/simple/console/Program.fs b/examples/dotnetcoresdk/simple/console/Program.fs new file mode 100644 index 000000000000..7375d5c554ff --- /dev/null +++ b/examples/dotnetcoresdk/simple/console/Program.fs @@ -0,0 +1,16 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace TestApp + +open System +open System.Diagnostics + +module Program = + + open TestLibrary + + [] + let Main (args: string array) = + printfn "%s" (TestLibrary.Helper.GetMessage()) + 0 diff --git a/examples/dotnetcoresdk/simple/lib/Helper.fs b/examples/dotnetcoresdk/simple/lib/Helper.fs new file mode 100644 index 000000000000..bd7d56acde1c --- /dev/null +++ b/examples/dotnetcoresdk/simple/lib/Helper.fs @@ -0,0 +1,9 @@ +namespace TestLibrary + +open Lib + +type Helper() = + + static member GetMessage () = Lib.message () + + static member SayHi () = Lib.sayHi () diff --git a/examples/dotnetcoresdk/simple/lib/Helper2.fs b/examples/dotnetcoresdk/simple/lib/Helper2.fs new file mode 100644 index 000000000000..f121c49c6336 --- /dev/null +++ b/examples/dotnetcoresdk/simple/lib/Helper2.fs @@ -0,0 +1,9 @@ +module Lib + +open System + +let message () = + "This string came from the test library!" + +let sayHi () = + Console.WriteLine("Hello there!") diff --git a/examples/dotnetcoresdk/simple/lib/Library1.fsproj b/examples/dotnetcoresdk/simple/lib/Library1.fsproj new file mode 100644 index 000000000000..5c8369535463 --- /dev/null +++ b/examples/dotnetcoresdk/simple/lib/Library1.fsproj @@ -0,0 +1,20 @@ + + + + netstandard1.6 + + + + + + + + + + + + All + + + + diff --git a/scripts/use_dotnet_core_sdk.README.md b/scripts/use_dotnet_core_sdk.README.md new file mode 100644 index 000000000000..b5eca7efa3c8 --- /dev/null +++ b/scripts/use_dotnet_core_sdk.README.md @@ -0,0 +1,30 @@ +# To use .NET Core SDK + +From Command Prompt: + +``` +.\scripts\use_dotnet_core_sdk.bat +``` + +From Powershell: + +``` +.\scripts\use_dotnet_core_sdk.ps1 +``` + +After the script, if successful, the .NET Core SDK is avaiable in `PATH` +so `dotnet --version` will show the expected version + +The expected version is configured in `DotnetCoreSdkVersion.txt` file + +The .NET Core SDK is downloaded/installed only if not already avaiable, so the +script can be rerun at will + +# NOTE + +If the expected version is already avaiable in `PATH` (maybe is already installed globally +in the machine), that installation is used (so no need to download/install) + +Otherwise (if the expected version is not avaiable in `PATH`), the .NET Core SDK is downloaded +and installed (using the `scripts/obtain/dotnet-install` from http://github.com/dotnet/cli repo) +in `.dotnetsdk` directory, and that directory is added to `PATH` diff --git a/scripts/use_dotnet_core_sdk.bat b/scripts/use_dotnet_core_sdk.bat new file mode 100644 index 000000000000..38e673df318d --- /dev/null +++ b/scripts/use_dotnet_core_sdk.bat @@ -0,0 +1,25 @@ +@if "%_echo%"=="" echo off + +setlocal enableDelayedExpansion + +SET DOTNETPATH_FILE=%TMP%\dotnetsdk-%RANDOM%.txt + +powershell -ExecutionPolicy Unrestricted "scripts\use_dotnet_core_sdk.ps1" -OutPath "%DOTNETPATH_FILE%" +@if ERRORLEVEL 1 echo Error: .NET Core Sdk install failed && goto :failure + +set /p DOTNETSDK_DIR=<%DOTNETPATH_FILE% +goto :success + +:failure +endlocal +exit /b 1 + +:success +endlocal & ( + @REM add DOTNETSDK_DIR to PATH, if set + if not '%DOTNETSDK_DIR%' == '' ( + SET "PATH=%DOTNETSDK_DIR%;%PATH%" + ) +) + +exit /b 0 diff --git a/scripts/use_dotnet_core_sdk.ps1 b/scripts/use_dotnet_core_sdk.ps1 new file mode 100644 index 000000000000..847ffed7ea22 --- /dev/null +++ b/scripts/use_dotnet_core_sdk.ps1 @@ -0,0 +1,61 @@ +[cmdletbinding()] +param( + [string] $Version = "", + [string] $OutPath = "" +) + +Set-StrictMode -Version Latest +$ErrorActionPreference="Stop" +$ProgressPreference="SilentlyContinue" + +$rootDir = Split-Path -Parent $PSScriptRoot + +if ($Version -eq "") { $Version = Get-Content .\DotnetCoreSdkVersion.txt } +echo "Using .NET Core Sdk version $Version" + +$global:OutFilePath = $OutPath +$global:Version = $Version + +function Check-Dotnet +{ + $dotnet = $args[0] + $dotnetDir = Split-Path -Parent $dotnet + try { $dotnetVersion = iex '& "$dotnet" --version' -ErrorAction SilentlyContinue } catch { } + if (-not $?) { $dotnetVersion = "" } + if ($dotnetVersion -eq $global:Version) { + echo "Found the .NET Core Sdk $dotnetVersion in $($args[1])" + if ($global:OutFilePath -eq "") { #OutFilePath not set, add directly dir to PATH + if ($dotnetDir -ne "") { #is already in PATH, no need + $env:Path = "$dotnetDir;$env:Path" + } + } else { # write dir to OutFilePath + [System.IO.File]::WriteAllText("$global:OutFilePath", "$dotnetDir") + } + exit 0 + } else { + echo ".NET Core Sdk not found in $($args[1]), was '$dotnetVersion'" + } +} + +# check in PATH +Check-Dotnet "dotnet" "PATH" + +# check in .dotnetsdk dir +md -Force -Path "$rootDir\.dotnetsdk" | Out-Null + +$installDir = "$rootDir\.dotnetsdk" | Convert-Path + +Check-Dotnet "$installDir\dotnet" "$installDir" + +# not found, install it +$sdkBranch = ($Version.Split('-') | Select -First 2) -Join '-' +$installScriptPath = "$rootDir\scripts\dotnet-install.$sdkBranch.ps1" + +Invoke-WebRequest "https://raw.githubusercontent.com/dotnet/cli/rel/$sdkBranch/scripts/obtain/dotnet-install.ps1" -OutFile "$installScriptPath" + +iex '& $installScriptPath -InstallDir "$installDir" -Channel "preview" -version "$Version"' + +Check-Dotnet "$installDir\dotnet" "$installDir" + +echo "Error, the .NET Core Sdk $dotnetVersion was installed but not found in '$installDir' directory" +exit 1 diff --git a/src/FSharp.nugets.props b/src/FSharp.nugets.props new file mode 100644 index 000000000000..2ce69968eabb --- /dev/null +++ b/src/FSharp.nugets.props @@ -0,0 +1,10 @@ + + + + $([System.DateTime]::Now.ToString(`yyMMdd`)) + 1.0.0 + $(NuGetReleaseVersion)-rc + $(NuGetPreReleaseVersion)-$(BuildRevision.Trim()) + + + diff --git a/src/FSharpSource.UseProtoFsc.net40.props b/src/FSharpSource.UseProtoFsc.net40.props new file mode 100644 index 000000000000..2adb57e4c157 --- /dev/null +++ b/src/FSharpSource.UseProtoFsc.net40.props @@ -0,0 +1,9 @@ + + + + $(MSBuildThisFileDirectory)..\Proto\net40\bin + fsc-proto.exe + true + + + diff --git a/src/FSharpSource.netcore.props b/src/FSharpSource.netcore.props new file mode 100644 index 000000000000..fd402e5871f2 --- /dev/null +++ b/src/FSharpSource.netcore.props @@ -0,0 +1,60 @@ + + + + false + true + + + + $(OtherFlags) --delaysign+ + $(OtherFlags) --keyfile:"$(FSharpSourcesRoot)\fsharp\msft.pubkey" + STRONG_NAME_AND_DELAY_SIGN_FSHARP_COMPILER_WITH_MSFT_KEY;$(DefineConstants) + true + + + + $(DefineConstants);FX_PORTABLE_OR_NETSTANDARD + $(DefineConstants);NETSTANDARD1_6 + $(DefineConstants);PREFERRED_UI_LANG + $(DefineConstants);FX_NO_APP_DOMAINS + $(DefineConstants);FX_NO_ARRAY_LONG_LENGTH + $(DefineConstants);FX_NO_BEGINEND_READWRITE + $(DefineConstants);FX_NO_BINARY_SERIALIZATION + $(DefineConstants);FX_NO_CONVERTER + $(DefineConstants);FX_NO_DEFAULT_DEPENDENCY_TYPE + $(DefineConstants);FX_NO_CORHOST_SIGNER + $(DefineConstants);FX_NO_CRYPTO + $(DefineConstants);FX_NO_EVENTWAITHANDLE_IDISPOSABLE + $(DefineConstants);FX_NO_EXIT_CONTEXT_FLAGS + $(DefineConstants);FX_NO_HEAPTERMINATION + $(DefineConstants);FX_NO_LINKEDRESOURCES + $(DefineConstants);FX_NO_LOADER_OPTIMIZATION + $(DefineConstants);FX_NO_SIMPLIFIED_LOADER + $(DefineConstants);FX_NO_PARAMETERIZED_THREAD_START + $(DefineConstants);FX_NO_PDB_READER + $(DefineConstants);FX_NO_PDB_WRITER + $(DefineConstants);FX_NO_REFLECTION_MODULE_HANDLES + $(DefineConstants);FX_NO_REFLECTION_ONLY + $(DefineConstants);FX_NO_RUNTIMEENVIRONMENT + $(DefineConstants);FX_NO_SECURITY_PERMISSIONS + $(DefineConstants);FX_NO_SERVERCODEPAGES + $(DefineConstants);FX_NO_SYMBOLSTORE + $(DefineConstants);FX_NO_SYSTEM_CONFIGURATION + $(DefineConstants);FX_NO_THREAD + $(DefineConstants);FX_NO_THREADABORT + $(DefineConstants);FX_NO_WAITONE_MILLISECONDS + $(DefineConstants);FX_NO_WEB_CLIENT + $(DefineConstants);FX_NO_WIN_REGISTRY + $(DefineConstants);FX_NO_WINFORMS + $(DefineConstants);FX_REDUCED_EXCEPTIONS + $(DefineConstants);FX_REDUCED_CONSOLE + $(DefineConstants);FX_RESHAPED_REFEMIT + $(DefineConstants);FX_RESHAPED_CONSOLE + $(DefineConstants);FX_RESHAPED_GLOBALIZATION + $(DefineConstants);FX_RESHAPED_REFLECTION + $(DefineConstants);FX_RESHAPED_REFLECTION_CORECLR + $(DefineConstants);FX_RESHAPED_MSBUILD + $(DefineConstants);FSI_TODO_NETCORE + + + diff --git a/src/fsharp/FSharp.Compiler.Sdk.netcore.nuget/Microsoft.FSharp.Compiler.Sdk.netcore.nuspec b/src/fsharp/FSharp.Compiler.Sdk.netcore.nuget/Microsoft.FSharp.Compiler.Sdk.netcore.nuspec new file mode 100644 index 000000000000..f59110a1f568 --- /dev/null +++ b/src/fsharp/FSharp.Compiler.Sdk.netcore.nuget/Microsoft.FSharp.Compiler.Sdk.netcore.nuspec @@ -0,0 +1,23 @@ + + + + Microsoft.FSharp.Compiler.Sdk.netcore + + .NET Core compatible version of the fsharp compiler fsc.exe. + Supported Platforms: - .NET Core (.netstandard1.6) + + en-US + true + $version$ + $authors$ + $licenseUrl$ + $projectUrl$ + $tags$ + + + + + + + + diff --git a/src/fsharp/FSharp.Compiler.Sdk.netcore.nuget/build/Microsoft.FSharp.Compiler.Sdk.netcore.props b/src/fsharp/FSharp.Compiler.Sdk.netcore.nuget/build/Microsoft.FSharp.Compiler.Sdk.netcore.props new file mode 100644 index 000000000000..ed00438b3fa3 --- /dev/null +++ b/src/fsharp/FSharp.Compiler.Sdk.netcore.nuget/build/Microsoft.FSharp.Compiler.Sdk.netcore.props @@ -0,0 +1,21 @@ + + + + + $(MSBuildThisFileDirectory)\netcoreapp1.0\FSharp.Build.dll + $(MSBuildThisFileDirectory)\netcoreapp1.0 + fsc.dll + + + diff --git a/src/fsharp/FSharp.Compiler.Sdk.netcore.nuget/buildCrossTargeting/Microsoft.FSharp.Compiler.Sdk.netcore.props b/src/fsharp/FSharp.Compiler.Sdk.netcore.nuget/buildCrossTargeting/Microsoft.FSharp.Compiler.Sdk.netcore.props new file mode 100644 index 000000000000..fbcccfc14ddd --- /dev/null +++ b/src/fsharp/FSharp.Compiler.Sdk.netcore.nuget/buildCrossTargeting/Microsoft.FSharp.Compiler.Sdk.netcore.props @@ -0,0 +1,21 @@ + + + + + $(MSBuildThisFileDirectory)..\build\netcoreapp1.0\FSharp.Build.dll + $(MSBuildThisFileDirectory)..\build\netcoreapp1.0 + fsc.dll + + + diff --git a/src/fsharp/Fsc/Fsc.netcore.NuGet.Config b/src/fsharp/Fsc/Fsc.netcore.NuGet.Config new file mode 100644 index 000000000000..e88a9c235d0d --- /dev/null +++ b/src/fsharp/Fsc/Fsc.netcore.NuGet.Config @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/fsharp/Fsc/Fsc.netcore.fsproj b/src/fsharp/Fsc/Fsc.netcore.fsproj new file mode 100644 index 000000000000..3c31ae38329c --- /dev/null +++ b/src/fsharp/Fsc/Fsc.netcore.fsproj @@ -0,0 +1,103 @@ + + + + Exe + netcoreapp1.0 + + + + $(MSBuildProjectDirectory)\..\.. + + + + $(NoWarn);62 + fsc + + EXTENSIONTYPING; + COMPILER; + $(DefineConstants); + + $(OtherFlags) --warnon:1182 + + + + + + Resources/assemblyinfo.fsc.exe.fs + + + fscmain.fs + + + default.win32manifest + PreserveNewest + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + All + + + + diff --git a/tests/fsharp/test-framework.fs b/tests/fsharp/test-framework.fs index 0de22d8b9b6a..7b8a8594af05 100644 --- a/tests/fsharp/test-framework.fs +++ b/tests/fsharp/test-framework.fs @@ -4,10 +4,10 @@ open Microsoft.Win32 open System open System.IO open System.Text.RegularExpressions +open System.Runtime.InteropServices open Scripting open NUnit.Framework - [] module Commands = @@ -37,6 +37,11 @@ module Commands = let p = path |> getfullpath dir if File.Exists(p) then File.Delete(p) + let rmDir workDir path = + log "rmdir %s" path + let p = path |> getfullpath workDir + if Directory.Exists(p) then Directory.Delete(p, true) + let pathAddBackslash (p: FilePath) = if String.IsNullOrWhiteSpace (p) then p else @@ -93,6 +98,39 @@ module Commands = Directory.CreateDirectory path |> ignore path + let dotnet exec dotnetExe flags = + exec dotnetExe flags + + let copyDirectory target source = + let rec copyDirectoryInner (target: DirectoryInfo) (source: DirectoryInfo) = + for dir in source.GetDirectories() do + copyDirectoryInner dir (target.CreateSubdirectory(dir.Name)) + + for file in source.GetFiles() do + file.CopyTo(Path.Combine(target.FullName, file.Name)) |> ignore + + log "copy '%s/**/*' '%s'" source target + (DirectoryInfo source) |> copyDirectoryInner (DirectoryInfo target) + + let which exec cmd = + let whichCmd = + if RuntimeInformation.IsOSPlatform(OSPlatform.Windows) then + "where" + else + "which" + + let o = Path.GetTempFileName() + match exec o whichCmd cmd with + | CmdResult.ErrorLevel _ -> [] + | CmdResult.Success -> + try + match File.ReadAllText(o) with + | null -> [] + | v -> + v.Split([| Environment.NewLine |], StringSplitOptions.RemoveEmptyEntries) + |> List.ofArray + with _ -> + [] type TestConfig = { EnvironmentVariables : Map @@ -230,6 +268,7 @@ let logConfig (cfg: TestConfig) = log "ILDASM =%s" cfg.ILDASM log "NGEN =%s" cfg.NGEN log "PEVERIFY =%s" cfg.PEVERIFY + log "DOTNET =%s" cfg.DotNetExe log "---------------------------------------------------------------" @@ -270,6 +309,8 @@ let initializeSuite () = let suiteHelpers = lazy (initializeSuite ()) +#if !NO_NUNIT + [] type public InitializeSuiteAttribute () = inherit TestActionAttribute() @@ -288,6 +329,8 @@ type public InitializeSuiteAttribute () = [] () +#endif + let fsharpSuiteDirectory = __SOURCE_DIRECTORY__ let testConfig testDir = @@ -312,6 +355,19 @@ type FileGuard(path: string) = member x.Dispose () = remove path +[] +type HelperDirectory(path: string) = + let remove path = if Directory.Exists(path) then Commands.rmDir (Path.GetTempPath()) path + let create path = Commands.mkdir_p (Path.GetTempPath()) path + do if not (Path.IsPathRooted(path)) then failwithf "path '%s' must be absolute" path + do remove path + do create path + member x.Path = path + member x.Exists = x.Path |> Directory.Exists + + interface IDisposable with + member x.Dispose () = remove path + type RedirectToType = | Overwrite of FilePath | Append of FilePath @@ -439,6 +495,7 @@ let fsi cfg = Printf.ksprintf (Commands.fsi (exec cfg) cfg.FSI) let fsiExpectFail cfg = Printf.ksprintf (Commands.fsi (execExpectFail cfg) cfg.FSI) let fsiAppendIgnoreExitCode cfg stdoutPath stderrPath = Printf.ksprintf (Commands.fsi (execAppendIgnoreExitCode cfg stdoutPath stderrPath) cfg.FSI) let fileguard cfg = (Commands.getfullpath cfg.Directory) >> (fun x -> new FileGuard(x)) +let helperDir cfg = (Commands.getfullpath cfg.Directory) >> (fun x -> new HelperDirectory(x)) let getfullpath cfg = Commands.getfullpath cfg.Directory let fileExists cfg = Commands.fileExists cfg.Directory >> Option.isSome let fsiStdin cfg stdinPath = Printf.ksprintf (Commands.fsi (execStdin cfg stdinPath) cfg.FSI) @@ -446,6 +503,7 @@ let fsiStdinAppendBothIgnoreExitCode cfg stdoutPath stderrPath stdinPath = Print let rm cfg x = Commands.rm cfg.Directory x let mkdir cfg = Commands.mkdir_p cfg.Directory let copy_y cfg f = Commands.copy_y cfg.Directory f >> checkResult +let dotnet cfg arg = Printf.ksprintf (Commands.dotnet (exec cfg) cfg.DotNetExe) arg let diff normalize path1 path2 = let result = System.Text.StringBuilder() @@ -501,3 +559,9 @@ let requireENCulture () = match System.Globalization.CultureInfo.CurrentCulture.TwoLetterISOLanguageName with | "en" -> true | _ -> false + +let which envVars cmd = + let exec o = Command.exec (Path.GetTempPath ()) envVars ({ execArgs with Output = Output(Overwrite(o)) }) + Commands.which exec cmd + +let resolveCmdFromPATH envVars cmd = which envVars cmd |> List.tryHead diff --git a/tests/projects/assets/dotnetcoresdk/console/Program.fs b/tests/projects/assets/dotnetcoresdk/console/Program.fs new file mode 100644 index 000000000000..a4928de908e4 --- /dev/null +++ b/tests/projects/assets/dotnetcoresdk/console/Program.fs @@ -0,0 +1,8 @@ +// Learn more about F# at http://fsharp.org + +open System + +[] +let main argv = + printfn "Hello World from F#!" + 0 // return an integer exit code diff --git a/tests/projects/assets/dotnetcoresdk/console/console.fsproj b/tests/projects/assets/dotnetcoresdk/console/console.fsproj new file mode 100644 index 000000000000..4a43eb25c398 --- /dev/null +++ b/tests/projects/assets/dotnetcoresdk/console/console.fsproj @@ -0,0 +1,26 @@ + + + + Exe + netcoreapp1.0 + + + + + + + + + + + All + + + + + + + + diff --git a/tests/projects/assets/dotnetcoresdk/dotnetcoresdk.NuGet.Config b/tests/projects/assets/dotnetcoresdk/dotnetcoresdk.NuGet.Config new file mode 100644 index 000000000000..e88a9c235d0d --- /dev/null +++ b/tests/projects/assets/dotnetcoresdk/dotnetcoresdk.NuGet.Config @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/tests/projects/assets/dotnetcoresdk/lib/Library.fs b/tests/projects/assets/dotnetcoresdk/lib/Library.fs new file mode 100644 index 000000000000..29377c158851 --- /dev/null +++ b/tests/projects/assets/dotnetcoresdk/lib/Library.fs @@ -0,0 +1,5 @@ +namespace Library + +module Say = + let hello name = + printfn "Hello %s" name diff --git a/tests/projects/assets/dotnetcoresdk/lib/lib.fsproj b/tests/projects/assets/dotnetcoresdk/lib/lib.fsproj new file mode 100644 index 000000000000..4d1b596d18cb --- /dev/null +++ b/tests/projects/assets/dotnetcoresdk/lib/lib.fsproj @@ -0,0 +1,25 @@ + + + + netstandard1.6 + + + + + + + + + + + All + + + + + + + + diff --git a/tests/projects/dotnetcoresdk/DotnetCoreTestConfig.fs b/tests/projects/dotnetcoresdk/DotnetCoreTestConfig.fs new file mode 100644 index 000000000000..19946642f988 --- /dev/null +++ b/tests/projects/dotnetcoresdk/DotnetCoreTestConfig.fs @@ -0,0 +1,109 @@ +module DotnetCoreTestConfig + +open System +open System.IO +open System.Xml.Linq + +open Scripting +open TestFramework + +let fsharpSuiteDirectory = __SOURCE_DIRECTORY__ + +let config configurationName envVars = + + let SCRIPT_ROOT = __SOURCE_DIRECTORY__ + let FSCBinPath = SCRIPT_ROOT ++ ".." ++ ".." ++ configurationName ++ "net40" ++ "bin" + + let csc_flags = "/nologo" + let fsc_flags = "-r:System.Core.dll --nowarn:20 --define:COMPILED" + let fsi_flags = "-r:System.Core.dll --nowarn:20 --define:INTERACTIVE --maxerrors:1 --abortonerror" + + let CORDIR, CORSDK = WindowsPlatform.clrPaths envVars + + let Is64BitOperatingSystem = WindowsPlatform.Is64BitOperatingSystem envVars + + let fsiroot = if Is64BitOperatingSystem then "fsiAnyCpu" else "fsi" + + let CSC = (CORDIR ++ "csc.exe") + let NGEN = (CORDIR ++ "ngen.exe") + let ILDASM = (CORSDK ++ "ildasm.exe") + let SN = (CORSDK ++ "sn.exe") + let PEVERIFY = (CORSDK ++ "peverify.exe") + let FSC = (FSCBinPath ++ "fsc.exe") + let FSI = (FSCBinPath ++ (fsiroot+".exe")) + let FSCOREDLLPATH = (FSCBinPath ++ "FSharp.Core.dll") + + let defaultPlatform = + match Is64BitOperatingSystem with +// | PlatformID.MacOSX, true -> "osx.10.10-x64" +// | PlatformID.Unix,true -> "ubuntu.14.04-x64" + | true -> "win7-x64" + | false -> "win7-x86" + + let dotNetExe = + match resolveCmdFromPATH envVars "dotnet" with + | Some p -> p + | None -> failwith "dotnet not found in PATH" + + { EnvironmentVariables = envVars + CORDIR = CORDIR |> Commands.pathAddBackslash + CORSDK = CORSDK |> Commands.pathAddBackslash + FSCBinPath = FSCBinPath |> Commands.pathAddBackslash + FSCOREDLLPATH = FSCOREDLLPATH + ILDASM = ILDASM + SN = SN + NGEN = NGEN + PEVERIFY = PEVERIFY + CSC = CSC + BUILD_CONFIG = configurationName + FSC = FSC + FSI = FSI + csc_flags = csc_flags + fsc_flags = fsc_flags + fsi_flags = fsi_flags + Directory="" + DotNetExe = dotNetExe + DefaultPlatform = defaultPlatform } + +let initializeSuite () = + +#if DEBUG + let configurationName = "debug" +#else + let configurationName = "release" +#endif + let env = envVars () + + let cfg = + let c = config configurationName env + let usedEnvVars = c.EnvironmentVariables |> Map.add "FSC" c.FSC + { c with EnvironmentVariables = usedEnvVars } + + logConfig cfg + + cfg + +let testConfig testDir = + + let suiteHelpers = lazy (initializeSuite ()) + let cfg = suiteHelpers.Value + + let dir = Path.GetFullPath(fsharpSuiteDirectory ++ testDir) + log "------------------ %s ---------------" dir + log "cd %s" dir + { cfg with Directory = dir } + +let readFeedsFromNugetConfig (nugetConfig: string) = + let xn name = XName.Get(name) + XDocument + .Load(nugetConfig) + .Element(xn "configuration") + .Element(xn "packageSources") + .Elements(xn "add") + .Attributes(xn "value") + |> Seq.map (fun a -> a.Value) + |> Seq.toList + +let getArtifactsDir cfg = + + __SOURCE_DIRECTORY__ ++ ".." ++ ".." ++ ".." ++ (cfg.BUILD_CONFIG) ++ "artifacts" diff --git a/tests/projects/dotnetcoresdk/FSharp.Tests.DotnetCoreSdk.fsproj b/tests/projects/dotnetcoresdk/FSharp.Tests.DotnetCoreSdk.fsproj new file mode 100644 index 000000000000..e8fbceea233f --- /dev/null +++ b/tests/projects/dotnetcoresdk/FSharp.Tests.DotnetCoreSdk.fsproj @@ -0,0 +1,34 @@ + + + + Exe + netcoreapp1.0 + + + $(DefineConstants); + FX_PORTABLE_OR_NETSTANDARD; + FSHARP_SUITE_DRIVES_CORECLR_TESTS; + NO_NUNIT; + + + + + + + + + + + + + + + + + + + All + + + + diff --git a/tests/projects/dotnetcoresdk/Tests.fs b/tests/projects/dotnetcoresdk/Tests.fs new file mode 100644 index 000000000000..a7cf5a460d3a --- /dev/null +++ b/tests/projects/dotnetcoresdk/Tests.fs @@ -0,0 +1,91 @@ +module Tests + +open System +open System.IO +open Xunit + +open Scripting +open TestFramework +open DotnetCoreTestConfig + +let assetsDirectory = __SOURCE_DIRECTORY__ ++ ".." ++ "assets" +let getPackageToTest cfg = + match cfg.EnvironmentVariables |> Map.tryFind "TEST_COMPILERSDK_PACKAGE" with + | Some pkg -> pkg + | None -> failwith "TEST_COMPILERSDK_PACKAGE env var is not set, should be the package version to test" +let cloneAssets (major,name) toDir = + let dir = assetsDirectory ++ major ++ name + dir |> Commands.copyDirectory toDir + +[] +let ``console app should build`` () = + + let cfg = testConfig (Commands.createTempDir ()) + + use packagesDir = helperDir cfg (Commands.createTempDir () ++ "packages") + + let pkg = getPackageToTest cfg + + cloneAssets ("dotnetcoresdk","console") cfg.Directory + + dotnet cfg "--version" + + let feeds = + assetsDirectory ++ "dotnetcoresdk" ++ "dotnetcoresdk.NuGet.Config" + |> readFeedsFromNugetConfig + |> List.append [ getArtifactsDir cfg ] + + //using --packages directory and --no-cache is slower but it's done to be sure the right package is used + // because one with same version can be already saved in local cache, and nuget (dotnet restore) use always + // the package in local cache if version match + //the --no-cache just ignore cache for http requests, not the locally cached package in packages directory + + dotnet cfg """restore --packages "%s" --no-cache %s /p:CompilerSdkPackageVersion=%s -v n""" (packagesDir.Path) (feeds |> List.map (sprintf """--source "%s" """) |> String.concat " ") pkg + + dotnet cfg "build -c Debug -v n" + + dotnet cfg "run -c Debug -v n" + + dotnet cfg "build -c Release -v n" + + dotnet cfg "run -c Relase -v n" + + +[] +let ``lib should build`` () = + + let cfg = testConfig (Commands.createTempDir ()) + + use packagesDir = helperDir cfg (Commands.createTempDir () ++ "packages") + + let pkg = getPackageToTest cfg + + cloneAssets ("dotnetcoresdk","lib") cfg.Directory + + dotnet cfg "--version" + + let feeds = + assetsDirectory ++ "dotnetcoresdk" ++ "dotnetcoresdk.NuGet.Config" + |> readFeedsFromNugetConfig + |> List.append [ getArtifactsDir cfg ] + + //using --packages directory and --no-cache is slower but it's done to be sure the right package is used + // because one with same version can be already saved in local cache, and nuget (dotnet restore) use always + // the package in local cache if version match + //the --no-cache just ignore cache for http requests, not the locally cached package in packages directory + + dotnet cfg """restore --packages "%s" --no-cache %s /p:CompilerSdkPackageVersion=%s -v n""" (packagesDir.Path) (feeds |> List.map (sprintf """--source "%s" """) |> String.concat " ") pkg + + dotnet cfg "build -c Debug -v n" + + dotnet cfg "pack -c Debug /p:PackageVersion=1.0.0-alpha1 -v n" + + dotnet cfg "build -c Release -v n" + + dotnet cfg "pack -c Release /p:PackageVersion=1.0.0-alpha2 -v n" + +[] +let main argv = + ``console app should build`` () + ``lib should build`` () + 0 diff --git a/tests/projects/dotnetcoresdk/XunitToNunitShim.fs b/tests/projects/dotnetcoresdk/XunitToNunitShim.fs new file mode 100644 index 000000000000..101c1362b39e --- /dev/null +++ b/tests/projects/dotnetcoresdk/XunitToNunitShim.fs @@ -0,0 +1,7 @@ +namespace NUnit.Framework + +open Xunit + +module Assert = + + let Fail(message) = Assert.True(false, message)