Cocoapods: Linking issues for static versus dynamic frameworks and test targets

Created on 31 Oct 2018  ·  9Comments  ·  Source: CocoaPods/CocoaPods

Report

This gets a little complicated. I'm trying to make sure that I can add support for integration of my own libraries as static and dynamic frameworks. The first part of testing is taking one of the most basic projects and making sure I can update it as both static and dynamic and run unit tests.
I'm seeing strange issues in all of my attempts to get this to work.

Here is the starting Podfile:

platform :ios, '9.0'
use_frameworks!

target 'MyFramework' do
  pod 'Smartling.i18n', '1.0.14', :inhibit_warnings => true
  pod 'Starscream', '3.0.5', :inhibit_warnings => true
  pod 'ReachabilitySwift', '4.2.1'
end

target 'MyFrameworkTests' do
  pod 'Smartling.i18n', '1.0.14', :inhibit_warnings => true
  pod 'Starscream', '3.0.5', :inhibit_warnings => true
  pod 'ReachabilitySwift', '4.2.1'
end

When installing this, the unit tests work 100%. If I change from use_frameworks to use_modular_headers to convert from dynamic to static frameworks, the tests fail. The failure in this case is because the tests have to initialize an instance of a class that is specific to the Starscream framework and pass it to a function in MyFramework, but that instance is not exactly the same as instances natively created in MyFramework (which I think is expected, since in the unit tests in this case, the instance is really part of MyFrameworkTest.Starscream.Class instead of MyFramework.Starscream.Class).

To resolve this issue, I change the Podfile to the following:

platform :ios, '9.0'
use_modular_headers!

target 'MyFramework' do
  pod 'Smartling.i18n', '1.0.14', :inhibit_warnings => true
  pod 'Starscream', '3.0.5', :inhibit_warnings => true
  pod 'ReachabilitySwift', '4.2.1'

  target 'MyFrameworkTests' do
    inherit! :search_paths
  end
end

When I install this, the unit tests pass as expected. Unfortunately, if I change this back to use_frameworks, the tests now cannot run because of a linking error:

2018-10-31 14:47:24.932556-0400 xctest[70598:433759] The bundle “MyFrameworkTests” couldn’t be loaded because it is damaged or missing necessary resources. Try reinstalling the bundle.
2018-10-31 14:47:24.932882-0400 xctest[70598:433759] (dlopen_preflight(/Users/jszymanski/Library/Developer/Xcode/DerivedData/MyFramework-gtgqernucigaahgcvatneajsxzxc/Build/Products/Debug-iphonesimulator/MyFrameworkTests.xctest/TMyFrameworkTests): Library not loaded: @rpath/Reachability.framework/Reachability
  Referenced from: /Users/jszymanski/Library/Developer/Xcode/DerivedData/MyFramework-gtgqernucigaahgcvatneajsxzxc/Build/Products/Debug-iphonesimulator/MyFrameworkTests.xctest/MyFrameworkTests
  Reason: image not found)
Program ended with exit code: 82

I'm not sure what the best next steps are to try to resolve this issue.

CocoaPods Environment

Stack

   CocoaPods : 1.6.0.beta.2
        Ruby : ruby 2.2.5p319 (2016-04-26 revision 54774) [x86_64-darwin15]
    RubyGems : 2.4.8
        Host : Mac OS X 10.13.6 (17G65)
       Xcode : 10.0 (10A255)
         Git : git version 2.17.1 (Apple Git-112)
Ruby lib dir : /Users/jszymanski/.rvm/rubies/ruby-2.2.5/lib
Repositories : lovoo - [email protected]:lovoo/ios-specs.git @ d60470418ea3b47e24a54274a8aec59171b35fa4
               master - https://github.com/CocoaPods/Specs.git @ 9665656523d0323aae3e23e186baa0a6532fc9c4
               maxads - https://github.com/MAXAds/Specs @ 6cd81d1fa34f22fd7c00f59efb10f756697c945c

Installation Source

Executable Path: /Users/jszymanski/.rvm/gems/ruby-2.2.5/bin/pod

Plugins

cocoapods-deintegrate : 1.0.2
cocoapods-plugins     : 1.0.0
cocoapods-search      : 1.0.0
cocoapods-stats       : 1.0.0
cocoapods-trunk       : 1.3.1
cocoapods-try         : 1.1.0

Podfile

platform :ios, '9.0'
use_frameworks!

target 'MyFramework' do
  pod 'Smartling.i18n', '1.0.14', :inhibit_warnings => true
  pod 'Starscream', '3.0.5', :inhibit_warnings => true
  pod 'ReachabilitySwift', '4.2.1'

  target 'MyFrameworkTests' do
    inherit! :search_paths
  end
end

Project that demonstrates the issue

I don't currently have a sample project. I can look into generating a new project that shows the issue when I can get some time available.

awaiting input

Most helpful comment

I described a similar issue here. Changing inherit! to :complete solved this issue for me on Framework UnitTests target.

  target 'FrameworkTests' do
-    inherit! :search_paths
+    inherit! :complete
    ...
  end

All 9 comments

Likely you should rm -rf ~/Library/Developer/Xcode/DerivedData when switching between build types so that remnants from the previous configuration don't corrupt the new one.

Deleting derived data has no impact on the results of my testing. The issues seem to be related to how the linking works, particularly for the nested case (which is how I would expect this case to need to be configured).

@paulb777 I ran into the same issue w/ a universal framework, so I don't think it's always about switching build types.

In my case, it's because the test target doesn't get a [CP] Embed Pods Frameworks run script so it can't find the universal framework the app target is linked to. Once you duplicate the app target's run script onto a UI test target, it works.

Repro project: https://github.com/rob-keepsafe/PodTestFrameworks

I'm using CocoaPods 1.5.x's static lib support

I just noticed that in the case I am testing using the starting Podfile, I see the warning:

objc[12160]: Class _TtCC10Starscream9WebSocket10WSResponse is implemented in both MyFramework.framework/MyFramework (0x11f403e08) and MyFrameworkTests.xctest/MyFramework (0x11ef77140). One of the two will be used. Which one is undefined.

Which leads me to believe that this is definitely an issue where I'm supposed to be using the second nested version of the Podfile, even though I can't run any tests with it using dynamic frameworks.

Any other ideas @paulb777? This is currently blocking us from moving to using static frameworks.

@phalladar As far as I can tell, this issue has nothing to do with static frameworks. Static frameworks must be specified in a podspec. As far as I can tell, this issue is about switching between dynamic frameworks and static libraries via Podfile configurations.

I described a similar issue here. Changing inherit! to :complete solved this issue for me on Framework UnitTests target.

  target 'FrameworkTests' do
-    inherit! :search_paths
+    inherit! :complete
    ...
  end

There hasn't been any activity on this issue recently. Due to the high number of incoming GitHub notifications, we have to clean some of the old issues, as many of them have already been resolved with the latest updates.

This issue will be auto-closed because there hasn't been any activity for a few months. Feel free to open a new one if you still experience this problem :+1:

Was this page helpful?
0 / 5 - 0 ratings