170

I'm using CocoaPods with my Xcode 4 project and I have three targets for my project (the default, one for building a lite version and one for building a demo version). All the targets use the same libraries, but CocoaPods is only adding the static library and search paths to the primary target. My podfile looks like this:

platform :ios, '5.0'

pod 'TestFlightSDK', '>= 1.1'
pod 'MBProgressHUD', '0.5'
pod 'iRate', '>= 1.6.2'
pod 'TimesSquare', '1.0.1'
pod 'AFNetworking', '1.1.0'
pod 'KKPasscodeLock', '0.1.5'
pod 'iCarousel', '1.7.4'

The only way I was get this to work was to specify each target individually with all the the pods listed again.

platform :ios, '5.0'

target :default do  
    pod 'TestFlightSDK', '>= 1.1'
    pod 'MBProgressHUD', '0.5'
    pod 'iRate', '>= 1.6.2'
    pod 'TimesSquare', '1.0.1'
    pod 'AFNetworking', '1.1.0'
    pod 'KKPasscodeLock', '0.1.5'
    pod 'iCarousel', '1.7.4'
end

target :lite do 
    link_with 'app-lite'

    pod 'TestFlightSDK', '>= 1.1'
    pod 'MBProgressHUD', '0.5'
    pod 'iRate', '>= 1.6.2'
    pod 'TimesSquare', '1.0.1'
    pod 'AFNetworking', '1.1.0'
    pod 'KKPasscodeLock', '0.1.5'
    pod 'iCarousel', '1.7.4'
end

target :demo do 
    link_with 'app-demo'

    pod 'TestFlightSDK', '>= 1.1'
    pod 'MBProgressHUD', '0.5'
    pod 'iRate', '>= 1.6.2'
    pod 'TimesSquare', '1.0.1'
    pod 'AFNetworking', '1.1.0'
    pod 'KKPasscodeLock', '0.1.5'
    pod 'iCarousel', '1.7.4'
end

Is there a better way to do this?

Austin
  • 4,638
  • 7
  • 41
  • 60
  • Please, read about abstract target. It's what you need. https://guides.cocoapods.org/syntax/podfile.html#abstract_target – Nike Kov Nov 01 '17 at 15:20

4 Answers4

411

Since CocoaPods 1.0 has changed the syntax, instead of using link_with, do something like:

# Note; name needs to be all lower-case.
def shared_pods
    pod 'SSKeychain', '~> 0.1.4'
    pod 'INAppStoreWindow', :head
    pod 'AFNetworking', '1.1.0'
    pod 'Reachability', '~> 3.1.0'
    pod 'KSADNTwitterFormatter', '~> 0.1.0'
    pod 'MASShortcut', '~> 1.1'
    pod 'MagicalRecord', '2.1'
    pod 'MASPreferences', '~> 1.0'
end

target 'Sail' do
    shared_pods
end

target 'Sail-iOS' do
    shared_pods
end

Old answer Pre CocoaPods 1.0:

Yes there is a better way! Check out link_with where you can do link_with 'MyApp', 'MyOtherApp' to specify multiple targets.

