C/C++のソースコードを静的解析するツールのひとつにCppcheckがあります。 今回は、Cppcheckを使って実際に静的解析をするやりかたを紹介します。
公式サイトでは、Windows版のインストーラへのリンクしかありませんが、Windowsでしか使えないということはありません。
DebianやUbuntuなど、たいていのディストリビューション向けにパッケージが用意されているので、簡単にインストールすることができます。
ただ、ちょっとバージョンが古かったりすることもあるので、今回はあえてパッケージによらず最新のmasterをお試しで使ってみることにします。 その場合の情報は開発者向けページにあります。
最初にCppcheckのソースコードをcloneします。
% git clone git://github.com/danmar/cppcheck.git
次に、readme.mdにあるリリースビルドの手順を参考に、インストールします。
% sudo make PREFIX=/usr/local SRCDIR=build CFGDIR=/usr/local/share/cppcheck/cfg HAVE_RULES=yes CXXFLAGS="-O2 -DNDEBUG -Wall -Wno-sign-compare -Wno-unused-function" install
readme.mdではインストールせずに使う想定ですが、今回は/usr/localにインストールするものとします。*1
Cppcheckのセットアップができたので、実際に使ってみましょう。
例として、ククログでも何度もとりあげている、全文検索エンジンGroongaでやってみましょう。
すでに、Groongaのリポジトリをgroonga.clean
ディレクトリへとcloneしてあるものとします。
% /usr/local/bin/cppcheck --enable=all groonga.clean 2> cppcheck-master-groonga-master.log
Cppcheckのヘルプにもありますが、--enable=all
をつけるのがオススメ設定です。
--enable=all
では、次の観点からチェックを行います。
ほかにも、型や関数の付加情報を追加してチェックを行うことができます。
付加情報というのは、メモリの確保がmalloc
で、それに対応して解放するのがfree
でというようなことです。
こういったリソースの割り当てと解放というのは、プラットフォームであったりライブラリー特有の情報であることが多いので、そのための設定ファイルが標準でいくつか用意されています。
このうち、std.cfg
は自動で読み込まれます。--force
というオプションもあり、これを使うとすべての.cfgを強制的に読み込ませることができます。
cppcheck
を実行すると、解析結果が大量に出力されます。適宜リダイレクトしておくとよいでしょう。
ログは次のような形式で出力されます。
[対象ファイル:行]: (カテゴリ) 検出した問題点
カテゴリというのは、すでに紹介した、error
、warning
、performance
、portability
、style
、information
のいずれかです。
参考までにどんなふうに出力されるか、実際のログを抜粋します。
[groonga.clean/bindings/php/groonga.c:112]: (style) Variable 'rc' is assigned a value that is never used.
[groonga.clean/bindings/php/groonga.c:124]: (style) Variable 'res_id' is assigned a value that is never used.
[groonga.clean/bindings/php/groonga.c:154]: (style) Variable 'rc' is assigned a value that is never used.
[groonga.clean/bindings/php/groonga.c:109]: (error) Memory leak: ctx
[groonga.clean/bindings/php/php_groonga.h:13]: (error) Invalid number of character '{' when these macros are defined: '__cplusplus'.
[groonga.clean/bindings/python/ql/groongaql.c:35]: (style) Unused variable: rc
[groonga.clean/bindings/python/ql/groongaql.c:66]: (style) Variable 'grn_ctx_fin' is assigned a value that is never used.
[groonga.clean/bindings/python/ql/groongaql.c:79]: (style) Unused variable: rc
[groonga.clean/bindings/python/ql/groongaql.c:98]: (style) Unused variable: rc
[groonga.clean/bindings/python/ql/groongaql.c:119]: (style) Unused variable: rc
[groonga.clean/bindings/python/ql/groongaql.c:134]: (style) Unused variable: rc
[groonga.clean/lib/com.c]: (information) Too many #ifdef configurations - cppcheck only checks 12 of 61 configurations. Use --force to check all configurations.
[groonga.clean/lib/com.c:1085] -> [groonga.clean/lib/com.c:1106]: (warning) Either the condition 'if(ev)' is redundant or there is possible null pointer dereference: ev.
[groonga.clean/lib/com.c:1086] -> [groonga.clean/lib/com.c:1106]: (warning) Either the condition 'if(ev)' is redundant or there is possible null pointer dereference: ev.
上記のようなログを採取できたら、検出された箇所をチェックしていきましょう。
大量に検出されるので、error
やwarning
にしぼりこんで重点的に確認するとよいでしょう。ただし、Cppcheckも誤検出するケースがあるので万能ではありません。
C/C++のソースコードを静的解析するツールであるCppcheckを紹介しました。 ツールをうまく使って、これまで見落していた潜在的な問題点がないか、これを機会に調べてみるのはいかがでしょうか。
*1 インストールしていない場合には、常にカレントディレクトリにcfgディレクトリがあることを想定した振舞いをします。そのためclone先のディレクトリで常に実行しないとエラーになります。
先日告知した通り、2016年1月30日にOSS Gateワークショップを開催しました。
内容は前述の告知記事を参照してください。そこにざっくりした内容がまとめてあります。より詳細な内容はGitHubのoss-gate/workshopの中のtutorial/scenario.mdにあります。興味のある方は参照してください。なお、当日はこれの説明をところどころ省きながら進めました。理由はメンターが飽きていそうだったためです。もともと学生向けのワークショップをベースにしているので説明が冗長かもしれません。
ワークショップには「参加者」4名、「メンター」8名、合わせて12名が参加しました。(「参加者」とは「OSSの開発に参加したいけどまだ参加したことがない人」または「OSSの開発に参加したことはあるけどまだ自信がない人」です。)
今回のワークショップは「メンター」の人たちが「ワークショップを経験する」ことも大事なことだったので、人数が多すぎず適切な規模でした。このくらいの規模なら「進行役」の「メンター」が全体の様子を眺められるからです。
また、「参加者」1名につき「メンター」2名になれたこともよかったです。「メンター」も探り探りなので、1人だけで頑張るよりも他の誰かと協力してやれた方がその場で改良しながら進められるからです。
アンケート結果とワークショップ後に直接参加者に聞いた結果、参加者4名は全員OSS開発参加への不安が取り除かれていました。このワークショップの目的を達成できたということです。メンターの人たちもこのワークショップの効果を実感できていたようなので、今後のOSS Gateの進め方によいフィードバックとなりました。
ワークショップ参加者の何人かはWeb上に感想を書いているので、興味のある方はこちらも参考にしてください。
今回の結果をふまえて隔月でさらに2回開催することにしました。3月最終土曜日と5月最終土曜日です。
3月26日の方は「参加者」6名、「メンター」3名と圧倒的に「メンター」が足りない状況です。OSS開発への参加経験があり、OSSの開発に参加する人が増えるとうれしい、という方はぜひメンターとしてご協力ください。お待ちしています。
もちろん、「参加者」(「OSSの開発に参加したいけどまだ参加したことがない人」または「OSSの開発に参加したことはあるけどまだ自信がない人」)も募集しているので、「参加者」としての参加も歓迎です。
↑のワークショップには参加できないけど、OSS Gateの活動には参加したいという方は、まずはGitterのoss-gate/generalチャットルームにどうして参加したいか、ということを書き込んでみてください。他の参加者となにができそうかを相談できます。
2月8日に開催された「nginx実践入門」出版記念!執筆者らが語る nginx Tech TalksのLT枠が1つ余っていたので「ngx_http_groonga - 全文検索nginx」と題してGroongaでのnginx利用事例を紹介しました。
関連リンク:
nginxはHTTPサーバー・HTTPリバースプロキシサーバーだけでなく、メールプロキシサーバー・TCPプロキシサーバーにもなれます。いろいろなサーバーになれるので、全文検索エンジンにもなれるよ!全文検索nginxだよ!という話をしました。
nginxのモジュール機能を利用した例としてモジュールを開発したい人は参考にしてください。ソースはGroongaのリポジトリーのsrc/httpd/nginx-module/にあります。
nginxは高速なHTTPサーバーで、Groongaを組み込むことで高速な全文検索エンジンとしても使うことができます。Groongaが組み込まれていなくても有用なので、「nginx実践入門」を参考に使ってみてはいかがでしょうか。
年に一度の肉の日、2月9日に「MySQLとPostgreSQLと日本語全文検索」というイベントを開催しました。次の2つのことについて紹介するイベントです。
その中で、MySQLで日本語全文検索を実現するMroonga(むるんが)とPostgreSQLで日本語全文検索を実現するPGroonga(ぴーじーるんが)を紹介しました。
Mroonga(むるんが)もPGroonga(ぴーじーるんが)もどちらも国産の全文検索エンジンGroonga(ぐるんが)を利用しています。MySQLにGroongaを組み込んだのがMroongaで、PostgreSQLにGroongaを組み込んだのがPGroongaです。
Mroonga・PGroongaを使うと、Groongaの高速で高機能な全文検索機能をMySQL・PostgreSQLで使えます。資料にはベンチマーク結果もありますが、全体的に他の実現方法よりも高速であることがわかります。
MySQL・PostgreSQLで日本語全文検索を実現したいときはMroonga・PGroongaを検討してみてください。
イベントではMroonga・PGroonga以外にも、MySQL 5.7のInnoDBの日本語全文検索機能、pg_bigmを利用したPostgreSQLでの日本語全文検索機能の紹介がありました。MySQL・PostgreSQLでの日本語全文検索の歴史についての情報も紹介してあるので、MySQL・PostgreSQLでの日本語全文検索に興味のある方はこちらの資料もご覧ください。
他にも会場を提供してくれたDMM.comラボさんでの日本語全文検索の利用事例の紹介がありました。DMM.comラボさんではMySQLとMroongaを利用して日本語全文検索を実現しているとのことでした。
多くのデータはSQLで操作できる状態になっているため、SQLで日本語全文検索も実現できることは使い勝手の面で大きなメリットになります。当日の参加者の多くは「MySQLとPostgreSQLと日本語全文検索」の第2回があったら参加したいとのことでした。そのため、数カ月後に同様のイベントの開催を検討しています。SQLで日本語全文検索機能を実現したい場合はぜひご参加ください。
次回開催にあたり、会場提供をしてくれる方、次の製品での日本語全文検索機能の利用事例を紹介してくれる方を募集しています。ご協力いただける方は@ktouまたはkou@clear-code.com
までご連絡ください。
Mozillaサポート業務を主に担当している結城です。
明日までにこれを作らなくてはならない、何月何日までにこれを直さなくてはならない、期日は決まっていないがなるべく早くそれを完成させなくてはならない……こういった「タスク」をどのように管理するかは永遠の課題です。
例えば、プロジェクト管理ツールとして広く使われているRedmineには「チケット」(英語版では「issue」)を単位としてタスクを管理する機能が含まれています。 GmailのTODO機能も一種のタスク管理ですし、Remember The Milkのように専門のサービスもあります。
しかし、残念なことに筆者個人はそれらを使いこなせていません。 「このように使うツールだ」という説明を見聞きして「なるほど」と思っても、その使い方をどうしても憶えられなかったり、だんだん億劫になりいいかげんな使い方をして結局役に立たなくなってしまったりと、これまでタスク管理では失敗続きでした。
とはいえそれでは仕事が回りませんので、対策として、タスク管理が苦にならないタイプの人とチームを組む事により、会社としては安定したサービスを提供するという事を行っていました。 個人個人は不得意分野を抱えていながらも、お互いの得意分野を持ち寄ってそれをカバーし合うことによって、全体として最大の効果を上げられるというのは、個人ではできないチームプレイならではの利点だと言えます。
ただ、タスクを管理してくれる人がいなければ全く仕事ができないというのは、業務のアサインやチーム編成に制限が生じるということで、やはり望ましくない状況です。 そこで、筆者だけでも無理なくこなせるタスク管理方法を改めて模索していて、現在ではRedmineのチケット1つを軸にすることにより、筆者単独でも業務上のタスクをある程度までは管理できる状態になってきました。
この記事では、筆者が現在行っている「Redmineをほぼ既定の設定のままで運用している状態で、チケット機能を使って日々発生するタスクをこなしていく」というタスク管理の流れをご紹介します。
クリアコードでは開発業務以外に、フリーソフトウェアのサポート業務も行っています。 サポート業務では、例えば「Thundebrirdを使用していて削除できないメールができてしまった」や「Firefoxを使用していてTLSのページでエラーが表示されてしまった」といったトラブルについて調査・回答をするという事を行っています。 具体的なサービス内容については過去に詳しい紹介を掲載済みですので、そちらも併せてご覧下さい。
このサービスでは、お問い合わせを頂くタイミングが重なる場合や、お客様環境でのログ収集を依頼してその結果を待つ必要がある場合などがあり、個々のお問い合わせにその都度専任の人員を張り付けるという訳にはいかない場合が多いです。 そのため、「お問い合わせに対して回答をすること」をタスクとして一旦キューに溜め込んでおき、「受け付けから3営業日以内に回答する」という基準の範囲で順に処理しています。
何を置いても、まずはタスクがタスクとして登録される必要があります。
弊社サポート業務では、お客様からのお問い合わせはサポート業務担当者が参加しているメーリングリストへの投稿という形で受信されます。 例えば以下のような内容です。
クリアコード 担当者様
XXXのxxxです。
Firefoxを使用していて○○機能が動作しませんでした。
回避方法の調査をお願いします。
これを担当者が確認した後、まずRedmineの該当プロジェクト(クリアコード社内のRedmineでは、お客様ごと・ご契約ごとにRedmineのプロジェクトを作成して管理しています)のチケット一覧を調べます。
お問い合わせがいつ来るかはお客様次第なので、キューイングの作業は常に他の作業と並行して行う必要があります。
このようにしてタスク化されたお問い合わせは、以下のような流れで処理していきます。
クリアコードでは毎日朝会を実施しており、その際、「前日行った業務内容」と「当日行う予定の業務内容」を簡単に報告します。
その材料として、Redmineの「朝会」プロジェクトにはその日ごとの朝会に対応するチケットが用意されています。 朝会に参加するメンバーは各自で、朝会で喋る内容をこのチケットにコメントとしてメモしています。
後述しますが、筆者は当日分のチケットのコメントに、「当日の予定」として前日のうちに未処理のチケットの番号を以下のようなリスト形式で記載しています。
* #1234 Aさま 問い合わせ回答
* #1235 Bさま 問い合わせ回答
* #1236 Cさま 問い合わせ回答
Redmineでは #チケット番号
という記法で書いたテキストが自動的に当該チケットへのリンクになります。
そのため、この朝会用チケットを参照して個々のチケットを辿れば、回答するべきお問い合わせの内容やそれまでの議論をすべて読む事ができます。
筆者は、このチケットを一日中タブで開いたままの状態にしていて、その日の仕事の起点として何かある度に参照するようにしています。
なおこの時、前日の終業以後に新たに頂いたお問い合わせがある場合は、それもチケットに記録して「当日の予定」のリストに加えておきます。
その日の朝の段階で把握したタスクは、上から順に処理していきます。 一番上のチケットを開き、そこに書かれた内容に基づいて調査を実施して、結果が出たら、その内容を適宜当該チケットに記録しておきます。
その後、調査結果を元に最終回答や途中経過の報告をまとめて、お客様に回答します。 例えば以下のような内容です。
XXX xxx様。
クリアコード ***です。
お問い合わせを頂きました件について調査した結果、△△の可能性がある事が分かりました。
お手数をおかけしますが、××の手順でログを収集してご連絡いただけませんでしょうか?
回答をメールでお客様に送信したら、チケットのステータスを「解決」に変更します。 この場合、お客様からの連絡を待つ必要があるので、チケットは再びキューに戻った事になります。 (なので、ここでの「解決」とは「問題が解決した」ではなく「未処理のタスクを処理した」という意味になります。)
調査を行っている間に、既に回答した別のお問い合わせについての追加のお問い合わせや、依頼していた情報の提供の連絡を頂く事もあります。
その場合は、先に述べた通りのルールで新規チケットを作成したり、既存チケットへコメントを追加したりして、未処理タスクのキューに入れます。 具体的には、朝に参照したその日の朝会用チケットの「当日の予定」の末尾に項目を追加します。
* #1234 Aさま 問い合わせ回答
* #1235 Bさま 問い合わせ回答
* #1236 Cさま 問い合わせ回答
* #1237 Dさま 問い合わせ回答
業務時間中に受け付けたお問い合わせについては、その場ですぐに回答しないで、必ずこのようにキューにしてから処理するという運用を取っています。 そうしないと、レスポンスが速いお客様からすぐに回答を得られた場合や、問い合わせの件数が多いお客様がいた場合に、他の事が全くできなくなってしまいます。
一日の終わりには、次の日の朝会用チケットの準備をします。
この時にはまず、当日の朝会用チケットにコメントとして書いていた内容を丸ごとコピーして、翌日の朝会用チケットのコメント追加用のフォームにそのまま貼り付けます。 その後、「前日の業務」の内容を消して、「当日の予定」欄にあったタスクのうち処理済みの物を「前日の業務」欄に移動します。 そして、当日処理しきれなかった分のタスクはそのまま「当日の予定」欄に置いておきます。
これにより、翌日の朝には「その日処理するべきタスク」の一覧ができているという事になります。
前日の業務
* #1234 Aさま 問い合わせ回答
* #1235 Bさま 問い合わせ回答
* #1236 Cさま 問い合わせ回答
当日の予定
* #1237 Dさま 問い合わせ回答
また、前述したとおり、翌日朝には終業後に受信したメールを確認し、チケットに反映されていないお問い合わせを既存チケットのコメントや新規チケットとして記録して、「当日の予定」に反映します。 筆者はこのようにして、毎日コンスタントにタスクを消化していっています。
以上、五月雨式にタスクが発生する業務について、Redmineの標準的なチケット管理機能でタスクを管理する運用の例をご紹介しました。
このタスク管理の方法には「優先順位」という考え方が入っていませんので、処理能力を超えて多数のタスクが発生する状況では破綻してしまいます。 また、実際には個別のお問い合わせに対するサポート業務と並行して、「カスタマイズして導入済みのFirefox 38esrをFirefox 45esrに更新するために、それぞれのカスタマイズの反映方法をFirefox 45ベースで確認する」のような大きなまとまりのタスクもあります。 それらをどう管理していくかという点で、このタスク管理の流れにはまだ改善の余地があり、現在もそのような場面では、タスク管理を得意とする人の手助けを得て運用しています。
とはいえ、1人ではタスク管理ができないという状態からスタートして、ここまでは辿り着くことができたということで、筆者にとっては大きな改善でした。
筆者の場合、数ヶ月にわたって事前に朝会用チケットの運用を既に行っていた事から、「作業は朝会用チケットを起点にして行う」「作業内容は個別のチケットで把握する」ということについては既にできている状態でした。 そのため、「新しいお問い合わせを受け付けた際に、その情報をチケットに即座に記載する」ということと「朝会用チケットに記載する内容に必ず、タスクに対応するチケットの番号を記載してリンクするようにする」というインプットの2点に新たに気をつけるようにするだけで、そのままタスク管理の流れを確立することができました。
まず、他の人が用意してくれたタスクリストをそのまま使う形ででも、とにかく「自分のその日のタスクをチケットの一覧として把握して」「作業の節目にはタスクに対応するチケットにまめに情報を反映する」のを習慣づけること。
そして、それらを無理なく行えるようになった上で、「流入してくる情報から新たにタスクを作成し、タスクリストに項目を追加する」という、今まで自分では行っていなかった事を新たに行うようにすること。
このような2段階を経たソフトランディングによって、筆者は単独でもタスクの管理を行えるようになってきたと思います。 全く下地のない所から完全なタスク管理を始めようとしたら、あるいは、それまでの習慣とは全く別の「画期的なタスク管理手法」に飛びついて無理をしていたら、うまくいっていなかったのではないでしょうか。
状況が許すのであれば、このように時間をかけて少しずつ成功体験を重ねて要素要素の技能を身に付けていくことが、結果的には不得意を克服する近道となるのではないか……というのが、この記事を通じて筆者が最も伝えたかった事です。 今まさに苦手を抱えている人や、苦手を抱えているメンバーが近くにいるという人は、参考にしていただければ幸いです。
Debianプロジェクトでは、移植作業用のインフラが各アーキテクチャごとに用意されています。 それらのインフラはDebian開発者向けに提供されているものですが、開発者だけに限定されているわけではありません。 今回は、移植作業用のインフラをDebian開発者でない人が借りる方法について紹介します。
移植作業用のインフラのことをporterboxと呼んでいます。それらはdebian.org配下のドメインで提供されています。 どんなものが提供されているかはdebian.org Developer Machinesから一覧できます。 移植作業用に使われるのは、この一覧のうちpurpose欄がporterboxとなっているものです。 しかし、多種多様な目的のマシンが混在しているのでややわかりづらいです。
そこで便利なのがporterboxコマンドです。 これはPythonで実装されていて、実行すると対応アーキテクチャやドメイン、公開範囲について知ることができます。
% ./porterbox
Architecture Hostname Access
--------------------------------------------------------------------
armel abel.debian.org public
arm64 asachi.debian.org public
kfreebsd-amd64 asdfasdf.debian.net public (non-DSA-machine)
amd64 barriere.debian.org public
mipsel etler.debian.org public
hurd-i386 exodar.debian.net public (non-DSA-machine)
kfreebsd-amd64 falla.debian.org public
kfreebsd-i386 fischer.debian.org public
armhf harris.debian.org [unknown]
kfreebsd-i386 io.debian.net public (non-DSA-machine)
ia64 merulo.debian.org public
mips minkus.debian.org public
powerpc partch.debian.org public
ppc64el pastel.debian.net public (non-DSA-machine)
powerpc pizzetti.debian.org [unknown]
ppc64el plummer.debian.org [unknown]
sh4 sh4.g15.jp public (non-DSA-machine)
sparc smetana.debian.org public
hurd-i386 strauss.debian.net public (non-DSA-machine)
sh4 sumotsu.debian.net public (non-DSA-machine)
armhf turfan.debian.net public (non-DSA-machine)
avr32 xoothais.err.no public (non-DSA-machine)
s390x zelenka.debian.org public
Found 23 machines
実際にporterboxを借りるときの手続きは次の通りです。
移植作業向けにDebian開発者でなくても借りられるとはいっても、誰にでもほいほいと貸してくれるわけではありません。 というわけで、スポンサーになってくれるDebian開発者が必要です。 まわりにDebian開発者が生息していない場合は、Debian JP Developers メーリングリストで探すか、お近くで開催されているDebian勉強会などに参加してつかまえるとよいでしょう。
幸いにしてDebian開発者をつかまえることができたら、次はporterboxのアカウントの申請メールをスポンサーしてくれるDebian開発者に送ります。
Guest Access to porter machinesに記載されているように、以下の項目を埋める必要があります。
DMUPというのは、Debian マシン使用ポリシーのことです。要は目的外に使ったりしませんよというのに同意する必要があります。
アカウント申請メールを送ったら、次はDebian開発者にチケットを起票してもらいましょう。
アカウントの申請はrt.debian.orgで管理されています。 これにアクセスできるのはDebian開発者だけなので、スポンサーをお願いしたDebian開発者にチケットを作成してもらう必要があります。
チケットをDebian開発者に起票してもらうと、専用のトラッカー番号が割り当てられます。 これには、専用のメールアドレスがひもづけられています。例えば、トラッカー番号6092に対応して「rt+6092@rt.debian.org」といったような具合です。
しばらく待つと、DSAと呼ばれる管理者からアカウント作成完了通知がメールで届きます。 なかなか届かない場合は、専用のメールアドレスに対して現状どうなっているか確認のメールを投げるとよいでしょう。*1
申請通りにアカウントが作成されているかは次のコマンドで確認できます。*2
% ldapsearch -LLL -b dc=debian,dc=org -x -h db.debian.org uid=(申請したユーザー名) allowedHost
すると、次のようなレスポンスが返ってきます。
dn: uid=(申請したユーザー名),ou=users,dc=debian,dc=org
allowedHost: minkus.debian.org 20160427
allowedHost: etler.debian.org 20160427
ちなみに、この段階でDebian開発者でなくても(申請したユーザー名)@debian.orgが作成されますが、使ってはいけないことになっています。
アカウントが作成できても、サーバーには公開鍵を使ってアクセスする必要があるので、鍵を登録しないといけません。 これにはLDAPゲートウェイが用意されています。
例えば、minkusとetlerの申請をしている場合、公開鍵の先頭に以下を追加します。
allowed_hosts=minkus.debian.org,etler.debian.org ssh-rsa ....
そのあとで、cat (公開鍵ファイル) | gpg --armor --sign
などとして署名したものをメールの本文に貼りつけて、changes@db.debian.org宛てで送付します。
即座に反映されるわけではないので、しばらく待ちましょう。 各サーバーに反映されると、sshでporterboxにログインできるようになります。
今回は、移植作業用のインフラをDebian開発者でない人が借りる方法について紹介しました。 実機をもってないけど、特定のアーキテクチャへの対応をしたいなら検討してみてはいかがでしょうか。*3