Cocoapods: Podspec containing internal fat framework via vendored_frameworks is not finding the current compiled architecture (on example project)

Created on 15 Jan 2017  路  16Comments  路  Source: CocoaPods/CocoaPods

Report

What did you do?

I'm trying to wrap a dynamic _"fat"_ framework inside a pod and exposing an interface to internally use that framework, but not exposing it.

I've included the project of that framework on the following folder: SampleDynamicLib/ and copied the generated SampleDynamicLib.framework to the Pod's Frameworks folder:
BundledCocoapodDynamicFrameworkError/Frameworks/
Referenced on podspec via:
s.vendored_frameworks = 'BundledCocoapodDynamicFrameworkError/Frameworks/SampleDynamicLib.framework'

(using a simple symlink was making cocoapods to not properly integrating the framework, so I copied the generated _framework_ instead).

The pod example project is located on the Example dir.
I've run: bundle && bundle exec pod install on the example project folder to install the development pod.

What did you expect to happen?

I was hoping to integrate a closed source dynamic _"fat"_ framework inside a pod to avoid embedding the framework directly in the project.

What happened instead?

I cannot build my app since when I try to use the pod the app target always triggers an error claiming that the internal framework (active architecture slice) cannot be found:

ld: framework not found SampleDynamicLib for architecture x86_64
or when compiling to the device:
ld: framework not found SampleDynamicLib for architecture arm64

The weird thing is: this is a fat framework and ALL the architecture slices are inside the framework binary, check via file command:

$ file BundledCocoapodDynamicFrameworkError/Frameworks/SampleDynamicLib.framework/SampleDynamicLib

BundledCocoapodDynamicFrameworkError/Frameworks/SampleDynamicLib.framework/SampleDynamicLib: Mach-O universal binary with 4 architectures: [i386: Mach-O dynamically linked shared library i386] [x86_64: Mach-O 64-bit dynamically linked shared library x86_64] [arm_v7: Mach-O dynamically linked shared library arm_v7] [arm64: Mach-O 64-bit dynamically linked shared library arm64]
BundledCocoapodDynamicFrameworkError/Frameworks/SampleDynamicLib.framework/SampleDynamicLib (for architecture i386):    Mach-O dynamically linked shared library i386
BundledCocoapodDynamicFrameworkError/Frameworks/SampleDynamicLib.framework/SampleDynamicLib (for architecture x86_64):  Mach-O 64-bit dynamically linked shared library x86_64
BundledCocoapodDynamicFrameworkError/Frameworks/SampleDynamicLib.framework/SampleDynamicLib (for architecture armv7):   Mach-O dynamically linked shared library arm_v7
BundledCocoapodDynamicFrameworkError/Frameworks/SampleDynamicLib.framework/SampleDynamicLib (for architecture arm64):   Mach-O 64-bit dynamically linked shared library arm64

This is the second fat framework that I'm trying to integrate, in 2 different projects and this error always pops.

CocoaPods Environment

Stack

   CocoaPods : 1.2.0.rc.1
        Ruby : ruby 2.3.3p222 (2016-11-21 revision 56859) [x86_64-darwin16]
    RubyGems : 2.5.2
        Host : Mac OS X 10.12.2 (16C67)
       Xcode : 8.2.1 (8C1002)
         Git : git version 2.11.0
Ruby lib dir : /Users/ricardo.santos/.rbenv/versions/2.3.3/lib
Repositories : master - https://github.com/CocoaPods/Specs.git @ fd00cc25c25fbd7b8994db04fb398018d18db4dd
               swiftyjson - https://github.com/SwiftyJSON/SwiftyJSON.git @ adf34cfb4c9f2ff4e3c420c6d9fb1e2eaf3b3791

Installation Source

Executable Path: /Users/ricardo.santos/.rbenv/versions/2.3.3/bin/pod

Plugins

cocoapods-deintegrate : 1.0.1
cocoapods-plugins     : 1.0.0
cocoapods-search      : 1.0.0
cocoapods-stats       : 1.0.0
cocoapods-trunk       : 1.1.2
cocoapods-try         : 1.1.0

Podfile

use_frameworks!

target 'BundledCocoapodDynamicFrameworkError_Example' do
  pod 'BundledCocoapodDynamicFrameworkError', :path => '../'

  target 'BundledCocoapodDynamicFrameworkError_Tests' do
    inherit! :search_paths

    pod 'Quick', '~> 1.0.0'
    pod 'Nimble', '~> 5.1.1'
  end
end

Project that demonstrates the issue

This is the example of the pod that wraps a fat .framework here: https://github.com/crsantos/BundledCocoapodDynamicFrameworkError

If you have any more doubts, please shout.

hard confirmed defect

Most helpful comment

We are seeing the same issue with Google Analytics using 1.2.0 but not with 1.2.0.rc1 any thoughts on this would be great.

