Build mscolrib.dll on Unix
authorMatt Ellis <matell@microsoft.com>
Tue, 11 Aug 2015 05:36:57 +0000 (22:36 -0700)
committerMatt Ellis <matell@microsoft.com>
Tue, 18 Aug 2015 00:05:06 +0000 (17:05 -0700)
Initial work to get mscorlib.dll building via Roslyn + MSBuild running
on top of Mono on Linux.

- Use a newer version of BclRewriter.exe which works cross-platform,
  the major difference here is that now we need to specify the input
  assembly as a named argument instead (since fully qualified paths on
  Unix look like flags on Windows).

- The ResGen we use comes from Mono, which does not support the -d
  flag, so we need to stop passing defines to ResGen. I know the mono
  folks recently did some work to address this, but long term we need
  to move towards getting our ResGen.exe running on CoreCLR and use
  that instead.

- Don't require that mono is installed in order to build coreclr.  If
  mono is not on the path, skip the build step to enable folks to do
  development without Mono. In this case, they will need to continue
  to build mscorlib.dll on Windows, targeting Unix.

- Mono stability has been an issue for folks that have buddy tested
  this. I've found that recent mono 4.2 builds, when run with the
  Boehm GC work well for me. Other folks have other builds they like
  instead. The `skipmscorlib` flag can be passed to build.sh if you
  want to skip building mscorlib.dll locally.

build.sh
dir.props
src/.nuget/packages.Unix.config
src/.nuget/packages.Windows_NT.config
src/mscorlib/GenerateSplitStringResources.targets
src/mscorlib/Tools/BclRewriter/BclRewriter.targets
src/mscorlib/Tools/PostProcessingTools.targets
src/mscorlib/Tools/Versioning/GenerateVersionInfo.targets
src/mscorlib/mscorlib.csproj

index 14ef25f..f3cbb11 100755 (executable)
--- a/build.sh
+++ b/build.sh
@@ -2,7 +2,7 @@
 
 usage()
 {
-    echo "Usage: $0 [BuildArch] [BuildType] [clean] [verbose] [cross] [clangx.y]"
+    echo "Usage: $0 [BuildArch] [BuildType] [clean] [verbose] [cross] [clangx.y] [skipmscorlib]"
     echo "BuildArch can be: x64, ARM"
     echo "BuildType can be: Debug, Release"
     echo "clean - optional argument to force a clean build."
@@ -10,6 +10,7 @@ usage()
     echo "clangx.y - optional argument to build using clang version x.y."
     echo "cross - optional argument to signify cross compilation,"
     echo "      - will use ROOTFS_DIR environment variable if set."
+    echo "skipmscorlib - do not build mscorlib.dll even if mono is installed."
 
     exit 1
 }
@@ -17,7 +18,7 @@ usage()
 setup_dirs()
 {
     echo Setting up directories for build
-    
+
     mkdir -p "$__RootBinDir"
     mkdir -p "$__BinDir"
     mkdir -p "$__LogsDir"
@@ -31,10 +32,10 @@ clean()
     echo Cleaning previous output for the selected configuration
     rm -rf "$__BinDir"
     rm -rf "$__IntermediatesDir"
-       
+
     rm -rf "$__TestWorkingDir"
     rm -rf "$__TestIntermediatesDir"
-       
+
     rm -rf "$__LogsDir/*_$__BuildOS__$__BuildArch__$__BuildType.*"
 }
 
