trinhngocthuyen / cocoapods-spm

A CocoaPods plugin to add SPM dependencies to CocoaPods-based projects
MIT License
36 stars 7 forks source link

[QUESTION] NoMethodError - undefined method `linkage' for nil #33

Closed gajddo00 closed 5 months ago

gajddo00 commented 5 months ago

Hey, thanks a lot for the plugin. Unfortunately I haven't been able to make it work with my setup so I want to ask whether this scenario is even supported. It's similar to the examples except the local pod also has a Podfile with SPM dependencies.

Project

iOSSharedModule

If I run pod install on the iOSSharedModule, all works fine and the SPM package is imported correctly. But when I run pod install on Project that imports iOSSharedModule, I get this error

### Error
NoMethodError - undefined method `linkage' for nil
/opt/homebrew/lib/ruby/gems/3.3.0/gems/cocoapods-spm-0.1.0/lib/cocoapods-spm/def/spm_dependency.rb:19:in `linkage'
/opt/homebrew/lib/ruby/gems/3.3.0/gems/cocoapods-spm-0.1.0/lib/cocoapods-spm/def/spm_dependency.rb:23:in `dynamic?'
/opt/homebrew/lib/ruby/gems/3.3.0/gems/cocoapods-spm-0.1.0/lib/cocoapods-spm/hooks/pre_integrate/update_settings.rb:62:in `select'
/opt/homebrew/lib/ruby/gems/3.3.0/gems/cocoapods-spm-0.1.0/lib/cocoapods-spm/hooks/pre_integrate/update_settings.rb:62:in `linker_flags_for'
/opt/homebrew/lib/ruby/gems/3.3.0/gems/cocoapods-spm-0.1.0/lib/cocoapods-spm/hooks/pre_integrate/update_settings.rb:52:in `block in update_linker_flags'
/opt/homebrew/lib/ruby/gems/3.3.0/gems/cocoapods-spm-0.1.0/lib/cocoapods-spm/hooks/base.rb:62:in `block in perform_settings_update'
/opt/homebrew/lib/ruby/gems/3.3.0/gems/cocoapods-spm-0.1.0/lib/cocoapods-spm/hooks/base.rb:69:in `block (2 levels) in perform_settings_update'
/opt/homebrew/lib/ruby/gems/3.3.0/gems/cocoapods-spm-0.1.0/lib/cocoapods-spm/hooks/base.rb:68:in `each'
/opt/homebrew/lib/ruby/gems/3.3.0/gems/cocoapods-spm-0.1.0/lib/cocoapods-spm/hooks/base.rb:68:in `block in perform_settings_update'
/opt/homebrew/lib/ruby/gems/3.3.0/gems/cocoapods-spm-0.1.0/lib/cocoapods-spm/hooks/base.rb:67:in `each'
/opt/homebrew/lib/ruby/gems/3.3.0/gems/cocoapods-spm-0.1.0/lib/cocoapods-spm/hooks/base.rb:67:in `perform_settings_update'
/opt/homebrew/lib/ruby/gems/3.3.0/gems/cocoapods-spm-0.1.0/lib/cocoapods-spm/hooks/pre_integrate/update_settings.rb:49:in `update_linker_flags'
/opt/homebrew/lib/ruby/gems/3.3.0/gems/cocoapods-spm-0.1.0/lib/cocoapods-spm/hooks/pre_integrate/update_settings.rb:11:in `run'
/opt/homebrew/lib/ruby/gems/3.3.0/gems/cocoapods-spm-0.1.0/lib/cocoapods-spm/hooks/base.rb:49:in `block (2 levels) in run_hooks'
/opt/homebrew/lib/ruby/gems/3.3.0/gems/cocoapods-1.15.2/lib/cocoapods/user_interface.rb:149:in `message'
/opt/homebrew/lib/ruby/gems/3.3.0/gems/cocoapods-spm-0.1.0/lib/cocoapods-spm/hooks/base.rb:48:in `block in run_hooks'
/opt/homebrew/lib/ruby/gems/3.3.0/gems/cocoapods-spm-0.1.0/lib/cocoapods-spm/hooks/base.rb:44:in `each'
/opt/homebrew/lib/ruby/gems/3.3.0/gems/cocoapods-spm-0.1.0/lib/cocoapods-spm/hooks/base.rb:44:in `run_hooks'
/opt/homebrew/lib/ruby/gems/3.3.0/gems/cocoapods-spm-0.1.0/lib/cocoapods-spm/patch/installer.rb:49:in `run_spm_pre_integrate_hooks'
/opt/homebrew/lib/ruby/gems/3.3.0/gems/cocoapods-spm-0.1.0/lib/cocoapods-spm/patch/installer.rb:33:in `integrate'
/opt/homebrew/lib/ruby/gems/3.3.0/gems/cocoapods-1.15.2/lib/cocoapods/installer.rb:170:in `install!'
/opt/homebrew/lib/ruby/gems/3.3.0/gems/cocoapods-1.15.2/lib/cocoapods/command/install.rb:52:in `run'
/opt/homebrew/lib/ruby/gems/3.3.0/gems/claide-1.1.0/lib/claide/command.rb:334:in `run'
/opt/homebrew/lib/ruby/gems/3.3.0/gems/cocoapods-1.15.2/lib/cocoapods/command.rb:52:in `run'
/opt/homebrew/lib/ruby/gems/3.3.0/gems/cocoapods-1.15.2/bin/pod:55:in `<top (required)>'
/opt/homebrew/opt/ruby/bin/pod:25:in `load'
/opt/homebrew/opt/ruby/bin/pod:25:in `<main>'

Using latest bundler, cocoapods and ruby version. Thanks a lot!

trinhngocthuyen commented 5 months ago

@gajddo00 Thanks for reaching out!

I am slightly confused about the setup when you mentioned that "the local pod also has a Podfile". I guess the project dir structure of the current setup looks like the following:

-- project /-- Project.xcodeproj
              |-- Podfile
              |-- LocalPods /-- iOSSharedModule /-- iOSSharedModule.podspec
                                                |-- Podfile                                         

Not sure what the Podfile in iOSSharedModule is for, but they don't inherit from each other. Basically, all Podfiles using SPM packages must have package declarations.

In your case, SPM packages need to be declared in the project's Podfile.

  pod 'iOSSharedModule', :path => "~/path/to/iOSSharedModule"
  spm_pkg "name",
          :url => "url",
          :products => ["Product"],
          :version => "0.0.5",
          :linkage => :dynamic

On a side note, Podfile is a per-workspace configuration. Practically, we should have one Podfile for the whole workspace, IMHO :).

Hope the explanation helps!

gajddo00 commented 5 months ago

hey @trinhngocthuyen :) Thank you! The goal is to have the iOSSharedModule completely separate, it's not part of the project structure, we actually have it hosted on github as well (but I'm testing locally), so it's a module that other projects should be able to just use as a pod standalone. The iOSSharedModule has it's own dependencies, some of them are Pods and now there is a need to add an SPM package, so that's what I've been playing with. The project using this pod shouldn't have to add the pods dependencies into its own Podfile.

-- project /-- Project.xcodeproj
              |-- Podfile
-- iOSSharedModule /-- iOSSharedModule.podspec
              |-- Podfile                  

The iOSSharedModule used to be an SPM package, but we needed to add some Cocoapods only dependencies so we created a pod instead and now I'm struggling to add SPM dependencies :D

trinhngocthuyen commented 5 months ago

Basically, to make it work in this case, the package needs to be declared in the project's Podfile. So, in Podfile, we need to declare the pods we're using, and also those pods' packages if any.

  pod 'iOSSharedModule', :path => "~/path/to/iOSSharedModule"
  spm_pkg "name",
          :url => "url",
          :products => ["Product"],
          :version => "0.0.5",
          :linkage => :dynamic