[MacPorts] #62426: libc++: using a newer libc++ to build software on older macos systems

MacPorts 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>
MacPorts <https://www.macports.org/>
Ports system for macOS

More information about the macports-tickets mailing list