@@ -43,28 +44,28 @@ clean()
 check_prereqs()
 {
     echo "Checking pre-requisites..."
-    
+
     # Check presence of CMake on the path
     hash cmake 2>/dev/null || { echo >&2 "Please install cmake before running this script"; exit 1; }
-    
+
     # Check for clang
     hash clang-$__ClangMajorVersion.$__ClangMinorVersion 2>/dev/null ||  hash clang$__ClangMajorVersion$__ClangMinorVersion 2>/dev/null ||  hash clang 2>/dev/null || { echo >&2 "Please install clang before running this script"; exit 1; }
-   
+
 }
 
 build_coreclr()
 {
     # All set to commence the build
-    
+
     echo "Commencing build of native components for $__BuildOS.$__BuildArch.$__BuildType"
     cd "$__IntermediatesDir"
-    
+
     # Regenerate the CMake solution
     echo "Invoking cmake with arguments: \"$__ProjectRoot\" $__CMakeArgs"
     "$__ProjectRoot/src/pal/tools/gen-buildsys-clang.sh" "$__ProjectRoot" $__ClangMajorVersion $__ClangMinorVersion $__BuildArch $__CMakeArgs
-    
+
     # Check that the makefiles were created.
-    
+
     if [ ! -f "$__IntermediatesDir/Makefile" ]; then
         echo "Failed to generate native component build project!"
         exit 1
@@ -78,9 +79,9 @@ build_coreclr()
     else
        NumProc=$(($(getconf _NPROCESSORS_ONLN)+1))
     fi
-    
+
     # Build CoreCLR
-    
+
     echo "Executing make install -j $NumProc $__UnprocessedBuildArgs"
 
     make install -j $NumProc $__UnprocessedBuildArgs
@@ -90,6 +91,52 @@ build_coreclr()
     fi
 }
 
+build_mscorlib()
+{
+    hash mono 2> /dev/null || { echo >&2 "Skipping mscorlib.dll build since Mono is not installed."; return; }
+
+    if [ $__SkipMSCorLib == 1 ]; then
+        echo "Skipping mscorlib.dll build."
+        return
+    fi
+
+    echo "Commencing build of mscorlib components for $__BuildOS.$__BuildArch.$__BuildType"
+
+    # Pull NuGet.exe down if we don't have it already
+    if [ ! -e "$__NuGetPath" ]; then
+        hash curl 2>/dev/null || hash wget 2>/dev/null || { echo >&2 echo "cURL or wget is required to build mscorlib." ; exit 1; }
+
+        echo "Restoring NuGet.exe..."
+
+        # curl has HTTPS CA trust-issues less often than wget, so lets try that first.
+        which curl > /dev/null 2> /dev/null
+        if [ $? -ne 0 ]; then
+           mkdir -p $__PackagesDir
+           wget -q -O $__NuGetPath https://api.nuget.org/downloads/nuget.exe
+        else
+           curl -sSL --create-dirs -o $__NuGetPath https://api.nuget.org/downloads/nuget.exe
+        fi
+
+        if [ $? -ne 0 ]; then
+            echo "Failed to restore NuGet.exe."
+            exit 1
+        fi
+    fi
+
+    # Grab the MSBuild package if we don't have it already
+    if [ ! -e "$__MSBuildPath" ]; then
+        echo "Restoring MSBuild..."
+        mono "$__NuGetPath" install $__MSBuildPackageId -Version $__MSBuildPackageVersion -source "https://www.myget.org/F/dotnet-buildtools/" -OutputDirectory "$__PackagesDir"
+        if [ $? -ne 0 ]; then
+            echo "Failed to restore MSBuild."
+            exit 1
+        fi
+    fi
+
+    # Invoke MSBuild
+    mono "$__MSBuildPath" /nologo "$__ProjectRoot/build.proj" /verbosity:minimal "/fileloggerparameters:Verbosity=normal;LogFile=$__LogsDir/MSCorLib_$__BuildOS__$__BuildArch__$__BuildType.log" /t:Build /p:OSGroup=$__BuildOS /p:BuildOS=$__BuildOS /p:UseRoslynCompiler=true /p:BuildNugetPackage=false
+}
+
 echo "Commencing CoreCLR Repo build"
 
 # Argument types supported by this script:
@@ -142,11 +189,16 @@ __RootBinDir="$__ProjectDir/bin"
 __LogsDir="$__RootBinDir/Logs"
 __UnprocessedBuildArgs=
 __MSBCleanBuildArgs=
+__SkipMSCorLib=false
 __CleanBuild=false
 __VerboseBuild=false
 __CrossBuild=false
 __ClangMajorVersion=3
 __ClangMinorVersion=5
+__MSBuildPackageId="Microsoft.Build.Mono.Debug"
+__MSBuildPackageVersion="14.1.0.0-prerelease"
+__MSBuildPath="$__PackagesDir/$__MSBuildPackageId.$__MSBuildPackageVersion/lib/MSBuild.exe"
+__NuGetPath="$__PackagesDir/NuGet.exe"
 
 for i in "$@"
     do
