Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gcc: remove versions 4.9 and 5 #77985

Merged
merged 17 commits into from Jan 29, 2020
Merged

gcc: remove versions 4.9 and 5 #77985

merged 17 commits into from Jan 29, 2020

Conversation

Ma27
Copy link
Member

@Ma27 Ma27 commented Jan 18, 2020

Motivation for this change

In #66528 we're working on an update of glibc to version 2.30. One of the things changed is that the <sys/ustat.h>-header has been removed in 2.28 which is used by gcc5 and gcc49[1].

As both compiler versions are rather old, I figured that we might want to remove them from our package-set entirely. I decided to keep gcc48 for now as it doesn't seem to break with a new glibc though.

I did the following things:

  • Removed gcc49 and gcc5 packages
  • Removed some old packages that aren't buildable anymore or marked as broken for some time
  • Updated affected packages to a newer version to fix the build with a newer compiler
  • Used gcc6 for everything else affected (as "least" possible compiler)

[1] https://hydra.nixos.org/build/110380178, https://hydra.nixos.org/build/110418478

Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS linux)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Ensured that relevant documentation is up to date
  • Fits CONTRIBUTING.md.

Copy link
Member

@thoughtpolice thoughtpolice left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. I would also be fine with dropping FoundationDB 5.x builds, too, since they're pretty heavy to build and I imagine most people are running 6.x at this point.

@lblasc lblasc mentioned this pull request Jan 19, 2020
10 tasks
@samueldr
Copy link
Member

samueldr commented Jan 19, 2020

Some OEM kernels, even recent ones, require GCC 4.9 to build and run appropriately on mobile devices.

Pre-emptively, the same applies for GCC 6 (but not GCC 5 as of now).

I think it would be fine to adopt them in the Mobile NixOS overlay, but at the same time, the Mobile NixOS overlay aims to upstream all requirements back into Nixpkgs.

With that said, is there anything non-obvious y'all can see that would be problematic in adopting the compilers in an overaly? Sure, I would lose the binary cache for them, but that's already a non-issue because I generally build the cross-compiler variants already.


EDIT: Reading this PR description would have helped: glibc! It looks like gcc49 would need an older glibc, or some other fixup work.

@Ma27
Copy link
Member Author

Ma27 commented Jan 19, 2020

EDIT: Reading this PR description would have helped: glibc! It looks like gcc49 would need an older glibc, or some other fixup work.

May I ask what's your opinion about this now? Because I think that having to maintain an older glibc in an overlay means even more work, right?

@samueldr
Copy link
Member

samueldr commented Jan 19, 2020

I don't know yet! It's something that I'll need to investigate. Maybe the android toolchain fork already has fixes for more recent glibcs?


EDIT: Had a cursory look, maybe they do. They at least made one glibc related fixup, another could be hidden in commit where it's not part of the summary.

@vcunat
Copy link
Member

vcunat commented Jan 20, 2020

Do those cases need gcc 4.9 specifically? Note that 4.8 stays for now.

@Ma27
Copy link
Member Author

Ma27 commented Jan 20, 2020

@veprbl as you gave a 👎 here: would you mind elaborating your objections about this? :)

@veprbl
Copy link
Member

veprbl commented Jan 20, 2020

@Ma27,
I see a value in having "old" compilers available and maintained in the tree. I don't consider to be old, they are used and supported in production. The 4.8 is the default in RHEL 7 and, I believe, also Ubuntu Trusty. The gcc 4.9 is the default in Debian Jessie, and also it is the first release with "complete" support of C++11, so, I believe, many projects opted to work with that version.

It also is a bit suspicious to me that you say that 4.8 is working, but not 4.9 or 5.0, which makes me think that nothing is fundamentally wrong with modern glibc support in any of these compilers. If we delete the expressions now, they will not be coming back, and, to me, this just doesn't seem to be the right occasion to do so.

