It's not a typo.

The conventional name of a native code library (C, C++, etc) in Debian is derived from the SONAME of the library it installs. So you can be pretty sure that libfoo.so.3 is shipped in a binary package libfoo3.

So what about the weird exceptions, like zlib1g?

Well the package name deviates from the standard in two ways.

Firstly, you'd think it should be called 'libz1'. Given the age of zlib (the first entry in /usr/share/doc/zlib1g/changelog.Debian.gz dates back to September 1996!), I think that the naming of the binary package predates the adoption of the convention that would have resulted in it being named 'libz1'.

Second, what is this 'g' suffix? This dates back to the GLibc transition.

You see, a long time ago, Linux distributions used a fork of Glibc, known as 'Linux libc'. See https://manpages.debian.org/libc.7 for details. Long story short, it was decided to abandon the fork and adopt the GNU C Library (Glibc).

For many end-user programs, a recompile was all that was needed to effect this transition. Before switching, the the binary package of such a program would depend on libc5; afterwards it would depend on libc6. Simple.

But many programs depend on shared libraries. In this case, the program could not be rebuilt against Glibc until all its dependend-upon libraries had also been rebuilt against Glibc. Effectively, libfoo-built-with-Glibc was an ABI change from libfoo-built-with-Linux-libc.

In order to prevent crashes and other malfunctions from linking libc.so.5 and libc.so.6 into the same program at runtime, the decision was made to rename the binary packages libfoo3 to libfoo3g (the g being short for Glibc). Once upstream bumped its SONAME to libfoo.so.4, libfoo3g would be replaced by libfoo4, which has always been linked against Glibc and so the 'g' suffix could be dropped.

(Aside: I don't know the reason why why SONAME of libraries was not changed at the same time, i.e. change from libfoo.so.3 to libfoo.so.3g... perhaps because co-ordinating that rename across all Linux distributions was too big a job for too small a gain?)

If you look at the dependencies for the zlib1g package, you will notice 'Conflicts: zlib1 (<= 1:1.0.4-7)'. This is there to prevent the zlib1g package being installed on the same system as a package 'bar' which still depends on zlib1 (because 'bar' hasn't been rebuilt against glibc yet...)

If we refer back to the changelog.Debian file, we find...

zlib (1:1.0.4-7.1) unstable; urgency=low

* Updated for libc6
* Compiled with -D_REENTRANT.
* Non mantainer release.

-- Enrique Zanardi <ezanardi@molec1.dfis.ull.es> Wed, 17 Sep 1997 01:28:05 +0100

Which tells us that 1:1.0.4-7.1 was the version where the binary package was renamed to zlib1g. Ok, the changelog message is a little terse, but the community was a lot smaller in those days and who could call themselves a serious user of Linux without being aware of the Glibc transition? ;)

Over the years, similar transitions have taken place. The 'c102' transition occurred when GCC 3.2 broke the ABI for all C++ code. 'libbar3' became 'libbar3c102' when libbar was changed to being built with GCC 3.2, and the 'c102' prefix was similarly dropped once libbar upstream bumped its SONAME to libbar.so.4 which was packages as 'libbar4'. It looks like libfam0c102 is the sole remaining package with this naming convention in the archive, all others having dropped the prefix long ago. You can read about the GCC transition plan at https://lists.debian.org/debian-devel-announce/2003/01/msg00... the Glibc transition occurred so long ago that I wasn't able to find any similar documents explaining it (admittedly after only brief Google searches). Although https://lists.debian.org/debian-gcc/2002/08/msg00091.html (also about the c102 transition) refers to the Glibc transition:

> This is similar in spirit to the glibc transition adding `g' to the end of libraries.

TL;DR: the package is called zlib1g because it was called 'zlib' before the standard Debian naming scheme for libraries was adopted; and because it was renamed to 'zlib1g' when it was transitioned from building against Linux libc to Glibc, and since then it was remained ABI stable. If zlib upstream ever bump the SONAME to libz.so.2 then zlib1g will be replaced by libz2.

There are a couple of other packages in the archive which haven't had a SONAME bump since the glibc transition: libcanna1g and libpam0g. Their changelogs confirm that they are named so due to the glibc transition.

(There's one other package, libgjs0g that is a red herring. It looks like upstream broke ABI without bumping the SONAME for whatever reason, leaving it to distributions to pick up the pieces. Typical. The way this was solved in Debian was to rename the binary package from libgjs0 -> libgjs0a -> libgjs0b -> ... -> libgjs0e -> libgjs0g and since then it's remained stable.)