link 未来から過去へ表示(*)
link 過去から未来へ表示

link もっと前
   2015年 6月 3日 ---> 2015年 5月 25日
link もっと後

2015年 6月 3日

ビルド高速化ツール ccache

巨大なプロジェクト(Android など)をコンパイルするときに欠かせない ccache というツールがあります。

簡単に説明すると、過去にコンパイルした結果をキャッシュデータとして保存しておき、一致する場合はコンパイルをスキップして、結果をキャッシュデータから引き出してくるツールです。

使い方は大きく分けて 2つあって、1つは環境変数や Makefile などを書き換えてコンパイラの名前を変更する方法です。

例えば今まで gcc hoge.c としていたところを ccache gcc hoge.c と書き換えたり、make としていた部分を CC='ccache gcc' make とします。簡単ですが透過性が無いのが欠点で、そこらじゅうの Makefile を変えて回るのは非常に大変だろうことは、容易に想像できるかと思います。

もう 1つはコンパイラの起動をフックする方法です。ccache はシンボリックリンク経由で起動された場合、シンボリックリンクの名前に該当するコンパイラを探して起動する、という動作をします。やることとしては、

  • ccache へのシンボリックリンクを作成し、名前をキャッシュしたいコンパイラと同じ名前にします
  • gcc を起動したときに ~/bin/gcc が選択されるように、PATH を書き換えます

例えば /usr/bin/gcc のコンパイル結果をキャッシュするなら…、

ccache を使う準備
$ which gcc
/usr/bin/gcc

$ ln -s /usr/bin/ccache ~/bin/gcc

$ export PATH=~/bin:$PATH
$ which gcc
/home/katsuhiro/bin/gcc

このようにします。また ccache -s でどれくらいキャッシュが効いているかを見ることができますので、実際キャッシュ出来ているかどうかを見てみます。

ccache が働いている様子
$ echo 'int main;' > a.c

$ ccache -s
cache directory                     /home/katsuhiro/.ccache
cache hit (direct)                     0
cache hit (preprocessed)               0
cache miss                             0
files in cache                         0
cache size                             0 Kbytes
max cache size                       1.0 Gbytes

$ gcc -Wall a.c -c -o a.o
a.c:1:5: warning: ‘main’ is usually a function [-Wmain]
 int main;
     ^
$ ccache -s
cache directory                     /home/katsuhiro/.ccache
cache hit (direct)                     0
cache hit (preprocessed)               0
cache miss                             1 ★★キャシュから結果を返せなかった★★
files in cache                         3
cache size                            12 Kbytes
max cache size                       1.0 Gbytes

$ gcc -Wall a.c -c -o a.o
a.c:1:5: warning: ‘main’ is usually a function [-Wmain]
 int main;
     ^
$ ccache -s
cache directory                     /home/katsuhiro/.ccache
cache hit (direct)                     1 ★★キャシュから結果を返せた★★
cache hit (preprocessed)               0
cache miss                             1
files in cache                         3
cache size                            12 Kbytes
max cache size                       1.0 Gbytes

きちんと働いてくれていそうです。

ccache と PATH 環境変数

で、今日の本題なんですが、会社で ccache が動かないというので相談を受けて見に行ったら、確かに PATH をどう設定しても「コンパイラが見つからない」というエラーが出ていました。

散々悩んで辿り着いた答えは CCACHE_PATH 環境変数でした。man ccache とすると、しっかり説明が載っています。

この名前だけ聞いて、ああ、あれね?とわかる方は、かなり ccache を使い慣れている方だと思います。恥ずかしながら、わたくし全く知りませんでした…。

先の節で説明した 2つ目の方法で ccache を起動すると、ccache は PATH に列挙されたディレクトリからコンパイラを探そうとします。

しかし実はこの挙動は CCACHE_PATH という環境変数により変えることができて、もし CCACHE_PATH という環境変数が定義されていた場合、ccache は PATH の代わりに CCACHE_PATH に列挙されたディレクトリからコンパイラを探そうとします。

