ソース管理のバイナリ


30

組み込みデバイスやその他の奇妙な世界向けに開発する場合、ビルドプロセスに非常に特殊なバージョンを使用する複数の独自のバイナリが含まれる可能性が非常に高くなります。質問は、ソース管理の一部ですか?私のオフィスでは、「ソース管理からのチェックアウトにはコードをコンパイルするために必要なすべてが含まれます」というルールに従っており、これはいくつかの深刻な議論につながっています。

これに対する主な議論は、ソース管理DBの肥大化、バイナリファイルの差分の欠如です(この件に関する以前の質問を参照)。これは、前の開発者が意図した正確な環境があることを確認し、ビルドし、適切なファイルを探し出すことなく(特定のバージョンも同様に!)


3
または、bash / python / perl / batスクリプトを記述してソースをチェックアウトし、他のすべての依存コンポーネントを単一のステップでダウンロードできます。ただし、リビジョンを保持するためだけに、バージョン管理にバイナリをチェックインすることをお勧めします。リポジトリにチェックインしないファイルは、バージョン管理されたファイルから簡単に再生成できるファイルのみです。ディスク容量は安価であり、重要な考慮事項ではありません。
ライライアン

回答:


28

VERSION CONTROL(誤名:ソース管理)の考え方は、履歴をロールバックし、変更の効果を回復し、変更とその理由を確認できるようにすることです。これは一連の要件であり、その中にはバイナリのものが必要なものとそうでないものがあります。

例:組み込みファームウェアの作業には、通常、完全なツールチェーンがあります:高価な専用のコンパイラーか、gccの何らかのバージョンです。出荷実行可能ファイルを取得するには、ツールチェーンとソースが必要です。

ツールチェーンをバージョン管理にチェックインするのは苦痛であり、diffユーティリティは恐ろしい(もしあったとしても)ですが、代替手段はありません。5年後にあなたのコードを見て、それが何をするのかを理解するようになった人のためにツールチェーンを保存したい場合、選択の余地はありません。ツールチェーンもバージョン管理下になければなりません。

何年もの間、これを行う最も簡単な方法は、インストールCDのZIPまたはISOイメージを作成してチェックインすることです。チェックインコメントは、ツールチェーンの特定のメーカーバージョン番号である必要があります。gccなどの場合は、使用しているすべてのものを大きなZIPにまとめて同じことを行います。

私がやった最も極端なケースは、「ツールチェーン」が実行中のWindows XP VMであるWindows XP Embeddedで、これには(当時)SQL Serverと何百ものパッチファイルと共に構成ファイルのスタックが含まれていました。ロット全体をインストールして最新の状態にするには、約2〜3日かかりました。後世のためにそれを維持することは、VM全体をバージョン管理にチェックインすることを意味しました。仮想ディスクが約6 x 2GBのイメージで構成されているのを見ると、実際には非常にうまく行きました。一番上に聞こえますが、それは私の後に来て、それを使用しなければならなかった人にとって人生を非常に楽にしました-5年後。

要約:バージョン管理はツールです。効果的に使用し、言葉の意味などにこだわらないでください。それよりも大きいため、「ソース管理」と呼ばないでください。


1
また、VMを更新する必要がある場合、レポバルーンを12 GBに更新しますか?たとえあなたが良いバイナリ差分を持っているとしても、あなたはまだ10GB以上のレポを話している
TheLQ

3
うーん、ダメ。VMWareを使用する場合、ディスクスナップショットを使用できます。これらは元のベースラインディスクイメージを保存し、非常に小さいデルタのみを含む新しいファイルを追加します。新しく作成したファイルをチェックインすることを忘れないでください。最後にこれを見て、約250Kの更新が追加されました-チキンフィード。その上、レポのサイズを心配することは無意味です-ディスクは安いです。
すぐに

組み込みツールチェーンがネットワークライセンスに依存する場合はどうですか:)
ダン

18

Neal FordはThe Productive Programmerで、ソース管理にバイナリ保持する必要があると主張しています。

なぜバイナリを保持するのですか?今日のプロジェクトは、一連の外部ツールとライブラリに依存しています。人気のあるロギングフレームワーク(Log4JやLog4Netなど)のいずれかを使用しているとします。ビルドプロセスの一部としてそのロギングライブラリのバイナリをビルドしない場合は、バージョン管理に保管する必要があります。これにより、問題のフレームワークまたはライブラリがなくなった場合(または、新しいバージョンに重大な変更が加えられた場合)でも、ソフトウェアのビルドを続行できます。バージョン管理でソフトウェアを構築するために必要な宇宙全体を常に維持する(オペレーティングシステムを除いたものであり、仮想化でも可能です。この章で後述する「仮想化を使用する」を参照してください)。バイナリをバージョン管理と共有ネットワークドライブの両方に保持することで、バイナリの保持を最適化できます。そうすれば、1時間ごとに対処する必要はありませんが、1年後に何かを再構築する必要がある場合に備えて保存されます。何かを再構築する必要があるかどうかはわかりません。動作するまでビルドし、それを忘れます。2年前から何かを再構築する必要があり、すべての部品が揃っていないことに気付くと、パニックになります。

