How can I create Linux executable code that can be run on any version of GLIBC smaller than 2.34?
Thanks for the answers. I was expecting a compile and/or link option that will prevent the usage of GLIBC 2.34.
Is there some more significant change taken place with 2.34 ?
fedkad, is your Buster test system up to date ?
Noting what everybody else has said, but I believe that the fundamental issue is that the linker resolves/follows symlinks so the actual filename in the executable is that of the actual library.
The error states that dlopen/dlsym/dlclose are not available in the libc/'c'.
My guess is there is something wrong somewhere in your code or its dependency, which define dlopen/dlsym/dlclose manuall as external 'c'.
Perhaps try to use the unit dl which defines things as expected.
Anyway, there it is, if you build and distribute binaries to other Linux users, beware !
2.34-2.35 are considered as unstable and 2.36 is experimental.Yes Fred but consider that with Ubuntu, arguably the most used distro, the 22.04 long term release, already 5 months old, is using 2.35, that means that all the Ubuntu derivatives such as Linux Mint are also using 2.35 ! The cat is well and truly out of the bag !
...
I hope that in the future Lazarus can improve a solution to this case.
Thank you for your reply.
How could I configure a chroot environement? Where could I find documentation? I've no experience with this.
Thank you again, best regards,
Stephanie
I hope that in the future Lazarus can improve a solution to this case.
...
I hope that in the future Lazarus can improve a solution to this case.
The best solution would be that fpc does not need to link libc.so for his /rtl/.
But this is not for soon (afaik).
Hello,
an AppImage might be a solution?
I don't know if there is an easy tool to generate a Linux AppImage from Lazarus.
An AppImage should have all dipendences in the unique file.
Anyone has tried?
Best regards,
Stephanie
an AppImage might be a solution?
I don't know if there is an easy tool to generate a Linux AppImage from Lazarus.
An AppImage should have all dipendences in the unique file.
...
One last question: being Linux Open Source, couldn't you add some older version library packages, with an option to compile with them?
One last question: being Linux Open Source, couldn't you add some older version library packages, with an option to compile with them?
Another thing worth keeping in mind is that this is, hopefully, a one-off problem.
Over time, all the systems running <v2.34 will be updated and will work in a post 2.34 world. I have tested the latest Ubuntu, it uses 2.35 and binaries made there work fine on a 2.34 system. Promising ...
readelf -Ws {file} | grep GLIBC
Also one of such cases if one creates absolutely new "simple program" having nothing in it and compiling into 200k executable. You readelf it, you won't find any glibc dependencies.
But add dynlibs to uses section and you will get dlopen and several other dl... functions with version information (probably 2.34 for recent linux versions, since this glibc version is notable in that they merged different so modules to reside in the single libc so they have to do version increase for plenty of related functions). But the glibc binding is unexpected, the dl unit having dlopen declaration uses "dl" lib. Here we have an indirect consequence, it's probably the smart linker of recent versions who knows (or resolved with symbol chaining) that here it maps dl* function to newly reappeared ones in glibc.
So fpc (and probably lazarus also) formally distance themselves from the c runtime in most of basic cases (probably threads is another exception) but has no full control about it.
But in case with acknowledge that investigation of basic glibc usage in fpc/lazaraus is possible then the capping might look like this
@MarkMLl, thanks for mentioning dynamic loading, if one has control of a unit with external declarations to glibc he or she can choose dynamic loading instead of static declarations and this can help with avoiding the problem with versioned symbols
"Debug: Executing "/usr/bin/ld" with command line "-b elf64-x86-64 -m elf_x86_64 --dynamic-linker=/lib64/ld-linux-x86-64.so.2 -L. -o {pathToTargetExeFile} -T {pathToScript} -e _start"
I'd throw in (after a few minutes playing) that on Linux Lazarus Options -> Compiler Options -> Custom Options -> All Options ... gives you a checkbox for -sh ....Great to know, thanks. I wish I knew, my post would be much shorter :)
I can confirm that for sh/st options the res file is exactly the same as the one that is created and deleted without it.
I can confirm that for sh/st options the res file is exactly the same as the one that is created and deleted without it. Also the shell script generated by fpc works when executed on another machine (providing other necessary steps were made). It links and aslo extracts debug symbols (if necessary) and strips. The only difference I noticed between sh and st (shell for target linking) options is that latter uses the tool executable names without full paths, probably assuming that the tools locations might be different.
-sh -> Script for linking on host
-st -> Script for linking on target
That's why there are differences.
> (GLIBC_2.2.5) dlsym
(GLIBC_2.34) dlerror | (GLIBC_2.2.5) dlclose
(GLIBC_2.34) dlopen <
(GLIBC_2.34) dlclose <
(GLIBC_2.34) __libc_start_main | (GLIBC_2.2.5) dlerror
(GLIBC_2.34) dlsym <
> (GLIBC_2.2.5) dladdr
> (GLIBC_2.2.5) dlopen
(GLIBC_2.34) dladdr | (GLIBC_2.2.5) __libc_start_main
the status quo: sending someone a program file that simply does not run, is a bit of a disaster. i feel we should be able to do better.
... is there not surely some simple way to pick up the library file: /lib/x86_64-linux-gnu/libc-2.27.so and place it where the linker will find and make use of it?There is not a proficiency present in the compiler / build system that I am aware of.
the status quo: sending someone a program file that simply does not run, is a bit of a disaster. i feel we should be able to do better.As said, FPC is not the only compiler having to deal with this issue (more accurate: the dev using the compiler)
wget https://ftp.gnu.org/gnu/glibc/glibc-2.2.5.tar.gz
tar -xvzf glibc-2.2.5.tar.gz
cd glibc-2.2.5
mkdir build
cd build
../configure --prefix=~/opt/glibc-2.2.5 #or wherever you prefer
make -j8 #or however many procs you have
make install #add sudo if you don't have write privileges like to /usr/local in prefix
Then in C++ you want to use -Wl,--rpath=~/opt/glibc-2.2.5 and -Wl,--dynamic-linker=~/opt/glibc-2.2.5/ld-linux.so.2.27. I'm not sure how you set those in FPC.
Warning: Only one source file supported, changing source file to compile from "~/pascal/GFXterm 2.1c/libc.so.6" into "project1.lpr"
i've got two copies of the 'good' library file (uplifted from mint 19.3), one named libc.so.6, the other named libc-2.27.so, sitting in my project folder. i've also tried copying these into the lib/x86_64-linux directory of my project. but no luck. it seems that persuading the IDE to allow picking up a library from somewhere other than what it considers to be the correct location is not so easy!
i've tried all combinations of -Fl, -Xr and -FD plugged into the Custom Options field in the IDE, but the result when compiling is always much the same:That is strange (or I am extremely lucky).Code: [Select]Warning: Only one source file supported, changing source file to compile from "~/pascal/GFXterm 2.1c/libc.so.6" into "project1.lpr"
i've got two copies of the 'good' library file (uplifted from mint 19.3), one named libc.so.6, the other named libc-2.27.so, sitting in my project folder. i've also tried copying these into the lib/x86_64-linux directory of my project. but no luck. it seems that persuading the IDE to allow picking up a library from somewhere other than what it considers to be the correct location is not so easy!
i've tried all combinations of -Fl, -Xr and -FD plugged into the Custom Options field in the IDE, but the result when compiling is always much the same:Code: [Select]Warning: Only one source file supported, changing source file to compile from "~/pascal/GFXterm 2.1c/libc.so.6" into "project1.lpr"
i've got two copies of the 'good' library file (uplifted from mint 19.3), one named libc.so.6, the other named libc-2.27.so, sitting in my project folder. i've also tried copying these into the lib/x86_64-linux directory of my project. but no luck. it seems that persuading the IDE to allow picking up a library from somewhere other than what it considers to be the correct location is not so easy!
an idea that did occur: could one be tricky and create a 'fake' dynamic library containing just the 6 offending symbols, convincing lazarus that the symbols are not part of the operating system? this library does not need to be functional, just provide the symbols and links that go either nowhere or to empty routines. the fake library would serve purely to 'guide' the compiling/linking process, and would be deleted/removed/renamed once that is finished.
btw: i am far from a linux expert, but i do usually manage to muddle my way through!
cheers,
rob :-)
Maybe not related but, fpc using "external", does not allow "extended" so extension ( libc.so.6 vs libc.so ).
You may try using a symlink libc.so with target libc.so.6.
I find it hard to believe that its not easier (and safer) to have a VM setup
Maybe not related but, fpc using "external", does not allow "extended" so extension ( libc.so.6 vs libc.so ).
You may try using a symlink libc.so with target libc.so.6.
Compile Project, Mode: Release, Target: project1: Exit code 1, Errors: 1, Hints: 4
Hint: Start of reading config file /etc/fpc.cfg
Hint: End of reading config file /etc/fpc.cfg
unit1.pas(216,7) Hint: Local const "SoftwareKey" is not used
unit1.pas(365,7) Note: Local variable "CPC" not used
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `lstat64@GLIBC_2.33'
linker: /usr/bin/ld: /lib/x86_64-linux-gnu/libmount.so.1: undefined reference to `fstatat@GLIBC_2.33'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_rwlock_trywrlock@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_rwlock_wrlock@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `dlinfo@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `pthread_mutexattr_init@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `fcntl64@GLIBC_2.28'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `stat64@GLIBC_2.33'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `pthread_create@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `close_range@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `lstat@GLIBC_2.33'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `dlclose@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_rwlock_tryrdlock@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_detach@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_setname_np@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_key_delete@GLIBC_2.34'
linker: /usr/bin/ld: /lib/x86_64-linux-gnu/libselinux.so.1: undefined reference to `gettid@GLIBC_2.30'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `dlsym@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_rwlock_unlock@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_setspecific@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `dlopen@GLIBC_2.34'
linker: /usr/bin/ld: /lib/x86_64-linux-gnu/libgio-2.0.so.0: undefined reference to `statx@GLIBC_2.28'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `fstat64@GLIBC_2.33'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_rwlock_init@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_sigmask@GLIBC_2.32'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `dlerror@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_getspecific@GLIBC_2.34'
linker: /usr/bin/ld: /lib/x86_64-linux-gnu/libgio-2.0.so.0: undefined reference to `dn_expand@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `pthread_mutex_trylock@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `pthread_mutexattr_destroy@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_attr_setstacksize@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `pthread_join@GLIBC_2.34'
linker: /usr/bin/ld: /lib/x86_64-linux-gnu/libgio-2.0.so.0: undefined reference to `res_nquery@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `pthread_mutexattr_settype@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_rwlock_rdlock@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `stat@GLIBC_2.33'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `fstat@GLIBC_2.33'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `pthread_once@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `dladdr@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_rwlock_destroy@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_key_create@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `dladdr1@GLIBC_2.34'
project1.lpr(24,1) Error: Error while linking
That is strange (or I am extremely lucky).
[...]
Have you tried to look at what adding the FPC option -k--trace produces for you ?
i suspect you are extremely lucky! i'm picking that it is dependent on when everything else on your system was built and what versions of various libraries were present at that time.Sorry I thought it was clear from fredvs' comment. I placed the literal named file "libc.so" in my build directory. and end up with your result.
using the lazarus IDE, where can "-k--trace" be inserted? i have never tried using FPC at the commandline to build one of my projects.Lazarus has a special linker section for that in your project options.
Sorry I thought it was clear from fredvs' comment. I placed the literal named file "libc.so" in my build directory. and end up with your result.
A file or a symlink?Literally a file. But because you asked I tried that with a symlink as well -> works.
$ ldd --version ldd
ldd (Ubuntu GLIBC 2.35-0ubuntu3.1) 2.35
$ mkdir build
$ cd build
$ ../configure --prefix=/tmp/glibc-2.36
$ make
$ make install
$ cat hello.c
#include <stdio.h>
int main(void) {
printf("hello\n");
return 0;
}
$ g++ -Xlinker -Map=b.map -o xhello -static -L /tmp/glibc-2.36/lib -I /tmp/glibc-2.36/include -Wl,--rpath=/tmp/glibc-2.36/lib -Wl,--dynamic-linker=/tmp/glibc-2.36/lib/ld-linux-x86-64.so.2 hello.c
$ more b.map
Archive member included to satisfy reference by file (symbol)
/tmp/glibc-2.36/lib/libc.a(libc-start.o)
/usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-l
inux-gnu/crt1.o (__libc_start_main)
/tmp/glibc-2.36/lib/libc.a(check_fds.o)
/tmp/glibc-2.36/lib/libc.a(libc-start.o) (__libc_c
heck_standard_fds)
/tmp/glibc-2.36/lib/libc.a(libc-tls.o)
...
$ cd /tmp
$ mv glibc-2.36 noglibc-2.36
$ ls -ld glibc-2.36
ls: cannot access 'glibc-2.36': No such file or directory
$ ./xhello
hello
...
I built a different version of glibc into /tmp/glibc-2.36Code: [Select]$ mkdir build
$ cd build
$ ../configure --prefix=/tmp/glibc-2.36
$ make
$ make install
$ sudo apt-get download regina-rexx
It will save the package to your CWD.$ ar x regina-rexx_3.6-2.4_amd64.deb
$ ls
control.tar.xz data.tar.xz debian-binary regina-rexx_3.6-2.4_amd64.deb
$ unxz data.tar.xz
$ tar -xvf data.tar
./
./usr/
./usr/bin/
./usr/bin/regina
./usr/bin/rexx
./usr/bin/rxqueue
./usr/bin/rxstack
...
$ cd usr/bin
$ rexx --version
Regina REXX-Regina_3.6 5.00 31 Dec 2011. All rights reserved.
Regina is distributed under the terms of the GNU Library Public License
and comes with NO WARRANTY. See the file COPYING-LIB for details.
To run a Rexx program:
./rexx [-h?vrt[ir]ap] program [arguments...]
...
A file or a symlink?Literally a file. But because you asked I tried that with a symlink as well -> works.
...
Hopefully that is what you're looking for?
- you probably only need to add "--trace" (without quotes) to the edit box
Hint: (11030) Start of reading config file /etc/fpc.cfg
Hint: (11031) End of reading config file /etc/fpc.cfg
Free Pascal Compiler version 3.2.0 [2020/07/07] for x86_64
Copyright (c) 1993-2020 by Florian Klaempfl and others
(1002) Target OS: Linux for x86-64
(3104) Compiling project1.lpr
(3104) Compiling unit1.pas
(3104) Compiling unit2.pas
[...]
(3104) Compiling unit3.pas
[...]
(3104) Compiling unit4.pas
[...]
(3104) Compiling unit5.pas
[...]
(9022) Compiling resource /home/user/pascal/GFXterm 2.1c/lib/x86_64-linux/project1.or
(9015) Linking /home/user/pascal/GFXterm 2.1c/project1
/usr/lib/x86_64-linux-gnu/crti.o
/usr/lib/gcc/x86_64-linux-gnu/9/crtbeginS.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/si_c.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/abitag.o
/home/user/pascal/GFXterm 2.1c/lib/x86_64-linux/project1.o
/home/user/pascal/GFXterm 2.1c/lib/x86_64-linux/project1.or
/usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/system.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/fpintres.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/objpas.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/cthreads.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/interfaces.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/forms.o
/home/user/pascal/GFXterm 2.1c/lib/x86_64-linux/unit1.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/linux.o
[...]
/usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/unixcp.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2disableliboverlay.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2int.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/classes.o
[...]
/usr/lib/fpc/3.2.0/units/x86_64-linux/x11/x.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/gtk2/gdk2x.o
[...]
/usr/lib/fpc/3.2.0/units/x86_64-linux/gtk2/pango.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/lazfileutils.o
[...]
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/lazstringutils.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/dialogs.o
[...]
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/lcltype.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/graphtype.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/graphmath.o
[...]
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2msgqueue.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/x11/xrender.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/cairo/cairo.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/gtk2/atk.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/lazutilsstrconsts.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/fpcadds.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/rtl-objpas/strutils.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-base/gettext.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/lazclasses.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/lazmethodlist.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/laz_avl_tree.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/fgl.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/laztracer.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/lazutilities.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/lresources.o
[...]
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/lcltaskdialog.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/uitypes.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/fileutil.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/rtl-objpas/variants.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/lazconfigstorage.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/dynqueue.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/lazutf8classes.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/rtl-objpas/varutils.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/avglvltree.o
[...]
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/lazsysutils.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-image/fpimage.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/intfgraphics.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-image/fpreadbmp.o
[...]
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-image/fptiffcmn.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/lclversion.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/icnstypes.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-image/fpimgcmn.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-image/pngcomn.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/paszlib/zstream.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/paszlib/zbase.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/paszlib/gzio.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/hash/crc.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/paszlib/zdeflate.o
[...]
/usr/lib/fpc/3.2.0/units/x86_64-linux/paszlib/inffast.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/lazversion.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-base/contnrs.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-image/fpcanvas.o
[...]
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-image/fpreadgif.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/lclrescache.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/wsreferences.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-image/clipping.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/pasjpeg/jpeglib.o
[...]
/usr/lib/fpc/3.2.0/units/x86_64-linux/pasjpeg/jfdctflt.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-base/syncobjs.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/tmschema.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/masks.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-process/process.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-process/pipes.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/termio.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-base/custapp.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/customtimer.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/actnlist.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/helpintfs.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/imglist.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-base/singleinstance.o
[...]
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-image/ellipses.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/wsimglist.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/wsproc.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/wsfactory.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/propertystorage.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-base/rttiutils.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/wsmenus.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/lazlogger.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/chm/fasthtmlparser.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/wsforms.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/imagelistcache.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/textstrings.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/extendedstrings.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/wsstdctrls.o
[...]
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/wstoolwin.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/gtk2/gtk2ext.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/extdlgs.o
[...]
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/lclmemmanager.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2wsprivate.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-base/uriparser.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2wscontrols.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/lazlinkedlist.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2wsfactory.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2wsstdctrls.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2wschecklst.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2themes.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/spin.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/grids.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/pairsplitter.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/wsspin.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-xml/htmldefs.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/maskedit.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/dynamicarray.o
[...]
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/laz2_xmlutils.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/wsgrids.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/wspairsplitter.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2wsbuttons.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2wscalendar.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2wscomctrls.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2wsdialogs.o
/usr/bin/ld: /usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/cthreads.o: in function `CTHREADS_$$_LOADPTHREADS$$BOOLEAN':
cthreads.pp:(.text.n_cthreads_$$_loadpthreads$$boolean+0xe): undefined reference to `dlopen'
/usr/bin/ld: cthreads.pp:(.text.n_cthreads_$$_loadpthreads$$boolean+0x34): undefined reference to `dlsym'
/usr/bin/ld: cthreads.pp:(.text.n_cthreads_$$_loadpthreads$$boolean+0x4e): undefined reference to `dlsym'
/usr/bin/ld: cthreads.pp:(.text.n_cthreads_$$_loadpthreads$$boolean+0x68): undefined reference to `dlsym'
/usr/bin/ld: cthreads.pp:(.text.n_cthreads_$$_loadpthreads$$boolean+0x82): undefined reference to `dlsym'
/usr/bin/ld: cthreads.pp:(.text.n_cthreads_$$_loadpthreads$$boolean+0x9c): undefined reference to `dlsym'
/usr/bin/ld: /usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/cthreads.o:cthreads.pp:(.text.n_cthreads_$$_loadpthreads$$boolean+0xb6): more undefined references to `dlsym' follow
/usr/bin/ld: /usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/cthreads.o: in function `CTHREADS_$$_UNLOADPTHREADS$$BOOLEAN':
cthreads.pp:(.text.n_cthreads_$$_unloadpthreads$$boolean+0xd): undefined reference to `dlclose'
/usr/bin/ld: /usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/dl.o: in function `DL_$$_UNIXGETMODULEBYADDR$POINTER$POINTER$OPENSTRING':
dl.pp:(.text.n_dl_$$_unixgetmodulebyaddr$pointer$pointer$openstring+0x39): undefined reference to `dladdr'
/usr/bin/ld: /usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/dynlibs.o: in function `DYNLIBS_$$_SYSLOADLIBRARYA$RAWBYTESTRING$$INT64':
dynlibs.pas:(.text.n_dynlibs_$$_sysloadlibrarya$rawbytestring$$int64+0x17): undefined reference to `dlopen'
/usr/bin/ld: /usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/dynlibs.o: in function `DYNLIBS_$$_SYSGETPROCEDUREADDRESS$INT64$ANSISTRING$$POINTER':
dynlibs.pas:(.text.n_dynlibs_$$_sysgetprocedureaddress$int64$ansistring$$pointer+0x12): undefined reference to `dlsym'
/usr/bin/ld: /usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/dynlibs.o: in function `DYNLIBS_$$_SYSUNLOADLIBRARY$INT64$$BOOLEAN':
dynlibs.pas:(.text.n_dynlibs_$$_sysunloadlibrary$int64$$boolean+0x6): undefined reference to `dlclose'
/usr/bin/ld: /usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/dynlibs.o: in function `DYNLIBS_$$_SYSGETLOADERRORSTR$$SHORTSTRING':
dynlibs.pas:(.text.n_dynlibs_$$_sysgetloaderrorstr$$shortstring+0xd): undefined reference to `dlerror'
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2wsextctrls.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2wsextdlgs.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2wsforms.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2wsgrids.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2wsimglist.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2wsmenus.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2wsspin.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2wspairsplitter.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/unitywsctrls.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2cellrenderer.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2listviewtreemodel.o
/home/user/pascal/GFXterm 2.1c/lib/x86_64-linux/unit2.o
/home/user/pascal/GFXterm 2.1c/lib/x86_64-linux/unit3.o
/home/user/pascal/GFXterm 2.1c/lib/x86_64-linux/unit4.o
/home/user/pascal/GFXterm 2.1c/lib/x86_64-linux/unit5.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/lconvencoding.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/dos.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/strings.o
/usr/lib/x86_64-linux-gnu//libpthread.a
/usr/lib/x86_64-linux-gnu//libasound.so
/usr/lib/x86_64-linux-gnu//libdl.a
/usr/lib/x86_64-linux-gnu//libgdk-x11-2.0.so
/usr/lib/x86_64-linux-gnu//libX11.so
/usr/lib/x86_64-linux-gnu//libgdk_pixbuf-2.0.so
/usr/lib/x86_64-linux-gnu//libgtk-x11-2.0.so
/usr/lib/x86_64-linux-gnu//libgobject-2.0.so
/usr/lib/x86_64-linux-gnu//libglib-2.0.so
/usr/lib/x86_64-linux-gnu//libgthread-2.0.so
/usr/lib/x86_64-linux-gnu//libgmodule-2.0.so
/usr/lib/x86_64-linux-gnu//libpango-1.0.so
/usr/lib/x86_64-linux-gnu//libcairo.so
/usr/lib/x86_64-linux-gnu//libatk-1.0.so
./libc.so
/usr/lib/gcc/x86_64-linux-gnu/9/crtendS.o
/usr/lib/x86_64-linux-gnu/crtn.o
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `lstat64@GLIBC_2.33'
/usr/bin/ld: /lib/x86_64-linux-gnu/libmount.so.1: undefined reference to `fstatat@GLIBC_2.33'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_rwlock_trywrlock@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_rwlock_wrlock@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `dlinfo@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `pthread_mutexattr_init@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `fcntl64@GLIBC_2.28'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `stat64@GLIBC_2.33'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `pthread_create@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `close_range@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `lstat@GLIBC_2.33'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `dlclose@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_rwlock_tryrdlock@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_detach@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_setname_np@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_key_delete@GLIBC_2.34'
/usr/bin/ld: /lib/x86_64-linux-gnu/libselinux.so.1: undefined reference to `gettid@GLIBC_2.30'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `dlsym@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_rwlock_unlock@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_setspecific@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `dlopen@GLIBC_2.34'
/usr/bin/ld: /lib/x86_64-linux-gnu/libgio-2.0.so.0: undefined reference to `statx@GLIBC_2.28'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `fstat64@GLIBC_2.33'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_rwlock_init@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_sigmask@GLIBC_2.32'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `dlerror@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_getspecific@GLIBC_2.34'
/usr/bin/ld: /lib/x86_64-linux-gnu/libgio-2.0.so.0: undefined reference to `dn_expand@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `pthread_mutex_trylock@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `pthread_mutexattr_destroy@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_attr_setstacksize@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `pthread_join@GLIBC_2.34'
/usr/bin/ld: /lib/x86_64-linux-gnu/libgio-2.0.so.0: undefined reference to `res_nquery@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `pthread_mutexattr_settype@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_rwlock_rdlock@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `stat@GLIBC_2.33'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `fstat@GLIBC_2.33'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `pthread_once@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `dladdr@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_rwlock_destroy@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_key_create@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `dladdr1@GLIBC_2.34'
/home/user/pascal/GFXterm 2.1c/project1.lpr(24,1) Error: (9013) Error while linking
/home/user/pascal/GFXterm 2.1c/project1.lpr(24,1) Fatal: (10026) There were 1 errors compiling module, stopping
Fatal: (1018) Compilation aborted
Error: /usr/bin/ppcx64 returned an error exitcode
- you probably only need to add "--trace" (without quotes) to the edit box
Are you talking about the trick to use -Fl, -Xr, Xd and -FD and symlink without extended number extension?I am saying that I am investigating if the normal route can be made shorter (meaning that I can compile the required libraries myself instead of the need to copy them over from an older system) and see if it can be done in a bit more civil manner (other then sysrooting etc)).
And saying it works for you?
Even better, give in attachment the zipped files of old libc.so.6 and other files needed for linking?I have no problem zipping up the libraries from an older (debian) system and make them available. But why rely on someone else ? I do not even trust myself ;D
;)
is this the output you are after? my apologies for it being so long, you'll see i needed to trim it before the forum software would let me post it!Thank you for having posted your output.
i'm thinking more again about a 'fake' libc.so, no functioning code (or just stubs if needsbe) but the necessary symbols to keep the linker happy. one could then within it have defined the necessary minimum version numbers to match the requirements of your project.Yes, also a possibility according to some online posts but do note that other report that this also could give issues (It goes out of scope for me to repeat those issues here as most go beyond my technical understanding)
what the linker does NOT know, however, is the minimum versions are for the your project it has just built. for instance, it might be imposing dlopen@GLIBC_2.34 based upon data it has gleaned from libc.so, but your project may only be making use of dlopen functionality that has been present since the 2.1.0 version.Yes, that is how I understand things to be/work as well.
or are you after the file link.res?That is indeed another step in the process to determine what the linker actually does.
[...]
edit: I had a closer look. Yes, it seems to pickup on the correct libc. That raises the following question: did you have the units recompiled using the "other" libc ? Note that I am currently facing the exact same issue and am trying to wrap my head around the removal of phthread from libc (in theory it should not matter but afaik you would need to compile/link against libpthreads as well).
So, please be careful :)
I have no idea why you seem unable to delete the file(s) as shown
[...]
Also note that Lazarus version 2.0.12 is /very/ old (read officially unsupported)
Are you talking about the trick to use -Fl, -Xr, Xd and -FD and symlink without extended number extension?I am saying that I am investigating if the normal route can be made shorter (meaning that I can compile the required libraries myself instead of the need to copy them over from an older system) and see if it can be done in a bit more civil manner (other then sysrooting etc)).
And saying it works for you?
so much for the being able to 'compile once, run anywhere' that windows gave us!I'm currently a bit busy to be able to write a elaborated response but as a quick note: you can always compile Free Pascal and Lazarus manually from source (it isn't that difficult to do) or use FPCDeluxe (https://wiki.freepascal.org/fpcupdeluxe) to do it for you.
I'm currently a bit busy to be able to write a elaborated response but as a quick note: you can always compile Free Pascal and Lazarus manually from source (it isn't that difficult to do) or use FPCDeluxe (https://wiki.freepascal.org/fpcupdeluxe) to do it for you.
there is also another problem to consider - lazarus 2.2.6 won't run on all older linux distros >:(
...
so much for the being able to 'compile once, run anywhere' that windows gave us!
.....
is this perhaps a bug/oversight in lazarus - when trying to delete files in places like /usr/share lazarus should surely be wrapping it in a sudo? not a problem that crops up under windows i'd imagine, so maybe no one has tried/tested it under linux.
Removing version info post-link is infeasible -- these strings are entered into hash tables, and rebuilding these hash tables is too complicated a thing to do with objcopy.
What you want to do is create a stub libssl.so.10 with DT_SONAME set to libssl.so.10, which defines all the symbols you need from it, but without any version info. For example, this would do if you only needed the SSL_new symbol:Code: [Select]echo "void SSL_new() { }" > t.c &&
gcc -fPIC -shared -o libssl.so -Wl,--soname='libssl.so.10' t.c
Now link your program against this stub library, and it will not require any versioned symbols.
The runtime linker will then satisfy this undefined unversioned SSL_new with SSL_new@libssl.so.10 on CentOS, and with SSL_new@Base on CloudLinux.
gcc -fPIC -shared -o libc.so -Wl,--soname='libc.so.6' test.c
Compile Project, Mode: Release, Target: project1: Exit code 1, Errors: 1
project1.lpr(24,1) Error: Error while linking
QuoteWhat you want to do is create a stub libssl.so.10 with DT_SONAME set to libssl.so.10, which defines all the symbols you need from it,
Date | Release |
2021-08-02 | GLIBC 2.34 |
2012-03-21 | GLIBC 2.15 |
2002-01-20 | GLIBC 2.2.5 |
Robert, please look back on page one of this thread. As usual, PascalDragon's posts are authoritative.
Davo
...
Distros that cannot make a binary to run on systems with 'earlier' libc6 -
- U21.04 - 2.33
- U21.10 - 2.34 (Impish)
- U22.04 - 2.35 (Jammy)
- Linux Mint 21.1
- Debian Bookworm - 2.36 (release in a few months)
...
.......
Note too that those distros accept only some libraries compiled on those last distros.
For example, the library libsndfile.so from earlier distros cannot be used in the last distros mentioned ( and libsndfile.so from last distros does not work on previous distros), so no solution of backward compatibility here.
Hum, I am not sure I like what the core-dev of Linux have done recently.
Fre;D
Fred, I don't think anyone ever suggested that every Library is forward compatible. That would be quite impossible because the new system would not find the new functions in old library that it expects, functions that had not been thought of when the older version of the library was made.
A library is expected to be backwards compatible, that is, offer the same services as a earlier version did. Generally, a binary application is expected to be forward compatible, it should run on future systems (because the libraries on that future system are backwards compatible).
In this situation, we asking for our binary application to be backward compatible and its NOT. Its an absolute pain in what you sit on and I desperately wish it had not be allowed to happen but it did happen. And its entirely reasonable that it might happen again in the future.
But for more than 10 years now, libsndfile.so was backward compatible, a older libsndfile.so can be used in newer distros.
But for more than 10 years now, libsndfile.so was backward compatible, a older libsndfile.so can be used in newer distros.
But that's not the definition of backwards compatibility. That's the definition of forwards compatibility.
As long as the new DLL in the new OS still runs programs that were compiled previously, which reference the old DLL, and they still work when you run that old binary on the new OS, then you have backwards compatibility.
That's not what appears to be in place here. If the app is compiled with the new version is cannot be run, after the fact, on the old version of the OS. That's not a backwards compatibility issue.
Robert - https://forum.lazarus.freepascal.org/index.php/topic,58888.msg442518.html#msg442518 but you are more than welcome to dig your Windows CD out of the bottom drawer. I wonder what version of Windows it is ?
The issue is that newer libcs have a versioned symbol and according to the ELF spec when a symbol that has a version attached is used then this needs to be referenced as such in the ELF binary so that the dynamic linker can then resolve this using the correct version of the symbol, this implicitly also means that if you try to run a binary that uses such a versioned symbol on a system where the corresponding library does not have this symbol with the suitable version (or none at all) then the binary simply won't load. It's as if you'd use a symbol that doesn't exist at all.
But for more than 10 years now, libsndfile.so was backward compatible, a older libsndfile.so can be used in newer distros.
But that's not the definition of backwards compatibility. That's the definition of forwards compatibility.
As long as the new DLL in the new OS still runs programs that were compiled previously, which reference the old DLL, and they still work when you run that old binary on the new OS, then you have backwards compatibility.
That's not what appears to be in place here. If the app is compiled with the new version is cannot be run, after the fact, on the old version of the OS. That's not a backwards compatibility issue.
Ha, ok, clear now, thanks.
What I wanted to note ( how to call this ? ) is that before those last distros mentioned, programs that dynamically loaded libraries with "loadlibrary()" could load older libraries on new distros.
It is not the case for some libraries with those last distros mentioned.
without binary application compatibility, linux on the desktop will die. or everything will be written in python.
without binary application compatibility, linux on the desktop will die. or everything will be written in python.
libsndfile.soBut Fred, why not just use the newer version of the library, as the distro builders intend ? You use Debian, in Bullseye its 1.0.31-2 and in the forthcoming Bookworm, its 1.2.0-1. Its there and its the one that Debian will have subjected to extensive testing.
...
What I wanted to note ( how to call this ? ) is that before those last distros mentioned, programs that dynamically loaded libraries with "loadlibrary()" could load older libraries on new distros.
It is not the case for some libraries with those last distros mentioned.
........Yes, to some degree that is the case. It must, over time, happen. What is surprising really is not that there is an non-backward compatibility issue right now, when you think about it, we should be surprised its worked at all over the last few years. No one has ever set that backward compatibility requirement in an application as a requirement or a guarantee or even a performance measure. We were, for a few years, lucky !
i also understand why this is likely being done, it is an attempt to shed some of the load of maintaining backward compatibility. ....
Sorry Robert, but that is, frankly, nonsense. * The vast majority of linux application code people use comes from the distribution's repo. Its built from source provided by developers but, importantly, its built using the forerunner of that distribution release. There is no forward or backward comparability issues.
without binary application compatibility, linux on the desktop will die. or everything will be written in python.
libsndfile.soBut Fred, why not just use the newer version of the library, as the distro builders intend ? You use Debian, in Bullseye its 1.0.31-2 and in the forthcoming Bookworm, its 1.2.0-1. Its there and its the one that Debian will have subjected to extensive testing.
...
What I wanted to note ( how to call this ? ) is that before those last distros mentioned, programs that dynamically loaded libraries with "loadlibrary()" could load older libraries on new distros.
It is not the case for some libraries with those last distros mentioned.
Davo
Sorry Robert, but that is, frankly, nonsense. * The vast majority of linux application code people use comes from the distribution's repo. Its built from source provided by developers but, importantly, its built using the forerunner of that distribution release. There is no forward or backward comparability issues.
(*) sorry if I have offended with use of word 'nonsense' but it does annoy me when people say "unless {insert mildly annoying issue} is fixed, the world will end". The fact is, its entirely manageable. Annoying but manageable !
I wonder what version of Windows it is ?
......
this leaves limited options open - and the further i dig, the less confidence i have that building binaries on an old distro is a good long-term solution. i get the feeling that window is slowly closing.
....
for generating win32 applications i use an XP VM.
Jeremy Andrews 9 months ago
It's worth noting that this change breaks some older applications that were compiled against glibc earlier than 2.34. It's very hit and miss, but I have encountered older applications that don't work at all on 2.34 and work fine on 2.33, and any kind of attempt to debug shows that things are getting gummed up in futex-internal or that pthread_mutex_lock isn't working. Mostly it seems to happen where stack protection is involved.
/media/ramdisk/fpc$ fpc -B -k--library-path="/media/ramdisk/fpc/linklibs" -k--trace threadtest.pas
Free Pascal Compiler version 3.2.2 [2021/05/16] for x86_64
Copyright (c) 1993-2021 by Florian Klaempfl and others
Target OS: Linux for x86-64
Compiling threadtest.pas
threadtest.pas(81,21) Warning: Conversion between ordinals and pointers is not portable
threadtest.pas(85,8) Warning: Local variable "s" of a managed type does not seem to be initialized
threadtest.pas(86,23) Warning: Conversion between ordinals and pointers is not portable
threadtest.pas(89,21) Warning: Conversion between ordinals and pointers is not portable
threadtest.pas(101,24) Warning: Conversion between ordinals and pointers is not portable
Linking threadtest
/usr/lib/x86_64-linux-gnu/crti.o
/usr/lib/gcc/x86_64-linux-gnu/12/crtbegin.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/si_c.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/abitag.o
threadtest.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/system.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/cthreads.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/sysutils.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/objpas.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/linux.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/baseunix.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/unix.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/unixtype.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/initc.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/dl.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/unixutil.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/ctypes.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/errors.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/sysconst.o
/media/ramdisk/fpc/linklibs/libpthread.so
/media/ramdisk/fpc/linklibs/libdl.so
/media/ramdisk/fpc/linklibs/libc.so
/usr/lib/gcc/x86_64-linux-gnu/12/crtend.o
/usr/lib/x86_64-linux-gnu/crtn.o
/usr/bin/ld: /media/ramdisk/fpc/linklibs/libpthread.so: undefined reference to `_dl_make_stack_executable@GLIBC_PRIVATE'
threadtest.pas(104,1) Error: Error while linking
threadtest.pas(104,1) Fatal: There were 1 errors compiling module, stopping
Fatal: Compilation aborted
Error: /home/apps/fpc/3.2.2/bin/x86_64-linux/ppcx64 returned an error exitcode
And that is where I get stuck. ld-linux-x86-64.so.2 needed by /media/ramdisk/fpc/linklibs/libpthread.so.0
attempt to open /usr/lib/x86_64-linux-gnu/libfakeroot/ld-linux-x86-64.so.2 failed
attempt to open /usr/local/lib/i386-linux-gnu/ld-linux-x86-64.so.2 failed
attempt to open /lib/i386-linux-gnu/ld-linux-x86-64.so.2 failed
attempt to open /usr/lib/i386-linux-gnu/ld-linux-x86-64.so.2 failed
attempt to open /usr/local/lib/i686-linux-gnu/ld-linux-x86-64.so.2 failed
attempt to open /lib/i686-linux-gnu/ld-linux-x86-64.so.2 failed
attempt to open /usr/lib/i686-linux-gnu/ld-linux-x86-64.so.2 failed
attempt to open /usr/local/lib/ld-linux-x86-64.so.2 failed
attempt to open /usr/local/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 failed
found ld-linux-x86-64.so.2 at /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
I have tried all 3 (together as well):/* GNU ld script
Use the shared library, but some functions are only in
the static library, so try that secondarily. */
OUTPUT_FORMAT(elf64-x86-64)
GROUP ( /media/ramdisk/fpc/linklibs/libpthread.so.0 /media/ramdisk/fpc/linklibs/libpthread_nonshared.a /media/ramdisk/fpc/linklibs/ld-linux-x86-64.so.2)
Copied required files from squeeze to bookworm linklibs directoryfpc -B -XR/media/ramdisk/fpc/linklibs -k--library-path="/media/ramdisk/fpc/linklibs" -k--trace -Fl"/media/ramdisk/fpc/linklibs" -k-L/media/ramdisk/fpc/linklibs/lib64 threadtest.pas
which outputs:Free Pascal Compiler version 3.2.2 [2021/05/16] for x86_64
Copyright (c) 1993-2021 by Florian Klaempfl and others
Target OS: Linux for x86-64
Compiling threadtest.pas
threadtest.pas(81,21) Warning: Conversion between ordinals and pointers is not portable
threadtest.pas(85,8) Warning: Local variable "s" of a managed type does not seem to be initialized
threadtest.pas(86,23) Warning: Conversion between ordinals and pointers is not portable
threadtest.pas(89,21) Warning: Conversion between ordinals and pointers is not portable
threadtest.pas(101,24) Warning: Conversion between ordinals and pointers is not portable
Linking threadtest
./linklibs/crti.o
./linklibs/crtbegin.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/si_c.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/abitag.o
threadtest.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/system.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/cthreads.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/sysutils.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/objpas.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/linux.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/baseunix.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/unix.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/unixtype.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/initc.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/dl.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/unixutil.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/ctypes.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/errors.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/sysconst.o
/media/ramdisk/fpc/linklibs/libpthread.so
/media/ramdisk/fpc/linklibs/libpthread.so.0
/media/ramdisk/fpc/linklibs/libpthread_nonshared.a
/media/ramdisk/fpc/linklibs/ld-linux-x86-64.so.2
/media/ramdisk/fpc/linklibs/libpthread_nonshared.a
/media/ramdisk/fpc/linklibs/libdl.so
/media/ramdisk/fpc/linklibs/libc.so
./linklibs/crtend.o
./linklibs/crtn.o
/usr/bin/ld: warning: threadtest has a LOAD segment with RWX permissions
104 lines compiled, 0.1 sec
5 warning(s) issued
./threadtest
./threadtest: /lib/libc.so.6: version `GLIBC_2.34' not found (required by ./threadtest)
thread 6 started
thread 6 thri 0 Len(S)= 1
thread 6 thri 1 Len(S)= 2
thread 6 thri 2 Len(S)= 3
thread 6 thri 3 Len(S)= 4
thread 6 thri 4 Len(S)= 5
thread 6 thri 5 Len(S)= 6
thread 6 thri 6 Len(S)= 7
thread 6 thri 7 Len(S)= 8
thread 6 thri 8 Len(S)= 9
threathread 8 started
...
thread 1 thri 998 Len(S)= 999
thread 1 thri 999 Len(S)= 1000
thread 1 finished
10
Thus successful, except perhaps for the part that the libpthread linker script needs to be (manually) adjusted. At least you have to do that only once and you would need to set things up anyhow.... and here is an even simpler variation that does not require making any changes to the FPC RTL, however it does leave all six of the symbols unversioned in your application's Dynamic Symbol Table. i am undecided if this is, or is not, a bad thing.
...
Hum, about __libc_start_main(), does anybody knows when it is called? (apart in si_g.inc and si_c.inc there are methods that call __libc_start_main() but that methods are never used, nor in fpc, rtl or Lazarus, afaik).
Hum, about __libc_start_main(), does anybody knows when it is called? (apart in si_g.inc and si_c.inc there are methods that call __libc_start_main() but that methods are never used, nor in fpc, rtl or Lazarus, afaik).
These are the entrypoints of the generated ELF binaries and they call __libc_start_main to initialize the C library.
Hum, about __libc_start_main(), does anybody knows when it is called? (apart in si_g.inc and si_c.inc there are methods that call __libc_start_main() but that methods are never used, nor in fpc, rtl or Lazarus, afaik).
These are the entrypoints of the generated ELF binaries and they call __libc_start_main to initialize the C library.
Ha, ok, thanks (not sure to understand, so it is not called by fpc but systematically by the entrypoints of the ELF ? :-\)
Hum, about __libc_start_main(), does anybody knows when it is called? (apart in si_g.inc and si_c.inc there are methods that call __libc_start_main() but that methods are never used, nor in fpc, rtl or Lazarus, afaik).
These are the entrypoints of the generated ELF binaries and they call __libc_start_main to initialize the C library.
Ha, ok, thanks (not sure to understand, so it is not called by fpc but systematically by the entrypoints of the ELF ? :-\)
It's what is called by either the OS or the dynamic loader (depending on whether it's a dynamic binary or not) and what is located in the ELF binary's entrypoint field.
May I ask your thinking about the solution of Robert?
May I ask your thinking about the solution of Robert?
We are not interested in such solutions. The current way is how code/binaries are supposed to behave on Linux and we'll not change that.
:D, I am so surprised!It was clear before even 'targeting' this issue that it will not find it's way back to the FPC source-tree. And that is not so strange as it is Linux itself who provided us with this mess. So the thing that FPC needs to do (at a minimum) is follow the lead.
OK, thanks for that deep thinking.
So the thing that FPC needs to do (at a minimum) is follow the lead.
But that is the magical of Robert solution!I think you misunderstood. Robert's solution most definitely requires for Free Pascal source-code to be touched.
No touch to FPC code, let FPC do his right and perfectly understood way.
Not a single unit from FPC is changed, nor in RTL nor in Lazarus.Ah, and where do you think those include-files that Robert proposes to be changed actually get included ? If you guessed the Free Pascal RTL then your are correct. That requires a complete rebuilt of all your units and compiler. They can not be used interchangeable with non patched units.
Linking with your custom libdl.c works well.
In my case, I needed few more extras:
void openlog() { }
void closelog() { }
void syslog() { }
void sysconf() { }
If above added, the cross-compiled fpcupdeluxe linux binary is fully GLIBC-unversioned !
It is just what it is and if not mistaken you've dealt with such things in the past before (mse etc).
Robert, do you want to write a Wiki page, maybe called, simply, "glibc symbols" or something similar?
GLIBC_2.2.5 {
global: dlopen; dlsym; dladdr; dlclose; dlerror;
};
GLIBC_2.2.5 {
*;
};
In the version fileCode: [Select]GLIBC_2.2.5 {
global: dlopen; dlsym; dladdr; dlclose; dlerror;
};
Why not just wildcard it?Code: [Select]GLIBC_2.2.5 {
*;
};
however it does leave all six of the symbols unversioned in your application's Dynamic Symbol Table.A version script has three purposes:
Create a fake libdl.so file using the following libdl.c:
void dlopen() { } void dlsym() { } void dladdr() { } void dlclose() { } void dlerror() { } void __libc_start_main() { }
* Scope reduction
Delete this comment if you want, but I'll never know because I am never coming back here and refuse to let some elitist piece of **** talk down to me.
Hello. About libc.so and symbols table. A signed symbol is for example @GLIBC_2.2.5. What happen if no symbols are assigned. That table is used at linking of programs.
In the context of the GNU C Library (glibc), symbol versions are used to manage changes in the library's interfaces over time. Each symbol in the library is assigned a version, such as "@GLIBC_2.2.5" as you mentioned.
When a program is linked against the glibc, the linker will resolve the symbols used by the program to their corresponding implementations in the library. If a symbol is assigned a specific version, such as "@GLIBC_2.2.5", it means that the program requires that particular version of the symbol or a newer version.
If a symbol is not assigned any version, it means that the program does not have a specific requirement for that symbol's version. In such cases, the linker will link the program to the default version of the symbol provided by the glibc at runtime. This allows the program to work with any compatible version of the symbol.
However, it's important to note that if a program uses a feature or functionality that is only available in a specific version of a symbol, and that version is not provided by the glibc at runtime, the program may fail to run correctly or may encounter compatibility issues.
To summarize, if no version is assigned to a symbol in glibc, the linker will link the program to the default version of the symbol provided by the glibc at runtime.
Does it exist a command parameter for the linker to force to link all the methods unversionned of libc.so and let all other libraries with no change?
Yes, there is a linker option that can be used to force the linker to resolve all symbols without version dependencies. The linker option is called `--version-script` or `-Wl,--version-script`, depending on how it is passed to the linker.
The `--version-script` option allows you to provide a script that specifies the version dependencies for symbols. By default, if no version script is provided, the linker will use the default version script, which includes version dependencies for symbols.
To force the linker to ignore version dependencies and link all symbols unversioned, you can create a version script file that includes a wildcard pattern for symbols and use that as an argument to the `--version-script` option. For example:
```shell
$ ld --version-script=unversioned.lds -o your_program your_object_files.o
```
Here, `unversioned.lds` is a text file containing the version script. You can define a wildcard pattern in the version script to match all symbols, like this:
```
{
global:
*;
};
```
This version script specifies that all symbols should be considered global and can be resolved without version dependencies.
By using this approach, you can override the default version script and force the linker to link all symbols unversioned, effectively ignoring any version dependencies.
Please note that modifying the versioning behavior of symbols should be done with caution, as it may lead to compatibility issues or unexpected behavior in your program. It's important to ensure that your program is compatible with the versions of symbols it is linked against.
And if I want to assign only some methods unsigned in libc.so, for example __libc_start_main
If you want to assign only specific symbols, such as `__libc_start_main`, as unsigned in `libc.so`, while leaving other symbols with their version dependencies intact, you can use a custom version script.
Here's an example of how you can achieve this:
1. Create a version script file, let's call it `libc_custom.lds`, with the following contents:
```text
GLIBC_2.2.5 {
global:
__libc_start_main;
local:
*;
};
```
In this version script, `GLIBC_2.2.5` is an example version, and `__libc_start_main` is the symbol you want to assign as unsigned. All other symbols in `libc.so` are designated as local, which means their version dependencies will be preserved.
2. Then, use the `--version-script` option to specify the custom version script during the linking process:
```shell
$ ld --version-script=libc_custom.lds -o your_program your_object_files.o -lX -lY -lc
```
This will link your program (`your_program`) with `libc.so` (`-lc`), while assigning `__libc_start_main` as unsigned.
.....
I am ashamed. :-[
.....
I am ashamed. :-[
This is, of course, the sort of thing that lead inexorably to the fall of the Roman Empire.
Oh well Fred, as long as you asked ChatGPT for a clear license statement, we could use some of it on a wiki page, its well put together .....
Davo
so this begs the question: if our Lazarus/FPC program has no knowledge of multiple different APIs for some glibc functions (and IF such differing APIs even exist in practice), what purpose does the symbol versioning serve in the context of Lazarus/FPC?!
Symbol versioning was not considered,
The libc RTL was created on FreeBSD, though Linux was only weeks later. Yet later again it was made default on OS X and iirc Solaris. Symbol versioning was not considered, for the simple reason that most difficult calls take structures (stat etc). And Pascal record definition don't automatically change due to linker scripts
FPC [...] and run only where it was compiled (or on exactly the same OS)
btw: i have no idea how to change the linker scripts myself.
Symbol versioning was not considered,
OK so why not use symbol unversioned?
Maybe you could change the slogan with this: FPC write once, compile everywhere and run only where it was compiled (or on exactly the same OS).
With FPC 3.0 to support native resources a linker script was introduced. But that is not RTL, that is the compiler linking backend. You can see in rtl/unix/oscdeclh.inc that the RTL uses all names are undecorated with versioning info.
QuoteMaybe you could change the slogan with this: FPC write once, compile everywhere and run only where it was compiled (or on exactly the same OS).
Incendiary remark, which is pointless and uncalled for.
With FPC 3.0 to support native resources a linker script was introduced. But that is not RTL, that is the compiler linking backend. You can see in rtl/unix/oscdeclh.inc that the RTL uses all names are undecorated with versioning info
Yes, there is a linker option that can be used to force the linker to resolve all symbols without version dependencies. The linker option is called `--version-script` or `-Wl,--version-script`, depending on how it is passed to the linker
[...]
To force the linker to ignore version dependencies and link all symbols unversioned...
In short, get your facts straight, and write a good summary. Linux changes all the time, and you all might have a point. But you do a s****y job in getting it across
Best would be to write a patch to run the system the way you seem fit, and preferably build a binary release with it. Then you can ask around if this improves compatibility
already done, in the form of the libdl.c file i've posted. it works, it solves the problem. the only improvement would be to gain a complete list of libc functions needing to be handled. if the Lazarus/FPC developers wanted to add something to the IDE where the build process automatically created the libdl.so file before linking, linked, then deleted the libdl.so file, then all well and good.Note that at least for Lazarus you are allowed before a build or compilation (but also after) you can invoke a custom exe or script to realize something like that manually yourself. It is not ideal but does make life a bit easier as the option is available. Using a fpc script (or a custom made frontend for fpc) for compilation allow you to do something similar (which then also automatically applies for Lazarus as long as you use the same script).
But you do a shitty job in getting it across.
With FPC 3.0 to support native resources a linker script was introduced. But that is not RTL, that is the compiler linking backend. You can see in rtl/unix/oscdeclh.inc that the RTL uses all names are undecorated with versioning info.
Maybe (dont worry I will deeply study it) but the fact is, at the present, the binary is versioned and makes the binary only usable on the same OS as where it was linked.
QuoteIncendiary remark, which is pointless and uncalled for.
Without fire, you dont move Marco and the remark is maybe pointless and uncalled for but is the reality.
Anyway, start documenting experiences and reproduction, and try to evaluate across the board (not just a few calls and 2 distros)
We got exactly this same discussion several times with glibc vs syscall [...] we were prepared for it, as the -dFPC_USE_LIBC rtl was added for that exact reason
Anyway, start documenting experiences and reproduction, and try to evaluate across the board (not just a few calls and 2 distros)
i am sitting back and waiting for the flood of users reporting their successes and failures :( i assume there are forum members who do actually write programs?!
am i then right in saying that FPC uses syscalls for the majority of functionality, and libc only if there isn't a syscall alternative?
these minority cases (predominantly) being threading and loading libraries (dlopen et al)?
are there realistic alternatives out there to using glibc/libc for threading and loading libraries?
It may be more practical, instead of having an old distro, to have a local file for libc as Robert proposed, that presents as an older version. One could thus control the minimum required version.
This can be an experimental feature, not applied by default. For example, this could be used/toggled when compiling a DEB file for direct download.
This stat record corresponds to a record defined in FreePascal source?
void dlopen() { }
void dlsym() { }
void dladdr() { }
void dlclose() { }
void dlerror() { }
void __libc_start_main() { }
gcc -fPIC -shared -o libdl.so -Wl,--soname='libdl.so.2' libdl.c
fpc -B -k--library-path="/media/ramdisk/patches/robert/fakelibdl" threadtest.pas
fpc -B -k--trace -k--library-path="/media/ramdisk/patches/robert/fakelibdl" threadtest.pas
[...] for Lazarus you are allowed before a build or compilation (but also after) you can invoke a custom exe or script to realize something [...]
...
attached is a 5-page writeup on the current state of things. subject to suggestions and corrections - i'm not 100% sure on many things!
dbannon: would this form a suitable basis for a wiki page?
marcov: is this the sort of summary you were thinking of?
cheers,
rob :-)
dbannon: would this form a suitable basis for a wiki page?
....
...
dbannon: would this form a suitable basis for a wiki page?
....
I think I would present, on the wiki page, the solution first, the supporting information can remain in the PDF, accessible from the forum post. Sadly, most users will want a simple solution that works. Few will read past that.
My guess is that the simple solution will encourage more people to test it, probably find problems so, will need refinement but it is a brilliant start. Once its stable, proven, we'll annoy the developers again !
...
Davo
can these be placed in the fpc.cfg file, so that the script or .exe is invoked for every project without needing to add it via the Lazarus IDE?Sure, no problem.
-k--library-path="/path/where/your/fake/libdl/is/stored"
... to your fpc.cfg file#ifdef usefakelibdl
-k--library-path="/path/where/your/fake/libdl/is/stored"
#endif
which would then allow to compile with FPC -B -dusefakelibdl programname.pas
Or in Lazarus's terms, you can add a define to either your project settings or create special build mode that defines the symbol (by default). Depends a little on your preference.#ifndef FPC_CROSSCOMPILING
#ifdef RELEASE
#ifdef LINUX
#ifdef CPUX64
#ifdef usefakelibdl
-k--library-path="/path/where/your/fake/libdls/are/stored/per/target/$FPCTARGET
#endif
#endif
#endif
#endif
#endif
but it depends a little for which exact situation(s) you want to make use of the fake libdl. I've gone overboard with the checks simply because I would opt using the fakelibdl only for this particular target (and only if you wan it to). Note a) the additional checks and b) the part where an extra directory ($FPCTARGET) is introduced which allows the fake dl library to be target dependent.Jus test for < 2.34Just to humor the idea. How do you suggest doing that when... let's say .. cross-compiling from x86_64 to arm ?
Jus test for < 2.34[...]
All possible solution mentions loading libc and use get_version_number
[...]
and therein lies the problem - you need to load libc in order to get the version number, but you need to know the version number before you load libc!Who would have thought chickens would produce eggs and vice verse :D
i have come up with a solution that can work around thistbh I haven't had the time to investigate further. In theory it should be possible to extract the information form the compiled lib but the main problem is figuring out how is it stored.
also Fred vS has now got a patched version of FPC that can generate GLIBC_2.2.5 versioned binaries without need for fake libraries or any other tricks:Thank you for mentioning that. I had no idea fred was working on that. It should be possible to clean that up a little but note that I'm not that familiar with the compiler internals.
looking at an old linux (Mint 19.3, GLIBC 2.27) it seems there may never have been a libdl.so file or symlink, which leaves me a little surprised that the linux related code in dl.pp ever worked as intended.Magic :D
If you look a bit closer then you'll notice that the dl functions are part of glibc and as such the FPC unit links against libc (on/for certain targets) so that is probably what you have overlooked ?
fpc -va -B -k--trace -k--verbose -k--stats test.pas
when f.e. you have changed the name of the library....you are in for a (output log) treat :)/usr/bin/ld: mode elf_x86_64
attempt to open /home/apps/fpc/3.2.2/units/x86_64-linux/rtl/si_prc.o succeeded
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/si_prc.o
attempt to open /home/apps/fpc/3.2.2/units/x86_64-linux/rtl/abitag.o succeeded
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/abitag.o
attempt to open test.o succeeded
test.o
attempt to open /home/apps/fpc/3.2.2/units/x86_64-linux/rtl/system.o succeeded
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/system.o
attempt to open dl.o succeeded
dl.o
attempt to open ./libdl.so failed
attempt to open ./libdl.a failed
attempt to open /usr/lib/x86_64-linux-gnu//libdl.so failed
attempt to open /usr/lib/x86_64-linux-gnu//libdl.a succeeded
/usr/lib/x86_64-linux-gnu//libdl.a
/usr/bin/ld: dl.o: in function `DL_$$_UNIXGETMODULEBYADDR$POINTER$POINTER$OPENSTRING':
dl.pp:(.text.n_dl_$$_unixgetmodulebyaddr$pointer$pointer$openstring+0x4c): undefined reference to `dladdr'
/usr/bin/ld: link errors found, deleting executable `test'
[0.031] Executing "/usr/bin/ld" with command line "-b elf64-x86-64 -m elf_x86_64 --trace --verbose --stats --dynamic-linker=/lib64/ld-linux-x86-64.so.2 -L. -o test -T link12679.res -e _dynamic_start"
[0.047] test.pas(6,1) Error: Error while linking
[0.047] test.pas(6,1) Fatal: There were 1 errors compiling module, stopping
[0.047] Fatal: Compilation aborted
Error: /home/apps/fpc/3.2.2/bin/x86_64-linux/ppcx64 returned an error exitcode
is my understanding of how external works wrong? is it that FPC simply can not see a library file that ends in .so.2 (or any other number)? i've had a hard time finding any useful documentation for external.Correct. To my knowledge FPC does not search for such an extension. Even stronger if you specify it in your header then the compiler simply ignores it (by overwriting the extension with .so). You can try it yourself now knowing how to generate some (meaningful) output ;) It depends on you installing the dev package which does that labour (of figuring out which specific library to use) for you.
It depends on you installing the dev package which does that labour (of figuring out which specific library to use) for you.
is this the dev package you mean?I was speaking generally. Whenever you need to use a versioned library, say for example libgtk2, then you are required to install libgtk2-dev in order to actually be able to make use of it (sorry for the bad example but it was the first things that came to mind)..
it comes pre-installed with the distros i am using - i didn't install it myself. but there is no libdl.so symlink in /lib/x86_64-linux-gnu:note the unversioned name libdl.a (analog for libdl.so in eyes of the linker/fpc) that symlinks to versioned name libdl.so.2
user@DH61BE:~$ user@DH61BE:~$ ls /lib/x86_64-linux-gnu/libdl* /lib/x86_64-linux-gnu/libdl.a /lib/x86_64-linux-gnu/libdl.so.2 user@DH61BE:~$
i shall sleep on this, it is now 9am here and i've been working away at this all night!No problem. Thank you for the interesting discussion. Sleep well.
is this the dev package you mean?In this particular case , yes.
In order to support smoother in-place-upgrades and to simplify
the implementation of the runtime all functionality formerly
implemented in the libraries libpthread, libdl, libutil, libanl has
been integrated into libc. New applications do not need to link with
-lpthread, -ldl, -lutil, -lanl anymore. For backwards compatibility,
empty static archives libpthread.a, libdl.a, libutil.a, libanl.a are
provided, so that the linker options keep working. Applications which
have been linked against glibc 2.33 or earlier continue to load the
corresponding shared objects (which are now empty). The integration
of those libraries into libc means that additional symbols become
available by default. This can cause applications that contain weak
references to take unexpected code paths that would only have been
used in previous glibc versions when e.g. preloading libpthread.so.0,
potentially exposing application bugs.
A very helpful read about versioning/symlinks/packaging/distributions: https://dmerej.info/blog/post/symlinks-and-so-files-on-linux/ (https://dmerej.info/blog/post/symlinks-and-so-files-on-linux/)
For more information, see (also) libc release notes (https://sourceware.org/pipermail/libc-alpha/2021-August/129718.html)
is this the dev package you mean?
Package: libc6-dev it comes pre-installed with the distros i am using - i didn't install it myself. but there is no [b][tt]libdl.so[/tt][/b] symlink in [b][tt]/lib/x86_64-linux-gnu[/tt][/b]: [code=plain]user@DH61BE:~$ user@DH61BE:~$ ls /lib/x86_64-linux-gnu/libdl* /lib/x86_64-linux-gnu/libdl.a /lib/x86_64-linux-gnu/libdl.so.2 user@DH61BE:~$
i get the same results from a fresh VM created from a Linux Mint 21.1 XFCE .iso. libc6-dev already installed, but no libdl.so symlink exists.
The development package should contain a symlink for the associated shared library without a version number. For example, the libgdbm-dev package should include a symlink from /usr/lib/libgdbm.so to libgdbm.so.3.0.0. This symlink is needed by the linker (ld) when compiling packages, as it will only look for libgdbm.so when compiling dynamically.
so libdl.a is not a symlink, but some sort of a 'signpost' for the linker that indicates "nothing more to see here, move along to the next library".Correct, though it could also be a symlink pointing to an 'empty' library.
Fred vS suggests that simply creating the symlink is safe and that it should not break anything - what do you think?In all honestly: that I know just enough to be dangerous. In principle I think it can't harm but on the other side how does it reflect on functions that really requires a fix especially when code relies on certain behaviour.
i'm currently think around the idea of creating a program or shell script that:My knowledge on linking is next to none but I still have the notion/idea that it should be possible to realize with a linker script that replaces the symbols. That would allow for a solution that is independent of any changes in the RTL/compiler.
- patches the RTL sources to add @GLIBC_2.2.5 to all the externals that reference know GLIBC 2.2.5 compatible functions,
If you wish to know more about those parameters (NEEDED etc) and about versioning then you could perhaps also have a look here (https://maskray.me/blog/2020-11-26-all-about-symbol-versioning) for more technical details.
QuoteFred vS suggests that simply creating the symlink is safe and that it should not break anything - what do you think?[...] I think it can't harm but on the other side how does it reflect on functions that really requires a fix especially when code relies on certain behaviour.
@WayneSherman: thank you for the pointers/links !
Basically, the naming convention allows for three levels of compatibility for programs that link against the library. A program can choose to link against the library name itself, a specific major number, or a specific major.minor number. This is really up to an application developer to determine what makes the most sense.
They are version numbers, and are there for two reasons; so that you can safely and easily upgrade your libraries, and so you can have more than one version of them installed at the same time.
When there's two numbers there's a major and a minor version. libncursesw.so.5.6 has major version 5 and minor version 6; in theory any minor version of the same major version is compatible without recompiling, so programs that linked to libncursesw.so.5 wouldn't miss a beat if you upgraded to 5.7 for a bugfix. If you had an ancient program demanding version 4, you could safely install a 4.x library alongside the 5.x ones, and nothing but that program would use it.
Sometimes programmers don't think that far ahead though; they might link to a too specific version, breaking their program every time you upgrade a library, or link to libncursesw.so itself, causing crashes and/or strange runtime errors when the library's not what they expected.
About specifying the minor version number, in general that may not be a good idea but unfortunately I have an example of a library (libavif) that has introducted breaking changes at many points, including minor version numbers.
In LazPaint, that runs as well on MacOS and Windows where I cannot know which version of the library would be available, the only solution I found was to bind without version but to check the version at runtime, and to use the version of the records that corresponds to it.
(my bold italics)as long as the version number used exists (which we have just checked using readelf) the linker should (as far as i can see, although i am far from an expert) be happy. we end up with a binary file that will run against an early version of glibc without needing to build on an 'old' VM. would this work?
And what if the user does not want the old behavior? What if the new function fixed some critical functionality and by using the old one you'll run into problems because code you expect to work against the new behavior will run into problems? The __libc_start_main is exactly such an example.
user@DH61BE:~$ readelf --dyn-syms -W /lib/x86_64-linux-gnu/libc.so.6 | grep -E " dl|start_main|Num:" | (sed -u 1q; sort -k 8) Num: Value Size Type Bind Vis Ndx Name 977: 000000000008fe60 74 FUNC GLOBAL DEFAULT 15 dladdr1@GLIBC_2.3.3 978: 000000000008fe60 74 FUNC GLOBAL DEFAULT 15 dladdr1@@GLIBC_2.34 139: 000000000008fe30 42 FUNC GLOBAL DEFAULT 15 dladdr@GLIBC_2.2.5 138: 000000000008fe30 42 FUNC GLOBAL DEFAULT 15 dladdr@@GLIBC_2.34 ...
now i have only checked a few of the symbols from GLIBC, someone else may wish to conduct a more exhaustive check. perhaps write something to pick out all the matching sets of functions and for each set check for 'value' fields that are not the same.
For example, if we look at the 32-bit libc-2.29.so's dynamic symbol table, we see three versions of the glob64 function (in 2017, the glob function was changed to handle dangling symlinks differently, which would cause older programs to crash, but that's a different story):Code: [Select]$ readelf --dyn-syms -W /lib/libc-2.29.so | grep glob64
411: 0012d0e0 7183 FUNC GLOBAL DEFAULT 14 glob64@GLIBC_2.1
412: 0012edb0 7183 FUNC GLOBAL DEFAULT 14 glob64@GLIBC_2.2
413: 000b69a0 7183 FUNC GLOBAL DEFAULT 14 glob64@@GLIBC_2.27
as long as the version number used exists (which we have just checked using readelf) the linker should (as far as i can see, although i am far from an expert) be happy. we end up with a binary file that will run against an early version of glibc without needing to build on an 'old' VM. would this work?
And what if the user does not want the old behavior? What if the new function fixed some critical functionality and by using the old one you'll run into problems because code you expect to work against the new behavior will run into problems? The __libc_start_main is exactly such an example.
...if we look at the 32-bit libc-2.29.so's dynamic symbol table, we see three versions of the glob64 function (in 2017, the glob function was changed to handle dangling symlinks differently, which would cause older programs to crash, but that's a different story):Code: [Select]$ readelf --dyn-syms -W /lib/libc-2.29.so | grep glob64
411: 0012d0e0 7183 FUNC GLOBAL DEFAULT 14 glob64@GLIBC_2.1
412: 0012edb0 7183 FUNC GLOBAL DEFAULT 14 glob64@GLIBC_2.2
413: 000b69a0 7183 FUNC GLOBAL DEFAULT 14 glob64@@GLIBC_2.27
BTW, one of my search results found an appropriate description which struck me as hilarious:
"Versioned Symbols - A New Level of Hell" :-)
checking for matching base name but different entry points reveals:
user@DH61BE:~$ readelf --dyn-syms -W /lib/x86_64-linux-gnu/libc.so.6 | (sed -u 1q; sort -k8) | ./project2 fmemopen GLIBC_2.22 GLIBC_2.2.5 glob64 GLIBC_2.2.5 GLIBC_2.27 glob GLIBC_2.2.5 GLIBC_2.27 ...
In addition, this shows glibc API and ABI changes and backward compatibility across versions:Thank you for that very informative link (I was not aware such thing even existed).
https://abi-laboratory.pro/?view=timeline&l=glibc
(the open source tools to generate these reports are linked at the bottom of the page)
If most agree that the final executable (elf) should have *versioned* symbols, then how they get there is the main question. Should the symbol versions be specified the the fpc source code or should the linker create the versioned symbols based on the libraries present on the system at compile time?
Are the fpc glibc header translations kept up-to-date with glibc API changes?
Is the fpc runtime itself a user the glibc api?
Does fpc expose any parts of the glibc api for general use by other developers?
[...] can someone please *exactly* explain [...] why [a symbol] would need to be versioned ?
[...] In order to solve a problem, you need first to exactly identify the problem.
Keep in mind that in general we only use syscall wrapping functions from libc, not the language utilities.You are right: most of the OS APIs are using direct syscall in the FPC RTL.
Also note that calling syscall is not a good idea, e.g. when there are some VDSO wrappers available.
clockgettime syscall is 20 times slower with a syscal than the one from libc... and this function could be very often call, e.g. if you measure execution time with accuracy, which is a very common task.
See https://synopse.info/forum/viewtopic.php?pid=31342#p31342
Keep in mind that in general we only use syscall wrapping functions from libc, not the language utilities.You are right: most of the OS APIs are using direct syscall in the FPC RTL.
But this is not true for the `__libc_start_main` link in system.pp nor libdl nor cthreads units, IIRC.
And a single broken name link is enough to avoid proper execution.
I am willing to help, if versioned linking might/will be accepted by FPC devs.
I have already made a FPC source scanner to find all libc-calls based on this header file.
Based on headers from: https://github.com/wheybags/glibc_version_header/blob/master/version_headers/x64/force_link_glibc_2.27.h
Proposal.
All libc-calls (the externals) might be defined from an include file that has a versioned and an unversioned definition of every call. Would also cleanup the FPC sources a bit. As stated previously, care must be taken to include all libc CPU-OS combo's.
Too many CPU-OS combos and too many places where libc is linked to be practical
Proposal.This include file could define such a constant:
All libc-calls (the externals) might be defined from an include file that has a versioned and an unversioned definition of every call. Would also cleanup the FPC sources a bit. As stated previously, care must be taken to include all libc CPU-OS combo's.
But can someone please *exactly* explain in a private mail to michael@freepascal.org why dlopen() would need to be versioned ?
Symbol versioning solves problems that are related to interface changes. One version of an interface might have been introduced in a previous version of the GNU C library but the interface or the semantics of the function has been changed in the meantime...
We don't advise building without symbol versioning, since you lose binary compatibility - forever! The binary compatibility you lose is not only against the previous version of the GNU libc but also against all future versions. This means that you will not be able to execute programs that others have compiled.
the necessary version number for each symbol can be extracted relatively easily from libc.so.6 using readelf.
the necessary version number for each symbol can be extracted relatively easily from libc.so.6 using readelf.
Each FPC rtl interface declaration for glibc (i.e. FPC glibc header translations) must be used with a compatible symbol version in the glibc library. Is there confidence that all the FPC glibc interface declarations are API compatible with the "base" versions of the glibc symbols?
A related, but separate question: Is there confidence that the behavior of the "base" version of the symbols is compatible with the way FPC expects it to behave?
I think a saner way would be to have a small patch to the linker backend of the compiler to do substitutions there based on a file ( symbol x in lib y should become y@4234 in lib x). That can be kept out of tree easily to prove the concept.
[...]
For symbol versioning to improve anything, a debian old stable and a new a flashy distro would both have to implement exactly the same base subset. i.e. using the exact same definition of the STAT record/struct etc. Or adding some extra constant to an ORed set of values, or change the implementation of some macro.
[...]
Also who is going to manage all this long term, monitor the glibc lists to provide updates or alert on changes etc etc?
for a given architecture there is no need for long term management. the original BASE set is fixed in stone. it will never change. it needs to be arrived at once, through a relatively simple process. after that, we can forget it and go back to using FPC/Lazarus to write useful programs for sharing with the wider community.
a new approach...involves modifying the function pd_external() in the file pdecsub.pas to automatically intercept and add versioning to selected glibc symbols...
Since this only needs to be done once, isn't the most direct and simple solution to manually add the symbol version to the external function declarations?
What if someone declares a specific version in their own code. Does the "pdecsub.pas" change cause a problem for this?:
// granted instead of static loading, it would be better to dynamically load any
// modern libc functions using gnu_get_libc_version(), dlopen(), and dlsym()
Since this only needs to be done once, isn't the most direct and simple solution to manually add the symbol version to the external function declarations?:
The declarations are shattered over many files and packages and are not Linux specific, but mostly for all *nix and even some half nixes like BeOS
In any case, it would preferable to solve this without source or language modifications, e.g. in the ELF object writer or so.
does BeOS suffer from symbol versioning as well?
one problem with attacking the problem at the ELF end is that then you will trample on any symbols that the programmer wants to be a specific version. for instance, the RTL may need to use an older version of memcpy, while someone writing a program using FPC may depend on a newer version of memcpy. the only ways around this are at the level of either the RTL source, or at the compiler.
there is also a problem with a couple of symbols, setenv and __cxa_finalize. both seem to be referenced from unknown places, with only my fake libdl.so catching them.
there is also a problem with a couple of symbols, setenv and __cxa_finalize. both seem to be referenced from unknown places, with only my fake libdl.so catching them.
Might be ld-linux or glibc startup code. Not necessarily FPC.