私は Gitサブモジュール の大ファンです。依存関係とそのバージョンを追跡できるようにしたいので、プロジェクトの以前のバージョンにロールバックして、対応するバージョンの依存関係を作成し、安全かつクリーンにビルドできます。さらに、ライブラリの履歴は、ライブラリに依存する(およびオープンソース化されない)アプリケーションの履歴とは別であるため、ライブラリをオープンソースプロジェクトとしてリリースする方が簡単です。
作業中の複数のプロジェクトのワークフローを設定していますが、単一のモノリシックプロジェクトを作成するのではなく、このアプローチを少し極端にするとどうなるかと思っていました。サブモジュールを使用してreallyにワームの潜在的な缶があることにすぐに気付きました。
アプリケーションのペアを想定すると、studio
とplayer
、および依存ライブラリcore
、graph
とnetwork
、依存関係は次のとおりです。
core
はスタンドアロンですgraph
はcore
に依存します(./libs/core
のサブモジュール)network
のcore
の詳細(./libs/core
のサブモジュール)studio
はgraph
およびnetwork
に依存します(./libs/graph
および./libs/network
のサブモジュール)player
はgraph
およびnetwork
に依存します(./libs/graph
および./libs/network
のサブモジュール)CMake を使用していて、これらの各プロジェクトにユニットテストとすべての作業があるとします。各プロジェクト(studio
とplayer
を含む)は、コードメトリックス、ユニットテストなどを実行するためにスタンドアロンでコンパイルできる必要があります。
再帰的なgit submodule fetch
の場合、次のディレクトリ構造になります。
studio/
studio/libs/ (sub-module depth: 1)
studio/libs/graph/
studio/libs/graph/libs/ (sub-module depth: 2)
studio/libs/graph/libs/core/
studio/libs/network/
studio/libs/network/libs/ (sub-module depth: 2)
studio/libs/network/libs/core/
core
は、studio
プロジェクトで2回複製されていることに注意してください。このディスク領域の浪費とは別に、core
を2回ビルドしていて、core
の2つの異なるバージョンを取得する可能性があるため、ビルドシステムに問題があります。
一般的なネストされたサブモジュールの複数のコピーを取得せずに、バージョン化された依存関係とスタンドアロンビルドを取得できるように、サブモジュールを整理するにはどうすればよいですか?
ライブラリの依存関係がいくらか示唆されており(つまり、「バージョンXで動作することがわかっている」または「バージョンXのみが公式にサポートされている」という方法で)、依存する可能性のあるアプリケーションまたはライブラリが、好きなバージョンでのビルドを担当している場合、次のシナリオを想像できます。
graph
とnetwork
のビルドシステムに、core
の場所を(コンパイラのインクルードパスなどを使用して)どこにあるかを伝えます。 「スタンドアロン」と「依存関係」の2つのビルドターゲットを定義します。「スタンドアロン」は「依存関係」に基づいており、ローカルのcore
サブモジュールを指すインクルードパスを追加します。studio
に対するcore
。次に、studio
はcore
をビルドし、インクルードパスをcore
サブモジュールの独自のコピーに設定してから、graph
およびnetwork
を「依存関係」モードでビルドします。結果のフォルダー構造は次のようになります。
studio/
studio/libs/ (sub-module depth: 1)
studio/libs/core/
studio/libs/graph/
studio/libs/graph/libs/ (empty folder, sub-modules not fetched)
studio/libs/network/
studio/libs/network/libs/ (empty folder, sub-modules not fetched)
ただし、これにはいくつかのビルドシステムの魔法が必要です(これはCMakeで実行できると確信しています)。バージョンの更新の部分で少し手作業を行う(graph
の更新には、core
とnetwork
の更新でcore
の互換バージョンを取得する必要がある場合もありますすべてのプロジェクトで)。
これについて何か考えはありますか?
私はこのパーティーに非常に遅れていますが、あなたの質問はまだ完全な答えを持っているようには見えません、そしてそれはグーグルからのかなり顕著なヒットです。
C++/CMake/Git/Submodulesでもまったく同じ問題が発生し、MATLAB/Git/Submodulesでも同様の問題が発生します。私は出会いました このビデオ 最近、「解決策」を提案しているようです。それは本質的にサブモジュールを捨てることを意味するので、私はソリューションが好きではありませんが、それは問題を排除します。 @errordeveloperが推奨するとおりです。各プロジェクトにはサブモジュールがありません。プロジェクトをビルドするには、スーパープロジェクトを作成してビルドし、依存関係の兄弟としてそれを含めます。
したがって、graph
を開発するためのプロジェクトは次のようになります。
buildgraph/graph
buildgraph/core
そしてスタジオのプロジェクトは次のようになります:
buildstudio/studio
buildstudio/graph
buildstudio/network
buildstudio/core
スーパープロジェクトはメインCMakeLists.txt
とサブモジュールの束。しかし、どのプロジェクトにもサブモジュール自体はありません。
このアプローチで私が見る唯一のコストは、実際のプロジェクトの構築に専念している些細な「スーパープロジェクト」の急増です。そして、誰かがあなたのプロジェクトのいずれかを手に入れたら、スーパープロジェクトも見つけなければ、その依存関係が何であるかを知る簡単な方法はありません。たとえば、Githubで見苦しく感じるかもしれません。
graph
とnetwork
の両方のサブモジュールをstudio
に統合する場合、履歴の特定の時点で常に同じバージョンのcore
が必要です/ studio
。 studio/libs/core
サブモジュールをstudio/libs/{graph,network}/libs
にsimlinkします。
更新:
私はあなたが述べた依存関係を持つ複数のリポジトリを作成しました:
./core <--- (v2)
./graph
./graph/libs
./graph/libs/core <--- (v2)
./graph/.gitmodules
./network
./network/libs
./network/libs/core <--- (v1)
./network/.gitmodules
./studio
./studio/libs
./studio/libs/graph
./studio/libs/graph/libs
./studio/libs/graph/libs/core <--- (v1)
./studio/libs/graph/.gitmodules
./studio/libs/network
./studio/libs/network/libs
./studio/libs/network/libs/core <--- (v1)
./studio/libs/network/.gitmodules
./studio/studio
./studio/.gitmodules
v1
とv2
は、core
の2つの異なるバージョンです。 graph
はバージョン2を処理しますが、network
は作業が必要でバージョン1のままです。studio
では、core
のローカル埋め込みバージョンはどちらもv1
を指します。実用的なプログラムを作るために。さて、ビルドの観点とは別に、すべてがサブモジュールでうまく機能します。
次のディレクトリを削除できます:
./studio/libs/network/libs/core
そして、それをシンボリックリンクに置き換えます:
./studio/libs/network/libs/core@ -> ../../graph/libs/core/
私はこの変更をローカルでコミットし、core
内にstudio
の2つの異なるバージョンを作成する機能を失いますが、core
をビルドするのは1回だけです。 v2
にアップグレードする準備ができたら、次のことができます。
git submodule update # (--rebase ?)
... studio/libs/network内。
サブモジュールは使用しません。
それは魅力的で、svn-externalsの場合と同じです。ただし、リンクしたプロジェクトがすべて1年間同じ場所にあることを確認できますか?五時はどうですか?
したがって、必要なすべての依存関係をプロジェクトにコピーするだけです。これは、私のリポジトリが有効である限り、正確な状態をチェックアウトできることを意味します。
基本的に、私は次のようなフォルダ構造を持っています:
myproject/... [sources etc]
ext/ [third-party dependencies]
e.g. ext/boost, ext/cppunit
これはディスクスペースの観点からはあまりいいとは言えませんが、レポがはるかに利用可能である限り、記録されたすべての状態をチェックアウトできることを保証します。
さらに、説明されているように、サブモジュールには多数の問題があります here
サブモジュールの深さを1にして、すべてのモジュールをサブモジュールとして保持し、READMEとビルドスクリプト以外には何もない)リポジトリを保持するように、それを平坦化します。依存関係をリンクするパッケージごとに個別のビルドスクリプトにするか、パッケージごとに個別のリポジトリを作成できます。
ここでまったく同じ問題に直面しています。解決策の1つは、サブモジュールとしてlibs
、core
、network
を保持するいくつかのリポジトリgraph
と、各ライブラリを通知するCMakeListsを用意することです。依存関係を見つける場所。各アプリケーションは、サブモジュールとしてlibs
を持ち、必要なライブラリのみを使用します。
各libのテストは、2つの方法で設定できます。