[MacPorts] #62426: libc++: using a newer libc++ to build software on older macos systems
noreply at macports.org
Wed Sep 21 21:16:48 UTC 2022
#62426: libc++: using a newer libc++ to build software on older macos systems
Reporter: kencu | Owner: kencu
Type: enhancement | Status: closed
Priority: Normal | Milestone:
Component: ports | Version:
Resolution: fixed | Keywords:
Port: libcxx macports-libcxx |
Comment (by RJVB):
Replying to [comment:56 kencu]:
> Perhaps a one-sentence line might put my nose right on it. I’m sorry,
you’re so clever about all this and I feel slow to catch on.
Look at the output from lsof above to see what libraries actually *remain*
loaded into memory while the application is running, and consider that
there is a distinction between ''loading'' a library into memory
(dlopen'ing it) and **importing** symbols from it.
(That was a single though long sentence ;) )
This must also be why we see a single DYLD_PRINT_LIBRARIES line for
/opt/local/lib/libc++.1.dylib and /opt/local/lib/libc++abi.1.dylib :
they're loaded and symbols are imported from it. Whereas I see multiple
cases of /usr/lib/libc++*.dylib being loaded; this has to mean that each
time the library is unloaded again because it is found to be superfluous.
I think of it this way. During the build process the linker (link editor,
ld) will have built a table of symbols that have to be loaded from shared
libraries, and in which library they are expected. When you launch the
program, dyld will read that table, starts loading the libraries
registered as dependencies (probably using dlopen()) and tries to obtain
the address of each of the listed symbols from the expected library
(importing; probably using dlsym()). Once an address is found, the symbol
is removed from the list.
Now maybe I'm wrong, maybe the application and its shared libraries aren't
all read into a single, global memory space. It's true that this process
works a bit differently on Linux, so I may be mixing observations from the
two systems and arriving at inappropriate conclusions.
If libc++ were made of a single source file then linking with the static
library would presumably be equivalent to using DYLD_INSERT_LIBRARIES. But
it's not, so ld will link only the required modules needed by the
application. I do not know to what extent ld will also consider the
symbols required by the shared libraries on which the application depends,
if those shared libraries are already linked to the shared libc++ from the
If it does, then linking to a static libc++ should indeed guarantee that
the executable contains all the required libc++ functions and no longer
needs to import anything from the shared libc++ system library.
But it looks like this is also what happens with my newer shared libc++ in
/opt/local/lib: dyld can apparently see it's the newest version of the 2
libc++ versions in the list of libraries to load, and is clever enough to
import from that newest version first.
This is quite a bit more than a single sentence and I hope I've not
managed to make things even less clear.
Ticket URL: <https://trac.macports.org/ticket/62426#comment:58>
Ports system for macOS
More information about the macports-tickets