
特定のシステム向けに、一部のライブラリや、ライブラリに含まれる一部の関数のみカスタイマイズするニーズは一般的です。本稿では、ライブラリ全体をリビルドすることなく、一部を上書き・リダイレクトする方法について、ご紹介します(ライブラリのソースコードは、製品版ライセンスをお持ちのお客様にのみ提供しております)。
1つ目の方法としては、変更した関数を含むライブラリのみリビルドすることです。通常、ライブラリのリビルドは複雑なプロセスです。C/C++の標準ライブラリの場合、非常に複雑です。様々なフォーマッタ、ファイル記述子、低レベルインタフェース、マルチバイトやfloat/double型のサポートといった各モジュールを個別にビルドしているためです。
IAR Embedded Workbenchのリンカは、ライブラリ全体をリビルドすることなく、一部の関数を上書きすることが可能です。コンセプトは単純で、ライブラリ関数よりユーザ定義の関数の優先度を高くするというものです。もう1つの解決策としては、ライブラリ関数の関数呼び出しをリダイレクトすることがあります。
リンカは、アプリケーションの開発で強力かつ柔軟なツールです。リンカは、コンパイラもしくはアセンブラが出力したリロケータブルなオブジェクトファイルを、選択されたライブラリのモジュールとともに、実行可能イメージを作るために連結します。リンカは、ユーザ定義のライブラリ・C/C++標準ライブラリ・その他のライブラリからアプリケーションが必要とするモジュールのみ自動的に読み込みます。
IAR Embedded Workbenchのリンカは、最終的な実行可能イメージの中で使用されている全てのシンボルについて、マップファイルに出力できます。マップファイルの出力はリンカオプションで指定します。マップファイルを参照することで、カスタマイズが必要なモジュールを特定でき、またライブラリ関数が属するモジュールを見つけることもできます。
一例として、ライブラリ関数である__write関数を上書きする例を見ましょう。__write関数を上書きすることで、printf関数が呼び出すデフォルトのターミナルI/Oを、UARTやLCDに変更することができます。マップファイルを見ると、__write関数はwrite.oの中に含まれることがわかります。
C/C++標準ライブラリのソースコードは、IAR Embedded Workbenchをインストールしたフォルダの相対パスarm\src\libにあります。
ソースコードを入手したら、あとはプロジェクトに追加するだけです。数行の変更により、リビルド後の__write関数のサイズは0x10から0x3Cバイトに増えています。
もう1つの解決策は、同じプロトタイプをベースに関数を作ることです。
__ATTRIBUTES size_t __write(int, const unsigned char *, size_t);
上記の記述は、リンカに関数単位で高い優先度を与えます。モジュール内の他の関数には影響しません。
最後に紹介する方法は、シンボルの参照を変更することです。この方法は、コマンドラインからリンカに対して—redirectオプションを指定することで可能です。例えば、未実装の関数の呼び出しをスタブ関数の呼び出しにリダイレクトしたり、実装済の別関数にリダイレクトすることが可能です。
例えば、__write関数の呼び出しを独自の実装を行った関数__write_ownにリダイレクトしたいとします。この場合、リンカオプションとして、コマンドラインから—redirect __write=__write_ownを指定します。ビルド後、__write関数の呼び出しが__write_ownの呼び出しに変わっていることを確認できます。
ライブラリ全体をリビルドすることなく、特定のライブラリ関数を上書きしたり、リダイレクトすることは、ユーザ独自のライブラリやサードパーティーのライブラリに対しても適用可能です。長い間テストされたライブラリおよびサードパーティーから提供されたライブラリの全体をリビルドせず、お客様のシステムに必要な部分のみカスタマイズすることができます。