まず、はい、この質問は主観的なものかもしれません。ただし、関連するすべての要因を考慮に入れると、おそらく「最良の」答えがあると思います。いずれにせよ、試してみる価値はあります:)
A、B、C の 3 つのライブラリがあるとします。
ライブラリ B はライブラリ A を使用します。ライブラリ C はライブラリ A を使用します。
A、B、Cを一緒に使ったり、A、B、Cを好きなように組み合わせて飲んだりできるようにしてほしいです。
ライブラリをソース コードと共に配布できるようにしたいと考えています。これにより、必要に応じてライブラリを自分でビルドしたり、個々のファイルを取得して使用したりできるようになります。
それらを 1 つの大きなモノリシックな塊にまとめて配布したくはありません。
かさばるという問題は別として、私がこれをやりたくないのには十分な理由があります。B が、一緒に動作するように設計された他のライブラリに外部依存しているとしましょう。C を使用したいだけの人に、B が使用しているという理由だけで、他のライブラリにリンクするように強制したくありません。したがって、A、B、C を 1 つのパッケージにまとめるのはよくありません。
私は、単に C が欲しいだけの人が、C を手に入れて、それで作業するために必要なものがすべて揃っていることを簡単に理解できるようにしたいと考えています。
これに対処する最善の方法は次のとおりです。
- 問題の言語はObjective-cです
- 私の好みの配信メカニズムは 1 つ以上のフレームワークです (ただし、他のオプションを検討します)
- 私の好みのホスティング メカニズムは git / github です
- パッケージマネージャーは必要ない
これは比較的簡単な質問のように思えますが、実際には非常に微妙な質問であることをお伝えしておきます。説明のために、いくつかの可能な解決策とおそらく欠陥のある解決策を次に示します。
封じ込め/サブモジュール
B と C が A を使用しているという事実は、おそらく A を含める必要があることを示唆しています。これは、git サブモジュールを使用して簡単に実現できます。しかし、もちろん、自分のプロジェクトで B と C の両方を使用している人は、A のコピーを 2 つ持つことになります。彼らのコードで A も使用したい場合、どちらを使用しますか? B と C に A のわずかに異なるリビジョンが含まれている場合はどうなるでしょうか?
相対位置
別の方法として、B と C をセットアップして、A のコピーが B と C に関連する既知の場所 (たとえば、B と C と同じ格納フォルダー) に存在することを期待するようにします。
このような:
libs/
libA/
libB/ -- expects A to live in ../
libC/ -- expects A to live in ../
これは良さそうに聞こえますが、「C を取得してすべてを取得できるようにする」というテストには失敗します。C をつかむだけでは十分ではなく、A をつかんで正しい場所に配置する必要もあります。
これは面倒です。たとえば、自動化されたテストをセットアップしたい場合は、自分でこれを行う必要があります。しかし、それより悪いのは、A のどのバージョンですか? A の特定のバージョンに対してのみ C をテストできます。そのため、それを公開するときに、他の人がそのバージョンを取得できるようにするにはどうすればよいでしょうか。B と C に異なるバージョンが必要な場合はどうなりますか?
暗黙の要件
これは上記の「相対位置」のバリエーションです。唯一の違いは、A が特定の相対位置にあることを期待するように C のプロジェクトを設定するのではなく、検索パスにあることを期待するように設定するだけです。どこか。
これは、特に Xcode のワークスペースを使用して可能です。C のプロジェクトが、A も追加されているワークスペースに追加されることを期待している場合は、C が A を見つけられるように調整できます。
ただし、これは「相対位置」ソリューションの問題には対処しません。そのワークスペースが A の相対的な位置について仮定しない限り、例のワークスペースで C を出荷することさえできません!
階層化されたサブモジュール
上記のソリューションのバリエーションは次のとおりです。
- A、B、C はすべて独自のリポジトリに存在します
- BまたはCをビルドおよびテスト(または使用)できるように、物事を適切に配置する公開「統合」リポジトリ(BIおよびCIと呼びましょう)を作成します。
したがって、CI には以下が含まれる可能性があります。
- C.xcworksheet
- modules/
- A (submodule)
- C (submodule)
これでだいぶ良くなりました。誰かが C を使いたいだけなら、CI を入手してすべてを手に入れることができます。
サブモジュールであるため、正しいバージョンを取得できます。新しいバージョンの CI を公開すると、暗黙のうちに「このバージョンの C はこのバージョンの A で動作する」ということになります。うまくいけば、あなたがそれをテストしたと仮定します。
CI を使用する人は、ビルド/テスト用のワークスペースを取得します。CI リポジトリには、サンプル コードやサンプル プロジェクトなどを含めることもできます。
ただし、B と C を一緒に使用したい場合は、まだ問題があります。BI と CI だけを使用すると、最終的に A の 2 つのコピーが作成されます。これは衝突する可能性があります。
さまざまな組み合わせで階層化されたサブモジュール
ただし、上記の問題は克服できないわけではありません。
次のような BCI リポジトリを提供できます。
- BC.xcworkspace
- modules/
- A (submodule)
- B (submodule)
- C (submodule)
あなたが「B と C を一緒に使いたいなら」と言っているなら、私が動作することがわかっているディストリビューションがあります。
これはすべて良いように聞こえますが、維持するのが少し難しくなっています。現在、A、B、C、BI、CI、BCI のリポジトリのさまざまな組み合わせを維持し、プッシュする必要がある可能性があります。
これまでのところ、3 つのライブラリについてのみ説明しています。これは私にとっては本当の問題ですが、現実の世界では潜在的に約 10 個あります。それは痛いです。
だから、あなたへの私の質問は次のとおりです。
- あなたならどうしますか?
- より良い方法はありますか?
- 小さなモジュールと大きなモノリシック フレームワークの間の選択は、モジュールのユーザーにとってより優れた柔軟性と、メンテナーにとってより多くの作業との間のトレードオフであることを受け入れる必要がありますか?