#この記事の内容
autotoolsを使ってfortranソースコードをコンパイルします。
../configure && make && make install
などとするアレです。autotoolsを使えば、外部ライブラリの場所を自動で探してリンクしたり、自作プログラムソースのライブラリ化(libtoolを使う)といったこともできます。もっと色々と凝った事をしたい場合はマニュアルをご覧ください。
https://www.gnu.org/software/autoconf/
Autotools以外にも、Cmakeオススメです。
CMakeによるFortranビルドの省力化
Cmakeはfortranモジュールの依存関係を自動で認識してくれます。Autotoolsで自動認識させる方法を知っている人がいれば教えてください。。
#ソースコードの構成
ソースコードをsrcディレクトリに保存している場合を想定してみました。
具体的には、以下のようなツリーでソースコードを保存したとします。
トップレベルには、autotoolsに必要なconfigure.acとMakefile.amを作成。
srcフォルダには、サブルーチン集subroutines.f90と、モジュールを収めたフォルダ
moduleがあり、これらをコンパイルするルールを記したMakefile.amを置いています。
- configure.ac
- Makefile.am
- src/
- Makefile.am
- subroutines.f90
- testlib.f90
- module/
- module_libfort.f90
#ソースの内容
自分で用意しなければならないファイルのみを以下に列挙します。
Makefile.amとconfigure.acはAutotoolsに必要なファイルで、f90はフォートランのファイルです。
configure.ac
ここでは自作のfortranソースのみを用いて実行プログラムを作成する場面を想定します。次のような内容をconfigure.acに記しました。
AC_PREREQ([2.69]) #autoconfの最低バージョン指定
AC_INIT([libfort],[0.9.1],[bugrep@ftn.jp])
AC_CONFIG_SRCDIR([src])
#LT_INIT #ライブラリを作るときはこれを有効化(libtoolの初期化)
#AC_CONFIG_MACRO_DIRS([m4]) #autoreconfで指摘されたら追加
AC_PROG_FC([nagfor ifort gfortran]) #fortranコンパイラの指定(空引数でも可)
AC_FC_MODULE_EXTENSION #モジュールファイルの拡張子
AC_FC_MODULE_FLAG #モジュールインクルードのフラグ
AC_FC_MODULE_OUTPUT_FLAG #モジュール出力フォルダを指定するフラグ
#ChangelogやReadmeなどを作らないのでforegin
#サブディレクトリにオブジェクトファイルを作るのでsubdir-objects
AM_INIT_AUTOMAKE([foreign subdir-objects])
#./とsrc/にMakefileを生成する
AC_CONFIG_FILES([Makefile
src/Makefile])
AC_OUTPUT
##Makefile.am
srcサブディレクトリをMakeの対象とする旨を指定します。
SUBDIRS=src
##src/Makefile.am
プログラムのコンパイルルールを記します。ここは、各自のプログラムの構成について色々と変える必要があります。
#configure.acで探したモジュールファイル拡張子を使う
#AC_FC_MODULE_EXTENSIONによって$(FC_MODEXT)が使えるようになる。
CLEANFILES=*.$(FC_MODEXT)
bin_PROGRAMS=testlib #プログラム名を指定
#testlibを作るためのソースコードを指定
testlib_SOURCES = \
subroutines.f90 \
module/module_libfort.f90 \
testlib.f90
##src/testlib.f90
外部サブルーチンやモジュールのサブルーチンを呼び出すプログラムです。
program testlib
use libfort
implicit none
print*,"This is the test program "
call sub1() !外部サブルーチン
call sub2() !外部サブルーチン
call libfort_sub1(3) !モジュールサブルーチン
end program
##src/subroutines.f90
外部サブルーチン例。ここではルーチン名を表示するのみ。
モジュール化する必要がないものなどを想定。
subroutine sub1()
print*,"sub1"
end subroutine
subroutine sub2()
print*,"sub2"
end subroutine
##src/module/module_libfort.f90
要素数nの配列に乱数を格納し、その和を返すようにしてみました。
module libfort
use iso_fortran_env
implicit none
contains
subroutine libfort_sub1(n)
integer :: n
real(kind=real64),dimension(n) :: x
call random_number(x)
print*,sum(x)
end subroutine
end module
#configureスクリプトの生成
configure.acのあるフォルダへ行き、"autoreconf"を実行します。
すると、./install-shが無いなどというメッセージとともに「automake --add-missingとすればinstall-shをインストールできます」と表示されるのでその通りにします。
すると、色々とファイルが追加されるので、念の為もう一度autoreconfを実行。
ここまで来ると、configureスクリプトが生成されているはずです。
#ビルド
configureスクリプトと同じフォルダで、以下を実行。
mkdir build && cd build
../configure && make
以上で、build/srcフォルダに実行可能プログラムtestlibが生成されます。