CPU caches aren't that big so it still matters today, at least for desktop applications.
$(HOME)/lib:/usr/local/lib:/lib:/usr/lib
You'll notice that those fallback paths do not include any location relative to the application. It's actually pretty difficult to get the object code to lookup libraries relative to its own directory. Explanation here:
https://birchlabs.co.uk/blog/alex/juicysfplugin/synth/cpp/20...
One could just use a wrapper script that sets the DYLD_FALLBACK_LIBRARY_PATH relative to the binary's directory and run it.
The program sets LD_RUNPATH_SEARCH_PATHS which bakes a list of paths into the binary. This can include relative paths as well as @loader_path and @executable_path. eg a plugin bundled with an app can specify @executable_path/../../Frameworks to reference the parent bundle's Frameworks directory. Libraries can also add search paths to help locate their dependencies. @loader_path will expand relative to the library that actually has the dependency.
Any linked library with a DYLD name of @rpath/ will be searched in those locations.
At build time the linker checks each library for its DYLD name and bakes that name into the final binary. Making sure all of your non-system dependencies are @rpath and relative to your app bundle is what makes it a "Relocatable" application.
We need to stop living in the past - this very issue has probably contributed to the scourge of Electron crap being thrown at our faces since it doesn't suffer from dependency hell they just throw a bunch of javascript into an encapsulated instance of chrome and call it a day.
2. Even in an absurd world where each coreutils executable required 100mb of libraries, a busybox-like delivery would already shave ~10GB off of that. Other improvements can be made: binary deltas for security updates, performing the final link step at package install time, probably others.
3. libc updates have introduced security issues; shared library updates in general break things. I can take a statically linked executable from 1998 and run it today.
Lastly, this is totally unrelated to the question because 971 statically linked command line applications will be well under 1GB, but a 250GB drive? The last time I had a drive that small was a 100GB drive in a PowerBook G4. Linux (and p9 from TFA) are OSes used primarily from the developers (at least until the mythical year of linux on the desktop). Springing $200 for a 512GB SSD upgrade seems well worth it if you are being paid a developers salary anywhere in the western world.
The largest executable is ptx at 272kb vs 72kb for the Ubuntu binary.
For the smallest, false is 48k statically linked vs 32k for the Ubuntu binary.
If all 970 executables in /usr/bin average out to 100kb of extra space, that's less than 100MB overhead.
[edit]
Stripping the binaries decreases the size to about 7MB total or byte sizes of 34312 vs 30824 for a stripped false binary and 251752 vs 71928 for ptx.
For download times, a tar.xz is a good measurement and it's 819k for the 105 statically linked files or 1015k for the full installation of coreutils including the info files and manpages.
[edit2]
Some proponents of static linking talk about performance, I think it's a negligible win, but as I have it handy I thought I'd measure:
10000 runs of a dynamically linked "false":
real 0m4.650s
user 0m3.602s
sys 0m1.391s
10000 runs if a statically linked "false": real 0m3.025s
user 0m2.047s
sys 0m1.287sLol, you have to do some kind of stripping or GC sections or what not for this to be a fair comparison. A proper version of false is 508bytes on my machine.