While I'm writing all of this, I also need to acknowledge that I'm not the one doing all the hard work here. Thus my thumbs down is only meant to be there in hope that people taking the final decision would think twice. I think, if we were to go for the "lazy" approach here, a compromise solution would be to mark the compilers in question as broken and push the work of fixing them onto the interested people.

@thoughtpolice
Copy link
Member

thoughtpolice commented Jan 20, 2020

While I'm writing all of this, I also need to acknowledge that I'm not the one doing all the hard work here. Thus my thumbs down is only meant to be there in hope that people taking the final decision would think twice. I think, if we were to go for the "lazy" approach here, a compromise solution would be to mark the compilers in question as broken and push the work of fixing them onto the interested people.

I'm not trying to derail this thread, but people make this argument all the time and I literally do not understand it. Does the problem somehow become untenable because you have to look at the logs first? This argument pre-supposes that interested parties are somehow motivated enough to un-break complex packages -- which might require serious work -- but are also too lazy to run git revert first. Are you suggesting that running git log and git revert before doing the actual hard part, which is un-breaking them, is somehow a show stopper?

Aside from that, even if packages are broken, they still have to evaluate, which means that any kind of refactoring has to take them into account. This means they have continuous maintenance overhead for as long as they're in the tree. They still use resources even if Hydra doesn't evaluate it.

Not every project immediately deletes broken code, and I'm not suggesting we delete packages the second they break. But this is a specious argument in general, I think. (I actually think the attractiveness of Nix, and how it makes these problems so much more tractable, is part of the reason people don't want to delete things. In other distros, it would be more clearcut because so many things we pull off are so hard. It's very tempting to keep things around "because it's just so easy". But those things still aren't free, either.)


I am also 100% uninterested in what compilers RHEL are shipping or what Ubuntu Trusty is shipping, frankly. The argument they're still supported is also not true: they literally are not supported by upstream GCC developers (in fact, only 8.x and 9.x are, and for good reason: it's difficult to maintain multiple years of release branches, backport relevant fixes, and generally do the work). They are only "maintained" insofar as the developers of distros that have stable releases using them may share patches or whatever for them if stuff breaks, but that's not quite the same thing.

But I don't see why the maintainers of categorically different distributions with vastly different designs (and funding!) should dictate our decisions, in this case. RHEL 7 also ships a 3.10.x franken-kernel that has millions of lines of code backported from the 4.x series, up to like kernel 4.5, at the expense of hundreds (thousands) of engineer hours. Our release branches live for 8 months, tops. They have completely different users and priorities than we do, it's simply not relevant or useful to contrast with them, IMO.

@Ma27
Copy link
Member Author

Ma27 commented Jan 20, 2020

Disclaimer: when I wanted to send that post, I've seen that @thoughtpolice answered as well and skimmed over it, so I might just repeat stuff here :)

The 4.8 is the default in RHEL 7 and, I believe, also Ubuntu Trusty.

Not sure if I misunderstand your point, but both are LTS distros that exist for a while, right? This change affects nixos-unstable and the upcomming release.

It also is a bit suspicious to me that you say that 4.8 is working, but not 4.9 or 5.0, which makes me think that nothing is fundamentally wrong with modern glibc support in any of these compilers.

Both GCC-versions used headers that were deprecated and removed from glibc and upstream didn't publish a version which fixes that. From my own perspective, the other option (well, apart from starting to have multiple glibc versions, but I'm really not sure which side-effects this will cause) would be to patch GCC accordingly and I'm not sure if we want to take that burden.

Please note that we don't have a gcc48Stdenv defined atm, so this compiler is hardly used.

While I'm writing all of this, I also need to acknowledge that I'm not the one doing all the hard work here. Thus my thumbs down is only meant to be there in hope that people taking the final decision would think twice.

Ah, no worries :) IMHO it's perfectly fine to raise concerns by such a change, no matter if they contribute to this change or not!

