Uploaded image for project: 'Swift'
  1. Swift
  2. SR-11907

Inferred Weak Linking when building an SPM package does not seem to be working

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Open
    • Priority: Medium
    • Resolution: Unresolved
    • Component/s: None
    • Labels:
      None
    • Environment:

      Description

      Swift compiler is not inferring that an imported system framework should be weak linked based on availability guards around code that accesses symbols in that framework. Or the compiler is erroneously marking the protected symbols as strongly referenced.

      I've filed this as FB7471728 but realized it should probably have been filed here instead.

      I found this related swift forum post ( https://forums.swift.org/t/weak-linking-of-frameworks-with-greater-deployment-targets/26017 ) which lists several feedback's filed on this from back in June (SwiftUI in their case, but it's a general problem as can be seen by this non-SwiftUI case: FB6170959 and FB6187287).

      In my case, I create a simple executable Swift package manage project and import CryptoKit (which is macOS 15+ only) and then put the code that references it inside #if available( iOS 13, macOS 15, *) {   // code referencing CryptoKit here   }

      On macOS 10.14.6 the project will fail to launch with the error:

      $ swift run

      dyld: Library not loaded: /System/Library/Frameworks/CryptoKit.framework/Versions/A/CryptoKit Referenced from: /Users/tyler/Desktop/testpkg/.build/x86_64-apple-macosx/debug/testpkg

      Reason: image not found

      Abort trap: 6

      if I comment out the code that accesses CryptoKit then the code will run fine.

      Sample project is on github here:

      Steps:

      1. clone the repo
      2. cd into the repo directory
      3. swift build
      4. once built, execute the resulting binary with:  

          ./.build/debug/testwlbug

       

      -> If you're on 10.14.x it should give you the same error.
      -> On 10.15.x it should work fine.

      On 10.14.x if you comment out the four lines inside the { } block protected by the if #available(...) and rebuild and run it it will run just fine.

      (if using Xcode then you'll have to go into Library/Derived Data/... to find the binary to execute it on the command line, but otherwise the same steps of get repo, build it, execute the resulting binary in terminal work to show the result).

       


      Update:

      Looking at the built binary with Hopper, I wonder if this is related?

      There is a function outside of the #available macro code that the compiler generated that accesses CryptoKit:

      int _$s9CryptoKit8InsecureO10SHA1DigestVAeA0E0AAWl() {
          rax = *lazy protocol witness table cache variable for type CryptoKit.Insecure.SHA1Digest and conformance CryptoKit.Insecure.SHA1Digest : CryptoKit.Digest in CryptoKit;
          var_8 = rax;
          if (rax == 0x0) {
                  rax = type metadata accessor for CryptoKit.Insecure.SHA1Digest(0xff);
                  rax = swift_getWitnessTable(*protocol conformance descriptor for CryptoKit.Insecure.SHA1Digest : CryptoKit.Digest in CryptoKit, rax, rax);
                  *lazy protocol witness table cache variable for type CryptoKit.Insecure.SHA1Digest and conformance CryptoKit.Insecure.SHA1Digest : CryptoKit.Digest in CryptoKit = rax;
                  var_8 = rax;
          }
          rax = var_8;
          return rax;
      }
      

        Attachments

          Activity

            People

            Assignee:
            Unassigned
            Reporter:
            haikuty Tyler M
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Dates

              Created:
              Updated: