Closed lauxjpn closed 2 months ago
[Triage] @richlander @sbomer do either of you have any input on this issue with cross-compiling the .NET runtime?
@lauxjpn the image you are using (mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-22.04-cross-arm64) was specifically added for our .NET 7 builds, before we transitioned to using CBL-Mariner in official builds in .NET 8 (and Azure Linux 3.0 in .NET 9).
I'd recommend checking https://github.com/dotnet/runtime/blob/main/eng/pipelines/common/templates/pipeline-with-resources.yml which lists the images we use for cross-building in our ci. For 8.0.4, you'll have better luck with mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-cross-arm64.
There are good instructions here: https://github.com/dotnet/runtime/blob/b194416ea68e2d1c93a91fc7abf80eb2607b4831/docs/workflow/building/coreclr/linux-instructions.md
Also checkout https://github.com/dotnet/dotnet
There are good instructions here: https://github.com/dotnet/runtime/blob/b194416ea68e2d1c93a91fc7abf80eb2607b4831/docs/workflow/building/coreclr/linux-instructions.md
Yes, all those runtime workflow docs are the first ones I read. But since the docs say This table of images might often become stale as we change our images as our requirements change.
and because the table mentioned the long outdated Alpine 3.13
and Ubuntu 16.04
and I didn't recognize mariner
, so I thought it is probably some very old distribution code name, I directly went to the referenced dotnet-buildtools-prereqs-docker repo instead and then chose a cross-compilation enabled dockerfile of a distribution that I recognized (so that I can easily extend it if necessary) and that seemed current.
Assumption is the mother of all mistakes.
@lauxjpn the image you are using (mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-22.04-cross-arm64) was specifically added for our .NET 7 builds, before we transitioned to using CBL-Mariner in official builds in .NET 8 (and Azure Linux 3.0 in .NET 9).
I'd recommend checking https://github.com/dotnet/runtime/blob/main/eng/pipelines/common/templates/pipeline-with-resources.yml which lists the images we use for cross-building in our ci. For 8.0.4, you'll have better luck with mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-cross-arm64.
Thanks, yes, the cbl-mariner-2.0-cross
images do just work out-of-the-box.
I guess we can close this one.
The table is accurate, however, I grasp the assumption.
This issue has relevant context: https://github.com/dotnet/runtime/pull/100942
It is on my list of TODOs to update that table to reflect the state of that merged PR.
We use a cross build approach for everything and use very old targets to ensure that our users can run our binaries (for the most part) everywhere. It enables us to both satisfy secure supply chain requirements and offer binary compat. That's very hard to do well.
The issue
I am trying to build the .NET runtime for different platforms, by using the Dockerfiles for .NET Core Builds.
There are multiple issues with the cross-compilation process.
Lets assume the following simple dockerfile to cross-compile the dotnet runtime on an
x64
machine forarm64
:If I build this dockerfile, I get the following error:
The reason is that while
.../prereqs:ubuntu-22.04-coredeps
(the base image used by.../prereqs:ubuntu-22.04-cross-arm64
) installs llvm/clang via script, it does not set the installed version as the default:Symbolic links missing for default llvm/clang usage
``` root@e269ef91fec7:/src/dotnet/runtime# ls -lah /usr/bin/*clang* lrwxrwxrwx 1 root root 26 Mar 17 02:35 /usr/bin/clang++-18 -> ../lib/llvm-18/bin/clang++ lrwxrwxrwx 1 root root 24 Mar 17 02:35 /usr/bin/clang-18 -> ../lib/llvm-18/bin/clang lrwxrwxrwx 1 root root 28 Mar 17 02:35 /usr/bin/clang-cpp-18 -> ../lib/llvm-18/bin/clang-cpp lrwxrwxrwx 1 root root 25 Mar 17 02:35 /usr/bin/clangd-18 -> ../lib/llvm-18/bin/clangd root@e269ef91fec7:/src/dotnet/runtime# ls -lah /usr/bin/*llvm* lrwxrwxrwx 1 root root 33 Mar 17 02:35 /usr/bin/llvm-addr2line-18 -> ../lib/llvm-18/bin/llvm-addr2line lrwxrwxrwx 1 root root 26 Mar 17 02:35 /usr/bin/llvm-ar-18 -> ../lib/llvm-18/bin/llvm-ar lrwxrwxrwx 1 root root 26 Mar 17 02:35 /usr/bin/llvm-as-18 -> ../lib/llvm-18/bin/llvm-as lrwxrwxrwx 1 root root 34 Mar 17 02:35 /usr/bin/llvm-bcanalyzer-18 -> ../lib/llvm-18/bin/llvm-bcanalyzer lrwxrwxrwx 1 root root 37 Mar 17 02:35 /usr/bin/llvm-bitcode-strip-18 -> ../lib/llvm-18/bin/llvm-bitcode-strip lrwxrwxrwx 1 root root 27 Mar 17 02:35 /usr/bin/llvm-cat-18 -> ../lib/llvm-18/bin/llvm-cat lrwxrwxrwx 1 root root 34 Mar 17 02:35 /usr/bin/llvm-cfi-verify-18 -> ../lib/llvm-18/bin/llvm-cfi-verify lrwxrwxrwx 1 root root 30 Mar 17 02:35 /usr/bin/llvm-config-18 -> ../lib/llvm-18/bin/llvm-config lrwxrwxrwx 1 root root 27 Mar 17 02:35 /usr/bin/llvm-cov-18 -> ../lib/llvm-18/bin/llvm-cov lrwxrwxrwx 1 root root 30 Mar 17 02:35 /usr/bin/llvm-c-test-18 -> ../lib/llvm-18/bin/llvm-c-test lrwxrwxrwx 1 root root 30 Mar 17 02:35 /usr/bin/llvm-cvtres-18 -> ../lib/llvm-18/bin/llvm-cvtres lrwxrwxrwx 1 root root 31 Mar 17 02:35 /usr/bin/llvm-cxxdump-18 -> ../lib/llvm-18/bin/llvm-cxxdump lrwxrwxrwx 1 root root 31 Mar 17 02:35 /usr/bin/llvm-cxxfilt-18 -> ../lib/llvm-18/bin/llvm-cxxfilt lrwxrwxrwx 1 root root 30 Mar 17 02:35 /usr/bin/llvm-cxxmap-18 -> ../lib/llvm-18/bin/llvm-cxxmap lrwxrwxrwx 1 root root 42 Mar 17 02:35 /usr/bin/llvm-debuginfo-analyzer-18 -> ../lib/llvm-18/bin/llvm-debuginfo-analyzer lrwxrwxrwx 1 root root 34 Mar 17 02:35 /usr/bin/llvm-debuginfod-18 -> ../lib/llvm-18/bin/llvm-debuginfod lrwxrwxrwx 1 root root 39 Mar 17 02:35 /usr/bin/llvm-debuginfod-find-18 -> ../lib/llvm-18/bin/llvm-debuginfod-find lrwxrwxrwx 1 root root 28 Mar 17 02:35 /usr/bin/llvm-diff-18 -> ../lib/llvm-18/bin/llvm-diff lrwxrwxrwx 1 root root 27 Mar 17 02:35 /usr/bin/llvm-dis-18 -> ../lib/llvm-18/bin/llvm-dis lrwxrwxrwx 1 root root 31 Mar 17 02:35 /usr/bin/llvm-dlltool-18 -> ../lib/llvm-18/bin/llvm-dlltool lrwxrwxrwx 1 root root 33 Mar 17 02:35 /usr/bin/llvm-dwarfdump-18 -> ../lib/llvm-18/bin/llvm-dwarfdump lrwxrwxrwx 1 root root 33 Mar 17 02:35 /usr/bin/llvm-dwarfutil-18 -> ../lib/llvm-18/bin/llvm-dwarfutil lrwxrwxrwx 1 root root 27 Mar 17 02:35 /usr/bin/llvm-dwp-18 -> ../lib/llvm-18/bin/llvm-dwp lrwxrwxrwx 1 root root 32 Mar 17 02:35 /usr/bin/llvm-exegesis-18 -> ../lib/llvm-18/bin/llvm-exegesis lrwxrwxrwx 1 root root 31 Mar 17 02:35 /usr/bin/llvm-extract-18 -> ../lib/llvm-18/bin/llvm-extract lrwxrwxrwx 1 root root 32 Mar 17 02:35 /usr/bin/llvm-gsymutil-18 -> ../lib/llvm-18/bin/llvm-gsymutil lrwxrwxrwx 1 root root 27 Mar 17 02:35 /usr/bin/llvm-ifs-18 -> ../lib/llvm-18/bin/llvm-ifs lrwxrwxrwx 1 root root 41 Mar 17 02:35 /usr/bin/llvm-install-name-tool-18 -> ../lib/llvm-18/bin/llvm-install-name-tool lrwxrwxrwx 1 root root 31 Mar 17 02:35 /usr/bin/llvm-jitlink-18 -> ../lib/llvm-18/bin/llvm-jitlink lrwxrwxrwx 1 root root 40 Mar 17 02:35 /usr/bin/llvm-jitlink-executor-18 -> ../lib/llvm-18/bin/llvm-jitlink-executor lrwxrwxrwx 1 root root 27 Mar 17 02:35 /usr/bin/llvm-lib-18 -> ../lib/llvm-18/bin/llvm-lib lrwxrwxrwx 1 root root 38 Mar 17 02:35 /usr/bin/llvm-libtool-darwin-18 -> ../lib/llvm-18/bin/llvm-libtool-darwin lrwxrwxrwx 1 root root 28 Mar 17 02:35 /usr/bin/llvm-link-18 -> ../lib/llvm-18/bin/llvm-link lrwxrwxrwx 1 root root 28 Mar 17 02:35 /usr/bin/llvm-lipo-18 -> ../lib/llvm-18/bin/llvm-lipo lrwxrwxrwx 1 root root 27 Mar 17 02:35 /usr/bin/llvm-lto-18 -> ../lib/llvm-18/bin/llvm-lto lrwxrwxrwx 1 root root 28 Mar 17 02:35 /usr/bin/llvm-lto2-18 -> ../lib/llvm-18/bin/llvm-lto2 lrwxrwxrwx 1 root root 26 Mar 17 02:35 /usr/bin/llvm-mc-18 -> ../lib/llvm-18/bin/llvm-mc lrwxrwxrwx 1 root root 27 Mar 17 02:35 /usr/bin/llvm-mca-18 -> ../lib/llvm-18/bin/llvm-mca lrwxrwxrwx 1 root root 26 Mar 17 02:35 /usr/bin/llvm-ml-18 -> ../lib/llvm-18/bin/llvm-ml lrwxrwxrwx 1 root root 34 Mar 17 02:35 /usr/bin/llvm-modextract-18 -> ../lib/llvm-18/bin/llvm-modextract lrwxrwxrwx 1 root root 26 Mar 17 02:35 /usr/bin/llvm-mt-18 -> ../lib/llvm-18/bin/llvm-mt lrwxrwxrwx 1 root root 26 Mar 17 02:35 /usr/bin/llvm-nm-18 -> ../lib/llvm-18/bin/llvm-nm lrwxrwxrwx 1 root root 31 Mar 17 02:35 /usr/bin/llvm-objcopy-18 -> ../lib/llvm-18/bin/llvm-objcopy lrwxrwxrwx 1 root root 31 Mar 17 02:35 /usr/bin/llvm-objdump-18 -> ../lib/llvm-18/bin/llvm-objdump lrwxrwxrwx 1 root root 34 Mar 17 02:35 /usr/bin/llvm-opt-report-18 -> ../lib/llvm-18/bin/llvm-opt-report lrwxrwxrwx 1 root root 29 Mar 17 02:35 /usr/bin/llvm-otool-18 -> ../lib/llvm-18/bin/llvm-otool lrwxrwxrwx 1 root root 31 Mar 17 02:35 /usr/bin/llvm-pdbutil-18 -> ../lib/llvm-18/bin/llvm-pdbutil lrwxrwxrwx 1 root root 38 Mar 17 02:35 /usr/bin/llvm-PerfectShuffle-18 -> ../lib/llvm-18/bin/llvm-PerfectShuffle lrwxrwxrwx 1 root root 32 Mar 17 02:35 /usr/bin/llvm-profdata-18 -> ../lib/llvm-18/bin/llvm-profdata lrwxrwxrwx 1 root root 31 Mar 17 02:35 /usr/bin/llvm-profgen-18 -> ../lib/llvm-18/bin/llvm-profgen lrwxrwxrwx 1 root root 30 Mar 17 02:35 /usr/bin/llvm-ranlib-18 -> ../lib/llvm-18/bin/llvm-ranlib lrwxrwxrwx 1 root root 26 Mar 17 02:35 /usr/bin/llvm-rc-18 -> ../lib/llvm-18/bin/llvm-rc lrwxrwxrwx 1 root root 31 Mar 17 02:35 /usr/bin/llvm-readelf-18 -> ../lib/llvm-18/bin/llvm-readelf lrwxrwxrwx 1 root root 31 Mar 17 02:35 /usr/bin/llvm-readobj-18 -> ../lib/llvm-18/bin/llvm-readobj lrwxrwxrwx 1 root root 32 Mar 17 02:35 /usr/bin/llvm-readtapi-18 -> ../lib/llvm-18/bin/llvm-readtapi lrwxrwxrwx 1 root root 30 Mar 17 02:35 /usr/bin/llvm-reduce-18 -> ../lib/llvm-18/bin/llvm-reduce lrwxrwxrwx 1 root root 34 Mar 17 02:35 /usr/bin/llvm-remarkutil-18 -> ../lib/llvm-18/bin/llvm-remarkutil lrwxrwxrwx 1 root root 30 Mar 17 02:35 /usr/bin/llvm-rtdyld-18 -> ../lib/llvm-18/bin/llvm-rtdyld lrwxrwxrwx 1 root root 27 Mar 17 02:35 /usr/bin/llvm-sim-18 -> ../lib/llvm-18/bin/llvm-sim lrwxrwxrwx 1 root root 28 Mar 17 02:35 /usr/bin/llvm-size-18 -> ../lib/llvm-18/bin/llvm-size lrwxrwxrwx 1 root root 29 Mar 17 02:35 /usr/bin/llvm-split-18 -> ../lib/llvm-18/bin/llvm-split lrwxrwxrwx 1 root root 30 Mar 17 02:35 /usr/bin/llvm-stress-18 -> ../lib/llvm-18/bin/llvm-stress lrwxrwxrwx 1 root root 31 Mar 17 02:35 /usr/bin/llvm-strings-18 -> ../lib/llvm-18/bin/llvm-strings lrwxrwxrwx 1 root root 29 Mar 17 02:35 /usr/bin/llvm-strip-18 -> ../lib/llvm-18/bin/llvm-strip lrwxrwxrwx 1 root root 34 Mar 17 02:35 /usr/bin/llvm-symbolizer-18 -> ../lib/llvm-18/bin/llvm-symbolizer lrwxrwxrwx 1 root root 30 Mar 17 02:35 /usr/bin/llvm-tblgen-18 -> ../lib/llvm-18/bin/llvm-tblgen lrwxrwxrwx 1 root root 35 Mar 17 02:35 /usr/bin/llvm-tli-checker-18 -> ../lib/llvm-18/bin/llvm-tli-checker lrwxrwxrwx 1 root root 31 Mar 17 02:35 /usr/bin/llvm-undname-18 -> ../lib/llvm-18/bin/llvm-undname lrwxrwxrwx 1 root root 31 Mar 17 02:35 /usr/bin/llvm-windres-18 -> ../lib/llvm-18/bin/llvm-windres lrwxrwxrwx 1 root root 28 Mar 17 02:35 /usr/bin/llvm-xray-18 -> ../lib/llvm-18/bin/llvm-xray ```There are e.g. no symbolic links for
/usr/bin/clang
, but only for/usr/bin/clang-18
. The dotnet runtime build system does not check the installed llvm/clang versions by default, but just tries to callclang
, which then fails.I have to explicitly specifiying the
--clang18
parameter tobuild.sh
, which requires me to know that the installed llvm version is18
:(It probably would also work to add
/usr/lib/llvm-18/bin/
to thePATH
environment variable instead.)This now starts the compilation process, until it hits the following error:
Looks like the source code is incompatible with llvm/clang
18
.To fix this issue, I install and use llvm/clang
14
instead:If I build this docker file, the runtime build continues further, until I hit:
It appears that the wrong version of
objcopy
(the not-cross-compile version) is used by the build system.There seems to be an
ObjCopyName
msbuild property that can be set to the name of the file that should be used instead, which would bellvm-objcopy-14
:(Appending
-p:ObjCopyName=llvm-objcopy-14
to thebuild.sh
parameter list instead would probably work as well.)This dockerfile is now finally able to finish the build process successfully.
Suggestions
--clang<major_version>
parameter (or change thePATH
environment variable).It took me quite some time to analyze and fix these issues. Currently, it is unreasonably hard to build a cross-compiled version of the dotnet runtime for someone who has never done it before.