All 16 comments

We are seeing the same issue with Google Analytics using 1.2.0 but not with 1.2.0.rc1 any thoughts on this would be great.

I believe this is confirmed. Seems like the -framework "SampleDynamicLib" is not added. Perhaps because its a local development pod will keep digging.

@crsantos the way to work around is by splitting your podspec into two, one for your lib with the sources and another one with just the vendored framework. I did it locally and it worked. I understand this is not ideal but we are discussing whether this has to change in CocoaPods.

Do you mean separate specs or just a Core spec for my wrapper lib and a subspec for the vendored framework?

One note: I don't have the source of the vendored framework

Not sure if the subspec would work but worth a shot. Splitting into two different podspecs should work.

I will try it and come back to you to confirm, but I guess that solution is perfectly viable 馃憤
Much better than embedding the framework directly on .pbxproj 馃槃

@dnkoutso We are seeing the same issue with simply using Google Analytics as a vendor dependency, it is working fine in a 1.2.0.rc1 but the 1.2.0 release something seems to have changed.

Example Podfile:

platform :ios, '9.0'

#Workspace
workspace 'SampleProjectIOS'

#Project
project 'SampleProject/SampleProject.xcodeproj'

def common_pods
    #Pods
    pod 'Google/Analytics'
    pod 'Google/SignIn'

end

target 'SampleProject' do
    use_frameworks!
    common_pods
    target 'SampleProjectTests' do
        inherit! :search_paths
        pod 'Nimble', '~> 5.1.1'
    end
end

Any thoughts?

Catching up:

Not sure if the subspec would work but worth a shot. Splitting into two different podspecs should work.

Didn't work using subspec, as you suspected.

the way to work around is by splitting your podspec into two, one for your lib with the sources and another one with just the vendored framework

Confirmed and it works fine having a podspec with only the vendored framework.

The tradeoffs are

  • I need to create a second pod just to wrap the first one (or I don't need it at all if I jut use the framework's public headers directly)
  • I can't import my "framework only" pod via its podspec name, but I have to import SampleDynamicLib instead

So for my case, that can work fine, my main problem was how can I reuse this dynamic framework across projects without embedding it in the project.

The main issue is: If we bundle some sources that try to access that vendored framework, the build will fail as @dnkoutso stated, because -framework "SampleDynamicLib" is not being added.

Thanks @dnkoutso for the tips. 馃挭

@crsantos would you mind sharing your two Podspecs? I'm having the same issue and not sure I understand what the 2 Podspecs need to contain.

Thanks!

Sure, my bad. Here you can check the 2 gists:

This is using the same repo for both specs and sources: SameRepoForAllPodSpecsAndSource

SampleDynamicLibPod.podspec
WrapperAroundSampleDynamicLibPod.podspec

One caveat: on the wrapper, you can't import SampleDynamicLibPod module name.
But the import SampleDynamicLib instead, we already discussed that above.

Don't forget that using multiple podspecs on the same repo requires some care: like FacebookSDk does, you can prefix your tags with the name of the module: :tag => "#{s.name}-#{s.version.to_s}".

If you have any doubt, please shout. Hope that helps

NOTE : if you don't need to wrap something around your Dynamic library, you can opt out the second podspec.

@crsantos Thanks for the info. It seems I have similar problem. However I wasn't able to solve it with your approach. Maybe you have completed example https://github.com/crsantos/BundledCocoapodDynamicFrameworkError with the podspecs you have given and you can push it to master or another branch. I would really appreciate it.

Thanks, anyway.

@Sander-Kornev The repo you linked is the proof that the error occurs.
How to bypass it is just a matter of using 2 specs like I explained on the previous comment

with these two podspecs gists:
SampleDynamicLibPod.podspec
WrapperAroundSampleDynamicLibPod.podspec

NOTE on the SampleDynamicLibPod you can't have any code that imports the framework, only on WrapperAroundSampleDynamicLibPod

I might have a closer look at this and figure it out.

Should this work with development pods? I am running 1.3.1 and it seems that the dSYM is not copied (or symlinked).

@crsantos I try 2 podspec on my project but get this error when run pod install on project that use Wrapper pod spec

target has transitive dependencies that include static binaries: (PATH TO .framework)

Have you got this error too?

Have you got this error too?

@sarunw Can't remember, but I guess not.
The problem I stated happened on 1.2.0.rc.1, I don't know if this still happens.
But I passed that a long time ago, by creating just a POD1 with just the framework inside, and creating another POD2 that wraps POD1 and uses it as a dependency.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

iosdev-republicofapps picture iosdev-republicofapps  路  3Comments

steffendsommer picture steffendsommer  路  3Comments

sonu5 picture sonu5  路  3Comments

tlandsmancars picture tlandsmancars  路  3Comments

k06a picture k06a  路  3Comments