dotnet / runtimelab

This repo is for experimentation and exploring new ideas that may or may not make it into the main dotnet/runtime repo.
MIT License
1.41k stars 197 forks source link

Publish for linux-musl-x64 fails with missing libraries #1891

Closed chuchu closed 2 years ago

chuchu commented 2 years ago

I'm on Ubuntu 20.04.4 LTS and dot net 6.0.300 and trying to compile the Hello World sample application. It works like a charm for linux-x64 but I'm facing some challenges for linux-musl-x64.

My first problem was that libc.musl-x86_64.so.1 was missing. So I installed two more packages and created a new link.

sudo apt-get install musl-dev
sudo apt install gcc-multilib
sudo ln -s /usr/lib/x86_64-linux-musl/libc.so /lib/libc.musl-x86_64.so.1

This fixed the issue for me. But I'm stuck at this error now:

chris@TUXEDO-Book-XP15-Gen12:~/Documents/Projects/NativeAOTSample$ dotnet publish -r linux-musl-x64 -c release
Microsoft (R) Build Engine version 17.2.0+41abc5629 for .NET
Copyright (C) Microsoft Corporation. All rights reserved.

  Determining projects to restore...
  All projects are up-to-date for restore.
/usr/share/dotnet/sdk/6.0.300/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.Sdk.targets(1114,5): warning NETSDK1179: One of '--self-contained' or '--no-self-contained' options are required when '--runtime' is used. [/home/chris/Documents/Projects/NativeAOTSample/NativeAOTSample.csproj]
  NativeAOTSample -> /home/chris/Documents/Projects/NativeAOTSample/bin/release/net6.0/linux-musl-x64/NativeAOTSample.dll
  Generating compatible native code. To optimize for size or speed, visit https://aka.ms/OptimizeNativeAOT
  Error loading shared library libstdc++.so.6: No such file or directory (needed by /home/chris/.nuget/packages/runtime.linux-musl-x64.microsoft.dotnet.ilcompiler/7.0.0-preview.4.22229.4/tools/ilc)
  Error loading shared library libgcc_s.so.1: No such file or directory (needed by /home/chris/.nuget/packages/runtime.linux-musl-x64.microsoft.dotnet.ilcompiler/7.0.0-preview.4.22229.4/tools/ilc)
  Error relocating /home/chris/.nuget/packages/runtime.linux-musl-x64.microsoft.dotnet.ilcompiler/7.0.0-preview.4.22229.4/tools/ilc: _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7reserveEm: symbol not found
  Error relocating /home/chris/.nuget/packages/runtime.linux-musl-x64.microsoft.dotnet.ilcompiler/7.0.0-preview.4.22229.4/tools/ilc: _ZNKSt5ctypeIcE13_M_widen_initEv: symbol not found
  Error relocating /home/chris/.nuget/packages/runtime.linux-musl-x64.microsoft.dotnet.ilcompiler/7.0.0-preview.4.22229.4/tools/ilc: _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE14_M_replace_auxEmmmc: symbol not found
...

I guess the problem are the missing libraries libstdc++.so.6 and libgcc_s.so.1. But running ldd shows that they are available:

chris@TUXEDO-Book-XP15-Gen12:~/Documents/Projects/NativeAOTSample$ ldd /home/chris/.nuget/packages/runtime.linux-musl-x64.microsoft.dotnet.ilcompiler/7.0.0-preview.4.22229.4/tools/ilc
    linux-vdso.so.1 (0x00007fff29363000)
    libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f870c941000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f870c926000)
    libc.musl-x86_64.so.1 => /lib/libc.musl-x86_64.so.1 (0x00007f870c872000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f870c723000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f870c531000)
    /lib/ld-musl-x86_64.so.1 => /lib64/ld-linux-x86-64.so.2 (0x00007f870cb55000)

My goal is to build a binary which can be run in an alpine container. Does anyone has an idea what the problem might be?

jkotas commented 2 years ago

The errors that you are seeing are caused by trying to run musl compiler binary on non-musl Linux.

If you are targeting alpine, it is easiest to run the compilation on alpine (e.g. in Alpine docker container). Otherwise, you need to setup a cross-compilation environment.

You can start with standard dotnet alpine container: docker run -it mcr.microsoft.com/dotnet/sdk:6.0-alpine3.14 Once in the container, add package that are pre-requisite for NativeAOT: apk add clang gcc lld musl-dev build-base zlib-dev krb5-dev

And then you should be setup to compile your app.

chuchu commented 2 years ago

Works. Thanks a lot! Just for reference here is the Dockerfile I have used:

FROM docker.io/library/alpine:latest AS base
WORKDIR /app

FROM mcr.microsoft.com/dotnet/sdk:6.0-alpine3.14 AS build
WORKDIR /src
COPY NativeAOTSample.csproj ./
RUN dotnet restore "./NativeAOTSample.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "NativeAOTSample.csproj" -c Release -o /app/build

FROM build AS publish
RUN apk add clang gcc lld musl-dev build-base zlib-dev krb5-dev
RUN dotnet publish "NativeAOTSample.csproj" -r linux-musl-x64 -c release -o /app/publish

FROM base AS final
RUN apk add libstdc++
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["./NativeAOTSample"]

The resulting image has only 25.1 MB :-)