I think, if we were to go for the "lazy" approach here, a compromise solution would be to mark the compilers in question as broken and push the work of fixing them onto the interested people.

Hmm, I see. What should happen with the affected packages I either fixed or dropped?

@ajs124
Copy link
Member

ajs124 commented Jan 20, 2020

I'm not really for or against this, but I wanted to mention that Gentoo seems to carry a bunch of patches, including stuff like this patch, to fix compilation of older compilers with newer glibcs.

@veprbl
Copy link
Member

veprbl commented Jan 20, 2020

Not sure if I misunderstand your point, but both are LTS distros that exist for a while, right? This change affects nixos-unstable and the upcomming release.

Actually, I am too not sure what you are saying here. Do you mean that if I want to use older gcc, I should be not using Nix/Nixpkgs? That defeats the purpose of my objection :)

It also is a bit suspicious to me that you say that 4.8 is working, but not 4.9 or 5.0, which makes me think that nothing is fundamentally wrong with modern glibc support in any of these compilers.

Both GCC-versions used headers that were deprecated and removed from glibc and upstream didn't publish a version which fixes that. From my own perspective, the other option (well, apart from starting to have multiple glibc versions, but I'm really not sure which side-effects this will cause) would be to patch GCC accordingly and I'm not sure if we want to take that burden.

I agree, the approach with multiple versions of glibc is not likely to work well. I'm not sure why do you call this a burden, the patch would need to be applied only once.

Please note that we don't have a gcc48Stdenv defined atm, so this compiler is hardly used.

I was using gcc48 for over a year now, and, honestly, didn't even know this was the case. An stdenv = overrideCC stdenv gcc48 override was doing it for me.

Ah, no worries :) IMHO it's perfectly fine to raise concerns by such a change, no matter if they contribute to this change or not!

Cheers!

Hmm, I see. What should happen with the affected packages I either fixed or dropped?

It seems like you already did all the work of fixing the affected packages to work without gcc48, so, I guess, those fixes should be used.

@veprbl
Copy link
Member

veprbl commented Jan 20, 2020

I'm not trying to derail this thread, but people make this argument all the time and I literally do not understand it. Does the problem somehow become untenable because you have to look at the logs first? This argument pre-supposes that interested parties are somehow motivated enough to un-break complex packages -- which might require serious work -- but are also too lazy to run git revert first. Are you suggesting that running git log and git revert before doing the actual hard part, which is un-breaking them, is somehow a show stopper?

It seems what you are saying here is that meta.broken is redundant
and all intelligent people should be studying git history and using
the git revert. I have no problem with that. In my mind the issue
here is a political one. This has to do with how peer reviewing
works. When you delete an expression the burden of proving that it
should be removed is on you. If I submit a PR which unbreaks an
expression, then accepting it is, usually, a matter of building on
ofborg and merging. When I need to "reintroduce" a previously removed
expression, you might be reviewing it and asking me what the hell am I
bringing and telling me that it was all already decided in #77985.
From the positions of the formal logic my two revert PR's are
equivalent, but in reality the outcomes may be not.

Aside from that, even if packages are broken, they still have to evaluate, which means that any kind of refactoring has to take them into account. This means they have continuous maintenance overhead for as long as they're in the tree. They still use resources even if Hydra doesn't evaluate it.

This is also why we delete broken expressions if they are not fixed
after some time. Also, I'm not so convinced that very much testing is
given to refactoring of the broken packages in real practice.

Not every project immediately deletes broken code, and I'm not suggesting we delete packages the second they break. But this is a specious argument in general, I think.

This is why we are having this discussion.

(I actually think the attractiveness of Nix, and how it makes these problems so much more tractable, is part of the reason people don't want to delete things. In other distros, it would be more clearcut because so many things we pull off are so hard. It's very tempting to keep things around "because it's just so easy". But those things still aren't free, either.)

Yes, Nix is amazing, it allows to easily tackle some problems that are
usually tricky. This is, however, was not one of my arguments for
keeping gcc 4.9.

I am also 100% uninterested in what compilers RHEL are shipping or what Ubuntu Trusty is shipping, frankly. The argument they're still supported is also not true: they literally are not supported by upstream GCC developers (in fact, only 8.x and 9.x are, and for good reason: it's difficult to maintain multiple years of release branches, backport relevant fixes, and generally do the work). They are only "maintained" insofar as the developers of distros that have stable releases using them may share patches or whatever for them if stuff breaks, but that's not quite the same thing.

But I don't see why the maintainers of categorically different distributions with vastly different designs (and funding!) should dictate our decisions, in this case. RHEL 7 also ships a 3.10.x franken-kernel that has millions of lines of code backported from the 4.x series, up to like kernel 4.5, at the expense of hundreds (thousands) of engineer hours. Our release branches live for 8 months, tops. They have completely different users and priorities than we do, it's simply not relevant or useful to contrast with them, IMO.

I am not a maintainer of any of those distros, and I am in no position
to dictate some decisions. I'm just claiming that there are reasonable
use cases for these expressions. As far as I know, there is no
officially declared goal for NixOS to "support latest versions only"
or "be more like ArchLinux rather than Ubuntu".

@thoughtpolice
Copy link
Member

thoughtpolice commented Jan 21, 2020

When I need to "reintroduce" a previously removed expression, you might be reviewing it and asking me what the hell am I bringing and telling me that it was all already decided in #77985. From the positions of the formal logic my two revert PR's are equivalent, but in reality the outcomes may be not.

Packages are not authored in a void, they have motivations behind why the user wants them, after all. If you're going to bring those packages back, you could start, for example, by explaining why you want or need a compiler that was released 5+ years ago when we will still have GCC 6, 7, 8, and 9 available, on top of a similar number of Clang versions. It's likely we'll even add GCC 10 and LLVM 10 too, before we get rid of the others. That reasoning you propose may, or may not, be accepted as valid -- but it's a good start. It's not like you're just randomly doing work for no reason, I assume?

The arguments for re-introducing broken/removed packages has to be handled on a case-by-case basis. If I remove a 10 line long expression that miscompiled and was broken, and someone re-adds it later on, and I ask "Why are you re-adding this thing that was broken? What's different this time", they might say "Because I'll maintain it now, the fix was easy, there was a fork with maintained versions, it's not hard to support, there are no actual alternatives, and it's useful". Great! Those are all good reasons to keep or re-add a package. The specifics can vary, but that's a start.

This is not that case, and in fact, it is nearly the opposite: this compiler is 5 years old, unmaintained (by upstream and by us), and there are literally a dozen packages that not only serve as legitimate, instant replacements (they compile C code, just like GCC 4.9 does!), they are objectively, literally better in every way: they have better security features, better optimizations, better error reporting/diagnostics, they have better runtime efficiency, and so on and so forth.

So yes, it's true that if someone came along and they wanted to re-add GCC 4.9, they might be met with more difficulties than if it was kept broken. That's a good thing, AFAICS. I would hope if you wanted to re-add GCC 4.8 for some reason, your reasons would be good ones, not "just because" or whatnot.

I'm just claiming that there are reasonable use cases for these expressions.

The only "reasonable use case" you brought up is that other distros use them. But the "use case" for GCC 4.9 in RHEL is that "RHEL users will get pissed off if they get a default compiler change out of the blue and it takes a ridiculously long time to QA those changes", it's not because GCC 4.x is in wide demand from C/C++ programmers everywhere like vintage wine. It's useful, but not for no reason, it's the result of a direct policy decision. It is something that only exists in the world of Red Hat, and can only make sense for us if we think we want to emulate them. I don't think we do. (In fact, as someone who writes C daily for work, at a company that writes a huge amount of C, I can tell you I adore all the features available in new compilers.)