@@ -197,6 +249,7 @@ for i in "$@"
         __ClangMinorVersion=7
         ;;
         skipmscorlib)
+        __SkipMSCorLib=1
         ;;
         *)
         __UnprocessedBuildArgs="$__UnprocessedBuildArgs $i"
@@ -245,6 +298,10 @@ check_prereqs
 
 build_coreclr
 
+# Build mscolrib.
+
+build_mscorlib
+
 # Build complete
 
 echo "Repo successfully built."
index 5fc9429..c004378 100644 (file)
--- a/dir.props
+++ b/dir.props
@@ -10,7 +10,7 @@
   <!-- Build Tools Versions -->
   <PropertyGroup>
     <BuildToolsVersion>1.0.25-prerelease-00056</BuildToolsVersion>
-    <BuildToolsCoreCLRVersion>1.0.2-prerelease</BuildToolsCoreCLRVersion>
+    <BuildToolsCoreCLRVersion>1.0.3-prerelease</BuildToolsCoreCLRVersion>
     <DnxVersion Condition="'$(OsEnvironment)'!='Unix'">1.0.0-beta5-12101</DnxVersion>
     <DnxVersion Condition="'$(OsEnvironment)'=='Unix'">1.0.0-beta5-12101</DnxVersion>
     <DnxPackageName Condition="'$(DnxPackageName)' == '' and '$(OsEnvironment)'!='Unix'">dnx-coreclr-win-x86.$(DnxVersion)</DnxPackageName>
     <NuSpecs Condition="'$(Configuration)'=='Debug'" Include="$(PackagesBinDir)\Microsoft.DotNet.CoreCLR.Debug.Development.nuspec" />
   </ItemGroup>
 
+  <!--
+    Set up Roslyn predefines
+  -->
+  <PropertyGroup>
+    <RoslynPackageDir>$(PackagesDir)/$(RoslynPackageName).$(RoslynVersion)/</RoslynPackageDir>
+    <RoslynPropsFile>$(RoslynPackageDir)build/Microsoft.Net.ToolsetCompilers.props</RoslynPropsFile>
+  </PropertyGroup>
+
   <!-- Setup common target properties that we use to conditionally include sources -->
   <PropertyGroup>
     <TargetsFreeBSD Condition="'$(BuildOS)' == 'FreeBSD'">true</TargetsFreeBSD>
     
     <TargetsUnix Condition="'$(TargetsFreeBSD)' == 'true' or '$(TargetsLinux)' == 'true' or '$(TargetsOSX)' == 'true'">true</TargetsUnix>
   </PropertyGroup>
-</Project>
\ No newline at end of file
+</Project>
index b7a7e0b..0f758ef 100644 (file)
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="Microsoft.DotNet.BuildTools.CoreCLR" version="1.0.2-prerelease" />
   <package id="Microsoft.DotNet.BuildTools" version="1.0.25-prerelease-00056" />
-  <package id="dnx-coreclr-win-x86" version="1.0.0-beta5-12101" />
-</packages>
\ No newline at end of file
+  <package id="Microsoft.DotNet.BuildTools.CoreCLR" version="1.0.3-prerelease" />
+  <package id="dnx-mono" version="1.0.0-beta5-12101" />
+  <package id="Microsoft.Net.ToolsetCompilers" version="1.0.0-rc3-20150510-01" />
+</packages>
index 872e60d..6379b79 100644 (file)
@@ -2,5 +2,5 @@
 <packages>
   <package id="Microsoft.DotNet.BuildTools" version="1.0.25-prerelease-00056" />
   <package id="dnx-coreclr-win-x86" version="1.0.0-beta5-12101" />
-  <package id="Microsoft.DotNet.BuildTools.CoreCLR" version="1.0.2-prerelease" />
-</packages>
\ No newline at end of file
+  <package id="Microsoft.DotNet.BuildTools.CoreCLR" version="1.0.3-prerelease" />
+</packages>
index dd00efd..4b69ba6 100644 (file)
@@ -1,6 +1,7 @@
 <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <PropertyGroup>
