dotnet / corert

This repo contains CoreRT, an experimental .NET Core runtime optimized for AOT (ahead of time compilation) scenarios, with the accompanying compiler toolchain.
http://dot.net
MIT License
2.91k stars 508 forks source link

Add support for Alpine Linux #4552

Open sergiy-k opened 7 years ago

sergiy-k commented 7 years ago

In response to requests from community (https://github.com/dotnet/coreclr/issues/917, https://github.com/dotnet/dotnet-docker/issues/22), @janvorli did quite a bit of work to enable CoreCLR on Alpine Linux. We should do the same for CoreRT. I think that a tree-shaken single-file executable produced by the CoreRT compiler can suit well Alpine Linux based containers.

For example, some time ago I hacked up a few things together that allowed me to run a simple console “Hello, world” app on Alpine Linux. The executable binary was about 3.5MB (which included the app code, the Frameworks code required by the app and the runtime, InvariantGlobalization-only config); the size of the alpine-3.5 based container was ~5.5MB.

am11 commented 7 years ago

Current blocker: ILC is not executable on Alpine Linux and thus the test runs fail.

After complete build on Alpine (and test failures), if we search instances of ilc in corert directory, we get this:

/corert # find . -name "ilc"

./bin/Linux.x64.Debug/tools/ilc
./src/ILCompiler/netcoreapp/obj/netcoreapp2.0/ubuntu.14.04-x64/host/ilc
./src/ILCompiler/netcoreapp/bin/Debug/netcoreapp2.0/ubuntu.14.04-x64/ilc

They are all native executables and were built on Ubuntu. If we ldd each one of them, we get:

/corert # ldd src/ILCompiler/netcoreapp/bin/Debug/netcoreapp2.0/ubuntu.14.04-x64/ilc

        /lib64/ld-linux-x86-64.so.2 (0x7f63e4fd1000)
        libdl.so.2 => /lib64/ld-linux-x86-64.so.2 (0x7f63e4fd1000)
        libpthread.so.0 => /lib64/ld-linux-x86-64.so.2 (0x7f63e4fd1000)
        libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x7f63e4c7f000)
        libm.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7f63e4fd1000)
        libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x7f63e4a6d000)
        libc.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7f63e4fd1000)

However, on Alpine, we expect it to link with libc.musl-xxx. Something like:

/corert # ldd Tools/dotnetcli/dotnet

        /lib/ld-musl-x86_64.so.1 (0x7fd73e897000)
        libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x7fd73e327000)
        libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x7fd73e115000)
        libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x7fd73e897000)

@jkotas, if we have all the sources available, can we compile ILC native on the target platform instead of relying on what gets restored from Ubuntu package?

jkotas commented 7 years ago

ilc is self-contained .NET Core app running on top of CoreCLR. It is created by the dotnet publish command here: https://github.com/dotnet/corert/blob/master/buildscripts/build-managed.sh#L54. To fix that for Alpine:

janvorli commented 7 years ago

There is no official support for Alpine yet. I have changes that will enable official packages build ready, but I am waiting for some infrastructure changes before I can merge them in. However, there already is a bootstrap cli that the build is able to use to compile managed code (I've tried that on Alpine some time ago myself and even xunit tests were succeeding. Only our basic tests were failing)

am11 commented 7 years ago

Thanks! Since #4579, the managed code is compiling fine with bootstrapped CLI (dotnet exe) as you mentioned. However it's the native ilc executable, which is required to build some of the cpp/wasm tests, that is incompatible.

I modernized the RID detection code in buildvars-setup.sh: am11/corert@834a07d, but then ran into dependency resolution issue for Alpine as expected.

The following three build time errors were encountered:

/corert/Tools/depProj.targets(83,5): error : Error no assets were resolved from NuGet packages. [/corert/src/ILCompiler/ObjectWriter/ObjectWriter.depproj]
/corert/Tools/depProj.targets(83,5): error : Error no assets were resolved from NuGet packages. [/corert/src/ILCompiler/RyuJIT/RyuJIT.depproj]
/corert/Tools/depProj.targets(83,5): error : Error no assets were resolved from NuGet packages. [/corert/src/Framework/Framework-native.depproj]

Seems like there were Alpine 3.4 packages published sometime ago at https://dotnet.myget.org/gallery/dotnet-core:

image

(but no 3.6)

have changes that will enable official packages build ready, but I am waiting for some infrastructure changes before I can merge them in.

👍 looking forward to it. Technically, if I'm not mistaken and based on the ongoing efforts at: https://github.com/dotnet/source-build, it seems quite possible to build the end to end .NET Core product even offline on any OS. On Alpine however, the init-tools.sh in that repo needs update for Alpine as well (gnu-libc based dotnet isn't executable).

