Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent Transitive Dependency Errors in Swift Project with Vendored Frameworks #3289

Closed
blakewatters opened this issue Mar 18, 2015 · 34 comments
Assignees

Comments

@blakewatters
Copy link

I’ve recently had to push a release of two of my libraries that included a workaround for the transitive dependency error:

[!] The 'Pods' target has transitive dependencies that include static binaries: (<path>/Pods/LayerKit/LayerKit.framework

The setup of the pods is this:

  1. We internally build LayerKit from a number of internal and external dependencies
  2. We produce a distribution framework and podspec using cocoapods-packager. The Podspec pulls in the framework via vendors_frameworks (see the podspec here)
  3. We recently released Atlas, an Open Source UI library that has a direct dependency on LayerKit.

Under Objective-C projects in v0.35.0 and v0.36.0, this installs without issue. In a project with a Podfile that includes Swift dependencies such as:

platform :ios, '8.0'
use_frameworks!

pod 'Atlas', '= 1.0.1’

# Swift Pods
pod 'SwiftyJSON'
pod 'OAuthSwift'

You run into the transitive dependency issue referenced above. In researching this problem I found mention somewhere that the problem is that since the dependency (LayerKit) doesn’t have any source files, its linking process is different from a source based pod and the error is triggered.

I managed to work around this in Atlas v1.0.2 by adding a dummy source file to my distribution repository and pulling it into the podspec. See the file here and the relevant podspec change here.

So my question is:

  1. Is the transitive dependency error actually an error or is this a case that would succeed?
  2. If this workaround is necessary, can/should we just handle the creation of the dummy source file within CP so that pod authors don’t have to do it?

/cc @neonichu @segiddins

@neonichu neonichu self-assigned this Mar 18, 2015
@neonichu
Copy link
Member

I'm assuming that LayerKit is only used via Atlas in this case? Could you also try what happens if you were to import and use LayerKit directly in the target app?

@blakewatters
Copy link
Author

@neonichu Do you mean import it as a direct dependency also in the podfile?

@neonichu
Copy link
Member

@blakewatters No, I meant actually importing the module and using it inside the app directly.

@fluidsonic
Copy link
Contributor

We have a similar structure where one Pod of our app (ChatModule) depends on LayerKit, which contains a static binary.
This was working fine so far (though with evil hacks) but the latest CocoaPods update just forbids this behavior and we cannot build our project anymore.

Is there any reason this is an error instead of a warning??

PS: If I recall correct we link the static library to the app target and use -undefined dynamic_lookup in the ChatModule Pod.

PPS: We hope this is a temporary workaround until @blakewatters releases a dynamic framework version of LayerKit :)

@neonichu
Copy link
Member

We made this fail to front-load inevitable build failures, a warning that basically says "this will not build" would be weird :) It obviously shouldn't stop any working cases, though, so it might need to be even more specific.

@blakewatters
Copy link
Author

eh sigh @neonichu you are correct — it’s having trouble resolving the Obj-C imports both within Atlas and if you directly import LayerKit. I’ll pull the source file workaround that prevented the build failure as its just moved it from Pod install time to build time.

What’s the remedy here? Do I need to declare Swift as unsupported until the packager can output dynamic frameworks?

@segiddins
Copy link
Member

Well, you can support Swift as long as your users are using a bridging header

On Mar 19, 2015, at 10:49 AM, Blake Watters <notifications@github.com mailto:notifications@github.com> wrote:

eh sigh @neonichu https://github.com/neonichu you are correct — it’s having trouble resolving the Obj-C imports both within Atlas and if you directly import LayerKit. I’ll pull the source file workaround that prevented the build failure as its just moved it from Pod install time to build time.

What’s the remedy here? Do I need to declare Swift as unsupported until the packager can output dynamic frameworks?


Reply to this email directly or view it on GitHub #3289 (comment).

@neonichu
Copy link
Member

@segiddins and are not integrating any Swift pods.