私はこれ以上同意できませんでした。これは間違いなく、VCSが設計されていないタスク(バイナリを保持)のVCSを破壊している一方で、潜在的な欠点を上回る利点があると思います。しかし、著者が後に述べるように、VCSにバイナリを保持することは実際的なソリューションではない場合があるため、マップされたネットワークドライブに保持するなど、他のオプションを検討する必要があります。

バイナリが大きすぎなければ、間違いなくVCSに保存します。バイナリはおそらく小さいので、これは、あなたのケースでも、より真実のようだ、あなたは非常に特定のバージョンで動作します。また、さまざまな理由により、見つけにくい場合があります(作成者がWebサイトをシャットダウンするか、必要なバージョンがダウンロード用にリストされなくなります)。ありそうにありませんが、数年後に何が起こるかわかりません。

数年前、グラフィックスライブラリ(dllファイル)を使用してゲームに取り組んでいたときに、この本を読みたいと思います。開発をしばらく中断しましたが、続行したいときにプロジェクトが終了したため、再びdllを見つけることができませんでした。


2
はい、これは頻繁に起こります。私は3〜4年前に作者によって放棄されたスキャナージェネレーターに依存する趣味のプロジェクトを持っています。幸い、常にバージョン管理下にありました。
クリスチャンクラウザー

9

原則として、「ソース管理に組み込むために必要なものすべてをチェックする」キャンプに感謝しますが、Maven、Ivy、NuGetなどのツールによって、依存関係管理はここ数年でかなり進化しました。

また、実際には、バイナリをチェックインして、多くの不快な副作用を引き起こします。たとえば、Git / Mercurialは実際にはチューニングされていません。また、SubversionとPerforceは、バイナリを含むブランチをマージする際に気を配ることができます。

依存関係管理ソリューションでは、プロジェクト内のソース管理ファイルで、パッケージ名とプロジェクトが依存するバージョンを指定します。ほぼすべての依存関係管理ツールを使用すると、何らかのバージョン管理と命名規則に従って、依存関係のプライベートリポジトリを作成できます。ビルドを行うと、依存関係管理ツールは、承認されたソースのリストからすべてのオープンソースとプロプライエタリの依存関係を解決し、ローカルキャッシュに詰め込みます。次回同じバージョンの依存関係を使用してビルドすると、すべてがすでに存在し、はるかに高速になります。

その後、従来のファイルシステムバックアップツールを使用して、プライベートリポジトリをバックアップできます。

これにより、大量のバイナリがソースツリーから取り出されるときに私が経験した速度低下を回避し、リポジトリに多数の差分の難しいファイルが含まれることを防ぎます。名前とバージョン番号によって、特定の依存関係の場所は1つだけなので、マージの競合はありません。また、ローカルファイルシステムのキャッシュにより、ローカルコピーが変更されたかどうかを評価するコストを処理する必要がなくなります。更新をプルします。


8

ソース管理はソース用です。ソースは、他のものから構築できないものです。ソースとして認定されるファイルの中には、たまたまバイナリであるものがあります。

私のVCSには多くのバイナリがチェックインされていますが、各バイナリは、私が書いたり管理したりしていない製品のリリースの単位です。これは、圧縮されたtarballとしてリリースされるGNU ccRTPのようなものです。そのtarballは私のソースであり、1つの自動化されたステップで完成品(私の場合はMakefileとRPM仕様)に変換するために必要なインフラストラクチャと一緒にチェックインされます。ccRTPの新しいバージョンがある場合、新しいtarballを変更されたソースとして扱います。チェックアウトされたコピーに入り、ビルドされ、テストされ、VCSにコミットされます。ソース(コンパイラ、ライブラリなど)に同梱されていない商用製品でも同じことを行いましたが、同じように機能します。unpack-configure-compile-packageの代わりに、単にunpack-packageです。ナイトリービルドを行うソフトウェアはmake 完成品を取得します。

ほとんどのVCSには、人間が読めるソースを扱いやすく、効率的に保存する機能がありますが、バイナリに適していないと言うのは、バイナリが入れられて元通りになった場合、本当ではありません。VCSが内部的にバイナリを処理する方法は、作成者が差分のみを保存しようとするのは努力する価値があると考えたかどうかに完全に依存します。個人的には、ccRTPディストリビューションの完全なコピーを600Kポップで保存することは、他のすべてのソースと一緒にバージョンをタグ付けする機能によって補われていると思います。


4

これは、Javaがかつて持っていた「リポジトリ内のjar」問題を思い出させます。Javaアプリを作成する人々は、依存関係(バイナリjarファイル)をリポジトリにプッシュするために使用されました。誰もがこれに満足していました。なぜなら、「ワンクリック」ビルドシステムが必要であり、ディスクスペースが安いからです。その後、Mavenが登場し、バイナリクラフトをすべて取り除くことができ、ローカルキャッシュのみのリポジトリを使用して、bullet-profビルドを維持できます。まだ「ワンクリック」ビルドシステムがありますが、ソース管理は意味のないバイナリファイルをシャッフルする必要はありません。