janvorli commented 7 years ago

@am11 The 3.4.3 packages are remnants of the old attempt to bring up Alpine that didn't do the last step - to enable Alpine support for CLI that would keep producing new versions of the CLI instead of relying on the bootstrap CLI. So once we needed to bump the tools versions in coreclr, corefx and core-setup, we would need to rebuild the boostrap cli and the native build on 3.4.3 got broken due to a problem with the lttng dependency where it required MUSL from the testing repo. So that's why I have restarted the effort with 3.6.

mahald commented 7 years ago

not sure wheter this would Help, but there is a apline-glibc https://hub.docker.com/r/frolvlad/alpine-glibc/ Version in docker, using: https://github.com/sgerrand/alpine-pkg-glibc

janvorli commented 7 years ago

@mahald thank you for the links. But the native Alpine support is ready, the last step is to finish infrastructure changes to enable official builds and publishing of Alpine nuget packages. And then we can enable the build of CLI for Alpine.

daniel-white commented 6 years ago

@janvorli is there a issue # for the infrastructure changes that i can follow or will it be this issue?

ShalokShalom commented 6 years ago

So this is solved?

enoch85 commented 6 years ago

bump

janvorli commented 6 years ago

The Alpine has been enabled end to end in the middle of December 2017.

enoch85 commented 6 years ago

@janvorli Thanks!

So to install it it's something like this?

sudo sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-alpine-prod alpine main" > /etc/apt/sources.list.d/dotnetdev.list'
sudo apk update
sudo apk add dotnet-sdk-2.1.4

Taken from here.

am11 commented 6 years ago

CoreRT-specific remaining item is ObjectWriter package for Alpine, tracked by https://github.com/dotnet/corert/issues/5177.

janvorli commented 6 years ago

@enoch85 no, we are not providing alpine native packages ourselves and we don't have a plan to do that. Once our "build from sources" effort is complete, we think that distro owners could use it to build their packages themselves. We are providing a .tar.gz file instead. You can get the latest SDK package here: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/master/dotnet-sdk-latest-alpine.3.6-x64.tar.gz (you can find this link on https://github.com/dotnet/cli) You can also develop on a different Linux or Windows and use dotnet publish -r alpine.3.6-x64 to get your application as self contained set of binaries and just copy it to Alpine (provided all dotnet dependencies are installed over there). Please note that until the 2.1 is released, you'll need to create file NuGet.config in the root of your app sources with the following contents so that dotnet restore can find the packages.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <add key="dotnet-core" value="https://dotnet.myget.org/F/dotnet-core/api/v3/index.json" />
  </packageSources>
</configuration>
ShalokShalom commented 6 years ago

Sounds nice :)

enoch85 commented 6 years ago

@janvorli I'd love to be able to install dotnet with @alpinelinux package manager apk. Is it up Alpine to add that or @microsoft to support it?

Sorry if I'm not completlety understand how this works. I would want it to work similar to how Ubuntu / Debian / Red Hat / Centos does it according to the Microsoft documentation.

janvorli commented 6 years ago

@enoch85 our plan was to provide deb and rpm packages only since they cover a large subset of the distros and leave the production of other packages on the distro owners. But to enable them to do that, we need to finish the build from sources effort (https://github.com/dotnet/source-build) I have mentioned above that will allow the distro owners to build the whole product end to end from sources without using any prebuilt bootstrap binaries. @richlander, is it still the case that we are planning to build only the deb and rpm packages?

enoch85 commented 6 years ago

@janvorli Thanks for the explanation! Now it makes more sense.

Do you have any ETA on the "sources effort"?

janvorli commented 6 years ago

@weshaggard might be able to provide more details on the ETA.

weshaggard commented 6 years ago

We don't have an exact ETA but you your interested you can watch the work going on in the repo at https://github.com/dotnet/source-build. There are still lots of challenges to figure out, especially around keeping a consistent set of source hashes across many repos.

enoch85 commented 6 years ago

@weshaggard @janvorli Thanks guys!

imacks commented 5 years ago

Hi there I'm playing around with dotnet sdk 2.2.105 on alpine 3.9. I notice that CoreRT still doesn't work with error:

/root/.nuget/packages/microsoft.dotnet.ilcompiler/1.0.0-alpha-27509-01/build/Microsoft.NETCore.Native.Publish.targets(68,5): error : The PrivateSdkAssemblies ItemGroup is required for _ComputeAssembliesToCompileToNative [/app/rtapp.csproj]

There seem to be an issue with linux-musl-x64 as a RID. Is it going to be supported anytime soon?