This may be technically off topic, but it is for an on-topic purpose...
Is there a command (like ldd) that will tell me what dynamic libraries a static library pulls in?
I believe I've succeeded in getting FLTK to use only Wayland stuff on this RHEL9 machine. However, when I run
ldd ./myapp
I get a huge list of libraries -- that clearly include X11 stuff. I'd like to figure out who is pulling it in -- perhaps it is FLTK, or maybe GLEW, or maybe something else...
Is there an equivalent to 'ldd' on Linux for *.a files?
How about for *.so files?
$ lddtree lib/libfltk.so
lib/libfltk.so (interpreter => None)
libX11.so.6 => /lib/x86_64-linux-gnu/libX11.so.6
libxcb.so.1 => /lib/x86_64-linux-gnu/libxcb.so.1
libXau.so.6 => /lib/x86_64-linux-gnu/libXau.so.6
libXdmcp.so.6 => /lib/x86_64-linux-gnu/libXdmcp.so.6
libbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0
libmd.so.0 => /lib/x86_64-linux-gnu/libmd.so.0
libXinerama.so.1 => /lib/x86_64-linux-gnu/libXinerama.so.1
libXext.so.6 => /lib/x86_64-linux-gnu/libXext.so.6
libXfixes.so.3 => /lib/x86_64-linux-gnu/libXfixes.so.3
...
On 3/13/24 17:27, Rob McDonald wrote:
This may be technically off topic, but it is for an on-topic purpose...Is there a command (like ldd) that will tell me what dynamic libraries a static library pulls in?
Hmm, I think that might be a trick question.
AFAIK, technically static libs don't reference other
libraries, there's just .o files
that haven't been linked yet, so they don't hold any info
about how to find external
references.. that happens during linking, e.g. when a binary
is being created.
At the link stage you get to choose how external libs are
resolved, by either referring
to static or dynamic libs to resolve them.
I believe I've succeeded in getting FLTK to use only Wayland stuff on this RHEL9 machine. However, when I run
ldd ./myapp
I get a huge list of libraries -- that clearly include X11 stuff. I'd like to figure out who is pulling it in -- perhaps it is FLTK, or maybe GLEW, or maybe something else...
$ lddtree /lib/x86_64-linux-gnu/libcairo.so.2
/lib/x86_64-linux-gnu/libcairo.so.2 (interpreter => None)
libpixman-1.so.0 => /lib/x86_64-linux-gnu/libpixman-1.so.0
ld-linux-x86-64.so.2 => /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
libfontconfig.so.1 => /lib/x86_64-linux-gnu/libfontconfig.so.1
libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1
libfreetype.so.6 => /lib/x86_64-linux-gnu/libfreetype.so.6
libbrotlidec.so.1 => /lib/x86_64-linux-gnu/libbrotlidec.so.1
libbrotlicommon.so.1 => /lib/x86_64-linux-gnu/libbrotlicommon.so.1
libpng16.so.16 => /lib/x86_64-linux-gnu/libpng16.so.16
libxcb-shm.so.0 => /lib/x86_64-linux-gnu/libxcb-shm.so.0
libxcb.so.1 => /lib/x86_64-linux-gnu/libxcb.so.1
libXau.so.6 => /lib/x86_64-linux-gnu/libXau.so.6
libXdmcp.so.6 => /lib/x86_64-linux-gnu/libXdmcp.so.6
libbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0
libmd.so.0 => /lib/x86_64-linux-gnu/libmd.so.0
libxcb-render.so.0 => /lib/x86_64-linux-gnu/libxcb-render.so.0
libXrender.so.1 => /lib/x86_64-linux-gnu/libXrender.so.1
libX11.so.6 => /lib/x86_64-linux-gnu/libX11.so.6
libXext.so.6 => /lib/x86_64-linux-gnu/libXext.so.6
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6
I suggest that you try to find out if this is the case on your
system as well. If this is the case then libcairo.so
pulls in the X11 dependencies.Package: libcairo2 Version: 1.16.0-7 Priority: optional Section: libs Source: cairo Maintainer: Debian GNOME Maintainers <pkg-gnome-...@lists.alioth.debian.org> Installed-Size: 1,338 kB Depends: libc6 (>= 2.35), libfontconfig1 (>= 2.12.6), libfreetype6 (>= 2.9.1), libpixman-1-0 (>= 0.30.0), libpng16-16 (>= 1.6.2-1), libx11-6, libxcb-render0, libxcb-shm0, libxcb1 (>= 1.6), libxext6, libxrender1, zlib1g (>= 1:1.1.4) ...
On 3/13/24 19:22, 'Albrecht Schlosser' via fltk.general wrote:
...
What do you want to achieve? Do you want to build an executable that can be deployed to other (similar) systems that don't have X11 libs installed? Is this a security issue?
Just a guess: he's probably deploying binaries to customers,
and wants to minimize runtime dynamic link errors by trying to
pull as many libs in statically as possible.
Nothing worse than a customer who has to struggle with
"libxxx.so: not found" errors, and the developer having to try to
figure out what distro the end user is using, and which "yum/apt
install libxyz" commands are needed to get them running.
I need to build my program for computers that have notoriously stingy sys admins. I don't have a list of pre-installed packages, but I can generally assume that the package list is minimal.
My users do not have sudo access -- or really even the ability to ask admins to add additional packages. These computers are air-gapped from the internet. I do not have access to one of these, so I'm building / testing on a local VM (that I do have sudo access to) and will be sending them a package to test on their machines.
If the machine is a Wayland machine, I struggle to see why a bunch of X11 libraries would be installed.
I'm approaching this from a perspective of minimizing external dependencies -- statically link everything I can -- don't have a bunch of crud that isn't really needed.
g++ -o hello ../../test/hello.cxx `fltk-config --cxxflags` /git/fltk/master/build/debug/lib/libfltk.a \ -lm -lpthread -L/usr/lib/x86_64-linux-gnu -lpango-1.0 -lgobject-2.0 -lglib-2.0 \ -lharfbuzz -lwayland-cursor -lwayland-client -lxkbcommon -ldbus-1 -lfontconfig -ldl \ -lpangocairo-1.0 \ /usr/lib/x86_64-linux-gnu/libX11.a /usr/lib/x86_64-linux-gnu/libxcb.a /usr/lib/x86_64-linux-gnu/libXau.a \ /lib/x86_64-linux-gnu/libXdmcp.a /lib/x86_64-linux-gnu/libXcursor.a /lib/x86_64-linux-gnu/libXrender.a \ /usr/lib/x86_64-linux-gnu/libcairo.a -lfontconfig /usr/lib/x86_64-linux-gnu/libfreetype.a \ /usr/lib/x86_64-linux-gnu/libpixman-1.a -lpng -lz /usr/lib/x86_64-linux-gnu/libXrender.a \ /usr/lib/x86_64-linux-gnu/libX11.a /usr/lib/x86_64-linux-gnu/libXext.a /usr/lib/x86_64-linux-gnu/libfreetype.a \ /usr/lib/x86_64-linux-gnu/libbrotlidec.a /usr/lib/x86_64-linux-gnu/libbrotlicommon.a \ /usr/lib/x86_64-linux-gnu/libXinerama.a /usr/lib/x86_64-linux-gnu/libXfixes.aWell, that doesn't look simple, but it's a progress, lddtree shows:
./hello (interpreter => /lib64/ld-linux-x86-64.so.2)
libpango-1.0.so.0 => /lib/x86_64-linux-gnu/libpango-1.0.so.0
libglib-2.0.so.0 => /lib/x86_64-linux-gnu/libglib-2.0.so.0
libpcre2-8.so.0 => /lib/x86_64-linux-gnu/libpcre2-8.so.0
libgio-2.0.so.0 => /lib/x86_64-linux-gnu/libgio-2.0.so.0
libgmodule-2.0.so.0 => /lib/x86_64-linux-gnu/libgmodule-2.0.so.0
libmount.so.1 => /lib/x86_64-linux-gnu/libmount.so.1
libblkid.so.1 => /lib/x86_64-linux-gnu/libblkid.so.1
libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1
libfribidi.so.0 => /lib/x86_64-linux-gnu/libfribidi.so.0
libthai.so.0 => /lib/x86_64-linux-gnu/libthai.so.0
libdatrie.so.1 => /lib/x86_64-linux-gnu/libdatrie.so.1
libharfbuzz.so.0 => /lib/x86_64-linux-gnu/libharfbuzz.so.0
libfreetype.so.6 => /lib/x86_64-linux-gnu/libfreetype.so.6
libbrotlidec.so.1 => /lib/x86_64-linux-gnu/libbrotlidec.so.1
libbrotlicommon.so.1 => /lib/x86_64-linux-gnu/libbrotlicommon.so.1
libgraphite2.so.3 => /lib/x86_64-linux-gnu/libgraphite2.so.3
libgobject-2.0.so.0 => /lib/x86_64-linux-gnu/libgobject-2.0.so.0
libffi.so.8 => /lib/x86_64-linux-gnu/libffi.so.8
libwayland-cursor.so.0 => /lib/x86_64-linux-gnu/libwayland-cursor.so.0
libwayland-client.so.0 => /lib/x86_64-linux-gnu/libwayland-client.so.0
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0
libxkbcommon.so.0 => /lib/x86_64-linux-gnu/libxkbcommon.so.0
libdbus-1.so.3 => /lib/x86_64-linux-gnu/libdbus-1.so.3
libsystemd.so.0 => /lib/x86_64-linux-gnu/libsystemd.so.0
libcap.so.2 => /lib/x86_64-linux-gnu/libcap.so.2
libgcrypt.so.20 => /lib/x86_64-linux-gnu/libgcrypt.so.20
libgpg-error.so.0 => /lib/x86_64-linux-gnu/libgpg-error.so.0
liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5
libzstd.so.1 => /lib/x86_64-linux-gnu/libzstd.so.1
liblz4.so.1 => /lib/x86_64-linux-gnu/liblz4.so.1
libpangocairo-1.0.so.0 => /lib/x86_64-linux-gnu/libpangocairo-1.0.so.0
libpangoft2-1.0.so.0 => /lib/x86_64-linux-gnu/libpangoft2-1.0.so.0
libcairo.so.2 => /lib/x86_64-linux-gnu/libcairo.so.2
libpixman-1.so.0 => /lib/x86_64-linux-gnu/libpixman-1.so.0
libxcb-shm.so.0 => /lib/x86_64-linux-gnu/libxcb-shm.so.0
libxcb.so.1 => /lib/x86_64-linux-gnu/libxcb.so.1
libXau.so.6 => /lib/x86_64-linux-gnu/libXau.so.6
libXdmcp.so.6 => /lib/x86_64-linux-gnu/libXdmcp.so.6
libbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0
libmd.so.0 => /lib/x86_64-linux-gnu/libmd.so.0
libxcb-render.so.0 => /lib/x86_64-linux-gnu/libxcb-render.so.0
libXrender.so.1 => /lib/x86_64-linux-gnu/libXrender.so.1
libX11.so.6 => /lib/x86_64-linux-gnu/libX11.so.6
libXext.so.6 => /lib/x86_64-linux-gnu/libXext.so.6
libfontconfig.so.1 => /lib/x86_64-linux-gnu/libfontconfig.so.1
libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1
libpng16.so.16 => /lib/x86_64-linux-gnu/libpng16.so.16
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1
libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6
As you can see, the problem with this build is that I had to link `-lpangocairo-1.0`
dynamically because I didn't find the static lib on my system.
Although all the Cairo stuff has been linked statically this pulls
in libcairo.so.2 with
all its dependencies.On Wednesday, March 13, 2024 at 8:37:48 PM UTC-7 Albrecht-S wrote:On 3/14/24 03:46 Rob McDonald wrote:If the machine is a Wayland machine, I struggle to see why a bunch of X11 libraries would be installed.
Maybe because Wayland or (more likely: other applications) need pango and cairo etc. and therefore the minimal set of X11 libs are also installed.
I'm approaching this from a perspective of minimizing external dependencies -- statically link everything I can -- don't have a bunch of crud that isn't really needed.
OK, I tried to compile and link hello.cxx statically as a Wayland-only app (linked against a Wayland-only libfltk.a) with several statically linked libs.
[...]
you can see that I had to link in several X11 related libs statically. That means that you'd need these static libs on your development system but if you can avoid linking libpangocairo dynamically you could maybe succeed.
Good luck ...
Thanks for all this help.
I'll have to see what I can do to make something like this work.
I will also run an iteration by them to see what we can get away with.
I found this article that indicates that RHEL10 (expected in 2025) will fully deprecate X11. That is still a long ways off (unless measured in FLTK release cycles).
It certainly makes clear that FLTK and the entire Linux stack needs to be ready to weather this transition away from X11 once and for all.
I believe you should somehow find out which libs are installed on your target system(s), particularly if this is all for one specific organization. For instance, if you knew that they have libpangocairo, then trying to link libpangocairo and all of its dependencies statically would be unnecessary. This would definitely make your task much easier.
If that means, which libs they have installed, I'd clearly go for it.
I'm striving for much shorter release cycles in the near future, but anyway, who knows...
It certainly makes clear that FLTK and the entire Linux stack needs to be ready to weather this transition away from X11 once and for all.For FLTK this means: we *need* Wayland support (which we have now, thanks to Manolo's efforts) and we must support X11 for old systems for many years, even if major Linux distros and DE's move entirely to Wayland.
On Thursday, March 14, 2024 at 7:20:39 AM UTC-7 Manolo wrote:
... it's possible to build differently the cairo library without X dependency, and to use that
alternative cairo library when linking an FLTK app.
...
Do you think we should consider embedding a Cairo build into FLTK (using ExternalProject or FetchProject) so that our FLTK CMake system can automatically configure and build a Cairo that meets the developer's intent?
The following are rhetorical questions -- me pontificating about the long-term transition to Wayland. I'm not actually expecting anyone to take action or answer these questions....
[...]
If both FLTK and GLEW are making a runtime choice between X11 and Wayland, how do we make sure they make the same choice? is it based on a heuristic, command line flag, environmental variable, something else?
Will there be consensus across tools for how to trigger this choice?
How will an application developer test all the combinations?