One way out could be moving the vendored LayerKit into the Atlas podspec directly, instead of a dependency, then it would all be linked into one dynamic framework.

@blakewatters
Copy link
Author

Would building LayerKit as a dynamic framework improve the situation or is vendoring LayerKit such that it rolls up into one installable unit the only choice? I’m still trying to get my head around the exact problem space here as I haven’t done any Swift work yet

@segiddins
Copy link
Member

Pretty sure that building it as a dynamic framework is all that's needed.

@neonichu
Copy link
Member

Building as a dynamic framework would also eventually work, the vendoring approach was more a workaround suggestion.

At the moment, CP doesn't handle dynamic frameworks properly (see #1993) and there's possibly additional changes involved to make them work as transitive dependencies once that is done.

@fluidsonic
Copy link
Contributor

Until this issue is resolved we worked around the static library check by simply disabling it in the Podfile:

pre_install do |installer|
    internalInstaller = installer.installer
    def internalInstaller.verify_no_static_framework_transitive_dependencies; end
end

We can build again :)

@neonichu
Copy link
Member

Closing, as there is nothing for us to do here.

@foobra
Copy link

foobra commented Apr 27, 2015

@fluidsonic how do you do pod lint? The error still happend

@fluidsonic
Copy link
Contributor

We're just using such a pod dependency and don't use pod lint.
I have no idea whether the workaround will work there.

@cooler333
Copy link

cooler333 commented Jul 14, 2016

fix for Podspec Podfile

    pre_install do |installer|
        def installer.verify_no_static_framework_transitive_dependencies; end
    end

@k06a
Copy link

k06a commented Oct 21, 2016

@cooler333 are you sure it can be written in podspec? Can't make it work.

@cooler333
Copy link

@k06a read again)

@k06a
Copy link

k06a commented Oct 21, 2016

@cooler333 I am working on library that have a problem with dependency pod. And I have problems with pod spec lint. I need to fix it in podspec, not 'podfile'.

@cooler333
Copy link

@k06a look at YandexMapKit Podspec.

how they integrate static library.

  "ios": {
    "vendored_libraries": "libYandexMapKit.a"
  }

I'm trying do the same in my swift library, but with no success.
If you fix this error, please, give me feedback.

@cooler333
Copy link

@k06a Does You try to integrate sub pod with static library inside it?

@k06a
Copy link

k06a commented Oct 21, 2016

My podspec have s.dependency 'PLCrashReporter' which have vendored_libraries inside itself. So my podspec can not be verified because of dependency issues.

@k06a
Copy link

k06a commented Oct 21, 2016

@neonichu we are unable to have a dependencies with static libraries inside because can not manipulate installer.verify_no_static_framework_transitive_dependencies from a podspec. How we can solve our problem?

@k06a
Copy link

k06a commented Oct 21, 2016

@orta, @neonichu why static libraries can not be statically linked with some stub pod target, which will produce dynamic framework while use_frameworks! is active?

@ghost
Copy link

ghost commented Jul 3, 2018

It was not added to the latest cocoapod, which is 1.5 something

@nicubarbaros
Copy link

@fluidsonic Thanks

@iba-ragi
Copy link

iba-ragi commented Nov 1, 2018

Thanks!!
I had same problem.

@noamtamim
Copy link

I publish a pod that requires apps to add this workaround to their Podfile. However, when I try to lib lint my pod, the build fails because of this issue.
Is there any way I can apply this workaround to "Pods-App" that is generated by lib lint?

@darhonbek
Copy link

Thank you @fluidsonic ❤️

@martinthedinov
Copy link

martinthedinov commented Sep 2, 2020

I believe in the latest version of Pods it's not installer but install. That change (which Pods tells you about anyway if you had tried the installer version) works.

pre_install do |installer|
    internalInstaller = installer.installer
    def internalInstaller.verify_no_static_framework_transitive_dependencies; end
end

but:

pre_install do |installer|
    internalInstaller = installer.installer
    def internalInstaller.verify_no_static_framework_transitive_dependencies; end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests