Why does libc have two version numbers (on Ubuntu)? - libc

If I run this in Docker's ubuntu:latest:
root#4304dfbfa661:/# ls lib/x86_64-linux-gnu/libc* -l
-rwxr-xr-x 1 root root 1868984 Jan 15 02:51 lib/x86_64-linux-gnu/libc-2.23.so
lrwxrwxrwx 1 root root 12 Jan 15 02:51 lib/x86_64-linux-gnu/libc.so.6 -> libc-2.23.so
It seems that libc is numbered as both 6 and 2-23. Why are there two version numbers?
NB libc is (idiosyncratically) executable and running it gives
root#4304dfbfa661:/# ./lib/x86_64-linux-gnu/libc.so.6
GNU C Library (Ubuntu GLIBC 2.23-0ubuntu10) stable release version 2.23, by Roland McGrath et al.
So it's the libc.so.6 that's surprising. Does libc [or to be precise, glibc] have sonames that are unrelated to the version numbers?
Edit: to clarify, I understand the symlink. What confuses me is the existence of two numbering schemes. If you look at e.g. libstdc++, you find
lrwxrwxrwx 1 root root 19 Sep 11 2017 ./usr/lib64/libstdc++.so.6 -> libstdc++.so.6.0.19
-rwxr-xr-x 1 root root 995840 Aug 1 2017 ./usr/lib64/libstdc++.so.6.0.19
Having foo.so.6 as a symlink to foo.so.6.0.19 makes sense. Having foo.so.6 as a symlink to foo-2.23.so is confusing...

What confuses me is the existence of two numbering schemes.
Before the invention of GNU symbol versioning, any change to the ABI required that an entirely new version of the library was introduced, and two (or more) copies had to be present on the system.
External library versioning is described e.g. here.
With the introduction of per-symbol versioning (GNU symbol versioning), external library versioning became completely unnecessary: multiple ABIs could be supported in a single library.
This is why libc.so.6 stayed at version 6 since forever (late 1990s). There is no reason to have a symlink at all -- the library could simply be named libc.so.6. However, it is convenient to have the symlink and have it point to current library version, e.g. libc-2.27.so.
The libstdc++.so is also stuck at libstdc++.so.6, but it is different: maintaining multiple C++ ABIs is much more difficult. So the library keeps incrementing minor version with each GCC version (newer GCC requires newer versions of libstdc++.so).
But they don't change the .so.6 part because doing so would require having multiple libstdc++.so copies (which will share 99% of the code).

History about the two numbering schemes:
Linux libc was forked from FSF's glibc in 1980s, and turned back to glibc again in 1997-98 to correct the 'strategic mistake'.
Then:
The version numbers were a minor problem: The GNU/Linux guys had already reached 5.4.47, while FSF was just hitting 2.0. They probably pondered for about a millisecond asking Stallman to make his next version 6.0 for their benefit. Then they laughed, said "This is Stallman we're talking about, right?", and decided out-stubborning Richard was not a wise idea. So, the convention is that Linux libc version 6.0 is the same as glibc 2.0.
details here
So, libc.so.6 is just something like a conversional name.

Related

Yoctoproject - include newer coreutils (stat)

I am trying to build a custom distribution for an embedded device. I need the 'stat'-command (which is part of GNU coreutils) to support long-options, e.g. stat --printf.
The stat-version the build currently includes is ancient and does not support long-options.
root#target:/# stat -v
stat version 3.0
The receipe for stat is located at sources/poky/meta/recipes-extended/stat_3.3.bb which points to http://www.ibiblio.org/pub/Linux/utils/file/stat-3.3.tar.gz as its SRC_URI.
The coreutils receipe is located at sources/poky/meta/recipes-core/coreutils/coreutils_8.27.bb which points to https://ftp.gnu.org/gnu/coreutils/coreutils-8.27.tar.xz as its SRC_URI.
How I understand it, bitbake uses ALTERNATIVE_PRIORITY[stat] which is defined in both recipes to decide which version is to be included. Since the coreutils_8.27 should be new enough, I tried to simply delete the stat_3.3-receipe. This didn't work, the old 3.3 version of stat is still included.
What would be the best way to include a newer version or coreutils (or stat) which supports long-options?
To fix this I had to include the 'coreutils'-package (IMAGE_INSTALL_append += " coreutils") in my local.conf and raise the ALTERNATIVE_PRIORITY for the coreutils-package.

How can I use an older version of package gregor?