そのため、ソース管理からバイナリファイルを取得できますが、これにはビルド時にそれらを取得するためにビルドシステムを調整する必要があります。専用のソフトウェア(Mavenなど)がなければ、これを入手するのに多大な労力がかかる可能性があります。


1
主にチームの大部分が数学者であり、プロセスの大ファンではないため、ビルドプロセスが複雑になるのが心配です。
ダニエルゴールドバーグ

3

あなたのソース管理はあなたがすることのソースを保持します。特定のバイナリBLOBをソースから再構築できる場合、それはソースではないため、ソースコードリポジトリに入れないでください。ソース管理では、再作成不可能なblobのみを使用する必要があります。

通常、ソースの時間を通じて構築したバイナリBLOBの別の リポジトリネットワークフォルダーがあります。これらは、顧客に展開したり、プロジェクトで使用したりすることができます(毎回すべてをゼロから構築する代わりに)。

それで、それがソースならそれを入れてください。そうでない場合はいけません。


誰がこれに反対票を投じますか?? 興味深い理由:D

それは私ではありませんでしたが、答えの後半に反対した人は誰でも疑います。
ジョエルCoehoorn

@JoelCoehoorn、興味深い、まさにMavenリポジトリーだからです。

2

目標は、何もインストール/セットアップすることなく、最新のコードを取得してビルドできるようにすることです(つまり、「シングルクリック」ビルド)。

私が行った多くの場所で、それは依存関係のバイナリをチェックインすることを意味します。他では、これはビルドスクリプトが依存関係を自動的にダウンロードして取得することを意味します。

このテーマについては、Derek Greerによるこのブログ投稿を参照してください。


2

私は2つの異なるビルド段階のプロジェクトで働いています

  • 「メインプログラムビルド」に必要なバイナリは数千個のソースコードテキストファイルに比べてわずかであるため、バイナリはリポジトリにチェックインされます。これは正常に機能します。

  • インストーラービルドには多くのサードパーティコンポーネントが必要です(一部はAdobe ReaderなどのインストールCDにコピーされるだけです)。これらはリポジトリに入れません。代わりに、これらのコンポーネントはネットワークドライブ(それらの古いバージョンも含む)に存在し、ビルドスクリプトはそれらを適切な場所にコピーします。もちろん、再現可能なビルドを作成するには、サードパーティのコンポーネントが保存されているフォルダーを変更しないように注意する必要があります。

どちらの戦略もうまく機能し、「ソース管理からのチェックアウトにはコードのコンパイルに必要なすべてが含まれます」要件を満たします。


1

将来のある時点で製品の特定のバージョンを再構築するために必要なすべてのものを保持する必要があります。

ただし、すべてをソース管理に保持する必要はありません。

ある会社は、凍結されたサーバーラックを保持していました(OSはその特定のハードウェアでのみ実行され、ツールチェーンはそのOSでのみ実行され、ソースはそのツールチェーンに依存していたため)。それをソース管理にチェックインできません。

ビルドの要件を分割する必要がある場合、2つのバージョン管理システムの同期を維持するという会計上の問題があります。たとえば、このクローゼット内のハードウェアボックス、またはこの保存されたバックアップボリューム内のVMまたはバイナリは、このSVNソースコードリビジョンなどに対応します。


0

バイナリをSCMにチェックインするのは非常に混乱しています。私は非常に複雑なプロジェクトを実行していましたが、これにはサードパートライブラリへの多くの依存関係があります。採用した原則:

  1. すべてのソースコードはSCMで管理されます
  2. すべての依存関係はIvyで管理され、IvyにはEclipseの優れた統合があります。

これはかなりうまくいきます。ソースコードをコンパイルできる各外部ライブラリのバージョンに関する構成ファイルがあります。この構成ファイルはSCMにチェックインされるため、ソースコードが進化するにつれて進化します。このアプローチを適用することにより、外部ライブラリのバージョンをいじらずにビルドを正確に再現できます。


0

個人的に、哲学的には、ソース管理に、ファイルの内容ではなく、大きなバイナリファイル(小さなバイナリリソースでもかまいません)へのポインタをチェックインさせる傾向があります。このポインターには、バイナリファイルの内容のハッシュが含まれます。

バイナリファイル自体は、ソース管理によって管理されません。これは、ポインタまたはハッシュを使用して取得できる特定の種類のライブラリに保存されます。

Git LFSとgit annexはそれを行いますが、バイナリファイルをある程度まで管理しようとするため、そうしたいことはしたくありません。Gitにチェックサムのみを保存し、バイナリファイルが変更されたかどうかを教えてほしい-しかし、Gitにそれらを管理して保存しようとは望んでいません。これを自分でやりたいです。

gitは中小規模のバイナリファイルを処理できると思いますが、大規模なバイナリファイルを管理するための適切なツールであるかどうかはわかりません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.