Use dyld to link in frameworks at runtime. Use ld to make your programs and link archive libraries at build time.

Linker Documentation

Pinned Posts

Posts under Linker tag

165 Posts
Sort by:
Post not yet marked as solved
1 Replies
83 Views
I have an iOS SwiftUI app which uses some extensions like NotificationServiceExtension, NotificationContentExtension, WidgetExtension etc. I noticed that each extension uses its own process and has its own bundle with the .appex extension... and is packaged within the app bundle, with .app extension. In my case, most of my logic is in C++ and when the app starts up, it needs to 'startup' the C++ layer. Now, in WidgetExtension, if it's going to read data from disk and update its interface, I need to initialise my C++ layer first. The same can be said for NotificationServiceExtension. This is leading me to include all my C++ artefacts into the extension target as well. Here's my problem: If the size of my app (containing all my C++ artefacts) is 10MB and I'm using 20 extensions (say), the final size of the shipped app bundle is 10MB + (20 * 10MB) = 210MB, since extension bundle (.appex) is packaged within the app bundle (.app). Since the app and the extensions are using the same C++ artefacts, I was hoping to have one binary in the bundle. The app and its extensions will point to this binary. When the app is launched, the app entry point (struct conforming to App protocol) is invoked, in case of widget, the widget entry point (WidgetBundle) is invoked and so on for each extension. This will reduce the final size of the app bundle. Is it possible to have one binary and the app target, all extension targets would use this binary for there functioning?
Posted Last updated
.
Post not yet marked as solved
0 Replies
81 Views
Xcode 15 introduced official support for static frameworks. docs here This is presumably because there's quite a bit over overlap with the mergeable libraries feature. Static frameworks potentially give developers a nice option for bundling resources with a static library. This was previously only really viable if you explicitly packaged up a .bundle with your .a (static library) which could be cumbersome for both the creator and consumer of a library. Or you explicitly copied your framework resources into your main app binary when building your app. The release notes for Xcode 15 state: Embedding a static framework using a Copy Files build phase now removes the static archive from the framework when it is embedded in the target bundle. When inspecting the app target on disk this appears to be the case. In fact the behaviour is the same as with a mergable in release mode whereby a "stub" binary exists with no symbols. The release notes also state: The COPY_RESOURCES_FROM_STATIC_FRAMEWORKS build setting, previously used in the legacy build system to extract and copy the resources from a static framework to the target bundle, no longer has any effect with the new build system as the entire framework is copied instead This also appears to be the case when inspecting the files on disk as the frameworks appear to be present in the main app with their resources. So far so good. The issue arises when trying to access the bundle associated with this framework. The documentation doesn't mention any special access requirements to it's assumed that standard bundle access APIs should work. Using a class let bundle = Bundle(for: InfoCoreMain.self) This returns the main application bundle and therefore fails to find the correct asset. This can be rationalised by the fact that the InfoCoreMain class does now actually exist within the main app target binary due to being statically linked. It's worth noting however, that mergable libraries in release mode do seem to work in this way and can resolve the bundle fine*. Using an explicit bundle identifier let bundle = Bundle(identifier: "***.***.InfoCore") Using an explicit bundle identifier returns nil even though we can see the framework on disk. Using a path Using a path to access the framework also doesn't work. if let bundlePath = Bundle.main.path(forResource: "InfoCore", ofType: "framework") { let bundle = Bundle(path: bundlePath) // Now you can access resources in the framework bundle } else { // Framework bundle not found } All of the above is the same behaviour for release and debug builds. I have tried this on Xcode 15.2 and 15.3 *Mergeable libraries do seem to have issues in debug mode. See this forum post. https://forums.developer.apple.com/forums/thread/749818
Posted
by Rednaz.
Last updated
.
Post not yet marked as solved
11 Replies
2.2k Views
It seems impossible to me, but around the time I installed the latest command line tools (xcode-select version 2397) binaries what were built with linkages to @rpath/libfoo.dyld stopped being able to find their dependency. The error looks like this. dyld[1471]: Symbol not found: _GEOSGeomGetX Referenced from: <16DBE67F-CB32-31EE-BCE0-BFB58EEC9740> /Users/pramsey/tmp/capi_indexed_predicate Expected in: <no uuid> unknown zsh: abort ./capi_indexed_predicate If I turn on DYLD_PRINT_SEARCHING, I can see the linker giving up on the rpath entry. dyld[1501]: find path "@rpath/libgeos_c.1.dylib" dyld[1501]: not found: "@rpath/libgeos_c.1.dylib" I can work around, partially, by setting DYLD_LIBRARY_FALLBACK_PATH to have /usr/local/lib in it, but that is only a partial fix, because SIP will strip that variable for any child processes, which means most of my development and database work is borked. This seems like a very new quirk, maybe related to the XCode 15 update, at least in my personal time line, has anyone else seen it, or have any clue as to what has changed? (Worth noting, nothing changed in my code, just one day my builds wouldn't run anymore, and that day was the day after I had installed the new commandline tools).
Posted
by pwramsey3.
Last updated
.
Post not yet marked as solved
1 Replies
83 Views
Assuming I have a static library where all global symbols need to be re-exported by the target executable. How do I extract these symbols into a file to be used with ld's -exported_symbols_list and Xcode's EXPORTED_SYMBOLS_FILE? I was thinking about nm -gUjo … + sed but maybe there is abetter way?
Posted
by Kentzo.
Last updated
.
Post not yet marked as solved
1 Replies
74 Views
Hello Apple Developer Community, I am currently working on an xCode project that uses Objective-C and I am trying to integrate Apple's external purchase link APIs available in iOS 15.4. To use these APIs, I need to utilize async and completion handlers which are available from iOS 13 onwards. The issue I'm facing is that the current minimum deployment version for my project is iOS 12. I would like to ensure my code compiles properly for the correct iOS versions and I am also using #if available; to ensure this. However, I am unsure of how to guarantee my code builds effectively with the deployment version being set to either iOS 12 or 13. I am currently facing the following linker errors: ld: warning: Could not find or use auto-linked library 'swiftCompatibility56': library 'swiftCompatibility56' not found ld: warning: Could not find or use auto-linked library 'swiftCompatibilityConcurrency': library 'swiftCompatibilityConcurrency' not found ld: warning: Could not find or use auto-linked library 'swiftCompatibilityPacks': library 'swiftCompatibilityPacks' not found ld: Undefined symbols: __swift_FORCE_LOAD_$_swiftCompatibility51, referenced from: __swift_FORCE_LOAD_$_swiftCompatibility51_$_ProjectXYZ in ProjectXYZ.a[20](ExternalPurchaseLinkWrapper.o) __swift_FORCE_LOAD_$_swiftCompatibility56, referenced from: __swift_FORCE_LOAD_$_swiftCompatibility56_$_ProjectXYZ in ProjectXYZ.a[20](ExternalPurchaseLinkWrapper.o) __swift_FORCE_LOAD_$_swiftCompatibilityConcurrency, referenced from: __swift_FORCE_LOAD_$_swiftCompatibilityConcurrency_$_ProjectXYZ in ProjectXYZ.a[20](ExternalPurchaseLinkWrapper.o) clang: error: linker command failed with exit code 1 (use -v to see invocation) I would appreciate any guidance or advice on this matter. How do I ensure my code compiles and works only for the correct versions and how do I resolve the linker errors? Thank you in advance for your assistance. Best, Sumanth
Posted Last updated
.
Post not yet marked as solved
0 Replies
5.3k Views
Apple’s library technology has a long and glorious history, dating all the way back to the origins of Unix. This does, however, mean that it can be a bit confusing to newcomers. This is my attempt to clarify some terminology. If you have any questions or comments about this, start a new thread and tag it with Linker so that I see it. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" An Apple Library Primer Apple’s tools support two related concepts: Platform — This is the platform itself; macOS, iOS, iOS Simulator, and Mac Catalyst are all platforms. Architecture — This is a specific CPU architecture used by a platform. arm64 and x86_64 are both architectures. A given architecture might be used by multiple platforms. The most obvious example of this arm64, which is used by all of the platforms listed above. Code built for one platform will not work on another platform, even if both platforms use the same architecture. Code is usually packaged in either a Mach-O file or a static library. Mach-O is used for executables, dynamic libraries, bundles, and object files. These can have a variety of different extensions; the only constant is that .o is always used for a Mach-O containing an object file. Use otool and nm to examine a Mach-O file. Use vtool to quickly determine the platform for which it was built. Use size to get a summary of its size. Use dyld_info to get more details about a dynamic library. IMPORTANT All the tools mentioned here are documented in man pages; for information on how to access that documentation, see Reading UNIX Manual Pages. The term Mach-O image refers to a Mach-O that can be loaded and executed without further processing. That includes executables, dynamic libraries, and bundles, but not object files. A dynamic library has the extension .dylib. You may also see this called a shared library. A framework is a bundle structure with the .framework extension that has both compile-time and run-time roles: At compile time, the framework combines the library’s headers and its stub library (stub libraries are explained below). At run time, the framework combines the library’s code, as a Mach-O dynamic library, and its associated resources. The exact structure of a framework varies by platform. For the details, see Placing Content in a Bundle. macOS supports both frameworks and standalone dynamic libraries. Other Apple platforms support frameworks but not standalone dynamic libraries. Historically these two roles were combined, that is, the framework included the headers, the dynamic library, and its resources. These days Apple ships different frameworks for each role. That is, the macOS SDK includes the compile-time framework and macOS itself includes the run-time one. Most third-party frameworks continue to combine these roles. A static library is an archive of one or more object files. It has the extension .a. Use ar, libtool, and ranlib to inspect and manipulate these archives. The static linker, or just the linker, runs at build time. It combines various inputs into a single output. Typically these inputs are object files, static libraries, dynamic libraries, and various configuration items. The output is most commonly a Mach-O image, although it’s also possible to output an object file. The linker may also output metadata, such as a link map (see Using a Link Map to Track Down a Symbol’s Origin). The linker has seen three major implementations: ld — This dates from the dawn of Mac OS X. ld64 — This was a rewrite started in the 2005 timeframe. Eventually it replaced ld completely. If you type ld, you get ld64. ld_prime — This was introduced with Xcode 15. This isn’t a separate tool. Rather, ld now supports the -ld_classic and -ld_new options to select a specific implementation. Note During the Xcode 15 beta cycle these options were -ld64 and -ld_prime. I continue to use those names because the definition of new changes over time (some of us still think of ld64 as the new linker ;–). The dynamic linker loads Mach-O images at runtime. Its path is /usr/lib/dyld, so it’s often referred to as dyld, dyld, or DYLD. Personally I pronounced that dee-lid, but some folks say di-lid and others say dee-why-el-dee. IMPORTANT Third-party executables must use the standard dynamic linker. Other Unix-y platforms support the notion of a statically linked executable, one that makes system calls directly. This is not supported on Apple platforms. Apple platforms provide binary compatibility via system dynamic libraries and frameworks, not at the system call level. Note Apple platforms have vestigial support for custom dynamic linkers (your executable tells the system which dynamic linker to use via the LC_LOAD_DYLINKER load command). This facility originated on macOS’s ancestor platform and has never been a supported option on any Apple platform. The dynamic linker has seen 4 major revisions. See WWDC 2017 Session 413 (referenced below) for a discussion of versions 1 through 3. Version 4 is basically a merging of versions 2 and 3. The dyld man page is chock-full of useful info, including a discussion of how it finds images at runtime. One of the most common points of confusion with dynamic linker is the way that the dynamic linker identifies dynamic libraries. There are two standard approaches to this, as described in Dynamic Library Identification. Xcode 15 introduced the concept of a mergeable library. This a dynamic library with extra metadata that allows the linker to embed it into the output Mach-O image, much like a static library. Mergeable libraries have many benefits. For all the backstory, see WWDC 2023 Session 10268 Meet mergeable libraries. For instructions on how to set this up, see Configuring your project to use mergeable libraries. If you put a mergeable library into a framework structure you get a mergeable framework. Xcode 15 also introduced the concept of a static framework. This is a framework structure where the framework’s dynamic library is replaced by a static library. Note It’s not clear to me whether this offers any benefit over creating a mergeable framework. Earlier versions of Xcode did not have proper static framework support. That didn’t stop folks trying to use them, which caused all sorts of weird build problems. A universal binary is a file that contains multiple architectures for the same platform. Universal binaries always use the universal binary format. Use the file command to learn what architectures are within a universal binary. Use the lipo command to manipulate universal binaries. A universal binary’s architectures are either all in Mach-O format or all in the static library archive format. The latter is called a universal static library. A universal binary has the same extension as its non-universal equivalent. That means a .a file might be a static library or a universal static library. Most tools work on a single architecture within a universal binary. They default to the architecture of the current machine. To override this, pass the architecture in using a command-line option, typically -arch or --arch. An XCFramework is a single document package that includes libraries for any combination of platforms and architectures. It has the extension .xcframework. An XCFramework holds either a framework, a dynamic library, or a static library. All the elements must be the same type. Use xcodebuild to create an XCFramework. For specific instructions, see Xcode Help > Distribute binary frameworks > Create an XCFramework. Historically there was no need to code sign libraries in SDKs. If you shipped an SDK to another developer, they were responsible for re-signing all the code as part of their distribution process. Xcode 15 changes this. You should sign your SDK so that a developer using it can verify this dependency. For more details, see WWDC 2023 Session 10061 Verify app dependencies with digital signatures and Verifying the origin of your XCFrameworks. A stub library is a compact description of the contents of a dynamic library. It has the extension .tbd, which stands for text-based description (TBD). Apple’s SDKs include stub libraries to minimise their size; for the backstory, read this post. Stub libraries currently use YAML format, a fact that’s relevant when you try to interpret linker errors. Use the tapi tool to create and manipulate these files. In this context TAPI stands for a text-based API, an alternative name for TBD. Oh, and on the subject of tapi, I’d be remiss if I didn’t mention tapi-analyze! Mach-O uses a two-level namespace. When a Mach-O image imports a symbol, it references the symbol name and the library where it expects to find that symbol. This improves both performance and reliability but it precludes certain techniques that might work on other platforms. For example, you can’t define a function called printf and expect it to ‘see’ calls from other dynamic libraries because those libraries import the version of printf from libSystem. To help folks who rely on techniques like this, macOS supports a flat namespace compatibility mode. This has numerous sharp edges — for an example, see the posts on this thread — and it’s best to avoid it where you can. If you’re enabling the flat namespace as part of a developer tool, search the ’net for dyld interpose to learn about an alternative technique. WARNING Dynamic linker interposing is not documented as API. While it’s a useful technique for developer tools, do not use it in products you ship to end users. Apple platforms use DWARF. When you compile a file, the compiler puts the debug info into the resulting object file. When you link a set of object files into a executable, dynamic library, or bundle for distribution, the linker does not include this debug info. Rather, debug info is stored in a separate debug symbols document package. This has the extension .dSYM and is created using dsymutil. Use symbols to learn about the symbols in a file. Use dwarfdump to get detailed information about DWARF debug info. Use atos to map an address to its corresponding symbol name. Different languages use different name mangling schemes: C, and all later languages, add a leading underscore (_) to distinguish their symbols from assembly language symbols. C++ uses a complex name mangling scheme. Use the c++filt tool to undo this mangling. Likewise, for Swift. Use swift demangle to undo this mangling. Over the years there have been some really good talks about linking and libraries at WWDC, including: WWDC 2023 Session 10268 Meet mergeable libraries WWDC 2022 Session 110362 Link fast: Improve build and launch times WWDC 2022 Session 110370 Debug Swift debugging with LLDB WWDC 2021 Session 10211 Symbolication: Beyond the basics WWDC 2019 Session 416 Binary Frameworks in Swift — Despite the name, this covers XCFrameworks in depth. WWDC 2018 Session 415 Behind the Scenes of the Xcode Build Process WWDC 2017 Session 413 App Startup Time: Past, Present, and Future WWDC 2016 Session 406 Optimizing App Startup Time Note The older talks are no longer available from Apple, but you may be able to find transcripts out there on the ’net. Historically Apple published a document, Mac OS X ABI Mach-O File Format Reference, or some variant thereof, that acted as the definitive reference to the Mach-O file format. This document is no longer available from Apple. If you’re doing serious work with Mach-O, I recommend that you find an old copy. It’s definitely out of date, but there’s no better place to get a high-level introduction to the concepts. The Mach-O Wikipedia page has a link to an archived version of the document. For the most up-to-date information about Mach-O, see the declarations and doc comments in <mach-o/loader.h>. Revision History 2024-05-08 Added links to the demangling tools. 2024-04-30 Clarified the requirement to use the standard dynamic linker. 2024-03-02 Updated the discussion of static frameworks to account for Xcode 15 changes. Removed the link to WWDC 2018 Session 415 because it no longer works )-: 2024-03-01 Added the WWDC 2023 session to the list of sessions to make it easier to find. Added a reference to Using a Link Map to Track Down a Symbol’s Origin. Made other minor editorial changes. 2023-09-20 Added a link to Dynamic Library Identification. Updated the names for the static linker implementations (-ld_prime is no more!). Removed the beta epithet from Xcode 15. 2023-06-13 Defined the term Mach-O image. Added sections for both the static and dynamic linkers. Described the two big new features in Xcode 15: mergeable libraries and dependency verification. 2023-06-01 Add a reference to tapi-analyze. 2023-05-29 Added a discussion of the two-level namespace. 2023-04-27 Added a mention of the size tool. 2023-01-23 Explained the compile-time and run-time roles of a framework. Made other minor editorial changes. 2022-11-17 Added an explanation of TAPI. 2022-10-12 Added links to Mach-O documentation. 2022-09-29 Added info about .dSYM files. Added a few more links to WWDC sessions. 2022-09-21 First posted.
Posted
by eskimo.
Last updated
.
Post not yet marked as solved
0 Replies
59 Views
Recently a bunch of folks have asked about why a specific symbol is being referenced by their app. This is my attempt to address that question. If you have questions or comments, please start a new thread. Tag it with Linker so that I see it. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" Determining Why a Symbol is Referenced In some situations you might want to know why a symbol is referenced by your app. For example: You might be working with a security auditing tool that flags uses of malloc. You might be creating a privacy manifest and want to track down where your app is calling stat. This post is my attempt at explaining a general process for tracking down the origin of these symbol references. This process works from ‘below’. That is, it works ‘up’ from you app’s binary rather than ‘down’ from your app’s source code. That’s important because: It might be hard to track down all of your source code, especially if you’re using one or more package management systems. If your app has a binary dependency on a static library, dynamic library, or framework, you might not have access to that library’s source code. IMPORTANT This post assumes the terminology from An Apple Library Primer. Read that before continuing here. The general outline of this process is: Find all Mach-O images. Find the Mach-O image that references the symbol. Find the object files (.o) used to make that Mach-O. Find the object file that references the symbol. Find the code within that object file. This post assumes that you’re using Xcode. If you’re using third-party tools that are based on Apple tools, and specifically Apple’s linker, you should be able to adapt this process to your tooling. If you’re using a third-party tool that has its own linker, you’ll need to ask for help via your tool’s support channel. Find all Mach-O images On Apple platforms an app consists of a number of Mach-O images. Every app has a main executable. The app may also embed dynamic libraries or frameworks. The app may also embed app extensions or system extensions, each of which have their own executable. And a Mac app might have embedded bundles, helper tools, XPC services, agents, daemons, and so on. To find all the Mach-O images in your app, combine the find and file tools. For example: % find "Apple Configurator.app" -print0 | xargs -0 file | grep Mach-O Apple Configurator.app/Contents/MacOS/Apple Configurator: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit executable x86_64] [arm64] … Apple Configurator.app/Contents/MacOS/cfgutil: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit executable x86_64] [arm64:Mach-O 64-bit executable arm64] … Apple Configurator.app/Contents/Extensions/ConfiguratorIntents.appex/Contents/MacOS/ConfiguratorIntents: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit executable x86_64] [arm64:Mach-O 64-bit executable arm64] … Apple Configurator.app/Contents/Frameworks/ConfigurationUtilityKit.framework/Versions/A/ConfigurationUtilityKit: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit dynamically linked shared library x86_64] [arm64] … This shows that Apple Configurator has a main executable (Apple Configurator), a helper tool (cfgutil), an app extension (ConfiguratorIntents), a framework (ConfigurationUtilityKit), and many more. This output is quite unwieldy. For nicer output, create and use a shell script like this: % cat FindMachO.sh #! /bin/sh # Passing `-0` to `find` causes it to emit a NUL delimited after the # file name and the `:`. Sadly, macOS `cut` doesn’t support a nul # delimiter so we use `tr` to convert that to a DLE (0x01) and `cut` on # that. # # Weirdly, `find` only inserts the NUL on the primary line, not the # per-architecture Mach-O lines. We use that to our advantage, filtering # out the per-architecture noise by only passing through lines # containing a DLE. find "$@" -type f -print0 \ | xargs -0 file -0 \ | grep -a Mach-O \ | tr '\0' '\1' \ | grep -a $(printf '\1') \ | cut -d $(printf '\1') -f 1 Find the Mach-O image that references the symbol Once you have a list of Mach-O images, use nm to find the one that references the symbol. The rest of this post investigate a test app, WaffleVarnishORama, that’s written in Swift but uses waffle management functionality from the libWaffleCore.a static library. The goal is to find the code that calls calloc. This app has a single Mach-O image: % FindMachO.sh "WaffleVarnishORama.app" WaffleVarnishORama.app/WaffleVarnishORama Use nm to confirm that it references calloc: % nm "WaffleVarnishORama.app/WaffleVarnishORama" | grep "calloc" U _calloc The _calloc symbol has a leading underscore because it’s a C symbol. This convention dates from the dawn of Unix, where the underscore distinguish C symbols from assembly language symbols. The U prefix indicates that the symbol is undefined, that is, the Mach-O images is importing the symbol. If the symbol name is prefixed by a hex number and some other character, like T or t, that means that the library includes an implementation of calloc. That’s weird, but certainly possible. OTOH, if you see this then you know this Mach-O image isn’t importing calloc. IMPORTANT If this Mach-O isn’t something that you build — that is, you get this Mach-O image as a binary from another developer — you won’t be able to follow the rest of this process. Instead, ask for help via that library’s support channel. Find the object files used to make that Mach-O image The next step is to track down which .o file includes the reference to calloc. Do this by generating a link map. A link map is an old school linker feature that records the location, size, and origin of every symbol added to the linker’s output. To generate a link map, enable the Write Link Map File build setting. By default this puts the link map into a text (.txt) file within the derived data directory. To find the exact path, look at the Link step in the build log. If you want to customise this, use the Path to Link Map File build setting. A link map has three parts: A simple header A list of object files used to build the Mach-O image A list of sections and their symbols In our case the link map looks like this: # Path: …/WaffleVarnishORama.app/WaffleVarnishORama # Arch: arm64 # Object files: [ 0] linker synthesized [ 1] objc-file [ 2] …/AppDelegate.o [ 3] …/MainViewController.o [ 4] …/libWaffleCore.a[2](WaffleCore.o) [ 5] …/Foundation.framework/Foundation.tbd … # Sections: # Address Size Segment Section 0x100008000 0x00001AB8 __TEXT __text … The list of object files contains: An object file for each of our app’s source files — That’s AppDelegate.o and MainViewController.o in this example. A list of static libraries — Here that’s just libWaffleCore.a. A list of dynamic libraries — These might be stub libraries (.tbd), dynamic libraries (.dylib), or frameworks (.framework). Focus on the object files and static libraries. The list of dynamic libraries is irrelevant because each of those is its own Mach-O image. Find the object file that references the symbol Once you have list of object files and static libraries, use nm to each one for the calloc symbol: % nm "…/AppDelegate.o" | grep calloc % nm "…/MainViewController.o" | grep calloc % nm "…/libWaffleCore.a" | grep calloc U _calloc This indicates that only libWaffleCore.a references the calloc symbol, so let’s focus on that. Note As in the Mach-O case, the U prefix indicates that the symbol is undefined, that is, the object file is importing the symbol. Find the code within that object file To find the code within the object file that references the symbol, use the objdump tool. That tool takes an object file as input, but in this example we have a static library. That’s an archive containing one or more object files. So, the first step is to unpack that archive: % mkdir "libWaffleCore-objects" % cd "libWaffleCore-objects" % ar -x "…/libWaffleCore.a" % ls -lh total 24 -rw-r--r-- 1 quinn staff 4.1K 8 May 11:24 WaffleCore.o -rw-r--r-- 1 quinn staff 56B 8 May 11:24 __.SYMDEF SORTED There’s only a single object file in that library, which makes things easy. If there were a multiple, run the following process over each one independently. To find the code that references a symbol, run objdump with the -S and -r options: % xcrun objdump -S -r "WaffleCore.o" … ; extern WaffleRef newWaffle(void) { 0: d10083ff sub sp, sp, #32 4: a9017bfd stp x29, x30, [sp, #16] 8: 910043fd add x29, sp, #16 c: d2800020 mov x0, #1 10: d2800081 mov x1, #4 ; Waffle * result = calloc(1, sizeof(Waffle)); 14: 94000000 bl 0x14 <ltmp0+0x14> 0000000000000014: ARM64_RELOC_BRANCH26 _calloc … Note the ARM64_RELOC_BRANCH26 line. This tells you that the instruction before that — the bl at offset 0x14 — references the _calloc symbol. IMPORTANT The ARM64_RELOC_BRANCH26 relocation is specific to the bl instruction in 64-bit Arm code. You’ll see other relocations for other instructions. And the Intel architecture has a whole different set of relocations. So, when searching this output don’t look for ARM64_RELOC_BRANCH26 specifically, but rather any relocation that references _calloc. In this case we’ve built the object file from source code, so WaffleCore.o contains debug symbols. That allows objdump include information about the source code context. From that, we can easily see that calloc is referenced by our newWaffle function. To see what happens when you don’t have debug symbols, create an new object file with them stripped out: % cp "WaffleCore.o" "WaffleCore-stripped.o" % strip -x -S "WaffleCore-stripped.o" Then repeat the objdump command: % xcrun objdump -S -r "WaffleCore-stripped.o" … 0000000000000000 <_newWaffle>: 0: d10083ff sub sp, sp, #32 4: a9017bfd stp x29, x30, [sp, #16] 8: 910043fd add x29, sp, #16 c: d2800020 mov x0, #1 10: d2800081 mov x1, #4 14: 94000000 bl 0x14 <_newWaffle+0x14> 0000000000000014: ARM64_RELOC_BRANCH26 _calloc … While this isn’t as nice as the previous output, you can still see that newWaffle is calling calloc.
Posted
by eskimo.
Last updated
.
Post marked as solved
1 Replies
143 Views
Xcode version: 15.2, iOS deployment target 15.0 When experimenting with the new Xcode 15/new linker feature "Mergable Libraries" I came across an issue with subproject framework products. I have a workspace with two projects. I want to create a group framework named GroupFramework that consists of three other frameworks. FrameworkA, FrameworkB and FrameworkC. FrameworkA and FrameworkB are in the same project as the group framework I want to create. FrameworkC is a product of another project in my workspace. GroupFramework has all three frameworks linked in the "link binary with libraries" build phase. GroupFramework has "Create merged binary" set to manual because I want to control which frameworks are linked. FrameworkA, FrameworkB and FrameworkC all have "Build mergeabe library" set to YES. The application builds in both RELEASE and DEBUG. Running in DEBUG and RELEASE When running the application on a device in DEBUG or RELEASE it crashes with a linker error because FrameworkC can't be found on disk. When inspecting the app binary in RELEASE I can see that FrameworkA and FrameworkB are both in the ReexportedBinary folder, but FrameworkC is nowhere to be seen. I have tried embedding FrameworkC explicitly in the settings of the GroupFramework essentially creating an umbrella framework, and that also does not fix the issue. I have also tried embedding FrameworkC directly into the AppTarget that will consume GroupFramework. This solves the linking issue but a new issue regarding unresolved symbols then crops up. It appears as though the Reexporting and Merging of subproject frameworks is not working compared to a product that exists in the same project or at least may require a lot more manual configuration which is not currently documented anywhere. If this is the case, it could be very problematic when trying to adopt mergeable libraries in multi-project workspaces.
Posted
by Rednaz.
Last updated
.
Post not yet marked as solved
1 Replies
340 Views
I am wondering where the source code of ld-prime is on Github. There are references to it in the github for dyld, but I can't find it anywhere. I have a suspicion that it uses LLVM for linking. I'm looking out of curiosity to see if Apple is slowly closing down its compile toolchain and maybe learn how Apple sped up the linking stage.
Posted Last updated
.
Post not yet marked as solved
2 Replies
126 Views
The documentation about the Disable Library Validation Entitlement mentioned that the macOS dynamic linker (dyld) provides a detailed error message when the system prevents code from loading due to library validation. You can find more information here: https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_cs_disable-library-validation I need assistance in locating the dynamic linker (dyld) on macOS Ventura 13.0. What are the various methods available to locate it? How can I access or open it for reading? Additionally, do I need any external tools to facilitate this process? My ultimate goal is to examine the detailed error message to identify any issues I am encountering with my application. Additionally, I have found one at /usr/lib/dyld, but it's not human-readable, nor does it have timestamps for whatever is logged. Based on my findings, I should be able to locate dyld at System/Library, but I can't find it there either.
Posted Last updated
.
Post not yet marked as solved
1 Replies
99 Views
Hi Everyone, This is my first post here. I am a student looking for answers, and I would like to know how to use libraries such as the ones mentioned in the title. How do I link them? I have tried every method under the sun, but I cannot get Xcode to find the file I am trying to include.
Posted
by Ccervera.
Last updated
.
Post not yet marked as solved
2 Replies
148 Views
I'm doing the python dynamic module loading dance. As you likely know, this is not the typical shared library scenario described on all the docs, where an executable is linked against an existing shared lib. Instead cythonized python modules need to call back to the interpreter that loaded them for various functions. Thus, when creating the interpreter, some manner of symbol export must happen, which can then later be linked into a module's dynamic lib to resolve interpreter symbols. With GNU/GCC this is all magic with the -shared flag (perhaps GNU's weak symbol feature, unsupported on macOS, helps out?). With a MingW GCC variant on Windows -Wl,--output-def python.def is required, followed by dlltool -d python.def -l python.dll.a, which creates some object thingy that can be linked into the subsequent module .so files. I played with lipo python -create -output libpython.dylib on macOS, but saw that no one else uses this and abandoned it. The python3 on Darwin uses clang -bundle -undefined dynamic_lookup, but when I roll my own custom interpreter, building a module by hand with the above gives: ld: warning: -undefined dynamic_lookup may not work with chained fixups ... whatever that means. Link args of -bundle -bundle_loader ../python result in NO errors or warnings, but my interpreter cannot load these module .so files either, probably due to some error I have not yet unmasked. I am hoping to find a solution that works for both Xcode and Homebrew, and that will last for a decade or so, but for now would be happy getting something to work today.
Posted
by duanev.
Last updated
.
Post marked as Apple Recommended
627 Views
I am using #canImport(JournalingSuggestions), but something is going wrong and my app is attempting to import the framework on iPad, and crashing on launch. How can I ensure that it's properly filtered out from everything except iPhone? import SwiftUI #if canImport(JournalingSuggestions) import JournalingSuggestions #endif struct JournalingSuggestionsView: View { var body: some View { #if canImport(JournalingSuggestions) JournalingSuggestionsPicker { Text("Open Journaling Suggestions") } onCompletion: { suggestion in print(suggestion) } #else Text("Journaling suggestions not available on this platform.") #endif } } Error: dyld[8689]: Library not loaded: /System/Library/Frameworks/JournalingSuggestions.framework/JournalingSuggestions Referenced from: <A656E6BC-4883-3245-BE71-3F84C2F41119> /private/var/containers/Bundle/Application/C6C11F57-AFAA-442A-B726-7AADDDB50D79/Catalog.app/Catalog Reason: tried: '/System/Library/Frameworks/JournalingSuggestions.framework/JournalingSuggestions' (no such file), '/private/preboot/Cryptexes/OS/System/Library/Frameworks/JournalingSuggestions.framework/JournalingSuggestions' (no such file), '/System/Library/Frameworks/JournalingSuggestions.framework/JournalingSuggestions' (no such file, not in dyld cache) System info: Xcode 15.2 iPadOS 17.3.1
Posted
by aenewton.
Last updated
.
Post marked as solved
5 Replies
335 Views
It's not possible to merge a framework with resource into an iOS app target because the resource are not included in the app bundle. Steps to reproduce: Create an Xcode Project with iOS App Template Add a Framework Target (make sure to "Embed in Application") Add an Asset Catalog to Framework Target Add an Color Resource (or Image Set, or any other Resource) Reference the Resource in App Target (I have used a SwiftUI View) Run on Device (!) to make sure everything works as expected Change "Create Merged Binary (MERGED_BINARY_TYPE)" build setting of app target to "Automatic (automatic)" Change app target settings to link, but not embed framework target (e.g. change from "Embed and Sign" to "Do Not Embed" in "Frameworks, Libraries and Embedded Content" section in "General" tab) Run again (on Device!) and observe how the resources framework resource cannot be found anymore (using SwiftUI you will see a "No image/color named '...' in asset catalog for ..." error message in console logs) Note: Everything works fine in Simulator Same behavior for Release and Debug configuration Same behavior for manual and automatic merging Same behavior for resources which are not bundled in Asset Catalog When archiving the app, an "Assets.car" file is never present (even when creating archiving for Simulator target, when "Allow archiving for Simulator" is enabled) Reported as FB13716505 Test Project: https://github.com/iteracticman/MergeableResources/
Posted
by peweone.
Last updated
.
Post not yet marked as solved
1 Replies
217 Views
Xcode 15.2 linker error (Assertion failed: (rebasePtr->target == low56), function writeChainEntry, file ChainedFixups.cpp, line 1218) The same project builds fine on Xcode 14.3.1. It also builds fine when building a debug build to device. Any ideas on what we might be doing wrong?
Posted
by jacck.
Last updated
.
Post not yet marked as solved
1 Replies
308 Views
Hello everyone, Our iOS app is taking too long to launch. On checking the launch profile, we are seeing that most of the launch time is being spent in applying fixups which is taking more than a second and at times even more to complete. Our deployment target is iOS 15+. We have checked using dyld_info that our binary uses chained fixups. Since chained fixups are enabled, page-in linking should also be enabled for our app as per this WWDC session. Can someone please help us understand why the fixups application is taking this long and how can we improve it? Thanks.
Posted Last updated
.
Post not yet marked as solved
1 Replies
216 Views
Hi, I am splitting my iOS app into smaller components, the natural way of doing this is to create static libraries that I can link with the main binary. I did succeed at making small static libraries (.a) and link them, but I was struggling with static framework where I have color assets. Finally I was able to make it work by going to the app target > Build Phases > Copy Bundle Resources and add there the .xcassets from the static framework I created. The confusion on my side is that the assets are accessed from the Framework code not from the app target code, and the guidance I am asking for is: How to create and link a static framework on iOS so that the framework can load and use it's own defined assets without having to do the Copy Bundle Resources step. Best Regards, Ion
Posted
by iostafi.
Last updated
.
Post not yet marked as solved
1 Replies
236 Views
Hi everyone, Our app runs on iOS deployment target 15.0. As per the WWDC 2022 session, page-in linking should be enabled for apps where chained-fixups is enabled. Since chained fixups are enabled from iOS deployment target 13.4+ which is true for our app, will page-in linking be applied to it? Is there some flag which we can use to confirm if it is applied for our app or not? We have tried using dyld_info tool but could not find a command which can provide this information.
Posted Last updated
.
Post not yet marked as solved
4 Replies
675 Views
I have a React-Native App that I am trying to build to iOS using Xcode. When I build to my iPhone 12 Mini (iOS 17.4.1), the app works perfectly. When I build to my iPhone 7 Plus (iOS 15.8.2), the app pauses running immediately, and Xcode displays the following in the log: dyld[935]: Symbol not found: (_JSGlobalContextSetInspectable) Referenced from: '/private/var/containers/Bundle/Application/2579192B-74C5-4B54-AA59-948C49A4A7CA/MANHUNT2.app/MANHUNT2' Expected in: '/System/Library/Frameworks/JavaScriptCore.framework/JavaScriptCore' The app used to work perfectly on both phones, but this error has been happening recently, and I am unsure of the cause. Cleaning build folder and deleting derived data has not fixed the issue. Xcode: Version 15.3 React-Native: 0.73.6 Working Phone: iOS 17.4.1 Non-Working Phone: iOS 15.8.2
Posted Last updated
.