Fwd: Re: [MacPorts] #69411: ld64-latest upgrade time?

René J.V. Bertin rjvbertin at gmail.com
Mon Mar 11 13:31:04 UTC 2024

A quick heads-up to anyone with an interest in the linker (and who wasn't aware of the ticket yet).


Forwarded message:
Date: Monday March 11 2024
Subject: Re: [MacPorts] #69411: ld64-latest upgrade time?

#69411: ld64-latest upgrade time?
  Reporter:  RJVB     |      Owner:  (none)
      Type:  request  |     Status:  new
  Priority:  Normal   |  Milestone:
 Component:  ports    |    Version:
Resolution:           |   Keywords:
      Port:  ld64     |

Comment (by RJVB):

 So, I've been tinkering with lld and subsequently going down a rabbit hole
 with LLVM-17... Here's a rough overview about using lld before the details
 escape me completely...

 - lld won't generate 32bit code, at least not for Intel. Not the biggest
 problem probably, but a bummer since a (much) faster linker would be more
 beneficial for older systems that need to do (lots of) universal builds.
 - lld isn't a perfect drop-in replacement for ld64 (see below for the list
 of as-yet-unsupported arguments). I haven't found any adverse effects
 though. In this aspect lld-17 isn't better than lld-16.
 - somewhere between LLVM-12 and LLVM-15 a new `-platform_version` argument
 was introduced that apparently deprecates `-macosx_version_min` which is
 still accepted but apparently ignored at least to the extent that it
 doesn't provide the info expected via `-platform_version`. A wrapper
 script is thus required which must live at the place of the actual
 ld64.lld *hardlink*, and invoke lld as `ld64.lld` (so I moved the link to
 - `-fuse-ld=/path/to/l*d` is deprecated (because it doesn't allow to
 determine the linker variant ... easily); there is a new argument to
 specify /path/to/linker (which is incompatible with gcc). With the
 deprecated form the linker is apparently assumed to be compatible with
 ld64 (which is true via the aforementioned wrapper).
 - lld can be built as a standalone project, so against the already
 installed port:llvm-xy . I had hoped to build it as a monolithic
 standalone *port* with a minimal build of the required llvm bits ''linked
 statically''. Sadly it does not appear to be possible to build libLLVM as
 a static library, so ultimately I opted to write a subport that installs
 to its own subprefix `${prefix}/libexec/lld-17`, with only the libLLVM
 dylib (and currently libLTO which is probably NOT needed).
 - GCC's `-fuse-ld=lld` appears not to have any effect on Darwin and if you
 force it an error is raised:
 ld64.lld: error: No LC_DYLD_INFO_ONLY or LC_DYLD_EXPORTS_TRIE found in

 ld64.lld: warning: Option `-reexported_symbols_list' is not yet
 implemented. Stay tuned...
 ld64.lld: warning: Option `-force_symbols_not_weak_list' is undocumented.
 Should lld implement it?
 ld64.lld: warning: Option `-force_symbols_weak_list' is undocumented.
 Should lld implement it?
 ld64.lld: warning: Option `-reexported_symbols_list' is not yet
 implemented. Stay tuned...
 ld64.lld: warning: Option `-no_compact_unwind' is undocumented. Should lld
 implement it?

 "Standalone build":
 My goal was to have access to the most recent/capable lld without
 necessarily having to have at least the full corresponding llvm port
 active. Given what a resource hog LLVM has become there is a good reason
 not to waste possibly precious disk space to versions that you're not
 going to be using regularly. Plus, clang++-17 has proven to fail to link a
 lot of code (including `port:llvm-17` itself) because of symbols like
 (IIRC) `std::verbose_abort` missing from libc++ (and I have libc++ 13 in
 my personal $prefix!).

 Here's my current implementation:
 configured to install to `$prefix/libexec/lld-17`.
 Note that I fixed a number of other "issues" with the port, in particular
 - re-allow building with the MacPorts CMAKE_BUILD_TYPE (the build system
 no longer rejects unknown types)
 - use Ninja (or in my case, the lighter Samurai). All I needed to do was
 figure out the install targets that the cumbersome way of invoking `make
 install` from subdirectories evidently also use. FWIW, CMake makes this
 relatively easy because it generates a `help` target that will list all
 known targets (in the current dir, which means for the entire project when
 using Ninja).
 - fix the use of ccache (a complete rebuild after a clean or changing only
 a single C++ file takes about 35min instead of over 6 hours on my

Ticket URL: <https://trac.macports.org/ticket/69411#comment:6>

More information about the macports-dev mailing list