Azure/azure-sdk-for-ios

[BUG] Library not loaded: @rpath/AzureCommunicationCommon.framework/AzureCommunicationCommon

JasonWeinzierl opened this issue · 4 comments

Describe the bug

When installing the AzureCommunicationCalling pod into an iOS app using use_frameworks! :linkage => :static, the iOS app will crash with the following error:

dyld[1857]: Library not loaded: @rpath/AzureCommunicationCommon.framework/AzureCommunicationCommon
  Referenced from: <434CCE2B-75C9-3FDB-B89F-6A64D3190D20> /private/var/containers/Bundle/Application/91B08186-EBDD-4331-801D-543E9ED4B3F1/MyTestApp.app/Frameworks/AzureCommunicationCalling.framework/AzureCommunicationCalling
  Reason: tried: '/usr/lib/swift/AzureCommunicationCommon.framework/AzureCommunicationCommon' (errno=2, not in dyld cache), '/private/preboot/Cryptexes/OS/usr/lib/swift/AzureCommunicationCommon.framework/AzureCommunicationCommon' (errno=2), '/private/var/containers/Bundle/Application/91B08186-EBDD-4331-801D-543E9ED4B3F1/MyTestApp.app/Frameworks/AzureCommunicationCommon.framework/AzureCommunicationCommon' (errno=2), '/private/var/containers/Bundle/Application/91B08186-EBDD-4331-801D-543E9ED4B3F1/MyTestApp.app/Frameworks/AzureCommunicationCalling.framework/Frameworks/AzureCommunicationCommon.framework/AzureCommunicationCommon' (errno=2), '/usr/lib/swift/AzureCommunicationCommon.framework/AzureCommunicationCommon' (errno=2, not in dyld cache), '/private/preboot/Cryptexes/OS/usr/lib/swift/AzureCommunicationCommon.framework/AzureCommunicationCommon' (errno=2), '/private/var/containers/Bundle/Application/91B08186-EBDD-4331-801D-543E9ED4B3F1/MyTestApp.app/Frameworks/AzureCommunicationCommon.framework/AzureCommunicationCommon' (errno=2), '/usr/lib/swift/AzureCommunicationCommon.framework/AzureCommunicationCommon' (errno=2, not in dyld cache), '/private/preboot/Cryptexes/OS/usr/lib/swift/AzureCommunicationCommon.framework/AzureCommunicationCommon' (errno=2), '/private/var/containers/Bundle/Application/91B08186-EBDD-4331-801D-543E9ED4B3F1/MyTestApp.app/Frameworks/AzureCommunicationCommon.framework/AzureCommunicationCommon' (errno=2), '/private/preboot/Cryptexes/OS@rpath/AzureCommunicationCommon.framework/AzureCommunicationCommon' (errno=2), '/usr/lib/swift/AzureCommunicationCommon.framework/AzureCommunicationCommon' (errno=2, not in dyld cache), '/private/preboot/Cryptexes/OS/usr/lib/swift/AzureCommunicationCommon.framework/AzureCommunicationCommon' (errno=2), '/private/var/containers/Bundle/Application/91B08186-EBDD-4331-801D-543E9ED4B3F1/MyTestApp.app/Frameworks/AzureCommunicationCommon.framework/AzureCommunicationCommon' (errno=2), '/private/var/containers/Bundle/Application/91B08186-EBDD-4331-801D-543E9ED4B3F1/MyTestApp.app/Frameworks/AzureCommunicationCalling.framework/Frameworks/AzureCommunicationCommon.framework/AzureCommunicationCommon' (errno=2), '/usr/lib/swift/AzureCommunicationCommon.framework/AzureCommunicationCommon' (errno=2, not in dyld cache), '/private/preboot/Cryptexes/OS/usr/lib/swift/AzureCommunicationCommon.framework/AzureCommunicationCommon' (errno=2), '/private/var/containers/Bundle/Application/91B08186-EBDD-4331-801D-543E9ED4B3F1/MyTestApp.app/Frameworks/AzureCommunicationCommon.framework/AzureCommunicationCommon' (errno=2), '/usr/lib/swift/AzureCommunicationCommon.framework/AzureCommunicationCommon' (errno=2, not in dyld cache), '/private/preboot/Cryptexes/OS/usr/lib/swift/AzureCommunicationCommon.framework/AzureCommunicationCommon' (errno=2), '/private/var/containers/Bundle/Application/91B08186-EBDD-4331-801D-543E9ED4B3F1/MyTestApp.app/Frameworks/AzureCommunicationCommon.framework/AzureCommunicationCommon' (errno=2), '/System/Library/Frameworks/AzureCommunicationCommon.framework/AzureCommunicationCommon' (errno=2, not in dyld cache)