Here's how to simulate it.
$ cat t1.rkt
#lang racket/base
(require gregor)
(display "hello")
I'm running Racket 6.12. But the same happens to Racket 7.2.
$ racket t1.rkt
explode-path: contract violation
expected: (or/c path-for-some-system? path-string?)
given: #f
context...:
/usr/share/racket/collects/racket/path.rkt:116:0: do-explode-path
/usr/share/racket/collects/racket/path.rkt:126:0: find-relative-path7
/home/me/.racket/6.12/pkgs/tzinfo/tzinfo/private/zoneinfo.rkt:118:2: for-loop
/home/me/.racket/6.12/pkgs/tzinfo/tzinfo/private/zoneinfo.rkt:108:0: read-tzids
/home/me/.racket/6.12/pkgs/tzinfo/tzinfo/private/zoneinfo.rkt:71:0: make-zoneinfo-source
/usr/share/racket/collects/racket/contract/private/arrow-val-first.rkt:388:18
/home/me/.racket/6.12/pkgs/tzinfo/tzinfo/main.rkt:63:0: system-tzid
/usr/share/racket/collects/racket/contract/private/arrow-val-first.rkt:388:18
/home/me/.racket/6.12/pkgs/gregor-lib/gregor/private/moment.rkt: [running body]
/home/me/.racket/6.12/pkgs/gregor-lib/gregor/private/generics.rkt: [traversing imports]
/home/me/.racket/6.12/pkgs/gregor-lib/gregor/private/clock.rkt: [traversing imports]
/home/me/.racket/6.12/pkgs/gregor-lib/gregor/main.rkt: [traversing imports]
/home/me/issue-gregor/t1.rkt: [traversing imports]
$ racket --version
Welcome to Racket v6.12.
How could I go back to an older version of gregor? I installed it this one with raco pkg install gregor and installed all its dependencies.
I'm the author of Gregor. (I don't normally post on Stack Overflow, or even use it much, but John Clements brought this to my attention.)
There's a bit of an unfortunate naming issue here, since tzdata appears to be the name of an Ubuntu package that provides the normal zoneinfo files, as well as being the name of a Racket package that also provides those files.
gregor depends on a package called tzinfo. tzinfo, in turn, conditionally depends on tzdata (the Racket one, not the Ubuntu one). Specifically, it only depends on tzdata on Windows systems. This is because I assumed that all Unix systems would have the zoneinfo files. (It never occurred to be that anyone would run a Unix without them these days.) But it is certainly the case that tzinfo (and thus gregor) will not work unless it can find zoneinfo files.
Maybe I should update the documentation with a conspicuous warning. I'd rather not make tzinfo unconditionally depend on tzdata (again, the Racket one), because most Unix systems will already have the necessary files, and it could be unduly confusing for gregor to use a version of them different from the one the system is using.

Porting Newlib with current autotools

I'm trying to build a toolchain for my hobby kernel, but I'm running into problems when building Newlib. Whenever I try to run autoreconf in my kernels directory under newlib/libc/sys/ I get an error:
configure.in:5: error: support for Cygnus-style trees has been removed
Here is the content of configure.in (basically, taken from the below tutorial):
AC_PREREQ(2.59)
AC_INIT([newlib], [NEWLIB_VERSION])
AC_CONFIG_SRCDIR([crt0.S])
AC_CONFIG_AUX_DIR(../../../..)
NEWLIB_CONFIGURE(../../..)
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
and the source for Makefile.am (again mostly from tutorial):
AUTOMAKE_OPTIONS = cygnus
INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
AM_CCASFLAGS = $(INCLUDES)
noinst_LIBRARIES = lib.a
if MAY_SUPPLY_SYSCALLS
extra_objs = $(lpfx)syscalls.o
else
extra_objs =
endif
lib_a_SOURCES =
lib_a_LIBADD = $(extra_objs)
EXTRA_lib_a_SOURCES = syscalls.c crt0.S
lib_a_DEPENDENCIES = $(extra_objs)
lib_a_CCASFLAGS = $(AM_CCASFLAGS)
lib_a_CFLAGS = $(AM_CFLAGS)
if MAY_SUPPLY_SYSCALLS
all: crt0.o
endif
ACLOCAL_AMFLAGS = -I ../../..
CONFIG_STATUS_DEPENDENCIES = $(newlib_basedir)/configure.host
Yes, I have tried removing the AUTOMAKE_OPTIONS=cygnus.
I've Googled around and been trying to understand this, and as far as I can tell, it is because of the version of autotools I'm using. According to the tutorial I used originally (OSDev - OS Specific Toolchain), I need an older version. My problem is that I'm using Kubuntu, which uses the apt package manager, and that version is not available to fall back to even temporarily. There has to be some fix for this. Either Newlib is outdated (this release is from December of 2013...) or the developers are crazy for depending on an outdated autotools version.
The only other thing I can think is that this is a message from the newlib configuration scheme itself in which case I have no idea how to modify my configure.in and Makefile.am to align with the new newlib configure format. That tutorial is the only one I've found that didn't use libgloss (which I'd prefer not to do) so far and the documentation of adding a new target is rather lacking in the documentation for newlib (or I missed something).
Here is some version information:
System: Kubuntu 14.04
Automake: 1.14.1
Autoconf: 2.69
Newlib: 2.1.0
Unfortunately I'm afraid using automake 1.12 or earlier is your only choice. Ubuntu has an Automake1.11 separate package to help you there, if I'm not mistaken, since the compatibility between 1.12 and 1.14 is generally good, but before that it was spotty.
I am writing this answer for people struggling with the tutorial described here.
I am in the same situation you are (or were), I am building a kernel from scratch and I wanted to port newlib to my toolchain. Unfortunately I think the tutorial has become out of date because I followed the instructions EXACTLY, even installing the correct software with the proper versions (including the correct newlib version). The accepted solution above didn't work for me but I found another solution that might work for others:
Step 1 - get the correct software
Acquire Automake (v1.12) and Autoconf (v2.65) from here:
http://ftp.gnu.org/gnu/automake/automake-1.12.tar.gz
http://ftp.gnu.org/gnu/autoconf/autoconf-2.65.tar.gz
Step 2 - build process
Untar both of the archives:
tar xf automake-1.12.tar.gz
tar xf autoconf-2.65.tar.gz
Create a destination folder:
mkdir ~/bin
Create a build folder:
mkdir build
cd build
Configure automake first:
../automake-1.12/configure --prefix="~/bin"
Make and install
make && make install
Now lets configure autoconf
../autoconf-2.65/configure --prefix=~/bin
Then make and install:
make && make install
You should now have the proper binaries in ~/bin!
Step 3 - update PATH
To add these binaries to your path temporarily (recommended):
export PATH=~/bin:$PATH
Once you update your path, rerun autoconf and autoreconf and it should complete.

Building a perl extension module on OpenBSD

How ought I build an XS perl module on OpenBSD when the requisite .so files are missing?
Background: On a vanilla OpenBSD 5.3 vm install, I'm unable to build a perl module which needs to link against -lpthread. pthread.a and pthread.so.Maj.Min do exist on the system.
However Makefile.PL is looking for pthread.so, which is absent. Is this ordinary for OpenBSD? (I can coerce the Makefile to link against pthread.a and things work just fine, as it happens.)
In a Redhat-ish Linux environment, I'd just install the right -devel RPM and go again. On OpenBSD, however, I'm missing something very basic about the development environment.
UPDATE The core problem was Dynaloader mis-detection of libraries inside Makefile.PL.
The Makefile is wrong, report the bug to the upstream. It never should look for a specific file. Look this example:
$ cat test.c
int main(){
return 0;
}
$ gcc -lpthread -o test test.c
$ ldd test
test:
Start End Type Open Ref GrpRef Name
00000c4321600000 00000c4321a02000 exe 1 0 0 test
00000c4521f63000 00000c4522374000 rlib 0 2 0 /usr/lib/libpthread.so.17.1
00000c4524c1c000 00000c4525103000 rlib 0 1 0 /usr/lib/libc.so.68.2
00000c452a100000 00000c452a100000 rtld 0 1 0 /usr/libexec/ld.so
Also, in OpenBSD you don't need install a -devel package. OpenBSD has the batteries included.
While editing your Makefile.PL is one way to go, I generally see folks use link files to point generic library/executable names to version specific names.
For Example:
pthread.so -> pthread.so.maj.min
pthread.so.maj -> pthread.so.maj.min
This way things that want the 'latest' version can get it via the link & thinks that just care about major version can grab the most recent release of it's major version...

How do I compile Perl 5.10 with thread support under FreeBSD 7.1?

I'm trying to compile Perl 5.10 on my FreeBSD 7.1 (BSD) server but when I run the Configure script and answer the questions I get the following error:
...POSTIX threads should be supported by FreeBSD 7.1 ... but your system is missing the shared libc_r.
Googling for the answer came up with installing gethostnamadr.c which is fine except for two things:
I don't know where to put this file and
How does this solve my problem if Configure wants to see libc_r?
To enable Perl 5.10 threads on FreeBSD 7.* all you have to do is apply the following patch using patch. You can then build perl with -Dusethreads or answer the Configure file questions to enable threading and you're good to go. I haven't done any significant testing or comparisons yet but everything compiles fine including the thread libs and all my Perl programs work fine.
--- hints/freebsd.sh 2008/10/20 04:59:30 1.1
+++ hints/freebsd.sh 2008/10/20 22:49:29
## -211,6 +211,14 ##
exit 1
;;
+ 7.*)
+ # 7.x doesn't install libc_r by default, and Configure
+ # would fail in the code following
+ #
+ # gethostbyaddr_r() appears to have been implemented in 6.x+
+ ldflags="-pthread $ldflags"
+ ;;
+
*)
if [ ! -r "$lc_r" ]; then
cat <<EOM >&4
EDIT: I forgot my reference; check here for more info: http://www.gossamer-threads.com/lists/perl/porters/232518?nohighlight=1#232518.
Contrary to Spolsky who said "perl is pretty much forgotten"... perl is very much alive.
You have not indicated which version of FreeBSD you have installed... But assuming that you have installed a min of FreeBSD 7.1 then you failed to install the threads libraries or the thread libs are not in the library path.
NOTE that libc is a general 'c' library and that libc_r is the thread-safe version of that file. Some of the 2005 google results suggest that libc_r has been deprecated.
With that in mind it is likely that you are in the middle of a "revision collision". Sadly FreeBSD does not provide the thread safe version of perl natively, however, they do package perl 5.10 and several later revisions. I found this link to be useful:
http://www.nabble.com/How---where-to-get-a-Perl-that-has-threads--td22270858.html
you might also want to try installing the p5-fork library which is included with FreeBSD
http://www.nabble.com/How---where-to-get-a-Perl-that-has-threads--td22270858.html