Skip to content

.Net Core 3.0.0 for FreeBSD

Jason Pugsley edited this page Oct 18, 2019 · 1 revision

Hopefully these steps will allow you to build dotnet 3 on FreeBSD. Thanks to @wfurt for setting a direction around FreeBSD RIDs with this PR. Building the SDK on FreeBSD 11 should allow it to run on 11, 12 and 13. My testing shows this to be the case, though 13 has not yet been released so no guarantee there.

As it is, FreeBSD support still requires additional work to implement features that are missing in the runtime to reach parity with the other operating systems. The community will most likely need to do that work in .Net 3.0/3.1 but I would like to see official automated daily builds for FreeBSD restarted with the master (.Net 5) branches of the necessary repos.

If you want to try building/running a .Net Core app on FreeBSD, then how far you get will depend on whether you hit an unimplemented feature. If it's important to you then please create an github issue in the official repos for any problems you find, and submit a PR if you're able to.

FreeBSD Packages for rebuilding the SDK

Starting with a fresh install of FreeBSD 11, add these packages.

sudo pkg install libunwind lttng-ust icu curl openssl111 bash git llvm60 cmake krb5
sudo ln -s /usr/local/bin/bash /bin/bash

One of the other packages brought in python2.7 but I needed to create a softlink.

sudo ln -s /usr/local/bin/python2.7 /usr/local/bin/python

.NET Core 3.0.0 prebuilt SDK

I'll make my build available for a while on OneDrive dotnet-sdk-3.0.100-freebsd-x64.tar.gz. It's about 208MB. Extract the SDK to ~/dotnet-sdk so we can link to it from each repo.

mkdir ~/dotnet-sdk
tar xf dotnet-sdk-3.0.100-freebsd-x64.tar.gz -C ~/dotnet-sdk

Essential .Net NuGet Base Packages

You will also require some base packages that aren't yet provided officially. This archive includes everything built by the repos. It's about 628MB. Download dotnet_pkgs-3.0.0-freebsd.tar Extract the packages to a package staging directory.

mkdir ~/dotnet_pkgs
tar xf dotnet_pkgs-3.0.0-freebsd.tar -C ~/dotnet_pkgs

Set your NuGet configuration to use these packages ahead of the official ones, otherwise when restoring you will end up getting the official packages, some of which don't yet have references to FreeBSD. Edit ~/.nuget/NuGet/NuGet.Config and ensure you use the correct path for your package staging directory you created earlier. E.g. /home/<YOUR_HOME_DIR>/dotnet_pkgs

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <add key="local_pkgs" value="/home/<YOUR_HOME_DIR>/dotnet_pkgs" />
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
  </packageSources>
</configuration>

With the above done, you should test that the SDK works.

mkdir ~/testapp
cd ~/testapp
~/dotnet-sdk/dotnet new console -o myApp
cd myApp
~/dotnet-sdk/dotnet run

Runtime

If you want the runtime without the SDK, get it here dotnet-runtime-3.0.0-freebsd-x64.tar.gz It is included as part of the SDK. You will still need the base packages.

Building the SDK

The following steps assume you will clone the repos relative to ~/dotnet/ and are building version 3.0.0. You'll also need to have an existing SDK as above.

Clone the repos.

mkdir ~/dotnet
cd ~/dotnet
git clone https://github.com/dotnet/coreclr.git
git clone https://github.com/dotnet/corefx.git
git clone https://github.com/dotnet/core-setup.git
git clone https://github.com/dotnet/core-sdk.git

Note, the build system has an Official Build ID property, I'm using these for 3.0.0 from the source-build repo

./bin/git-info/coreclr.props:    <OfficialBuildId>20190912.5</OfficialBuildId>
./bin/git-info/corefx.props:    <OfficialBuildId>20190912.14</OfficialBuildId>
./bin/git-info/core-setup.props:    <OfficialBuildId>20190913.5</OfficialBuildId>
./bin/git-info/core-sdk.props:    <OfficialBuildId>20190918.4</OfficialBuildId>

coreclr

cd ~/dotnet/coreclr
git checkout release/3.0
git reset --hard v3.0.0

Apply the following changes:

git diff
diff --git a/global.json b/global.json
index ecfdff806f..8ef11e2107 100644
--- a/global.json
+++ b/global.json
@@ -1,6 +1,6 @@
 {
   "tools": {
-    "dotnet": "3.0.100-preview6-012264"
+    "dotnet": "3.0.100"
   },
   "native-tools": {
     "cmake": "3.11.1",

Create a link to the pre-built SDK.

ln -s ~/dotnet-sdk .dotnet

The build is done in two parts because the Microsoft.NETCore* and transport.Microsoft.NETCore* packages are not created when we specify OfficialBuildId for some reason. Possibly just a missing parameter.

First create a build with packages that will reference our official packages

./build.sh -x64 -release -clang6.0 -skiptests /p:VersionSuffix=rc2.19462.5 /p:VersionSuffixDateStamp=19462 /p:VersionSuffixBuildOfTheDay=5 /p:ContinuousIntegrationBuild=true /p:PortableBuild=true
cp bin/Product/FreeBSD.x64.Release/.nuget/pkg/Microsoft.NETCore.*.nupkg ~/dotnet_pkgs
cp bin/Product/FreeBSD.x64.Release/.nuget/pkg/transport.Microsoft.NETCore.*.nupkg ~/dotnet_pkgs

Then create a build with an official fixed-release version (OfficialBuildId)

rm -rf bin artifacts
./build.sh -x64 -release -clang6.0 -skiptests /p:OfficialBuildId=20190912.5 /p:ContinuousIntegrationBuild=true /p:PortableBuild=true
cp bin/Product/FreeBSD.x64.Release/.nuget/pkg/runtime*.nupkg ~/dotnet_pkgs
cp bin/Product/FreeBSD.x64.Release/.nuget/pkg/transport.runtime*.nupkg ~/dotnet_pkgs

corefx

cd ~/dotnet/corefx
git checkout release/3.0
git reset --hard v3.0.0

Apply the following changes, use your own value for /home/<YOUR_HOME_DIR>/dotnet_pkgs:

git diff
diff --git a/Directory.Build.props b/Directory.Build.props
index 9f8d8b5b47..101e3265cd 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -112,6 +112,7 @@
        -->
   <PropertyGroup>
     <RestoreSources Condition="'$(DotNetBuildOffline)' != 'true'">
+      /home/<YOUR_HOME_DIR>/dotnet_pkgs;
       https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json;
        https://dotnetfeed.blob.core.windows.net/dotnet-coreclr/index.json;
       https://api.nuget.org/v3/index.json;
diff --git a/NuGet.config b/NuGet.config
index 1451f6bc98..3817cd4c2b 100644
--- a/NuGet.config
+++ b/NuGet.config
@@ -6,6 +6,7 @@
   </fallbackPackageFolders>
   <packageSources>
     <clear />
+    <add key="local_pkgs" value="/home/<YOUR_HOME_DIR>/dotnet_pkgs" />
     <!--Begin: Package sources managed by Dependency Flow automation. Do not edit the sources below.-->
     <add key="darc-pub-dotnet-standard-a5b5f2e" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/darc-pub-dotnet-standard-a5b5f2e1/nuget/v3/index.json" />
     <!--End: Package sources managed by Dependency Flow automation. Do not edit the sources above.-->
diff --git a/eng/Versions.props b/eng/Versions.props
index 5b1fc4bdef..0f025ab1d0 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -15,7 +15,7 @@
     <DotNetFinalVersionKind Condition="'$(StabilizePackageVersion)' == 'true'">release</DotNetFinalVersionKind>
     <!-- Opt-in repo features -->
     <UsingToolMicrosoftNetCompilers>true</UsingToolMicrosoftNetCompilers>
-    <UsingToolIbcOptimization>true</UsingToolIbcOptimization>
+    <UsingToolIbcOptimization>false</UsingToolIbcOptimization>
     <!-- Opt-out repo features -->
     <UsingToolXliff>false</UsingToolXliff>
     <!-- Paths used during restore -->
diff --git a/global.json b/global.json
index 84f26c133c..a3cfde23fe 100644
--- a/global.json
+++ b/global.json
@@ -1,10 +1,10 @@
 {
   "sdk": {
-    "version": "3.0.100-preview7-012630",
+    "version": "3.0.100",
     "rollforward": "major"
   },
   "tools": {
-    "dotnet": "3.0.100-preview7-012630"
+    "dotnet": "3.0.100"
   },
   "msbuild-sdks": {
     "Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19461.7",
diff --git a/pkg/Microsoft.NETCore.Platforms/runtimeGroups.props b/pkg/Microsoft.NETCore.Platforms/runtimeGroups.props
index 5567506b33..ea0f89ee8d 100644
--- a/pkg/Microsoft.NETCore.Platforms/runtimeGroups.props
+++ b/pkg/Microsoft.NETCore.Platforms/runtimeGroups.props
@@ -98,7 +98,7 @@
     <RuntimeGroup Include="freebsd">
       <Parent>unix</Parent>
       <Architectures>x64</Architectures>
-      <Versions>11;11.0;11.1;11.2;11.3</Versions>
+      <Versions>11;12;13</Versions>
     </RuntimeGroup>

     <!-- rhel 6 is independent -->

Create a link to the pre-built SDK.

ln -s ~/dotnet-sdk .dotnet

The following directory needs to be created. I need to figure out why it's not being generated.

artifacts/bin/testhost/netcoreapp-FreeBSD-Release-x64

As with coreclr, the build is done in two parts.

First create a build with packages that will reference our official packages

mkdir -p artifacts/bin/testhost/netcoreapp-FreeBSD-Release-x64
./build.sh --framework netcoreapp --configuration Release --arch x64 --os FreeBSD /p:UpdateRuntimeFiles=true /p:PortableBuild=true /p:ContinuousIntegrationBuild=true /p:VersionSuffixDateStamp=19462 /p:VersionSuffixBuildOfTheDay=14 /p:VersionSuffix="rc2.19462.14"
cp artifacts/packages/Release/NonShipping/Microsoft.Private.CoreFx.NETCoreApp.4.6.0-rc2.19462.14.nupkg ~/dotnet_pkgs
cp artifacts/packages/Release/Shipping/*.nupkg ~/dotnet_pkgs

Then create a build with an official fixed-release version

rm -rf artifacts
mkdir -p artifacts/bin/testhost/netcoreapp-FreeBSD-Release-x64
./build.sh --framework netcoreapp --configuration Release --arch x64 --os FreeBSD /p:UpdateRuntimeFiles=true /p:PortableBuild=true /p:OfficialBuildId=20190912.14 /p:ContinuousIntegrationBuild=true
cp artifacts/packages/Release/NonShipping/runtime.freebsd-x64.Microsoft.Private.CoreFx.NETCoreApp.4.6.0-rc2.19462.14.nupkg ~/dotnet_pkgs

core-setup

cd ~/dotnet/core-setup
git checkout release/3.0
git reset --hard v3.0.0

Apply the following changes, use your own value for /home/<YOUR_HOME_DIR>/dotnet_pkgs:

git diff
diff --git a/Directory.Build.props b/Directory.Build.props
index a53af2f0..bfc88c4e 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -224,8 +224,6 @@

   <PropertyGroup>
     <DisableCrossgen>false</DisableCrossgen>
-    <!-- Disable cross-gen on FreeBSD for now. This can be revisited when we have full support. -->
-    <DisableCrossgen Condition="'$(OSGroup)'=='FreeBSD'">true</DisableCrossgen>
     <OutputVersionBadge>$(AssetOutputPath)sharedfx_$(OutputRid)_$(ConfigurationGroup)_version_badge.svg</OutputVersionBadge>
  </PropertyGroup>

@@ -259,6 +257,7 @@
   <PropertyGroup>
     <TargetsWindows>false</TargetsWindows>
     <TargetsOSX>false</TargetsOSX>
+    <TargetsFreeBSD>false</TargetsFreeBSD>
     <TargetsLinux>false</TargetsLinux>
     <TargetsUnix>false</TargetsUnix>
     <TargetsUbuntu>false</TargetsUbuntu>
@@ -283,6 +282,12 @@
         <TargetsUnix>true</TargetsUnix>
       </PropertyGroup>
     </When>
+    <When Condition="$(OutputRid.StartsWith('freebsd'))">
+      <PropertyGroup>
+        <TargetsFreeBSD>true</TargetsFreeBSD>
+        <TargetsUnix>true</TargetsUnix>
+      </PropertyGroup>
+    </When>
     <When Condition="$(OutputRid.StartsWith('debian'))">
       <PropertyGroup>
         <TargetsDebian>true</TargetsDebian>
@@ -359,6 +364,7 @@
     <CompressedFileExtension Condition="'$(OSGroup)' != 'Windows_NT'">.tar.gz</CompressedFileExtension>
     <InstallerExtension Condition="'$(OSGroup)' == 'Windows_NT'">.msi</InstallerExtension>
     <InstallerExtension Condition="'$(OSGroup)' == 'OSX'">.pkg</InstallerExtension>
+    <InstallerExtension Condition="'$(OSGroup)' == 'FreeBSD'">.pkg</InstallerExtension>
     <InstallerExtension Condition="'$(TargetsDebian)' == 'true' or '$(TargetsUbuntu)' == 'true' or '$(TargetsLinuxMint)' == 'true'">.deb</InstallerExtension>
     <InstallerExtension Condition="'$(TargetsRhel)' == 'true' or '$(TargetsCentos)' == 'true' or '$(TargetsOpensuse)' == 'true' or '$(TargetsFedora)' == 'true' or '$(TargetsOracle)' == 'true' or '$(TargetsSles)' == 'true'">.rpm</InstallerExtension>
     <CombinedInstallerExtension Condition="'$(OSGroup)' == 'Windows_NT'">.exe</CombinedInstallerExtension>
@@ -398,4 +404,4 @@
     <DisableImplicitNuGetFallbackFolder>true</DisableImplicitNuGetFallbackFolder>
   </PropertyGroup>

-</Project>
\ No newline at end of file
+</Project>
diff --git a/NuGet.config b/NuGet.config
index 7896fa0d..74a89985 100644
--- a/NuGet.config
+++ b/NuGet.config
@@ -6,6 +6,7 @@
   </fallbackPackageFolders>
   <packageSources>
     <clear />
+    <add key="local_pkgs" value="/home/<YOUR_HOME_DIR>/dotnet_pkgs" />
     <!--Begin: Package sources managed by Dependency Flow automation. Do not edit the sources below.-->
     <add key="darc-pub-dotnet-standard-a5b5f2e" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/darc-pub-dotnet-standard-a5b5f2e1/nuget/v3/index.json" />
     <add key="darc-pub-dotnet-corefx-4ac4c03" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/darc-pub-dotnet-corefx-4ac4c036/nuget/v3/index.json" />
diff --git a/global.json b/global.json
index 3275aa5f..b70e8408 100644
--- a/global.json
+++ b/global.json
@@ -1,6 +1,6 @@
 {
   "tools": {
-    "dotnet": "3.0.100-preview6-012264"
+    "dotnet": "3.0.100"
   },
   "msbuild-sdks": {
     "Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19461.7"
diff --git a/src/pkg/packaging-tools/framework.dependency.targets b/src/pkg/packaging-tools/framework.dependency.targets
index 1b3e5370..866d8f7b 100644
--- a/src/pkg/packaging-tools/framework.dependency.targets
+++ b/src/pkg/packaging-tools/framework.dependency.targets
@@ -438,7 +438,7 @@
   </Target>

   <Target Name="CreateCrossGenSymbols"
-          Condition="'$(CrossGenSymbolExtension)' != ''"
+          Condition="'$(CrossGenSymbolExtension)' != '' AND '$(OSGroup)' != 'FreeBSD'"
           DependsOnTargets="CreateCrossGenImages"
           Inputs="%(_filesToCrossGen.CrossGenedPath)"
           Outputs="%(_filesToCrossGen.CrossGenSymbolSemaphorePath)">
diff --git a/src/pkg/projects/netcoreappRIDs.props b/src/pkg/projects/netcoreappRIDs.props
index 7483d182..412ba01c 100644
--- a/src/pkg/projects/netcoreappRIDs.props
+++ b/src/pkg/projects/netcoreappRIDs.props
@@ -10,8 +10,7 @@
     <OfficialBuildRID Include="linux-musl-x64" />
     <OfficialBuildRID Include="rhel.6-x64" />
     <OfficialBuildRID Include="osx-x64" />
-    <!-- Not currently built by CoreFX. -->
-    <!-- <OfficialBuildRID Include="freebsd-x64" /> -->
+    <OfficialBuildRID Include="freebsd-x64" />
     <OfficialBuildRID Include="win-x86">
       <Platform>x86</Platform>
     </OfficialBuildRID>

Create a link to the pre-built SDK.

ln -s ~/dotnet-sdk .dotnet

Build the runtime.

./build.sh --configuration Release /p:OSGroup=FreeBSD /p:PortableBuild=true /p:OfficialBuildId=20190913.5 /p:ContinuousIntegrationBuild=true
cp artifacts/packages/Release/NonShipping/*3.0.0-rc2-19463-05.nupkg ~/dotnet_pkgs
cp artifacts/packages/Release/Shipping/*3.0.0.nupkg ~/dotnet_pkgs
cp artifacts/packages/Release/Shipping/NETStandard.Library.Ref.2.1.0.nupkg ~/dotnet_pkgs
cp artifacts/packages/Release/Shipping/dotnet-runtime-3.0.0-freebsd-x64.tar.gz ~/

core-sdk

cd ~/dotnet/core-sdk
git checkout release/3.0.1xx
git reset --hard v3.0.100

Apply the following changes, use your own value for /home/<YOUR_HOME_DIR>/dotnet_pkgs:

git diff
diff --git a/NuGet.config b/NuGet.config
index 64f186fd2..5e7b00466 100644
--- a/NuGet.config
+++ b/NuGet.config
@@ -6,6 +6,7 @@
   <!-- Only specify feed for Arcade SDK (see https://github.com/Microsoft/msbuild/issues/2982) -->
   <packageSources>
     <clear />
+    <add key="local_pkgs" value="/home/<YOUR_HOME_DIR>/dotnet_pkgs" />
     <!--Begin: Package sources managed by Dependency Flow automation. Do not edit the sources below.-->
     <add key="darc-pub-dotnet-wpf-3e99215" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/darc-pub-dotnet-wpf-3e992152/nuget/v3/index.json" />
     <add key="darc-pub-dotnet-templating-b2663fb" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/darc-pub-dotnet-templating-b2663fb0/nuget/v3/index.json" />
diff --git a/global.json b/global.json
index 320d8b25a..6b2e14c01 100644
--- a/global.json
+++ b/global.json
@@ -1,6 +1,6 @@
 {
   "tools": {
-    "dotnet": "3.0.100-preview6-012264"
+    "dotnet": "3.0.100"
   },
   "msbuild-sdks": {
     "Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19463.1"

Create a link to the pre-built SDK.

ln -s ~/dotnet-sdk .dotnet

Copy the runtime created in the previous repo

mkdir -p artifacts/obj/redist/Release/downloads
cp ../core-setup/artifacts/packages/Release/Shipping/dotnet-runtime-3.0.0-freebsd-x64.tar.gz artifacts/obj/redist/Release/downloads/

When building, ignore the errors about dotnet 2.1.0

./build.sh --configuration Release /p:PortableBuild=true /p:OfficialBuildId=20190918.4 /p:ContinuousIntegrationBuild=true /p:DisableSourceLink=true

ls artifacts/packages/Release/Shipping/
dotnet-sdk-3.0.100-freebsd-x64.tar.gz           dotnet-sdk-internal-3.0.100-freebsd-x64.tar.gz  freebsd_x64_Release_version_badge.svg
dotnet-sdk-3.0.100-freebsd-x64.zip              dotnet-sdk-internal-3.0.100-freebsd-x64.zip

At this point if all went well you will have rebuilt the runtime, sdk and the NuGet packages.

I don't claim to understand the build system in great detail as it's composed of many parts, but I've cumulatively spent several weeks out of the last six or more months going around in circles building over and over again to find what works and the process is pretty reliable for me now.

Let me know if you have success and I'll try to help where I can.