相談されたエラーは間違って CCACHE_PATH が定義してしまい、さらに CCACHE_PATH で何もないディレクトリを指していたため、ccache が「コンパイラが無いですねー?」とエラーを出していたのでした。

CCACHE_PATH の働き
$ gcc
gcc: fatal error: no input files
compilation terminated.

$ export CCACHE_PATH=/usr
$ gcc
ccache: FATAL: Could not find compiler "gcc" in PATH ★★コンパイラが見つからないと言っている★★

$ unset CCACHE_PATH
$ gcc
gcc: fatal error: no input files
compilation terminated.

わかっていれば、何だ、そんなこと…というレベルの話ですが、意外とハマって苦戦したので、思い出として書き残しておきます。

編集者: すずき(更新: 2015年 6月 5日 00:57)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2015年 5月 28日

GPS 故障?

先日(2015年 5月 8日の日記参照)の日記で壊れているのかと思っていた Globalsat BU-353-S4 ですが、実は壊れていませんでした。

GPS 受信機が受信状態を伝える通信方式には、NMEA 0183 という規格に基づいたテキストデータで送ってくるか、GPS の受信機メーカー独自のバイナリデータで送ってくるか、の 2つがあるようです。

恐らく大抵のメーカーは両方に対応しており、NMEA か、メーカー独自バイナリかが選択できます。もちろん Globalsat BU-353-S4 が採用している SiRF Star IV もどちらかを選ぶことができます。

どうも色々いじっているうちにバイナリモードになってしまっていたらしく、NMEA を期待していた GPS のデータ表示アプリなどが「何言ってるのかわからんわ、このデバイス」状態に陥っていました。故障じゃなくて良かったです。

GPS データの確認方法
stty -F /dev/ttyUSB0 ispeed 4800 && cat < /dev/ttyUSB0
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPGSV,3,1,12,01,00,000,,02,00,000,,03,00,000,,04,00,000,*7C
$GPGSV,3,2,12,05,00,000,,06,00,000,,07,00,000,,08,00,000,*77
$GPGSV,3,3,12,09,00,000,,10,00,000,,11,00,000,,12,00,000,*71
$GPRMC,,V,,,,,,,,,,N*53
...

もし上記のようにテキストデータが受信されれば NMEA モードになっています。もしグチャグチャの字が受信されるときは、ボーレートが間違っているか、バイナリモードになっている可能性が高いです。

モードの切り替え方

GPS データの通信方式を切り替えるには gpsctl というコマンドを使います。GPS デバイスが /dev/ttyUSB0 として認識されているとして、

GPS データの通信方式切り替え
# to NMEA
gpsctl -f -n /dev/ttyUSB0

# to Binary
gpsctl -f -b /dev/ttyUSB0

オプション -n は NMEA モードにする、-b はバイナリモードにするという意味で、-f はローレベル(gpsd を介さないという意味らしい)で GPS デバイスにアクセスするという意味です。

ちなみに SiRF Star IV はモード切り替えに数秒〜10秒近くの時間がかかることがあります。さすが「絶対買わない方が良いぜ」と言われるだけのことはある…。

無理やり変えてみる

これで終わりだとあまり面白くなかったので、Globalsat BU-353-S4 の通信方式を gpsctl -n 以外で切り替える方法も試してみます。

ありがたいことに Globalsat US のサイトから SiRF バイナリデータの仕様書を入手できますので、NMEA モードへの切り替えコマンドを送ってみようと思います。仕様書のダウンロードはこちらのサイトの「SiRF Binary Protocol Document」からできます。

ちなみに仕様書の「Switch To NMEA Protocol – Message ID 129」にそのまま使える例が載っていますので、これをそのまま送ってみます。

  • A0A20018 - Start Sequence and Payload Length
  • 810201010001010105010101000100010001000100012580 - Payload
  • 013AB0B3 - Message Checksum and End Sequence

このデータをバイナリエディタなどでファイル(to_nmea というファイル名だとします)に書いておき、

