CMakeとNinjaを組み込み向けに使ってみた

いまGNU make(Makefile)で作ってる某組み込み機器向けのプロジェクトを、CMakeに書き直したいと思った。だってMakefile書くのも読むのも苦手なんだもん。あと、いろいろな環境を横断して開発してるという事情も相まって、CMakeで書いたスクリプト(CMakeLists.txt)を極力使いまわしたいってのもあった。

しかし、ただCMakeに書き直すだけだとメリット薄い気がしたので、CMakeで吐き出すビルドスクリプトをMakefileじゃなくて、ドチャクソ速いと巷で噂のNinjaにも対応してみる事に。ビルドが速くなればそのぶん仕事サボれる時間が増えるからハッピーやね!

んで、いざ対応しようと思ったが右も左も分からんので、「CMake 組み込み」でググったら上の方に出てくるQiitaの記事(正直めっちゃ助かる)を参考にしつつお仕事の合間に組み込み環境に対応していったのだが、案の定ドハマリして1ヶ月ぐらい掛かってしまった。そもそもネット上にあんまり日本語の情報転がってないし、俺みたいなにわかビルドエンジニアには難易度高かったのよねぇ。

まあ、結果としてMakefileでやってたときに比べて、クリーンビルドの所要時間がだいたい半分になった。あと差分ビルドも一瞬で終わるので不安にはなるけど、機器に転送してみたらちゃんと動いてるみたいだから問題なかろう。たぶん今が一番覚えてる状態なので、忘れないうちに書き遺しておこう。
続きを読む CMakeとNinjaを組み込み向けに使ってみた

【CMake】add_customなにがし

最近お仕事でadd_custom_command()やadd_custom_target()を使う機会があったので、ざっくりとメモしとく。俺だけかもしれないが、こいつらパッと見が似てるからよくわかんなくなるのよね。

ビルドの前後で任意のコマンドを実行したい

VisualStudioとかだと「ビルド前イベント」「ビルド後イベント」みたいなプロパティが設定できるけど、それっぽいことをCMakeでもやりたい。そんなときは「add_custom_command()」を使えば良さげ。

add_executable(test "test.cpp" "test.h")
add_custom_command(TARGET test PRE_BUILD COMMAND echo wanwan)
add_custom_command(TARGET test POST_BUILD COMMAND echo nya-)

さっそくtestをビルドしてみる。

>cmake --build . --target test
wanwan
test.vcxproj -> test.exe
nya-

すると、ビルド前後で任意のコマンドが実行できていることがわかる。

add_custom_command(TARGET test POST_BUILD 
COMMAND echo wanwan
COMMAND echo nya-)

ちなみに、コマンドを連続で実行したいときはCOMMANDを並べれば良い。

オレオレターゲットを作りたい

ビルド済みのバイナリファイルを組み込み機器に転送したりだとか、ビルド作業とは分ける工程を別途ターゲットで作りたい。そんなときは「add_custom_target()」を使えば良さげ。

add_custom_target(inu echo wanwan)
add_custom_target(neko echo nya- DEPENDS inu)

DEPENDSをつけておけば「このターゲット実行してから走らすけん」てなことができる。

>cmake --build . --target inu
wanwan

inuをビルドするとそれ単体のコマンドが走るけれども、

>cmake --build . --target neko
wanwan
nya-

nekoをビルドすると、依存するターゲットinuのコマンドの後でnekoのコマンドが実行される。

【CMake】特定のソースコードをビルド対象から除外

# cファイルをビルド対象に加える
file(GLOB_RECURSE SOURCES "*.c")
# 実行ファイル作る
add_executable(unko ${SOURCES})

だいたいCMakeLists.txtを書くとき、こんな感じで「こっから下の階層にあるCファイルを全部ビルド対象に追加しといてねー!シクヨロー!」ってやってるのだけれども、厄介なことにビルド対象から外さないかんソースコードが混ざってるのを忘れてて、ビルドがズッコケちゃう事がある。具体的に言うと、下記のような書き方されてる困ったちゃん。

#include "nanigashi.c"

ちなみに、この「nanigashi.c」は他のCソースからincludeされる前提で書かれてるので、単体でコンパイルすると無慈悲に死ぬ。「ビルドしないんだったらヘッダにしとけばいいじゃん?」と思いはするのだが、古から伝わるソースコードだからおいそれと弄れないのよね。べっ、べつに改造ミスったときに責任負いたくないとかそんなことないんだからね!勘違いしないでよね!

まあ愚痴ってても始まらないので、例のソースをビルド対象から除外する某をCMakeで表現する手段を講じてみよう。この手の案件は基本的に日本語だとあんま情報出てこないので、いつものStackOverFlowとGoogle翻訳の黄金コンビでなんとかしてやろうじゃねえの。
続きを読む 【CMake】特定のソースコードをビルド対象から除外

【CMake】ヘッダファイルの参照を自動で追加したい

CMakeでコンパイラに対してinclude対象のディレクトリを設定するには、include_directories() だとか target_include_directories() がある。現在の推奨は後者らしいのだが、俺の場合わりと小規模なプロジェクト作ることが多いし、引数多いと面倒なので前者を使ってたりする。

# 以降のターゲット全てにincludeディレクトリを適用
include_directories(${INCLUDE_DIRS})
# fuga.exe には上記のinlucdeパスが適用される
add_executable(fuga ${SOURCES})

で、どちらを使うにせよ、予め洗い出しておいたinclude対象パスの一覧をテキトーなリスト(上記で言うところのINCLUDE_DIRS)に入れて渡してやる感じになる。

しかし、色々なディレクトリに参照したいヘッダファイルが散乱してる場合、includeディレクトリを手動で洗い出すのが面倒だ。可能であれば、「ヘッダファイルが入ってるディレクトリ」を勝手に走査して、勝手にリストにぶちこんでほしい。でもそれを外部スクリプトで書いて環境変数にぶちこむのもなんか嫌だし、CMakeLists.txtの中だけで完結させたい。
続きを読む 【CMake】ヘッダファイルの参照を自動で追加したい

SVGで自作フォント使ってHTMLで読み込む

世間一般的に需要はものすごく少ないと思うのだけれども、HTMLに埋め込んであるSVG画像内で独自フォントを使ってにゃんにゃんしたい場面が出てきた。HTMLで独自フォント使うだけならハードルはまだ低いと思うのだが、SVGを一枚噛ませるというのが曲者だ。

そもそも独自フォントってあれっしょ?作るの大変っしょ?と思ってたのだが、どーやらInkscapeでSVGフォント作ってから、そいつをクラウドの変換くんにぶちこめばTrueTypeFont(ttf)がサクッと作れるらしい。詳しい作り方については「inkscape svg font」とかでググったらそこそこ情報出てくるので、ここでは割愛しとくわね。
続きを読む SVGで自作フォント使ってHTMLで読み込む

VSCode+CMakeでVS2019のビルド環境を構築する

お仕事ではVisualStudio(*.sln)でMSVC(C/C++)の開発環境を構築しているのだけれども、他言語の開発環境はぜんぶVSCodeに統一してるからMSVCのビルド関係も揃えたいのよねー。しかしVSCodeを使ってVisualStudio同等の事をやるのって、それはそれで大変そう。要は、いままでGUIで設定してた某を事細かにMakefile的な奴へゴリゴリ書かなきゃいけないんでしょ?おじさん、ゆとりすぎてMakeよく分からないんよね。

そんなこんなでGoogle先生で色々調べてたら、CMakeとかいうツールが割とオススメらしい。「このコンパイラとかリンカ使いたいぜ」とか「ビルド対象はこのファイルだぜ」とか「実行ファイルとかライブラリとか作りたんだぜ」等のフワッとした願いを設定ファイルに書き込んでおけば、CMakeがそれを読み込んでステキなビルド環境を作ってくれるらしい。(フワッとした理解力)
続きを読む VSCode+CMakeでVS2019のビルド環境を構築する

【VSCode】ユーザスニペットが素晴らしい件

「よし、新しいコード組もう!」と思ったとき、前に作ったコードをエディタで開いてコピペしてくるって事がとにかく多い。俺の場合は特に、いろいろなプログラミング言語を横断的に使ってるせいで「あれどう書くんだったっけ?」ってなる事がガチで多い。

そんな痴呆ボーイにとってマジで助かるのが、VSCodeにくっついてる「ユーザスニペット」機能だ。スニペットってのはなんかっつーと、少ない記述で短いプログラムを呼び出せる素敵なサムシング。こいつを使わない手はなかろうもん。
続きを読む 【VSCode】ユーザスニペットが素晴らしい件

【Go】ファイルの更新日時を表示奴


特定のフォルダ以下の、特定の拡張子のファイルを拾い上げて、CSVでファイル名と更新時刻をリスト化したい。わざわざ専用プログラム作らなくても、もっと楽な手段あるじゃろ・・・とか思いつつも、ちょうどいい機会なので、Goの勉強がてら作ってみることにした。

docinfo.exe -walkdir ./sample -extension doc,xls,xlsx,xlsm,pdf > list.csv

go buildして作ったexeを、こんな感じで使いたい。-walkdirで指定したフォルダ以下の、-extensionで指定した拡張子のファイルを検索して、そいつの更新日時を一覧でCSV出力する。

かばん.doc,2018-04-13
サーバル.pdf,2018-07-22
ラッキービースト.xlsx,2019-04-11

出力結果はこうなる。もちろん、txtとか対象外のファイルは出力されない。

2期?知らない子ですねぇ・・・

イカソース。
続きを読む 【Go】ファイルの更新日時を表示奴

【Go】てきとーなコマンドラインツールを作ってみる


今週からお仕事でGoを使い始めた。といっても「A Tour of Go」を軽く流し読みした程度からのスタートだ。まあどんなプログラミング言語でも基本は一緒だから、なんとかなるっしょ。

とりあえずなんかテキトーな課題が無いと勉強になんないので、2つのファイルをぶちこんで簡易的に比較する処理でも作ってみる事にした。というか、Windowsだとcompだとかfcだとかのコマンドあるので、完全に車輪の再発明だけれども…
続きを読む 【Go】てきとーなコマンドラインツールを作ってみる

【BAT】特定の文字列を含む(含まない)ファイル名を抽出して変数にぶちこむ

Windowsバッチ、苦手だから極力使いたくないンゴねぇ。それでも使わにゃいかん場面も稀によくある。まぁ泣き言いっても始まりゃしねえので、今の俺にできるのは、忘れないようにメモしておくだけじゃろう。

ある条件下で、ビルドされた成果物を使いまわしていろいろなチェックにかける必要がでてきたのだが、厄介なことに、出力されるバイナリのファイル名は毎回ランダムなものになる。共通しているのは拡張子だけ。しかも、デバッグ用とリリース用のバイナリが同時出力されるので、そのうちリリース用のみを拾い出さなければならない。
続きを読む 【BAT】特定の文字列を含む(含まない)ファイル名を抽出して変数にぶちこむ