浮動小数点演算を使ったとき、-lm を付けないとバイナリサイズが巨大化する問題がある。-lm をつけない場合、デフォルトの (libgccの?) 浮動小数点関数がリンクされるけど、avr 用には高効率なものが libm に実装されている。libgcc だと 3k -> libm だと 1k ぐらいのインパクトがあるので必ず libm を使うようにしたい。

とはいえ、ちゃんと理解してないと libm にリンクされない……

結論からいうと以下じゃないとだめだった。

$(COMPILE) -o main.elf $(OBJECTS) -lm

以下のようだとうまくいかない。

$(COMPILE) -lm -o main.elf $(OBJECTS)
$(COMPILE) -o main.elf -lm $(OBJECTS)

というのも、リンカは、引数を順番に読みこんで、読み込み中のファイルに今までで未定義のシンボルがあったとき、それを解決する、という挙動をするらしい (なんとなく逆に、先に定義して解決していくもんだと思ってた)。

なので、先に -lm を指定しても、その時点では未定義のシンボルが何もないので何の意味もない。

gcc のオプションに -v (verbose) を渡すと、最終的に ld (collect2) に渡される引数がわかる。

うまくいく場合は main.o -lm -lgcc -lc -lgcc というふうになってる。main.o で使ってるシンボルが -lm で解決されて、あとまだ足りないのは -lgcc とかで解決される。-lgcc が2回出てくるのは、-lc が -lgcc を使ってるからかな。よくわかんない。

  1. トップ
  2. tech
  3. AVR 浮動小数点 (float) 演算
  1. トップ
  2. avr
  3. AVR 浮動小数点 (float) 演算
  1. トップ
  2. arduino
  3. AVR 浮動小数点 (float) 演算

関連エントリー

▲ この日のエントリ