LoginSignup
13
13

More than 5 years have passed since last update.

CocoaPods 0.38からのtarget重複排除を無効化する

Last updated at Posted at 2015-07-28

0.38以前で以下のようなPodfileを定義した場合…

Podfile
platform :ios, "7.0"

target "Foo" do
  pod "AFNetworking", "~> 2.5"
end

target "Bar" do
  pod "AFNetworking", "~> 2.5"
end

Podsプロジェクトで自動生成されるTARGETは、「Pods-Foo-AFNetworking」と「Pods-Bar-AFNetworking」の2つ出来上がります。
しかし0.38からは「AFNetworking」という1つのTARGETにまとめられるようになります。(例外あり)

開発ブログより

Target Deduplication
CocoaPods now de-duplicates Pod targets, which means that it recognises when a dependency is used multiple times across different user targets but only needs to be built once. But sometimes this is not possible and they still need to be generated in different variants and thus build multiple times. The targets in Pods.xcodeproj need to be duplicated when one of the following conditions applies:

  • They are used on different platforms.
  • They are used with differents sets of subspecs.
  • They have any dependency which needs to be duplicated.

This fixes several issues with Archiving apps with extensions, but also reduces build times significantly.

上記にある通り、いくつかの問題解決のためとビルド時間の短縮効果のためだと思われます。
そもそも、同じライブラリなのだから個別にビルドする必要は無いと言えばないのですが…

ところがどっこい!
有名な「AFNetworking」などは、本体とExtensionで別々のビルドコンフィグ(プリプロセッサ)を指定したい!
という事情があったりして、1つにまとめられてしまうと非常に困ります。

そこで、0.38以前のように個別のTARGETにするには上記開発ブログにある通り3つの例外を利用します。

1つ目が下記のように「Platform」指定を変えてしまうことです。

Podfile
target "Foo" do
  platform :ios, "7.0"
  pod "AFNetworking", "~> 2.5"
end

target "Bar" do
  platform :ios, "8.0"
  pod "AFNetworking", "~> 2.5"
end

iOSの場合、例えば「WatchKit Extension」は8.2からの指定で本体は7.0で良いというようなケースでこの方法が使えます。2つ目が別の「subspecs」を指定することです。

Podfile
platform :ios, "7.0"

target "Foo" do
  pod "AFNetworking", "~> 2.5"
end

target "Bar" do
  pod "AFNetworking", "~> 2.5", :subspecs => ['Serialization', 'Security', 'Reachability', 'NSURLConnection', 'NSURLSession']
end

「subspecs無指定」と「全指定」でも別々のTARGETになります。

3つ目が良くわからないのですが、CocoaPodsが重複して作る必要があると判断した場合(依存関係など?)のようです。
私は、今のところ「subspecs」を分けて指定することで問題が解決できています。

また、0.38から「installer」クラスのプロパティである「project」が無くなって「pods_project」に変わっているので、参考までにビルドコンフィグを変える所まで書いておきます。

Podfile
platform :ios, "7.0"

target "Foo" do
  pod "AFNetworking", "~> 2.5"
end

target "Bar" do
  pod "AFNetworking", "~> 2.5", :subspecs => ['Serialization', 'Security', 'Reachability', 'NSURLConnection', 'NSURLSession']
end

post_install do |installer|
  # 変更したいビルドターゲットを探す
  classy_pods_target = installer.pods_project.targets.find{ |target| target.name == "Pods-Bar-AFNetworking" }
  unless classy_pods_target
    raise ::Pod::Informative, "Not Found 'Pods-Bar-AFNetworking' target"
  end

  # ビルド設定を変更
  classy_pods_target.build_configurations.each do |config|
    # Preprocessor Macrosを変更する
    config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= ['$(inherited)', 'AF_APP_EXTENSIONS=1']
  end
end
13
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
13