Apple ld Manual Page

I’ve exported the ld man page from MacOS 13 as it doesn’t seem to be easy to find on the web, so thought it may be useful to replicate here.

Note that this is reproduced as-is for convenience, so the copyright stays with the original owner.

NAME
     ld – linker

SYNOPSIS
     ld files...  [options] [-o outputfile]

DESCRIPTION
     The ld command combines several object files and libraries, resolves references, and produces an
     output file.  ld can produce a final linked image (executable, dylib, or bundle), or with the -r
     option, produce another object file.  If the -o option is not used, the output file produced is
     named "a.out".

   Universal
     The linker accepts universal (multiple-architecture) input files, but always creates a "thin"
     (single-architecture), standard Mach-O output file.  The architecture for the output file is
     specified using the -arch option.  If this option is not used, ld attempts to determine the output
     architecture by examining the object files in command line order.  The first "thin" architecture
     determines that of the output file.  If no input object file is a "thin" file, the native 32-bit
     architecture for the host is used.

     Usually, ld is not used directly.  Instead the compiler driver invokes ld. The compiler driver can
     be passed multiple -arch options and it will create a universal final linked image by invoking ld
     multiple times and then running lipo(1) merge the outputs into a universal file.

   Layout
     The object files are loaded in the order in which they are specified on the command line.  The
     segments and the sections in those segments will appear in the output file in the order they are
     encountered in the object files being linked.  All zero fill sections will appear after all non-zero
     fill sections in their segments.

   Libraries
     A static library (aka static archive) is a collection of .o files with a table of contents that
     lists the global symbols in the .o files.  ld will only pull .o files out of a static library if
     needed to resolve some symbol reference.  Unlike traditional linkers, ld will continually search a
     static library while linking. There is no need to specify a static library multiple times on the
     command line.

     A dynamic library (aka dylib or framework) is a final linked image.  Putting a dynamic library on
     the command line causes two things: 1) The generated final linked image will have encoded that it
     depends on that dynamic library. 2) Exported symbols from the dynamic library are used to resolve
     references.
Both dynamic and static libraries are searched as they appear on the command line.

   Search paths
     ld maintains a list of directories to search for a library or framework to use.  The default library
     search path is /usr/lib then /usr/local/lib.  The -L option will add a new library search path.  The
     default framework search path is /Library/Frameworks then /System/Library/Frameworks.  (Note:
     previously, /Network/Library/Frameworks was at the end of the default path.  If you need that
     functionality, you need to explicitly add -F/Network/Library/Frameworks).  The -F option will add a
     new framework search path.  The -Z option will remove the standard search paths.  The -syslibroot
     option will prepend a prefix to all search paths.

   Two-level namespace
     By default all references resolved to a dynamic library record the library to which they were
     resolved. At runtime, dyld uses that information to directly resolve symbols.  The alternative is to
     use the -flat_namespace option.  With flat namespace, the library is not recorded.  At runtime, dyld
     will search each dynamic library in load order when resolving symbols. This is slower, but more like
     how other operating systems resolve symbols.

   Indirect dynamic libraries
     If the command line specifies to link against dylib A, and when dylib A was built it linked against
     dylib B, then B is considered an indirect dylib.  When linking for two-level namespace, ld does not
     look at indirect dylibs, except when re-exported by a direct dylibs.  On the other hand when linking
     for flat namespace, ld does load all indirect dylibs and uses them to resolve references.  Even
     though indirect dylibs are specified via a full path, ld first uses the specified search paths to
     locate each indirect dylib.  If one cannot be found using the search paths, the full path is used.

   Dynamic libraries undefines
     When linking for two-level namespace, ld does not verify that undefines in dylibs actually exist.
     But when linking for flat namespace, ld does check that all undefines from all loaded dylibs have a
     matching definition.  This is sometimes used to force selected functions to be loaded from a static
     library.

