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 · 29 comments

Comments

Projects
None yet
@blakewatters

blakewatters commented Mar 18, 2015

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

This comment has been minimized.

Show comment
Hide comment
@neonichu

neonichu Mar 18, 2015

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?

Member

neonichu commented Mar 18, 2015

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

This comment has been minimized.

Show comment
Hide comment
@blakewatters

blakewatters Mar 18, 2015

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

blakewatters commented Mar 18, 2015

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

@neonichu

This comment has been minimized.

Show comment
Hide comment
@neonichu

neonichu Mar 18, 2015

Member

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

Member

neonichu commented Mar 18, 2015

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

@fluidsonic

This comment has been minimized.

Show comment
Hide comment
@fluidsonic

fluidsonic Mar 18, 2015

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 :)

Contributor

fluidsonic commented Mar 18, 2015

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

This comment has been minimized.

Show comment
Hide comment
@neonichu

neonichu Mar 18, 2015

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.

Member

neonichu commented Mar 18, 2015

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

This comment has been minimized.

Show comment
Hide comment
@blakewatters

blakewatters Mar 19, 2015

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?

blakewatters commented Mar 19, 2015

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

This comment has been minimized.

Show comment
Hide comment
@segiddins

segiddins Mar 19, 2015

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).

Member

segiddins commented Mar 19, 2015

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

This comment has been minimized.

Show comment
Hide comment
@neonichu

neonichu Mar 19, 2015

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.

Member

neonichu commented Mar 19, 2015

@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

This comment has been minimized.

Show comment
Hide comment
@blakewatters

blakewatters Mar 19, 2015

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

blakewatters commented Mar 19, 2015

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

This comment has been minimized.

Show comment
Hide comment
@segiddins

segiddins Mar 19, 2015

Member

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

Member

segiddins commented Mar 19, 2015

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

@neonichu

This comment has been minimized.

Show comment
Hide comment
@neonichu

neonichu Mar 19, 2015

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.

Member

neonichu commented Mar 19, 2015

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

This comment has been minimized.

Show comment
Hide comment
@fluidsonic

fluidsonic Mar 20, 2015

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 :)

Contributor

fluidsonic commented Mar 20, 2015

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

This comment has been minimized.

Show comment
Hide comment
@neonichu

neonichu Apr 12, 2015

Member

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

Member

neonichu commented Apr 12, 2015

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

@neonichu neonichu closed this Apr 12, 2015

@foobra

This comment has been minimized.

Show comment
Hide comment
@foobra

foobra Apr 27, 2015

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

foobra commented Apr 27, 2015

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

@fluidsonic

This comment has been minimized.

Show comment
Hide comment
@fluidsonic

fluidsonic Apr 27, 2015

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.

Contributor

fluidsonic commented Apr 27, 2015

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

This comment has been minimized.

Show comment
Hide comment
@cooler333

cooler333 Jul 14, 2016

fix for Podspec Podfile

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

cooler333 commented Jul 14, 2016

fix for Podspec Podfile

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

This comment has been minimized.

Show comment
Hide comment
@k06a

k06a Oct 21, 2016

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

k06a commented Oct 21, 2016

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

@cooler333

This comment has been minimized.

Show comment
Hide comment
@cooler333

cooler333 commented Oct 21, 2016

@k06a read again)

@k06a

This comment has been minimized.

Show comment
Hide comment
@k06a

k06a 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'.

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

This comment has been minimized.

Show comment
Hide comment
@cooler333

cooler333 Oct 21, 2016

@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 commented Oct 21, 2016

@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

This comment has been minimized.

Show comment
Hide comment
@cooler333

cooler333 Oct 21, 2016

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

cooler333 commented Oct 21, 2016

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

@k06a

This comment has been minimized.

Show comment
Hide comment
@k06a

k06a 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 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

This comment has been minimized.

Show comment
Hide comment
@k06a

k06a 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 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

This comment has been minimized.

Show comment
Hide comment
@k06a

k06a 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?

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?

@orta

This comment has been minimized.

Show comment
Hide comment
@orta

orta Oct 21, 2016

Member

@k06a CocoaPods does not support frameworks with transitive static libraries - as mentioned in this thread, and many others - notably #1993, you need to have them compiled into dynamic libraries to use on trunk.

The code being passed around is a way to turn off the error reporter. You should not be trying to ship code into production.

Member

orta commented Oct 21, 2016

@k06a CocoaPods does not support frameworks with transitive static libraries - as mentioned in this thread, and many others - notably #1993, you need to have them compiled into dynamic libraries to use on trunk.

The code being passed around is a way to turn off the error reporter. You should not be trying to ship code into production.

@fluidsonic

This comment has been minimized.

Show comment
Hide comment
@fluidsonic

fluidsonic Jul 7, 2017

Contributor

Since 1.3.0.beta.2 the workaround is now like this:

pre_install do |installer|
	# workaround for https://github.com/CocoaPods/CocoaPods/issues/3289
	Pod::Installer::Xcode::TargetValidator.send(:define_method, :verify_no_static_framework_transitive_dependencies) {}
end

Yup, we still need that and it works perfectly.

Contributor

fluidsonic commented Jul 7, 2017

Since 1.3.0.beta.2 the workaround is now like this:

pre_install do |installer|
	# workaround for https://github.com/CocoaPods/CocoaPods/issues/3289
	Pod::Installer::Xcode::TargetValidator.send(:define_method, :verify_no_static_framework_transitive_dependencies) {}
end

Yup, we still need that and it works perfectly.

@GalaevAlexey

This comment has been minimized.

Show comment
Hide comment
@GalaevAlexey

GalaevAlexey Oct 10, 2017

Thanks a lot!

GalaevAlexey commented Oct 10, 2017

Thanks a lot!

@yasirmturk

This comment has been minimized.

Show comment
Hide comment
@yasirmturk

yasirmturk Jan 5, 2018

how to push such podspec to trunk?? it also causes lint failure

yasirmturk commented Jan 5, 2018

how to push such podspec to trunk?? it also causes lint failure

@fssrepository

This comment has been minimized.

Show comment
Hide comment
@fssrepository

fssrepository Jul 3, 2018

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

fssrepository commented Jul 3, 2018

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment