How to prevent installation of package gcc-4.0 on Debian

I run Debian unstable and these past days I’ve been unpleasantly surprised by GCC 4.0 a number of times. It had been introduced in the system automatically by bulk upgrades, but soon problems started arising.

One one particular system, more or less everything I compiled issued warnings related to pointer signedness. On my home box I wasn’t able to recompile an older kernel release because apparently it wasn’t prepared for GCC 4.0.

We all know you don’t mess with a guy’s kernel. GCC 4.0 had to go, at least for the time being.

The solution is not straightforward. With a “regular” package I would be able to hold its version or forbid it from updating via any number of means. But the gcc (and cpp, and gcc-*-base, and many other) packages are actually separated packages containing the version in their name. So the old package gcc-3.4 had nothing to do with gcc-4.0, so holding it would do no good.

Furthermore, the idea is to forbid yet-uninstalled packages from installing. Allowing gcc-4.0 to install messes up the system symlinks to the gcc and cpp binaries. Good luck getting them back other than manually. Apparently the update-alternatives setup doesn’t handle gcc & friends, although you can set it up yourself.

Going even further, I wanted a permanent solution which wouldn’t require any manual tweaks other than this one time. In particular, I want bulk upgrades to pick up on my interdiction regarding gcc and resolve dependencies automatically.

I found the solution in the Debian documentation, in the APT Howto. Yes, kids, reading documentation does pay.

The trick is to edit /etc/apt/preferences (create it if it doesn’t exist) and add the following:

Package: gcc-4.0
Pin: version 1.0*
Pin-Priority: 1001

Package: cpp-4.0
Pin: version 1.0*
Pin-Priority: 1001

Yes, that’s right. This is the mythical /etc file I wished for, which would allow me to forbid new packages from installing and be picked up by apt automatically.

What happened there? You can find detailed info in the APT Howto page I’ve linked above. Short version: I’ve targeted the undesirable packages (gcc-4.0 and cpp-4.0), pinned them down at version 1.0 and made the pinning more or less unbreakable. Since 1.0 won’t ever be touched by gcc 4.0, we’re in the clear.

After I ran apt-get dist-upgrade again, I was pleased to notice that the two offending package were automatically excluded from upgrades and all dependencies worked around this fact.

Warning: do not pin gcc-4.0-base, it is used by a number of other packages, including gcc-3.4 (go figure).

I’m still debating whether I should use a pin priority of 1000 or 1001, but overall I’m satisfied.