GPS データの通信方式切り替え SiRF 用
# gpsctl -f -b /dev/ttyUSB0
/dev/ttyUSB0 identified as a SiRF 9GSD4e_4.1.2-B2_RPATCH.02-F-GPS-4R-1301151 01/17/2013 017 at 9600 baud.
gpsctl:SHOUT: switching to mode BINARY.
falcon:~# stty -F /dev/ttyUSB0 ispeed 9600 && cat < /dev/ttyUSB0 | hexdump -C
00000000  a0 a2 00 29 02 00 00 00  00 00 00 00 00 00 00 00  |...)............|
00000010  00 00 00 00 00 00 00 00  00 00 03 36 02 6a 9c 5a  |...........6.j.Z|
00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 01 9d b0  |................|
00000030  b3 a0 a2 00 09 09 00 00  00 00 00 00 00 00 00 09  |................|
...

# cat to_nmea > /dev/ttyUSB0

# stty -F /dev/ttyUSB0 ispeed 9600 && cat < /dev/ttyUSB0
$GPGGA,163721.731,,,,,0,00,,,M,0.0,M,,0000*53
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPRMC,163721.731,V,,,,,,,280515,,,N*43
...

以上のようにバイナリを GPS デバイスに送りつけると、無事 NMEA モードに切り替わります。ちなみに上記の設定例だとボーレートが 4800bps から 9600bps に変わってしまうので注意してください。

編集者: すずき(更新: 2015年 5月 29日 01:42)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2015年 5月 26日

ピリオドとユーザ名の不思議

Debian のセットアップでユーザ名にピリオドを使ったら「不正なユーザ名」と言われるので、何故?と思って調べたら思いのほか歴史がありました。

元々 BSD では、chown のユーザ名とグループ名の区切りにピリオドを使っていたそうで、ユーザ名にピリオドを使うなど以ての外でした。

しかし POSIX がユーザ名にピリオドも使えるよ、と決めてしまったので、哀れ chown の区切りはピリオドからコロンになりました。

Debian のセットアップスクリプトは安全側、つまりユーザ名のピリオドに対応していない古いツールを考慮して BSD 時代のルールを守っているのだろう、と思われます。

実は誰も直さずに放置されているだけかも知れませんけど…真相はわかりません。

メモ: 技術系の話は Facebook から転記しておくことにした。

編集者: すずき(更新: 2015年 6月 5日 01:01)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link もっと前
   2015年 6月 3日 ---> 2015年 5月 25日
link もっと後

管理用メニュー

link 記事を新規作成

合計:  counter total
本日:  counter today

link About www.katsuster.net
RDF ファイル RSS 1.0
QR コード QR コード

最終更新: 4/20 02:25

カレンダー

<2015>
<<<06>>>
-123456
78910111213
14151617181920
21222324252627
282930----

最近のコメント 5件

  • link 21年04月12日
    すずき 「コメントありがとうございます。ご参考にな...」
    (更新:04/18 22:39)
  • link 21年04月12日
    たくじ 「こんにちは。\n記事読ませていただきまし...」
    (更新:04/16 17:22)
  • link 21年02月28日
    すずき 「ですね、その辺りも違います。違いを全部示...」
    (更新:03/06 00:21)
  • link 21年02月28日
    hdk 「109と109Aって、かなの記号も違うん...」
    (更新:03/05 21:43)
  • link 21年02月14日
    すずき 「そうですね、1年だけとか、出張の時だけ、...」
    (更新:02/15 11:27)

最近の記事 3件

link もっとみる
  • link 21年04月16日
    すずき 「[ドキュメントスキャナーで書類を電子化] 我が家の本棚は広い方では...」
    (更新:04/20 02:25)
  • link 21年04月12日
    すずき 「[Zenfone+ahamo にしたらハマった] ドコモがついに...」
    (更新:04/13 17:54)
  • link 21年04月06日
    すずき 「[ディスプレイアーム] 机の奥行きが 60cm のためか、ディスプ...」
    (更新:04/12 11:18)

こんてんつ

open/close wiki
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 2018年
open/close 2019年
open/close 2020年
open/close 2021年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報