Forget about ArchLinux or RHEL though. Really, the core problem, in this particular case and possibly not any other case, comes down to this: why on earth are we keeping 1 expression, which is not maintained by upstream, which has no users anywhere, when there are like ten functional replacements for it, which are all superior in every perceivable technical way? This hasn't been explained by anyone at all, as far as I can tell, and that fact is all the more reason to delete the old versions, IMO. In fact I literally am the maintainer of one of the only packages in the entire package set that needs GCC 4.9 as a hard technical requirement -- and I absolutely do not see a reason to keep it, nor do I think my one (or two) individual packages justify keeping it (and in fact, using GCC 4.9 has other negative consequences for my packages, particularly around linking libraries compiled with 4.9 vs newer versions.)

@7c6f434c
Copy link
Member

7c6f434c commented Jan 21, 2020 via email

@veprbl
Copy link
Member

veprbl commented Jan 22, 2020

@thoughtpolice In the interest of not blowing up the discussion, I will try to answer briefly. In the first paragraphs you explain how after the deletion of gcc 4.9 and 5 I will be struggling to prove that gcc 4.9 is better than gcc 10. I agree, it might be impossible to do that. Then, thank you for admitting that I do have at least one "reasonable use case". I never really wanted to go into details about qualities of RHEL. I think, what matters is that it does exist and has users, some of those use Nix and need to interact with the platform. Again, this is only a very short answer to your argumentation, I apologize for that.

@veprbl
Copy link
Member

veprbl commented Jan 22, 2020