-    <ResGenCommand Condition="'$(ResGenCommand)'==''">$(SDK40ToolsPath)ResGen.exe</ResGenCommand>
+    <ResGenCommand Condition="'$(ResGenCommand)'=='' and '$(OsEnvironment)'=='Windows_NT'">$(SDK40ToolsPath)ResGen.exe</ResGenCommand>
+    <ResGenCommand Condition="'$(ResGenCommand)'=='' and '$(OsEnvironment)'=='Unix'">resgen</ResGenCommand>
     <PrepareResourcesDependsOn>GenerateSplitStringResources;$(PrepareResourcesDependsOn)</PrepareResourcesDependsOn>
   </PropertyGroup>
     
@@ -8,12 +9,14 @@
           Inputs="$(MSBuildThisFileFullPath);$(MSBuildProjectFile);$(BclSourcesRoot)\mscorlib.txt"
           Outputs="@(SplitTextStringResource->'$(IntermediateOutputPath)%(Filename).resources')">
          
-    <ItemGroup>
+    <ItemGroup Condition="'$(OsEnvironment)'=='Windows_NT'">
       <Internal_ResGenDefines Remove="" />
+      <Internal_ResGenDefines Include="INCLUDE_DEBUG" />
+      <Internal_ResGenDefines Include="INCLUDE_RUNTIME" />
       <Internal_ResGenDefines Include="%(SplitTextStringResource.ResGenDefines)" />
     </ItemGroup>    
 
-    <Exec Command="&quot;$(ResGenCommand)&quot; &quot;%(SplitTextStringResource.Identity)&quot; &quot;$(IntermediateOutputPath)%(SplitTextStringResource.Filename).resources&quot; /D:INCLUDE_DEBUG /D:INCLUDE_RUNTIME @(Internal_ResGenDefines->'/D:%(Identity)', ' ')" />
+    <Exec Command="&quot;$(ResGenCommand)&quot; &quot;%(SplitTextStringResource.Identity)&quot; &quot;$(IntermediateOutputPath)%(SplitTextStringResource.Filename).resources&quot; @(Internal_ResGenDefines->'/D:%(Identity)', ' ')" />
 
     <ItemGroup>
       <EmbeddedResource Include="@(SplitTextStringResource->'$(IntermediateOutputPath)%(Filename).resources')">
@@ -27,4 +30,4 @@
         <Internal_ResGenDefines Remove="" />
     </ItemGroup>
   </Target>
-</Project>
\ No newline at end of file
+</Project>
index 837f14f..3588a77 100644 (file)
@@ -24,7 +24,7 @@
       <OSPlatform Condition="'$(TargetsWindows)' != 'true'">unix</OSPlatform>
     </PropertyGroup>
    
-    <Exec Command="&quot;$(BclRewriterCommand)&quot; &quot;@(AnnotatedAssembly)&quot; &quot;/out:$(BclRewriterOutput)&quot; &quot;/include:$(BclRewriterModelFile)&quot; /platform:$(OSPlatform) /architecture:$(Platform) /flavor:$(_BuildType) /define:$(DefineConstants) /keepTempFiles+" StandardOutputImportance="Normal" />
+    <Exec Command="&quot;$(BclRewriterCommand)&quot; -in:&quot;@(AnnotatedAssembly)&quot; -out:&quot;$(BclRewriterOutput)&quot; -include:&quot;$(BclRewriterModelFile)&quot; -platform:$(OSPlatform) -architecture:$(Platform) -flavor:$(_BuildType) -define:&quot;$(DefineConstants)&quot; -keepTempFiles+" StandardOutputImportance="Normal" />
 
     <!-- Update the location of the symbol file-->
     <PropertyGroup>
index 78768eb..7231540 100644 (file)
@@ -19,7 +19,7 @@
     <!-- Copy to the final output location -->
     <Copy Retries="3" SourceFiles="@(RewrittenAssembly)" DestinationFiles="$(FinalOutputPath)\%(RewrittenAssembly.FileName)%(RewrittenAssembly.Extension)"/>
     <Message Importance="High" Text="$(MSBuildProjectName) -&gt; $(FinalOutputPath)\%(RewrittenAssembly.FileName)%(RewrittenAssembly.Extension)" />
