12

私は組み込み Linux プロジェクトに取り組んでいる小さなチーム (4 ~ 5 人) の一員です。Buildroot と Linaro ツールチェーンを使用して、ターゲット用にビルドしています。バージョン管理には git を使用し、ナイトリー ビルドには Jenkins を使用します。

このようなプロジェクトに参加するのはこれが初めてで、この種の環境での開発モデルを説明するリソースを見つけることができませんでした。

毎晩のビルドの直後に、u-boot イメージとルート ファイル システムを含む Buildroot 'output' ディレクトリの tarball を作成します。これは、最後に成功したビルドの Jenkins の「アーカイブ」ページから直接ダウンロードできます。

私たちの中には、低レベルの開発に取り組む人もいれば、ユーザー空間の開発 (QT) に取り組む人もいます。私たちの問題は、人々がプロジェクト範囲内のさまざまな分野で作業することを考えると、このような環境で開発するための最も効率的/合理化されたアプローチは何かを決定することです. ユーザーランドの担当者は、すべてを含む tarball をダウンロードし、アプリケーションを rfs に組み込んでボード上で実行し、デバッグすることができますが、下位レベルの開発で行われた作業をどのように処理すればよいでしょうか? 基本的に、アーティファクトをチームに配布するにはどうすればよいでしょうか? どんな考えでも大歓迎です。

4

1 に答える 1

19

私は最近、OpenEmbedded ベースの Linux プロジェクトのビルド環境の再構築に時間を費やしました。Buildroot を直接使用した経験はありませんが、OpenEmbedded はあなたが使用しているものと十分に似ていると思います。私のセットアップについて説明します。運が良ければ、ここで役立つものを見つけることができます...

問題

個別に (つまり、互いに独立して) インストールできる 3 つのソフトウェア コンポーネントがあります。カーネル (Linux); およびファイルシステム イメージ。最終製品は、これら 3 つのコンポーネントのパッケージ リリースと共に出荷されます。つまり、u-boot、linux、およびファイル システム イメージの QA テスト済みで、連携して動作することがわかっているバージョンです。ただし、いずれかのコンポーネントを個別にアップグレードして (新しいカーネル イメージをインストールするなど)、一緒にテストされていないソフトウェア コンポーネントの組み合わせを作成することは可能です。

この問題は、ユーザー空間アプリケーションにも存在します。ファイルシステム イメージがターゲットにインストールされると、他のファイル システム オブジェクトとは無関係に、1 つまたは複数のユーザー空間バイナリを更新できるようになります (ファイル システムが読み取り専用ではない場合)。現在インストールされているユーザー空間アプリケーションの特定の組み合わせが連携できることをどのように判断しますか? この特定のユニットで実行されているバイナリの組み合わせが、QA 認定済みのバイナリの組み合わせと同じであることをどのように確認できますか? ソフトウェアの「バージョン」を知るにはどうすればよいですか?

私が解決する必要があったもう 1 つの問題は、質問で説明したのと同じ問題ですが、ソフトウェア スタックのさまざまな部分 (カーネル、ルート ファイルシステム、ユーザー空間 Qt アプリなど) で作業している開発者が連携できるようにする方法です。

解決策

私はこれと「バージョン」の問題に次のように対処しました。

  1. rootfs と sysroot を git リポジトリに保存します。
  2. git サブモジュールの自由な使用。

ターゲットのルート ファイルシステムとシステム ルート ファイルを git リポジトリに保存することは、最初は間違った方法でこすられました (出力ファイルをバージョン管理に保存するなんて!?!) が、次の利点があります。

  1. JFFS2 ファイルシステム イメージ (rootfs + カスタム ユーザー空間アプリケーション) は、ユーザー空間アプリケーションの構築にかかる時間 (つまり、数十秒) で構築できます。開発者は最初に rootfs をゼロからビルドする必要がなくなりました (OpenEmbedded では数時間かかります)。
  2. バージョン管理の他のすべての利点 (rootfs への変更は、時間の経過とともに簡単に追跡でき、リリースのタグ、ブランチなど)。
  3. 私は当初、rootfs と sysroot を tarball として保存することを検討していましたが、ファイルごとに変更を追跡する git のアイデアが気に入っています。

