runtime: runtime depends on extremely recent verisons of cmake, blocking adoption on Linux
Description
In order to help make .NET ubiquitous, I am working on packaging and including .NET (Core) into as many Linux distributions as I can. Some of these Linux distributions are included in the official support matrix of .NET:
https://github.com/dotnet/core/blob/master/release-notes/5.0/5.0-supported-os.md
May of the Linux distributions listed in the matrix above include much older versions of cmake than what dotnet/runtime requires to build. For example:
- CentOS 7: 2.8.12.2
- CentOS 8: 3.11.4
- Debian 9: 3.7.2
- Debian 10: 3.13.4
- OpenSuSE Leap 15.0: 3.10.2
- RHEL 7: 2.8.12.2
- RHEL 8: 3.11.4
- Ubuntu 18.04: 3.10.2
- Ubuntu 19.10: 3.13.4
Because of this, it becomes almost impossible to build or package .NET in those distributions š¦ That prevents us from easily including the upcoming .NET 5 in these distributions.
To work around this, we would have to revert a long series of non-trivial commits: like https://github.com/dotnet/coreclr/pull/26980
If it matters, for packaging on Linux, we are consuming dotnet/runtime indirectly via dotnet/source-build.
Configuration
Hereās a dockerfile that reproduces the problem:
FROM docker.io/centos:8
RUN dnf install --setopt tsflags=nodocs --refresh -y \
dnf-plugins-core && \
dnf config-manager --set-enabled PowerTools && \
dnf install --setopt tsflags=nodocs --refresh -y \
automake \
clang \
cmake \
curl-devel \
findutils \
git \
glibc-langpack-en \
hostname \
krb5-devel \
libicu-devel \
libtool \
lldb-devel \
llvm \
lttng-ust-devel \
make \
openssl-devel \
python3 \
tar \
wget \
which \
zlib-devel && \
dnf upgrade -y && \
dnf clean all -y
CMD git clone https://github.com/dotnet/runtime && \
cd runtime && \
git submodule update --init --recursive && \
./build.sh clr
$ podman build -t d -f Dockerfile .
$ podman run -it d
Cloning into 'runtime'...
remote: Enumerating objects: 32, done.
...
Setting up directories for build
Checking prerequisites...
Please install cmake v3.14.5 or newer from https://www.cmake.org/download/.
/runtime/src/coreclr/runtime.proj(32,5): error MSB3073: The command ""/runtime/src/coreclr/build-runtime.sh" -x64 -debug -os Linux" exited with code 1.
....
0 Warning(s)
13 Error(s)
Time Elapsed 00:03:53.27
Build failed (exit code '1').
Regression?
This is a build-time regression.
The situation was not so bad in the 3.1 timeframe where the minimum version required was much lower.
The situation seems to have gotten much worse with .NET 5: RHEL 8, Debian 9 and Ubuntu 18.04 all have incompatible versions of cmake.
Other information
- Do you know of any workarounds?
One possible option would be to upgrade or package up alternate versions of cmake in those Linux distributions. That becomes more challenging the older the Linux distribution we are looking at is. Itās harder both technically (compatibility impact, more recent versions of cmake require a more recent version of other dependencies) and process-wise (how do you convince others that adding new packages to a X year old distribution is a good idea now?)
Some distributions, like RHEL 7 use āalternateā packaging mechanisms (such as software collections) that allow using a custom cmake for building .NET 5, but have a significant usability impact for the end-user.
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 3
- Comments: 38 (36 by maintainers)
Commits related to this issue
- Move away from add_link_options to support building with older CMake versions. This is required to support being inserted into distro packages: see dotnet/runtime#38755 — committed to jkoritzinsky/arcade by jkoritzinsky 4 years ago
- Move away from add_link_options to support building with older CMake versions. (#5770) This is required to support being inserted into distro packages: see dotnet/runtime#38755 — committed to dotnet/arcade by jkoritzinsky 4 years ago
Based on the feedback here we will change our supported Cmake version from Linux to 3.6. @jkoritzinsky has started this work with #39044. In order to avoid regressing the build using older version of Cmake we will add in a CI job which specifically builds with 3.6 on CentOS.
For non-source build builds we will continue to use higher versions of CMake in the same way we use clang9 now.
/cc @dotnet/runtime-infrastructure @jkoritzinsky @omajid @jkotas @janvorli
Please let us know if there is anything else required.
This is a much more minor concern than the one cited, but this also makes it harder to get started contributing to dotnet/runtime.
For building on RHEL 7 (and CentOS 7), we have a version
3.6.2available. This is not the defaultcmake, but separate build maintained by thellvmteam.That would be our desired minimum version, and support all distros mentioned in the first comment.
Source-build and source-build bootstrapping is already quite complex and costly adding cmake bootstrap adds to that complexity significantly. That additional cost would be a significant detractor for maintainers wanting to bring in .NET into their distro.
We also are in the midst of a major effort to make source-build more maintainable https://github.com/dotnet/source-build/issues/1510 This effort will go a long way in surfacing difficult issues like this one earlier. Indeed, that source-build effort makes any additional effort to bootstrap cmake prohibitive. cc @dseefeld
We should be able to preserve most of the new design we have if we use functions to add the right defines. Itāll just be tedious to convert all of the
add_compile_definitionsandadd_link_optionstotarget_compile_definitionsandtarget_link_librariesthat are attached to specific targets.Thank you @omajid and @RheaAyase for providing all the details. It seems to me that it is inevitable to move back to using an older cmake.
Itās my mistake I didnāt look into all the default versions back then.
I thought the conversation was essentially about RHEL 7/CentOS 7 going from 3.14.x to 3.15.x.
3.1.5.x didnāt seem any worse than 3.14.x in terms of distribution inclusion. RHEL 7, as you can see from the matrix above, only has 2.x I figured that the version of 3.x wouldnāt matter.
I didnāt realize that the matrix was affecting RHEL 8 as well as many, many, many other distributions as well.
I would like to provide some additional context that might help clarify things.
The ultimate goal of the source-build effort is to package .NET into as many Linux distributions as possible. If/when we are successful, .NET will be available out of the box in those distributions, just like may other languages like C, Go, Java, Perl, Python, and Ruby.
To be included in distributions, generally packages are only allowed to use whatās already in the distribution. If a distribution doesnāt have
cmakeat all, for example, thereās no way we could package .NET in that distribution. We would first have to addcmakeand then try and package .NET in that distribution.The list of distributions I described above all already have an older version of cmake. So we canāt fix the problem by adding
cmake. We would have to upgradecmake. That has an unknown (at least to me) compatibility impact. I expect that upgrading the version ofcmakein, for example, RHEL 8 or Debian 9 is going to be quite a challenge. We would have to show that all programs that worked withcmake3.x.y continue to build the same withcmake3.14.5 (or newer). Thereās a very high bar for making what could be a breaking change to one of the fundamental build tools being used in a distribution. And we have to meet this bar for all the distributions we want to add .NET to.Thereās also the question of timing. Even if an upgrade was accepted (I dont think it will be in many such enterprise or stable distributions), a change can take a long, long time. If it takes 1 year from now for Debian 9 to get the new
cmakeversion in the main package repositories, it will be too late for use in .NET 5.Perhaps you might understand the impact of this issue more broadly if you mentally replaced
cmakewithglibcin this discussion. We donāt ask users to install a separateglibc. We donāt ask distributions to upgrade their version ofglibc. We look at our support matrix and try and support all theglibcversions available there.@wfurt said:
I hope it now makes sense why it doesnāt even work for the versions of Debian and Ubuntu I listed in my initial comment above. Those versions of Debian and Ubuntu do not have the required version of
cmakein the main package repositories. Using an external package repository is not acceptable for Debian.Thereās a very high compatibility bar that needs to be crossed. And it needs to be met for every distribution that we want to package .NET in. I know .NET cares mostly about run-time compatibility. But Linux distributions generally care about as much for build-time compatibility. Updating
cmakeis far from a trivial operation.Agreed. I can help with this.
@wfurt said:
@jkoritzinsky said:
Thatās true, but itās also non-usable in a distribution context. Most distributions (certainly the case for enterprise distributions like RHEL) wont break the trust model by using binaries compiled by someone else.
A general upgrade for every distribution might be next to impossible. Doing this as part of .NET Core build might something we could do as a last resort. That might still violate some distribution policies. For example last time I tried to use a new version of
cmakein RHEL, I had to bootstrap it using a prebuiltcmakebinary. This would not work for Fedora (but Fedora is not in the list of distributions that has and old version ofcmake).@wfurt said:
Thatās true for developers and contributors, but not builders and Linux distributions. We canāt use binaries produced by a third-party (except in very specific circumstances, like bootstrapping).
Community linux distributions that focus on Openness and Freedom want to be able to build everything from source and only ship things they have themselves built from source. That lets them be sure those users who do care about the source are satisifed.
Enterprise linux distributions (as well as various *BSDs, I think) care about sources because it lets them avoid risk; if an open source project canāt fix an major issue, then they can step in and fix things themselves.
Both models mean that being able to build everything from source is important. Thatās why thereās a source-build project in the first place.
I am trying to think what a solution that lives only on source-build-side would look like. Source-build will have to, some how, support older versions of
cmakeand build runtime based on that.One way to do that would be to build a newer
cmakeversion as part of source-build. I touched on this earlier in my reply: there may be issues with this.Another way source-build could support older versions of
cmakewould be to carry patches locally to remove the dependency on newercmakeversion. That would be, effectively, doing the same work that everyone wants to avoid here. Worse, it would be specific to source-build. It would be likely that some build bugs and issues will exist only in source-build. I would much rather do the changes here, in runtime, where everyone can collaborate and share issues and fixes.