-    <Copy Retries="3" SourceFiles="$(CurrentAssemblyPdb)" DestinationFiles="$(FinalOutputPath)\$(TargetName).pdb"/>
+    <Copy Condition="Exists('$(CurrentAssemblyPdb)')" Retries="3" SourceFiles="$(CurrentAssemblyPdb)" DestinationFiles="$(FinalOutputPath)\$(TargetName).pdb"/>
   </Target>
 
-</Project>
\ No newline at end of file
+</Project>
index 2a804b4..00f5282 100644 (file)
@@ -68,6 +68,7 @@
   </PropertyGroup>
 
   <Target Name="GenerateVersionHeader"
+          Condition="'$(GenerateNativeVersionInfo)'=='true'"
           Inputs="$(MSBuildProjectFile)"
           Outputs="$(NativeVersionHeaderFile)">
 
   </Target>
 
   
-  <PropertyGroup>
+  <PropertyGroup Condition="'$(GenerateNativeVersionInfo)'=='true'">
     <WindowsSdkDir Condition="'$(WindowsSdkDir)'==''">$(registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows\v8.1@InstallationFolder)</WindowsSdkDir>
     <RCPath Condition="'$(RCPath)' == ''">$(WindowsSdkDir)bin\x86\rc.exe</RCPath>
   </PropertyGroup>
   
-  <Target Name="NativeResourceCompile" DependsOnTargets="GenerateVersionHeader" Inputs="$(MsBuildThisFileDirectory)NativeVersion.rc" Outputs="$(Win32Resource)">
-    <Exec Command="&quot;$(RCPath)&quot; /nologo /x /i &quot;$(IntermediateOutputPath.TrimEnd('\'))&quot; /i &quot;$(WindowsSdkDir)Include\$(WindowsSDKVersion)um&quot; /i &quot;$(WindowsSdkDir)Include\$(WindowsSDKVersion)shared&quot; /D _UNICODE /D UNICODE /l&quot;0x0409&quot; /r /fo &quot;$(Win32Resource)&quot; &quot;$(MsBuildThisFileDirectory)NativeVersion.rc&quot;" />
+  <Target Name="NativeResourceCompile"
+          Condition="'$(GenerateNativeVersionInfo)'=='true'"
+          DependsOnTargets="GenerateVersionHeader"
+          Inputs="$(MsBuildThisFileDirectory)NativeVersion.rc"
+          Outputs="$(Win32Resource)">
+
+    <Exec Command="&quot;$(RCPath)&quot; /nologo /x /i &quot;$(IntermediateOutputPath.TrimEnd('\'))&quot; /i &quot;$(WindowsSdkDir)Include\$(WindowsSDKVersion)um&quot; /i &quot;$(WindowsSdkDir)Include\$(WindowsSDKVersion)\shared&quot; /D _UNICODE /D UNICODE /l&quot;0x0409&quot; /r /fo &quot;$(Win32Resource)&quot; &quot;$(MsBuildThisFileDirectory)NativeVersion.rc&quot;" />
+
   </Target>
-</Project>
\ No newline at end of file
+</Project>
index 559e685..a41f7b0 100644 (file)
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
   
@@ -29,7 +29,7 @@
     <HighEntropyVA>true</HighEntropyVA>
     <ErrorReport>prompt</ErrorReport>
     <Optimize Condition="'$(Optimize)' == ''">true</Optimize>
-    <GenerateNativeVersionInfo>true</GenerateNativeVersionInfo>
+    <GenerateNativeVersionInfo Condition="'$(OsEnvironment)'=='Windows_NT'">true</GenerateNativeVersionInfo>
     <CLSCompliant>true</CLSCompliant>
     <WarningLevel>4</WarningLevel>
     <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
     <DefineConstants>TRACE;$(DefineConstants)</DefineConstants>
   </PropertyGroup>
 
+  <!-- Roslyn does not support writing PDBs on Unix -->
+  <PropertyGroup Condition="'$(OsEnvironment)' == 'Unix'">
+    <DebugSymbols>false</DebugSymbols>
+    <DebugType>none</DebugType>
+  </PropertyGroup>
+
   <!-- Assembly attributes -->
   <PropertyGroup>
     <AssemblyName>mscorlib</AssemblyName>