FWIW here is a fix for gcc49 (using the patch suggested in #77985 (comment))

diff --git a/pkgs/development/compilers/gcc/4.9/default.nix b/pkgs/development/compilers/gcc/4.9/default.nix
index 2f85fc4b7e8..4f6665dadd3 100644
--- a/pkgs/development/compilers/gcc/4.9/default.nix
+++ b/pkgs/development/compilers/gcc/4.9/default.nix
@@ -61,7 +61,13 @@ let majorVersion = "4";
     inherit (stdenv) buildPlatform hostPlatform targetPlatform;
 
     patches =
-      [ ../use-source-date-epoch.patch ../parallel-bconfig.patch ./parallel-strsignal.patch ]
+      [ ../use-source-date-epoch.patch ../parallel-bconfig.patch ./parallel-strsignal.patch 
+        (fetchpatch {
+          name = "avoid-ustat-glibc-2.28.patch";
+          url = "https://gitweb.gentoo.org/proj/gcc-patches.git/plain/4.9.4/gentoo/100_all_avoid-ustat-glibc-2.28.patch?id=55fcb515620a8f7d3bb77eba938aa0fcf0d67c96";
+          sha256 = "0b32sb4psv5lq0ij9fwhi1b4pjbwdjnv24nqprsk14dsc6xmi1g0";
+        })
+      ]
       ++ optional (targetPlatform != hostPlatform) ../libstdc++-target.patch
       ++ optional noSysDirs ../no-sys-dirs.patch
       ++ optional langFortran ../gfortran-driving.patch

@veprbl
Copy link
Member

veprbl commented Jan 22, 2020

Fix for the gcc5:

diff --git a/pkgs/development/compilers/gcc/5/default.nix b/pkgs/development/compilers/gcc/5/default.nix
index f68ddc81f81..05ce3477107 100644
--- a/pkgs/development/compilers/gcc/5/default.nix
+++ b/pkgs/development/compilers/gcc/5/default.nix
@@ -59,7 +59,18 @@ let majorVersion = "5";
     inherit (stdenv) buildPlatform hostPlatform targetPlatform;
 
     patches =
-      [ ../use-source-date-epoch.patch ]
+      [ ../use-source-date-epoch.patch
+        (fetchpatch {
+          name = "libsanitizer-avoidustat.h-glibc-2.28-part-1.patch";
+          url = "https://gitweb.gentoo.org/proj/gcc-patches.git/plain/5.5.0/gentoo/25_all_libsanitizer-avoidustat.h-glibc-2.28-part-1.patch?id=9bb182e056c527bebbd290a8c896196e47eb26eb";
+          sha256 = "1n67phr8gcrnaiq611kj9w0v8w24zsjaqsw8yh5bbl8fmw5nq3lx";
+        })
+        (fetchpatch {
+          name = "libsanitizer-avoidustat.h-glibc-2.28-part-2.patch";
+          url = "https://gitweb.gentoo.org/proj/gcc-patches.git/plain/5.5.0/gentoo/26_all_libsanitizer-avoidustat.h-glibc-2.28-part-2.patch?id=9bb182e056c527bebbd290a8c896196e47eb26eb";
+          sha256 = "0n21sfypax6agbv7c040jy2xiqx3lc430jksbz7a77dwxg3khwqz";
+        })
+      ]
       ++ optional (targetPlatform != hostPlatform) ../libstdc++-target.patch
       ++ optional noSysDirs ../no-sys-dirs.patch
       ++ optional langFortran ../gfortran-driving.patch

Like the previous one this is tested on top of #66528

Ma27 and others added 15 commits January 28, 2020 20:11
This update was primarily done to update rPackages.V8 to 3.0 which
doesn't depend on an ancient version of v8 anymore.

Also dropped the `-lv8_libplatform` linker flag. It seems as this now
part of `v8.so` as `v8_libplatform.so` doesn't exist anymore on recent
v8 versions in nixpkgs, but the headers are still there and there aren't
any "undefined reference to" errors while linking.
Doesn't build with gcc>=5.
Latest gcc5 release was in 2017[1], doesn't build with glibc 2.30[2].

[1] https://gcc.gnu.org/gcc-5/
[2] https://hydra.nixos.org/build/110408216
Depends on a fairly old gcc, marked as insecure for ~2 years.
Marked as broken for >2 years, doesn't build with recent gcc.
Broken for almost 2 years, doesn't build with recent
gcc (-> incompatible with latest glibc).
Co-authored-by: Dmitry Kalinkin <dmitry.kalinkin@gmail.com>
@Ma27
Copy link
Member Author

Ma27 commented Jan 28, 2020

Just rebased onto latest master to fix the merge conflicts and added a note to the release-notes about the gcc5 removal. I think that it's a fair compromise to keep gcc49 as we have a valid use-case for it.

Unless there are any further objections, I'd merge tonight :)

@Ma27 Ma27 merged commit c55809e into NixOS:master Jan 29, 2020
@Ma27 Ma27 deleted the drop-old-gcc branch January 29, 2020 08:37
Ma27 added a commit that referenced this pull request Jan 29, 2020
In #77985 it was decided that gcc49 and gcc5 should be deprecated,
however we decided to keep gcc49[1].

I removed the commit which dropped gcc49, but apparently I staged the
gcc49Stdenv removal in a different commit. Readding this as we decided to
keep gcc49 for now.

[1] #77985 (comment)
anna328p pushed a commit to anna328p/nixpkgs that referenced this pull request Feb 2, 2020
anna328p pushed a commit to anna328p/nixpkgs that referenced this pull request Feb 2, 2020
In NixOS#77985 it was decided that gcc49 and gcc5 should be deprecated,
however we decided to keep gcc49[1].

I removed the commit which dropped gcc49, but apparently I staged the
gcc49Stdenv removal in a different commit. Readding this as we decided to
keep gcc49 for now.

[1] NixOS#77985 (comment)
jpgu-epam pushed a commit to jpgu-epam/nixpkgs that referenced this pull request Feb 4, 2020
In NixOS#77985 it was decided that gcc49 and gcc5 should be deprecated,
however we decided to keep gcc49[1].

I removed the commit which dropped gcc49, but apparently I staged the
gcc49Stdenv removal in a different commit. Readding this as we decided to
keep gcc49 for now.

[1] NixOS#77985 (comment)
@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/january-2020-in-nixos/5771/1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet