ライブラリなんかを引っ張ってきた時に実行させられるmakeコマンド。
makeが何をしているか、fortranコードのLETKFを例に見てみる。
##make
makeとはコンパイルとかその他もろもろをやってくれるコマンド。
makefileに書いてあることにしたがって実行される。
##makefile
目的のファイル: ソースファイル群
生成方法
って書く。
*ただし、生成方法が実行されるのは目的のファイルよりもソースファイルが新しかった場合のみ。
##ソースファイル群をまとめる
FILES= \
dyn_geop.o \
dyn_grtend.o \
dyn_implic.o \
dyn_sptend.o
#ほんとはもっと長いけど、一部抜粋
ソースファイル群はこうやって変数のように設定できる。
\
は行が続く意。改行しても続いてるって扱いになる。
こうすれば、毎回毎回これらのファイルを呼ぶときに全部書かなくて住み、以下のようにかけるようになる。
a.out: $(FILES)
gfortran $(FILES) -o a.out
##生成方法をまとめる
同じ生成方法を何度も書くのがだるいとき、コンパイル前後のファイルの名前を変えないなら、以下のように省略可能。
main.o: main.c #←生成に使用するファイルは指定するが、生成方法は書かない
sub.o: sub.c
%.o: %.c
gcc -O -c $< -o $@
ここで、
%:ファイル名の共通部分(拡張子以外)
$<:ソースファイル名(拡張子含む)
$@:アウトファイル名(拡張子含む)
##拡張子の関係を定義する
古い書き方。
.c``.h``.o``.a
以外の拡張子を使いたい時(fortranの.f
とか)、拡張子の関係を定義する。
fortranの.f
プログラムを機械語に直された.o
実行プログラムの関係を定義してある。
.SUFFIXES: .f .o #2種類の新拡張子を追加
.f.o: #.fから.oを生成する
gfortran $< -o $@
##生成に必要なファイルを指定
main.o: main.c #←生成に使用するファイルは指定するが、生成方法は書かない
sub.o: sub.c
これは、main.cとmain.oとを明示的に関連付ける方法。
main.cが更新された時にちゃんとmain.oが再コンパイルされるように設定する。
##実際のmakefileを見る
LETKF(局所アンサンブルカルマンフィルタ)のプログラムのmakefileを例に見る。
LETKFはhttps://github.com/takemasa-miyoshi/letkf でダウンロード可能。
COMPILE=ifc #ifcをコンパイラとしてセット
COMLIB1=
#COMOTT1= -tpp7 -O3 -r8 #tpp7はlinux用のコマンド
COMOTT1= -O3 -r8
#O3は最適化度合い O3が最高 O0は最適化なし
#r8はrealを倍精度実数として読むオプション
COMCONV= #エンディアンのconvertはなし
#ファイル群を変数として用意
FILES= \
dyn_geop.o \
dyn_grtend.o \
dyn_implic.o \
dyn_sptend.o \
dyn_step.o \
dyn_stloop.o \
ini_impint.o \
ini_indyns.o \
ini_inforc.o \
ini_iniall.o \
ini_inphys.o \
ini_inirdf.o \
ini_invars.o \
ini_stepone.o \
phy_convmf.o \
phy_fordate.o \
phy_lscond.o \
phy_phypar.o \
phy_radiat.o \
phy_shtorh.o \
phy_suflux.o \
phy_vdifsc.o \
ppo_diagns.o \
ppo_restart.o \
ppo_setctl.o \
ppo_setctl_daily.o \
ppo_setgrd.o \
ppo_tminc.o \
ppo_tminc_daily.o \
ppo_tmout.o \
ppo_tmout_daily.o \
sfc_anomod.o \
spe_matinv.o \
spe_spectral.o \
spe_subfft_fftpack.o
#.fは.oに変換すると教える
.SUFFIXES: .f .o
#.fをいかにして.oにするかを教える
.f.o:
$(COMPILE) $(COMOTT1) $(COMCONV) -c $<
#全部ま下に書いてある全ファイルを使ってimp.exeを作る
imp.exe: $(FILES) at_gcm.o
$(COMPILE) $(COMOTT1) $(COMCONV) $(FILES) at_gcm.o -o imp.exe $(COMLIB1)
#ファイル同士をひも付け
at_gcm.o : at_gcm.f
dyn_geop.o : dyn_geop.f
dyn_grtend.o : dyn_grtend.f
dyn_implic.o : dyn_implic.f
dyn_sptend.o : dyn_sptend.f
dyn_step.o : dyn_step.f
dyn_stloop.o : dyn_stloop.f
ini_impint.o : ini_impint.f
ini_indyns.o : ini_indyns.f
ini_inforc.o : ini_inforc.f
ini_iniall.o : ini_iniall.f
ini_inphys.o : ini_inphys.f
ini_inirdf.o : ini_inirdf.f
ini_invars.o : ini_invars.f
ini_stepone.o : ini_stepone.f
phy_convmf.o : phy_convmf.f
phy_lscond.o : phy_lscond.f
phy_fordate.o : phy_fordate.f
phy_phypar.o : phy_phypar.f
phy_radiat.o : phy_radiat.f
phy_shtorh.o : phy_shtorh.f
phy_suflux.o : phy_suflux.f
phy_vdifsc.o : phy_vdifsc.f
ppo_diagns.o : ppo_diagns.f
ppo_restart.o : ppo_restart.f
ppo_setctl.o : ppo_setctl.f
ppo_setctl_daily.o : ppo_setctl_daily.f
ppo_setgrd.o : ppo_setgrd.f
ppo_tminc.o : ppo_tminc.f
ppo_tminc_daily.o : ppo_tminc_daily.f
ppo_tmout.o : ppo_tmout.f
ppo_tmout_daily.o : ppo_tmout_daily.f
sfc_anomod.o : sfc_anomod.f
spe_matinv.o : spe_matinv.f
spe_spectral.o : spe_spectral.f
spe_subfft_fftpack.o : spe_subfft_fftpack.f