I use this with unit tests like link_with 'App', 'App-Tests' (beware of spaces in target's names).

Example:

platform :osx, '10.8'

link_with 'Sail', 'Sail-Tests'

pod 'SSKeychain', '~> 0.1.4'
pod 'INAppStoreWindow', :head
pod 'AFNetworking', '1.1.0'
pod 'Reachability', '~> 3.1.0'
pod 'KSADNTwitterFormatter', '~> 0.1.0'
pod 'MASShortcut', '~> 1.1'
pod 'MagicalRecord', '2.1'
pod 'MASPreferences', '~> 1.0'

Approach using abstract_target:

In below example, the 'ShowsiOS', 'ShowsTV' and 'ShowsTests' targets have their own separate pods, plus ShowsKit inherited, because they are all child of the dummy target 'Shows'.

# Note: There are no targets called "Shows" in any of this workspace's Xcode projects.
abstract_target 'Shows' do
  pod 'ShowsKit'

  target 'ShowsiOS' do
    pod 'ShowWebAuth'
  end

  target 'ShowsTV' do
    pod 'ShowTVAuth'
  end

  # Our tests target has its own copy
  # of our testing frameworks
  # (beside inheriting ShowsKit pod).

  target 'ShowsTests' do
    inherit! :search_paths
    pod 'Specta'
    pod 'Expecta'
  end
end
Top-Master
  • 7,611
  • 5
  • 39
  • 71
Keith Smiley
  • 61,481
  • 12
  • 97
  • 110
  • Great, so where would you put the link_with in my first example podfile? Can you show me an example? – Austin Feb 16 '13 at 18:42
  • Updated my answer. It shouldn't really matter. – Keith Smiley Feb 17 '13 at 04:34
  • Perfect, thank you. I just didn't have the link_with syntax correct the first time. – Austin Feb 18 '13 at 18:25
  • 4
    I am trying the same thing, but in my case, I am linking to multiple target dependencies of the main target. This is resulting in getting duplicate symbols error in the linking phase. Do you know how to get around this using Cocoapods? – Fergal Rooney Jun 24 '13 at 19:58
  • 2
    Looks like the brackets around your list of Targets is no longer needed (and does not work?). deets: http://guides.cocoapods.org/syntax/podfile.html#link_with – toblerpwn Jan 02 '14 at 03:56
  • @FergalRooney You may be a victim of this surprising behavior: https://github.com/CocoaPods/CocoaPods/issues/1729 – mkirk Apr 18 '14 at 19:12
  • @KeithSmiley Can you please elaborate more on 'beware of spaces in target's names'? Is it just writing and not forgetting the spaces or are you substituting the spaces with - as in 'App-Tests'? – hishamaus Aug 06 '14 at 07:07
  • @hishamaus I imagine that most of these issues are solved now but in the past there have been issues with those spaces not being escaped in the `xcconfig` files that are generated leading to build failures as Xcode tries to find multiple targets named each one of the words separated by spaces. This should no longer be something to worry about. – Keith Smiley Aug 06 '14 at 15:48
  • 2
    @KeithSmiley I see. I have been having trouble with those spaces still, actually. I had to rename all my targets to have no spaces. Sucks that Cocoapods doesn't have a (do for all targets) instead of link_with. – hishamaus Aug 06 '14 at 22:06
  • @hishamaus you should submit an issue for both of those things on the GitHub repo. If you can provide an example the spaces thing is definitely a bug. – Keith Smiley Aug 06 '14 at 23:06
  • This is outdated as of version 1.0.2b, "The specification of `link_with` in the Podfile is now unsupported, please use target blocks instead" – William Entriken Jan 16 '16 at 21:47
  • Feel free to edit this with the fix. Otherwise I plan to once 1.0 is actually released. – Keith Smiley Jan 16 '16 at 22:32
  • Targets that want to know about the pods for a target but don't need linking (for example, Test targets) can define that they inherit pods via their search paths (inherit! :search_paths). :exclusive => true and link_with have been removed in favour of the above. http://blog.cocoapods.org/CocoaPods-1.0-Migration-Guide/ – Abhishek Bedi Nov 25 '16 at 12:21
  • Above only for Target or it's also for Scheme? I got an error when I create a new scheme for my project. Error only in the created scheme only not for default project created. Error:`ld: warning: directory not found for option '-L/Users/user/Library/Developer/Xcode/DerivedData/Iris-hdctpethathavjfaecoqoutujkmx/Build/Products/WhiteLabel-iphonesimulator/AFNetworkActivityLogger` `ld: library not found for -lAFNetworkActivityLogger` `linker command failed with exit code 1 (use -v to see invocation)` – Mathi Arasan Apr 19 '18 at 13:20
104

I think better solution is

# Podfile

platform :ios, '8.0'

use_frameworks!

# Available pods

def available_pods
    pod 'AFNetworking', '1.1.0'
    pod 'Reachability', '~> 3.1.0'
end

target 'demo' do
  available_pods
end

target 'demoTests' do
    available_pods
end

Reference from : http://natashatherobot.com/cocoapods-installing-same-pod-multiple-targets/

Adarsh G J
  • 2,684
  • 1
  • 24
  • 25
  • 1
    Do you mind explaining why this is a better solution? – Warpling Aug 07 '15 at 21:53
  • 1
    @Warpling: Please go through this http://natashatherobot.com/cocoapods-installing-same-pod-multiple-targets/ – Adarsh G J Aug 10 '15 at 01:25
  • 12
    It'd be great if you added a bit of that explanation here. (It's nice to keep all info necessary on SO in case links go down, etc) It also might help people see the problem with `link_with` and upvote your answer :) – Warpling Aug 10 '15 at 17:51
  • I like this approach because it allows a bunch of pods available for all targets (available_pods) and target specific pods. – Apoc Nov 19 '15 at 10:21
  • This solution works fine, but something that is worth mentioning : your 'def' values must be lowercase. – Jerome Jun 07 '18 at 09:25
15

If you want multiple targets to share the same pods, use an abstract_target.

# There are no targets called "Shows" in any Xcode projects
abstract_target 'Shows' do
  pod 'ShowsKit'
  pod 'Fabric'

  # Has its own copy of ShowsKit + ShowWebAuth
  target 'ShowsiOS' do
    pod 'ShowWebAuth'
  end

  # Has its own copy of ShowsKit + ShowTVAuth
  target 'ShowsTV' do
    pod 'ShowTVAuth'
  end
end

or just

pod 'ShowsKit'
pod 'Fabric'

# Has its own copy of ShowsKit + ShowWebAuth
target 'ShowsiOS' do
  pod 'ShowWebAuth'
end

# Has its own copy of ShowsKit + ShowTVAuth
target 'ShowsTV' do
  pod 'ShowTVAuth'
end

source: https://guides.cocoapods.org/using/the-podfile.html

Adam Smaka
  • 5,977
  • 3
  • 50
  • 55
1

Easiest way is to use an abstract target, where each pod specified will be linked with all targets.

abstract_target 'someNameForAbstractTarget' do
  pod 'podThatIsForAllTargets'
end

target 'realTarget' do
  pod 'podThatIsOnlyForThisTarget'
end
Shaked Sayag
  • 5,712
  • 2
  • 31
  • 38