OPTIONS
   Options that control the kind of output
     -execute
             The default.  Produce a mach-o main executable that has file type MH_EXECUTE.

     -dylib  Produce a mach-o shared library that has file type MH_DYLIB.

     -bundle
             Produce a mach-o bundle that has file type MH_BUNDLE.
     -r      Merges object files to produce another mach-o object file with file type MH_OBJECT.

     -dylinker
             Produce a mach-o dylinker that has file type MH_DYLINKER.  Only used when building dyld.

     -dynamic
             The default.  Implied by -dylib, -bundle, or -execute

     -static
             Produces a mach-o file that does not use the dyld.  Only used building the kernel.

     -preload
             Produces a mach-o file in which the mach_header, load commands, and symbol table are not in
             any segment.  This output type is used for firmware or embedded development where the
             segments are copied out of the mach-o into ROM/Flash.

     -arch arch_name
             Specifies which architecture (e.g. ppc, ppc64, i386, x86_64) the output file should be.

     -o path
             Specifies the name and location of the output file.  If not specified, `a.out' is used.

   Options that control libraries
     -lx     This option tells the linker to search for libx.dylib or libx.a in the library search path.
             If string x is of the form y.o, then that file is searched for in the same places, but
             without prepending `lib' or appending `.a' or `.dylib' to the filename.

     -needed-lx
             This is the same as the -lx but means to really link with the dylib even if no symbols are
             used from it.  Thus, it can be used suppress warnings about unused dylibs.

     -reexport-lx
             This is the same as the -lx but specifies that the all symbols in library x should be
             available to clients linking to the library being created.  This was previously done with a
             separate -sub_library option.

     -upward-lx
             This is the same as the -lx but specifies that the dylib is an upward dependency.

     -hidden-lx
             This is the same as the -lx for locating a static library, but treats all global symbols
             from the static library as if they are visibility hidden.  Useful when building a dynamic
             library that uses a static library but does not want to export anything from that static
             library.

     -weak-lx
             This is the same as the -lx but forces the library and all references to it to be marked as
             weak imports.  That is, the library is allowed to be missing at runtime.

     -assert-weak-lx
             This is the same as the -weak-l but verifies that all references were marked as weak
             imports, instead of forcing it.

     -delay-lx
             This is the same as the -lx but specifies that the dylib should be delay initialized.

     -needed_library path_to_dylib
             This is the same as placing path_to_dylib on the link line but means to really link with the
             dylib even if no symbols are used from it.  Thus, it can be used suppress warnings about
             unused dylibs.

     -reexport_library path_to_library
             This is the same as listing a file name path to a library on the link line and it specifies
             that the all symbols in library path should be available to clients linking to the library
             being created.  This was previously done with a separate -sub_library option.

     -upward_library path_to_library
             This is the same as listing a file name path to a library on the link line but also marks
             the dylib as an upward dependency.

     -weak_library path_to_library
             This is the same as listing a file name path to a library on the link line except that it
             forces the library and all references to it to be marked as weak imports.

     -assert_weak_library path_to_library
             This is the same as the -weak_library but verifies that all references were marked as weak
             imports, instead of forcing it.

     -delay_library path_to_library
             This is the same as listing a file name path to a library on the link line except that will
             mark the dylib to be delay initialized.

     -Ldir   Add dir to the list of directories in which to search for libraries.  Directories specified
             with -L are searched in the order they appear on the command line and before the default
             search path. In Xcode4 and later, there can be a space between the -L and directory.

     -Z      Do not search the standard directories when searching for libraries and frameworks.

     -syslibroot rootdir
             Prepend rootdir to all search paths when searching for libraries or frameworks.

     -search_paths_first
             This is now the default (in Xcode4 tools).  When processing -lx the linker now searches each
             directory in its library search paths for `libx.dylib' then `libx.a' before the moving on to
             the next path in the library search path.

     -search_dylibs_first
             Changes the searching behavior for libraries.  The default is that when processing -lx the
             linker searches each directory in its library search paths for `libx.dylib' then `libx.a'.
             This option changes the behavior to first search for a file of the form `libx.dylib' in each
             directory in the library search path, then a file of the form `libx.a' is searched for in
             the library search paths.  This option restores the search behavior of the linker prior to
             Xcode4.

     -framework name[,suffix]
             This option tells the linker to search for `name.framework/name' the framework search path.
             If the optional suffix is specified the framework is first searched for the name with the
             suffix and then without (e.g. look for `name.framework/name_suffix' first, if not there try
             `name.framework/name').

     -needed_framework name[,suffix]
             This is the same as the -framework name[,suffix] but means to really link with the framework
             even if no symbols are used from it.  Thus, it can be used suppress warnings about unused
             dylibs.

     -weak_framework name[,suffix]
             This is the same as the -framework name[,suffix] but forces the framework and all references
             to it to be marked as weak imports.  Note: due to a clang optimizations, if functions are
             not marked weak, the compiler will optimize out any checks if the function address is NULL.

     -assert_weak_framework name[,suffix]
             This is the same as the -weak_framework but verifies that all references were marked as weak
             imports, instead of forcing it.

     -reexport_framework name[,suffix]
             This is the same as the -framework name[,suffix] but also specifies that the all symbols in
             that framework should be available to clients linking to the library being created.  This
             was previously done with a separate -sub_umbrella option.

     -upward_framework name[,suffix]
             This is the same as the -framework name[,suffix] but also specifies that the framework is an
             upward dependency.

     -delay_framework name[,suffix]
             This is the same as the -framework name[,suffix] but also specifies that the framework
             should be delay initialized.

     -Fdir   Add dir to the list of directories in which to search for frameworks.  Directories specified
             with -F are searched in the order they appear on the command line and before the default
             search path. In Xcode4 and later, there can be a space between the -F and directory.

     -all_load
             Loads all members of static archive libraries.

     -ObjC   Loads all members of static archive libraries that implement an Objective-C class, category
             or a Swift struct, class or an extesion.

     -force_load path_to_archive
             Loads all members of the specified static archive library.  Note: -all_load forces all
             members of all archives to be loaded.  This option allows you to target a specific archive.

     -load_hidden path_to_archive
             Uses specified static library as usual, but treats all global symbols from the static
             library to as if they are visibility hidden.  Useful when building a dynamic library that
             uses a static library but does not want to export anything from that static library.

     -image_suffix suffix
             Search for libraries and frameworks with suffix and then without.

   Options that control additional content
     -sectcreate segname sectname file
             The section sectname in the segment segname is created from the contents of file file. If
             there's a section (segname,sectname) from any other input, the linker will append the
             content from the file to that section.

     -add_empty_section segname sectname
             An empty section named sectname in the segment segname. If any of the inputs contains a
             section (segname,sectname), that section will be included in the output, and this option
             will be ignored.

     -add_ast_path file
             The linker will add a N_AST stab symbol to the output file where the string is the path
             pointed by file and its values is the modification time of the file.

     -filelist file[,dirname]
             Specifies that the linker should link the files listed in file.  This is an alternative to
             listing the files on the command line.  The file names are listed one per line separated
             only by newlines. (Spaces and tabs are assumed to be part of the file name.)  If the
             optional directory name, dirname is specified, it is prepended to each name in the list
             file.

     -dtrace file
             Enables dtrace static probes when producing a final linked image.  The file file must be a
             DTrace script which declares the static probes.

   Options that control optimizations
     -dead_strip
             Remove functions and data that are unreachable by the entry point or exported symbols.

     -order_file file
             Alters the order in which functions and data are laid out.  For each section in the output
             file, any symbol in that section that are specified in the order file file is moved to the
             start of its section and laid out in the same order as in the order file file.  Order files
             are text files with one symbol name per line.  Lines starting with a # are comments.  A
             symbol name may be optionally preceded with its object file leaf name and a colon (e.g.
             foo.o:_foo).  This is useful for static functions/data that occur in multiple files.  A
             symbol name may also be optionally preceded with the architecture (e.g. ppc:_foo or
             ppc:foo.o:_foo).  This enables you to have one order file that works for multiple
             architectures.  Literal c-strings may be ordered by by quoting the string (e.g. "Hello,
             world\n") in the order file.

     -no_order_inits
             When the -order_file option is not used, the linker lays out functions in object file order
             and it moves all initializer routines to the start of the __text section and terminator
             routines to the end. Use this option to disable the automatic rearrangement of initializers
             and terminators.

     -platform_version platform min_version sdk_version
             This is set to indicate the platform, oldest supported version of that platform that output
             is to be used on, and the SDK that the output was built against.  platform is a numeric
             value as defined in <mach-o/loader.h>, or it may be one of the following strings:
             • macos
             • ios
             • tvos
             • watchos
             • bridgeos
             • visionos
             • xros
             • mac-catalyst
             • ios-simulator
             • tvos-simulator
             • watchos-simulator
             • visionos-simulator
             • xros-simulator
             • driverkit
             • firmware
             • sepOS
             Specifying a newer min or SDK version enables the linker to assume features of that OS or
             SDK in the output file. The format of min_version and sdk_version is a version number such
             as 10.13 or 10.14

     -macos_version_min version
             This is set to indicate the oldest macOS version that that the output is to be used on.
             Specifying a later version enables the linker to assumes features of that OS in the output
             file.  The format of version is a macOS version number such as 10.9 or 10.14

     -ios_version_min version
             This is set to indicate the oldest iOS version that that the output is to be used on.
             Specifying a later version enables the linker to assumes features of that OS in the output
             file.  The format of version is an iOS version number such as 3.1 or 4.0

     -image_base address
             Specifies the preferred load address for a dylib or bundle. The argument address is a
             hexadecimal number with an optional leading 0x.  By choosing non-overlapping address for all
             dylibs and bundles that a program loads, launch time can be improved because dyld will not
             need to "rebase" the image (that is, adjust pointers within the image to work at the loaded
             address).  It is often easier to not use this option, but instead use the rebase(1) tool,
             and give it a list of dylibs.  It will then choose non-overlapping addresses for the list
             and rebase them all. When building a position independent executable, this option will be
             ignored.  This option is also called -seg1addr for compatibility.

     -no_implicit_dylibs
             When creating a two-level namespace final linked image, normally the linker will hoist up
             public dylibs that are implicitly linked to make the two-level namespace encoding more
             efficient for dyld.  For example, Cocoa re-exports AppKit and AppKit re-exports Foundation.
             If you link with -framework Cocoa and use a symbol from Foundation, the linker will
             implicitly add a load command to load Foundation and encode the symbol as coming from
             Foundation.  If you use this option, the linker will not add a load command for Foundation
             and encode the symbol as coming from Cocoa.  Then at runtime dyld will have to search Cocoa
             and AppKit before finding the symbol in Foundation.

     -no_zero_fill_sections
             By default the linker moves all zero fill sections to the end of the __DATA segment and
             configures them to use no space on disk.  This option suppresses that optimization, so zero-
             filled data occupies space on disk in a final linked image.

    -merge_zero_fill_sections
             Causes all zero-fill sections in the __DATA segment to be merged into one __zerofill
             section.

     -no_branch_islands
             Disables linker creation of branch islands which allows images to be created that are larger
             than the maximum branch distance. Useful with -preload when code is in multiple sections but
             all are within the branch range.

     -O0     Disables certain optimizations and layout algorithms to optimize build time. This option
             should be used with debug builds to speed up incremental development. The exact
             implementation might change to match the intent.

     -reproducible
             By default output content will be deterministic, but small changes in input files such as a
             compilation time might affect certain data structures in the linked binary. This option
             instructs ld to create a reproducible output binary by ignoring certain input properties or
             using alternative algorithms.

   Options when creating a dynamic library (dylib)
     -install_name name
             Sets an internal "install path" (LC_ID_DYLIB) in a dynamic library. Any clients linked
             against the library will record that path as the way dyld should locate this library.  If
             this option is not specified, then the -o path will be used.  This option is also called
             -dylib_install_name for compatibility.

     -compatibility_version number
             Specifies the compatibility version number of the library.  When a library is loaded by
             dyld, the compatibility version is checked and if the program's version is greater that the
             library's version, it is an error.  The format of number is X[.Y[.Z]] where X must be a
             positive non-zero number less than or equal to 65535, and .Y and .Z are optional and if
             present must be non-negative numbers less than or equal to 255.  If the compatibility
             version number is not specified, it has a value of 0 and no checking is done when the
             library is used.  This option is also called -dylib_compatibility_version for compatibility.

     -current_version number
             Specifies the current version number of the library. The current version of the library can
             be obtained programmatically by the user of the library so it can determine exactly which
             version of the library it is using.  The format of number is X[.Y[.Z]] where X must be a
             positive non-zero number less than or equal to 65535, and .Y and .Z are optional and if
             present must be non-negative numbers less than or equal to 255.  If the version number is
             not specified, it has a value of 0.  This option is also called -dylib_current_version for
             compatibility.

   Options when creating a main executable
     -pie    This makes a special kind of main executable that is position independent (PIE).  On Mac OS
             X 10.5 and later, the OS the OS will load a PIE at a random address each time it is
             executed.  You cannot create a PIE from .o files compiled with -mdynamic-no-pic.  That means
             the codegen is less optimal, but the address randomization adds some security. When
             targeting Mac OS X 10.7 or later PIE is the default for main executables.

     -no_pie
             Do not make a position independent executable (PIE).  This is the default, when targeting
             10.6 and earlier.

     -pagezero_size size
             By default the linker creates an unreadable segment starting at address zero named
             __PAGEZERO.  Its existence will cause a bus error if a NULL pointer is dereferenced.  The
             argument size is a hexadecimal number with an optional leading 0x.  If size is zero, the
             linker will not generate a page zero segment.  By default on 32-bit architectures the page
             zero size is 4KB.  On 64-bit architectures, the default size is 4GB.

     -stack_size size
             Specifies the maximum stack size for the main thread in a program.  Without this option a
             program has a 8MB stack.  The argument size is a hexadecimal number with an optional leading
             0x. The size should be a multiple of the architecture's page size (4KB or 16KB).

     -allow_stack_execute
             Marks executable so that all stacks in the task will be given stack execution privilege.
             This includes pthread stacks. This option is only valid when targeting architectures that
             support stack execution (i.e. Intel).

     -export_dynamic
             Preserves all global symbols in main executables during LTO.  Without this option, Link Time
             Optimization is allowed to inline and remove global functions. This option is used when a
             main executable may load a plug-in which requires certain symbols from the main executable.

   Options when creating a bundle
     -bundle_loader executable
             This specifies the executable that will be loading the bundle output file being linked.
             Undefined symbols from the bundle are checked against the specified executable like it was
             one of the dynamic libraries the bundle was linked with.

   Options when creating an object file
     -keep_private_externs
             Don't turn private external (aka visibility=hidden) symbols into static symbols, but rather
             leave them as private external in the resulting object file.

     -d      Force definition of common symbols.  That is, transform tentative definitions into real
             definitions.

   Options that control symbol resolution
     -exported_symbols_list filename
             The specified filename contains a list of global symbol names that will remain as global
             symbols in the output file.  All other global symbols will be treated as if they were marked
             as __private_extern__ (aka visibility=hidden) and will not be global in the output file. The
             symbol names listed in filename must be one per line.  Leading and trailing white space are
             not part of the symbol name.  Lines starting with # are ignored, as are lines with only
             white space.  Some wildcards (similar to shell file matching) are supported.  The * matches
             zero or more characters.  The ? matches one character.  [abc] matches one character which
             must be an 'a', 'b', or 'c'.  [a-z] matches any single lower case letter from 'a' to 'z'.

     -exported_symbol symbol
             The specified symbol is added to the list of global symbols names that will remain as global
             symbols in the output file.  This option can be used multiple times.  For short lists, this
             can be more convenient than creating a file and using -exported_symbols_list.

     -no_exported_symbols
             Useful for main executable that don't have plugins and thus need no symbol exports.

     -unexported_symbols_list file
             The specified filename contains a list of global symbol names that will not remain as global
             symbols in the output file.  The symbols will be treated as if they were marked as
             __private_extern__ (aka visibility=hidden) and will not be global in the output file. The
             symbol names listed in filename must be one per line.  Leading and trailing white space are
             not part of the symbol name.  Lines starting with # are ignored, as are lines with only
             white space.  Some wildcards (similar to shell file matching) are supported.  The * matches
             zero or more characters.  The ? matches one character.  [abc] matches one character which
             must be an 'a', 'b', or 'c'.  [a-z] matches any single lower case letter from 'a' to 'z'.

     -unexported_symbol symbol
             The specified symbol is added to the list of global symbols names that will not remain as
             global symbols in the output file.  This option can be used multiple times.  For short
             lists, this can be more convenient than creating a file and using -unexported_symbols_list.

     -reexported_symbols_list file
             The specified filename contains a list of symbol names that are implemented in a dependent
             dylib and should be re-exported through the dylib being created.

     -alias symbol_name alternate_symbol_name
             Create an alias named alternate_symbol_name for the symbol symbol_name.  By default the
             alias symbol has global visibility.  This option was previous the -idef:indir option.

     -alias_list filename
             The specified filename contains a list of aliases. The symbol name and its alias are on one
             line, separated by whitespace.  Lines starting with # are ignored.

     -flat_namespace
             Alters how symbols are resolved at build time and runtime.  With -two_levelnamespace (the
             default), the linker only searches dylibs on the command line for symbols, and records in
             which dylib they were found.  With -flat_namespace, the linker searches all dylibs on the
             command line and all dylibs those original dylibs depend on.  The linker does not record
             which dylib an external symbol came from, so at runtime dyld again searches all images and
             uses the first definition it finds.  In addition, any undefines in loaded flat_namespace
             dylibs must be resolvable at build time.

     -u symbol_name
             Specified that symbol symbol_name must be defined for the link to succeed.  This is useful
             to force selected functions to be loaded from a static library.

     -U symbol_name
             Specified that it is ok for symbol_name to have no definition.  With -two_levelnamespace,
             the resulting symbol will be marked dynamic_lookup which means dyld will search all loaded
             images.

     -undefined treatment
             Specifies how undefined symbols are to be treated. Options are: error, warning, suppress, or
             dynamic_lookup.  The default is error. Note: dynamic_lookup that depends on lazy binding
             will not work with chained fixups.

     -rpath path
             Add path to the runpath search path list for image being created.  At runtime, dyld uses the
             runpath when searching for dylibs whose load path begins with @rpath/.

     -commons treatment
             Specifies how commons (aka tentative definitions) are resolved with respect to dylibs.
             Options are: ignore_dylibs, error.  The default is ignore_dylibs which means the linker will
             turn a tentative definition in an object file into a real definition and not even check
             dylibs for conflicts.  The error option means the linker should issue an error whenever a
             tentative definition in an object file conflicts with an external symbol in a linked dylib.
             See also -warn_commons.

   Options for introspecting the linker
     -why_load
             Log why each object file in a static library is loaded. That is, what symbol was needed.
             Also called -whyload for compatibility.

     -why_live symbol_name
             Logs a chain of references to symbol_name.  Only applicable with -dead_strip .  It can help
             debug why something that you think should be dead strip removed is not removed.  See
             -exported_symbols_list for syntax and use of wildcards.

     -print_statistics
             Logs information about the amount of memory and time the linker used.

     -t      Logs each file (object, archive, or dylib) the linker loads.  Useful for debugging problems
             with search paths where the wrong library is loaded.

     -order_file_statistics
             Logs information about the processing of a -order_file.

     -map map_file_path
             Writes a map file to the specified path which details all symbols and their addresses in the
             output image.

   Options for controlling symbol table optimizations
     -S      Do not put debug information (STABS or DWARF) in the output file.

     -x      Do not put non-global symbols in the output file's symbol table. Non-global symbols are
             useful when debugging and getting symbol names in back traces, but are not used at runtime.
             If -x is used with -r non-global symbol names are not removed, but instead replaced with a
             unique, dummy name that will be automatically removed when linked into a final linked image.
             This allows dead code stripping, which uses symbols to break up code and data, to work
             properly and provides the security of having source symbol names removed.

     -non_global_symbols_strip_list filename
             The specified filename contains a list of non-global symbol names that should be removed
             from the output file's symbol table.  All other non-global symbol names will remain in the
             output files symbol table. See -exported_symbols_list for syntax and use of wildcards.

     -non_global_symbols_no_strip_list filename
             The specified filename contains a list of non-global symbol names that should be remain in
             the output file's symbol table.  All other symbol names will be removed from the output
             file's symbol table. See -exported_symbols_list for syntax and use of wildcards.

     -oso_prefix prefix-path
             When generating the debug map, the linker will remove the specified prefix-path from the
             path in OSO symbols. This can be used so to help build servers generate identical binaries.
             If '.' is passed as argument, the linker will expand the argument to the current working
             directory.

Leave a Reply

Your email address will not be published. Required fields are marked *