Autotoolsを使ってFortranソースコードをコンパイルする

#この記事の内容
autotoolsを使ってfortranソースコードをコンパイルします。
``` ../configure && make && make install ``` 
などとするアレです。autotoolsを使えば、外部ライブラリの場所を自動で探してリンクしたり、自作プログラムソースのライブラリ化(libtoolを使う)といったこともできます。もっと色々と凝った事をしたい場合はマニュアルをご覧ください。
https://www.gnu.org/software/autoconf/

Autotools以外にも、Cmakeオススメです。
 [CMakeによるFortranビルドの省力化](https://qiita.com/ijknabla/items/05270ae5e597705d0dae)
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に記しました。

```config: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の対象とする旨を指定します。

```config:Makefile.am
SUBDIRS=src
```

##src/Makefile.am
プログラムのコンパイルルールを記します。ここは、各自のプログラムの構成について色々と変える必要があります。

```makefile: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
外部サブルーチンやモジュールのサブルーチンを呼び出すプログラムです。

```fortran: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
外部サブルーチン例。ここではルーチン名を表示するのみ。
モジュール化する必要がないものなどを想定。

```fortran:src/subroutines.f90
subroutine sub1()
  print*,"sub1"
end subroutine
subroutine sub2()
  print*,"sub2"
end subroutine
```

##src/module/module_libfort.f90
要素数nの配列に乱数を格納し、その和を返すようにしてみました。

```fortran:src/module/module_libfort.f90
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スクリプトと同じフォルダで、以下を実行。

```bash
mkdir build && cd build
../configure && make
```

以上で、build/srcフォルダに実行可能プログラムtestlibが生成されます。