動機
makefile(のシェルスクリプト部分)でGCCのバージョンの比較をしたくなった。
GCCのバージョン番号は gcc -dumpversion
を実行することで、例えば 4.8.1
のように出力される。
このバージョン番号の大小を比較したいのだが、インターネットを検索してみたところStack Overflowの記事 http://stackoverflow.com/questions/5188267/checking-the-gcc-version-in-a-makefile くらいしか見つけることができず、その記事の回答に満足できなかったので、自分で考えた。
コード
例としてGCC 4.8.1以上かどうかの比較を行う。
shell scriptでなら
GCC_VERSION=$(gcc -dumpversion | (IFS=. read -r major minor micro; printf "%2d%02d%02d" ${major:-0} ${minor:-0} ${micro:-0}))
if [ "$GCC_VERSION" -ge 40801 ]; then
...
fi
makefileでなら
GCC_VERSION=$(shell gcc -dumpversion | (IFS=. read -r major minor micro; printf "%2d%02d%02d" $${major:-0} $${minor:-0} $${micro:-0}))
GCC_GE40801=$(shell if [ $(GCC_VERSION) -ge 40801 ]; then echo yes; fi)
ifeq ($(GCC_GE40801),yes)
...
endif
もっと分かりやすくシンプルに出来るだろうか。
追記@2017.1.17
gccに限らないでバージョン番号比較の方法を検索したところ、
awkを使うともっと短くできるのを見つけた。
http://bashscripts.org/forum/viewtopic.php?f=16&t=1248
GCC_VERSION=$(gcc -dumpversion | awk -F. '{printf "%2d%02d%02d", $1,$2,$3}')
if [ "$GCC_VERSION" -ge 40801 ]; then
...
fi
awkでは、フィールド数より大きいフィールドを指定した時のそのフィールドは空文字になり、それを数値として扱おうとした時は0に変換される、ということをうまく利用している。
(cf. http://gauc.no-ip.org/translation/gawk.html#SEC43
レコード中にフィールドが七個しかないときに $8のように最後の要素を越えて参照しようとしたときには、空の文字列が返ってくる (数値オペレーションで使用した場合にはゼロが得られる)。
)
なお、
http://stackoverflow.com/questions/16989598/bash-comparing-version-numbers
には sort -V
を使う方法も紹介されており、面白い。