LoginSignup
0
1

More than 5 years have passed since last update.

超人的な速さでソース書き換えとmakeを繰り返すと更新がすっぽ抜けて死ぬ(タイムスタンプの精度より早くソースの書き換えとビルドを行うと更新漏れにつながる)

Last updated at Posted at 2018-06-26

概要

  • makeはタイムスタンプを見てファイルの更新管理をしている
    • (依存物のタイムスタンプ) > (生成物のタイムスタンプ)⇒ 更新
  • タイムスタンプの精度は意外と荒い
  • 実行速度がタイムスタンプの精度に勝つと(ソース(更新前)のタイムスタンプ) == (ソース(更新後)のタイムスタンプ)になってしまうことがある
  • そうなると更新の必要性判定がうまく動いてくれず、更新がうまくいかなくなる
  • だからシェルやニンジャパワー1でファイルの書き換えとビルドを行うなら、ファイルの上書きとビルドをする時とかは気を付けよう

問題

Q ①のような状況で ②を実行したとき、 ファイル dst には何が書かれている?
(脳内bashで実行してみよう)

$ ls
Makefile  dst  src

$ cat Makefile
dst:src
    cat src > dst

init:
    > dst
make init 
echo "foo" >src
make dst

A fooが書かれてる

本当に?

筆者が使っているサーバで試したところ、以下のような結果となった

$ make init ;echo "foo" >src;make dst
> dst
cat src > dst
$ make init ;echo "foo" >src;make dst
> dst
make: `dst' は更新済みです

なぜか実行毎にdstが更新されたり更新済みだったりした

何が起こった?

シェルの実行速度がタイムスタンプの精度を上回った結果、
srcが前回から変更されてない→dstも更新する必要なしと判断された

makeはファイルのタイムスタンプを見て更新の不要必要を判断している

つまり、
(srcのタイムスタンプ) > (dstのタイムスタンプ) なら
『srcのほうがdstより新しい→最後にmakeしてからsrcが更新された→再ビルドが必要』となる

問題の例だと
1. make init で dst更新
2. echo "foo" >src でsrc更新
3. make dst(srcのタイムスタンプ) > (dstのタイムスタンプ) なら dst更新

という流れになる

しかし、1と2がタイムスタンプの精度より高速に終わると
`(srcのタイムスタンプ) == (dstのタイムスタンプ) という状況が成立し、
3でdstの更新が行われなくなる

現に3で更新に失敗した際、タイムスタンプは以下のようになっていた
dstとsrcのタイムスタンプが同じである

$ ls --full-time src dst
-rw-rw-r-- 1 fuyutsubaki fuyutsubaki 0 2018-06-26 12:31:16.196755342 +0900 dst
-rw-rw-r-- 1 fuyutsubaki fuyutsubaki 4 2018-06-26 12:31:16.196755342 +0900 src

対策

  • ファイルの上書きが発生する処理を避ける
  • ニンジャパワー2を手に入れてもむやみやたらに使わない

  1. ニンジャは早い 

  2. ニンジャは早い 

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1