To Reproduce

  1. Create a new App in Xcode.
  2. pod init, then add the following, then pod install. Open the generated Xcode workspace.
target 'MyTestApp' do
  use_frameworks! :linkage => :static

  pod 'AzureCommunicationCalling', '2.3.0'

end
  1. Build will fail with Failed to build module 'AzureCommunicationCalling'; this SDK is not supported by the compiler (the SDK is built with 'Apple Swift version 5.7.2 (swiftlang-5.7.2.135.5 clang-1400.0.29.51)', while this compiler is 'Apple Swift version 5.8 (swiftlang-5.8.0.124.2 clang-1403.0.22.11.100)'). Please select a toolchain which matches the SDK.
  • To resolve this, add a bridging header in Xcode with the following. The build will succeed.
#import <AzureCommunicationCalling/AzureCommunicationCalling.h>
  1. Launch the app on an iPhone. It crashes with the aforementioned stack trace.

Expected behavior

:linkage => :static should work. Not all projects can use :linkage => :dynamic, and there's an existing issue with omitting the use_frameworks! line entirely ( #1517 ).

Setup

  • macOS 13.3.1
  • Xcode 14.3
  • library version 2.3.0

@AikoBB can you take a look at this?

One workaround is switching just the Calling & Common pods to :dynamic, while using static library or static framework for the rest of the pods.

target 'MyTestApp' do

  pod 'AzureCommunicationCalling', '2.3.0'

  pre_install do |installer|
    installer.pod_targets.each do |target|
      case target.name
        when 'AzureCommunicationCommon', 'AzureCommunicationCalling'
          def target.build_type;
            Pod::BuildType.new(:linkage => :dynamic, :packaging => :framework)
          end
      end
    end
  end

end
AikoBB commented

Hi @JasonWeinzierl ! Thanks for reporting it, our team will be looking at the issue.

One workaround is switching just the Calling & Common pods to :dynamic, while using static library or static framework for the rest of the pods.

Note that that only framework expected to be dynamic is AzureCommunicationCommon, I think you could've still link AzureCommunicationCalling statically.

target 'App' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks! :linkage => :static

  # Pods for App
  pod 'AzureCommunicationCalling', '~> 2.3.0'
  
  pre_install do |installer|
      installer.pod_targets.each do |target|
        case target.name
          when 'AzureCommunicationCommon'
            def target.build_type;
              Pod::BuildType.new(:linkage => :dynamic, :packaging => :framework)
            end
        end
      end
  end
end

This is not in itself a bug, but rather a not supported use case, so right now that is the only option due how AzureCommunicationCalling binary framework interact with the AzureCommunicationCommon dependency as it expects that to be a dynamic library.
We distribute the calling binary framework compiled against common library and linked dynamically and require clients to install the common dependency as a dynamic library( if we inspect the mach-o binary we will see a LC_LOAD_DYLIB(AzureCommunicationCommon) as one of the entries for load commands section) and that is why we see the dynamic loader failing at startup of the process(opening the app) because it failed to load the expected dynamic library.

So in other to support this we would have to re-think how we ship the calling binary and the interaction with the common dependency. Maybe link it statically and ship that embedded with the binary? But this needs a bit more investigation as we don't know the consequences of that but right of the start we can expect an increase on binary size for all customers and maybe we could hit ABI limitations.
But this is definitely something we can experiment with =]