ディレクトリ構造は次のようになります (悪意のない人を保護するために一部の名前は変更されています)。

\---proj [*]             # Name of your project
    +---u-boot [*]
    +---linux [*]
    +---toolchain [*]
    \---fs [*]           # Filesystem stuff.
        +---oe [*]       # OpenEmbedded.
        +---qt [*]       # Qt framework.
        +---apps [*]     # Custom user-space applications.
        \---bin [*]      # Revision controlled binaries
            +---rootfs   # Target root filesystem, output of OpenEmbedded.
            \---sysroot  # System root, output of OpenEmbedded (headers, etc).

スター付きの各ディレクトリ [*] は git リポジトリであり、各 git リポジトリはその親のサブモジュールです。

git submodule initビルド環境は、基本的に再帰的なandを実行する最上位の Makefile から初期化されますgit submodule update。すべての開発者は次のことを行います。

$ git clone git@your.url:proj proj
$ cd proj
$ make git-init

ユーザー空間の開発者は、すぐにビルドできます。

$ make --directory proj/fs/apps all       # Build apps
$ make --directory proj/fs install        # Create JFFS2 image

ファイルシステム管理者は rootfs を更新できます:

$ cd proj/fs/oe
$ # Modify build recipes and other OpenEmbedded black magic stuff.
$ make
$ # Go make coffee while oe builds every package on the planet.
$ cd proj/bin    # OE writes output files here.
$ git commit     # Commit latest rootfs and sysroot.

ソフトウェアのバージョン管理

最上位のメイクファイル ( proj/Makefile) から、すべてのソフトウェア コンポーネント (カーネル、u-boot、ファイル システム イメージ) をビルドできます。次の git コマンドを使用すると、makefile はすべてのサブ make プロセスにVER_TAG、現在のソフトウェア バージョンを記述する単一の環境変数 (例: ) をエクスポートします。バージョンは、git リポジトリのタグまたは SHA (例: v1.0471087ec254e8e353bb46c533823fc4ece3485b4または471087ec254e8e353bb46c533823fc4ece3485b4-modified) のいずれかです。

git rev-parse HEAD                 # Get current SHA
git status --porcelain | wc -c     # Is working copy modified?
git describe --exact-match HEAD    # Is the working copy a tag?

プロジェクトのサブディレクトリのいずれかのファイルが 1 つでも変更された場合、VER_TAG常にxxxx-modified. この単一のVER_TAG変数は、コンパイル時の定数としてすべてのビルド (u-boot、カーネル、ユーザー空間アプリなど) に渡されます。

実行時に、カスタム ユーザー空間アプリケーションVER_TAGはすべてのコンポーネントから値を蓄積し、それらがすべて同じ値を報告する場合、その文字列は製品によって報告される正式なバージョンになります。1 つの値でもVER_TAG他の値と異なる場合、ソフトウェア スタックは同じトップレベル SHA から構築されておらず、実際にリリースすることはできません (テストのための QA、製造のためのプロダクションなど)。

ソフトウェア コンポーネントが最上位の makefile (例: make --directory proj/fs/apps all)からビルドされていない場合、VER_TAGそのコンポーネントの は未定義になり、結果として得られるソフトウェア スタックは「内部使用のみ」になります。つまり、すべてのソフトウェア コンポーネントの「リリース」は、最上位の makefile からビルドすることによってのみ行うことができます。

参考までに、linuxVER_TAGは procfs のカスタム ファイルを介してレポートし、u-boot は Linux コマンド ラインを介してレポートし ( /proc/cmdline)、各ユーザー空間アプリケーションはプロセス間通信を介してレポートします。

概要

警告。私はこのビルド環境を 1 か月前に開発したばかりなので、その堅牢性を主張することはできませんが、今のところはうまくいっているようです...

特定の質問や明確にしたい点がある場合は、喜んで回答を更新します。

于 2012-06-25T08:01:28.487 に答える