Mbed OS 5を静的ライブラリとしてビルドする

【2020/05/21 追記】
本記事の手順で作成したMbed OS 5の静的ライブラリを使用すると正常に動作しないケースがありました。発生条件や原因は調査中です。

やりたいこと

Mbed OS 5をあらかじめ静的ライブラリとしてビルドしておく。

背景

Mbed OS 5のソースコードは膨大な量で、非力なPCではフルビルドに数十分もかかります。またインクリメンタルビルドですら更新チェックにかかる時間が煩わしいです。ユーザープログラムの開発者がOSのソースコードを変更することはふつう無いので、これは時間の無駄です。

そこで、Mbed OS 5を別プロジェクトであらかじめ静的ライブラリとしてビルドしておき、ユーザープログラムのプロジェクトではビルド済みの静的ライブラリを利用することでビルド時間を短縮したいと思いました。

開発環境

ここでは例として、Nucleoボード(STM32マイコン)をターゲットとし、ローカルビルド環境としてSW4STM32 (Eclipseベース)を使用します。他のEclipseIDEでもだいたい似たようなものだろうと思います。

Mbed CLI ならもっと洗練された方法があるのでしょうか? 今回はそちらは未調査です。

Mbed OS 5用プロジェクトの作成

  • Mbedのオンラインコンパイラでプロジェクトを作成します。ここでは「プラットフォーム」を「NUCLEO-F767ZI」、「テンプレート」を「mbed OS Blinky LED HelloWorld」、「プログラム名」を「mbed-os」とします。
  • 「プログラムのエクスポート」でこのプロジェクトをzipでダウンロードします。ここでは「Export Target」を「NUCLEO-F767ZI」、「Export Toolchain」を「SW4STM32」とします。

f:id:licheng:20200516161254p:plain

  • SW4STM32を起動し、[File] > [Import] > [Existing Projects into Workspace] でzipファイルを選択してプロジェクトをインポートします。
  • main.cppは不要なので削除します。 (エクスプローラで削除した場合はSW4STM32でF5キーを押してリフレッシュします。)
  • [Project] > [Properties] > [C/C++ Build] > [Build Artifact] で [Artifact Type] を Static Library に変更し、[Artifact name] を ${ProjName} に、[Artifact Extension] を a に、[Output prefix] を lib にします。

f:id:licheng:20200516230806p:plain:w640

  • [Project] > [Properties] > [C/C++ Build] > [Build Steps] で [Post-build steps] を空欄にします。

f:id:licheng:20200516174206p:plain:w640

Mbed OS 5の静的ライブラリをビルド

  • [Project] > [Build Project] でプロジェクトをビルドします。
  • MBED_COMPILER_BARRIER の行で「'asm' undeclared」というエラーが発生する場合はこちらを参照。
  • ビルドが成功するとプロジェクトフォルダの下の Debug または Release フォルダに libmbed-os.a というファイルができます。
  • これがMbed OS 5の静的ライブラリファイルですので取っておきます。

ユーザープログラムのプロジェクトを作成

  • Mbedのオンラインコンパイラでプロジェクトを作成し、zipファイルにエクスポートしてSW4STM32にインポートします。手順は上記「Mbed OS 5用プロジェクトの作成」の場合と同様です。
  • プロジェクトフォルダの下の mbed-os フォルダの下に、さきほどビルドした libmbed-os.a をコピーします。
  • プロジェクトフォルダの下の mbed-os フォルダの下にある、拡張子が c または cpp のファイルを全て削除します。Windosの場合は下記のようなバッチをプロジェクトフォルダの下で実行すると削除できます。
@echo off
for /R mbed-os %%i in (*.c) do del %%i
for /R mbed-os %%i in (*.cpp) do del %%i
  • Linuxの場合はプロジェクトフォルダの下で下記コマンドを実行すれば削除できます。たぶんMacでも同様。
find mbed-os -type f -name "*.c" -delete
find mbed-os -type f -name "*.cpp" -delete
  • SW4STM32でF5キーを押してリフレッシュします。
  • [Project] > [Properties] > [C/C++ General] > [Paths and Symbols] > [Library Paths] に mbed-os を追加します。 (これは libmbed-os.a を置いたフォルダの指定です。)

f:id:licheng:20200516221148p:plain:w640

  • [Project] > [Properties] > [C/C++ General] > [Paths and Symbols] > [Libraries] に mbed-os を追加します。(これはライブラリ名の指定です。頭に「lib」を付けないことと、拡張子「.a」を付けないことに注意してください。)

f:id:licheng:20200516221205p:plain:w640

ユーザープログラムをビルド

  • [Project] > [Build Project] でプロジェクトをビルドします。
  • かなり短い時間でビルドが完了するようになります。
  • 「undefined reference to `__wrap__free_r'」等のエラーが発生する場合はこちらを参照。
  • さらにビルド時間を短縮するためにMakefile生成を抑制するにはこちらを参照。
  • デバッグ実行時に「OpenOCD Binary not found」と言われたらこちらを参照。

以上で非力なPCでもMbed OS 5の開発できそうな気がしてきました。