fpm (Fortran Package Manager)のプロジェクトの作成例

# 概要
本記事では簡単なプロジェクトを作成して，fpmの使用方法やマニフェスト（`fpm.toml`）の作成方法を説明します．

fpmの[使用例](https://qiita.com/implicit_none/items/6a65ac1b83efefc782db)やマニフェスト（`fpm.toml`）の[設定項目](https://qiita.com/implicit_none/items/99c5d12f5c18733c66fd)について説明しました．fpmも徐々に機能が増えているので，それらをどう使うかが判りにくいという意見もあるかと思います．そういった声に応えられれば幸いです．

# 環境
- Windows 10
- fpm 0.5.0
- gfortran 10.3.0 (TDM-GCC-64)

Windowsで実行し，動作確認をしています．パスの区切りは`\`になっています．Unix系OSで動かす場合には，ドライブレターを無視し，パスの区切りを`/`に置き換えてください．

# プロジェクトの作成
## プロジェクト概要
`NaN`や`Inf`など，浮動小数点には数値ではない値があります．それらを取り扱うライブラリ`non_number`を作成します．なお，本記事の目的はfpmの使い方などを説明することですので，その目的からずれないように，ライブラリは作り込みません．単精度および倍精度の浮動小数点数を受け取って，それらの値が`NaN`であるか否かを判別する関数`is_nan`のみを作成します．同じ機能を持った関数`ieee_is_nan`がFortran標準で用意されています[^isnan]．`ieee_`が冗長なので，短い名前で呼べるようにしたということです．

[^isnan]: コンパイラによっては`isNan`が方言として提供されています．

実装は簡単で，関数内で`ieee_is_nan`を呼んでその結果を返しているだけです．異なる型に対応するために，`interface`を利用しています．

```Fortran
    interface is_nan
        module procedure :: is_nan_real32
        module procedure :: is_nan_real64
    end interface

contains

    logical function is_nan_real32(x)
        implicit none
        real(real32), intent(in) :: x

        is_nan_real32 = ieee_is_nan(x)
    end function is_nan_real32

    logical function is_nan_real64(x)
        implicit none
        real(real64), intent(in) :: x

        is_nan_real64 = ieee_is_nan(x)
    end function is_nan_real64
```

## fpmプロジェクトの作成
`fpm new`を実行してプロジェクトを作成します．ライブラリを作成するので`--lib`オプションを付けて実行します．

```console
D:\project> fpm new non_number --lib
 + mkdir non_number
 + cd non_number
 + mkdir non_number\src
 + git init non_number
Initialized empty Git repository in D:/project/non_number/.git/
fpm: Leaving directory 'D:'

D:\project> cd non_number

D:\project\non_number>
```

`non_number`ディレクトリ以下は下記のようになっています．`--lib`オプション（もしくは`--src`）を付けているので，ライブラリとしてビルドされるソースを配置する`src`ディレクトリのみが作成されています．

```
.
├── README.md
├── fpm.toml
└── src
    └── non_number.f90
```

## プロジェクトのビルド
### ソースの編集
`non_number.f90`を，先述の通り編集します．

```Fortran:src\non_number.f90
module non_number
    use, intrinsic :: iso_fortran_env
    use, intrinsic :: ieee_arithmetic
    implicit none
    private
    public :: is_nan

    interface is_nan
        module procedure :: is_nan_real32
        module procedure :: is_nan_real64
    end interface
contains
    logical function is_nan_real32(x)
        implicit none
        real(real32), intent(in) :: x

        is_nan_real32 = ieee_is_nan(x)
    end function is_nan_real32

    logical function is_nan_real64(x)
        implicit none
        real(real64), intent(in) :: x

        is_nan_real64 = ieee_is_nan(x)
    end function is_nan_real64
end module non_number
```

また，プロジェクトルートに作成されたマニフェストファイル`fpm.toml`も編集します．`license`, `author`, `copyright`を書き換えました．

```toml:fpm.toml
name = "non_number"
version = "0.1.0"
license = "MIT"
author = "Implicit None"
copyright = "Copyright 2021, Implicit None"

[build]
auto-executables = true
auto-tests = true
auto-examples = true

[install]
library = false
```

### ビルド
`fpm build`を実行してビルドします．

```console
D:\project\non_number>fpm build
 + mkdir build\dependencies
 + mkdir build\gfortran_2A42023B310FA28D
 + mkdir build\gfortran_2A42023B310FA28D\non_number\
 + gfortran -c .\.\src\non_number.f90  -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single -J build\gfortran_2A42023B310FA28D -Ibuild\gfortran_2A42023B310FA28D -o build\gfortran_2A42023B310FA28D\non_number\src_non_number.f90.o
 + ar -rs build\gfortran_2A42023B310FA28D\non_number\libnon_number.a @build\gfortran_2A42023B310FA28D\non_number\libnon_number.a.resp
ar: creating build\gfortran_2A42023B310FA28D\non_number\libnon_number.a
```

出力を見ると，`non_number.f90`のビルドに成功して`libnon_number.a`が作成されていることが確認できました．

## プロジェクトのテスト
### テストの作成
さて，ライブラリが作成できたとして，それをリンクしてアプリケーションを作り，それを実行してみるまで実行内容が正しいか判らないという状況はよろしくありません．プロジェクト内でテストを行い，正しさを保証しておく必要があります．

既存のfpmプロジェクトにテストを追加するには，`--backfill`オプション付きで`fpm new`を実行します．

```console
D:\project\non_number> cd ..

D:\project> fpm new non_number --test --backfill
backfilling non_number
 + cd non_number
<INFO>   non_number\README.md already exists. Not overwriting
 + mkdir non_number\test
<INFO>   non_number\fpm.toml already exists. Not overwriting
 + git init non_number
Reinitialized existing Git repository in D:/project/non_number/.git/
fpm: Leaving directory 'D:'
```

`test`ディレクトリが追加されました．

```
.
├── README.md
├── build\
├── fpm.toml
├── src
│   └── non_number.f90
└── test
    └── check.f90
```

テストを単一のファイルに書くというルールはないので，既定のファイル`check.f90`を削除して，単精度実数用の`is_nan`に対するテスト`test_is_nan_real32.f90`と倍精度実数用の`is_nan`に対するテスト`test_is_nan_real64.f90`を追加します．

```
.
├── README.md
├── build\
├── fpm.toml
├── src
│   └── non_number.f90
└── test
    ├── test_is_nan_real32.f90
    └── test_is_nan_real64.f90
```

テストの中でやっていることは簡単です．

`test_is_nan_real32.f90`の中では，二つのサブルーチン`returns_true_for_fp32_number_that_is_nan`, `returns_false_for_fp32_number_that_is_not_nan`を実行しています．

`returns_true_for_fp32_number_that_is_nan`の中では，`ieee_value(0., ieee_quiet_nan)`で発生させた`NaN`を`is_nan`に渡し，その戻り値が`.true.`かを判定し，真であれば成功，偽であれば`error stop`で実行を停止し手います．

```Fortran
retval = is_nan(ieee_value(0., ieee_quiet_nan))
if (retval .eqv. .true.) then
    print '(A)', TAB//"True"
else
    print '(A)', TAB//"False"
    error stop
end if
```

`returns_false_for_fp32_number_that_is_not_nan`の中では，少し複雑な処理をしています．`is_nan`は`NaN`以外を渡した時に`.false.`を返すことを想定していますが，一つの値だけでテストを行って`.false.`が返ってきたとしても，その値以外`.true.`が返ってくることを否定できません．一方で，全ての値でテストを行うことは現実的ではありません．広範囲の値をテストするために，[0,1]の乱数に単精度実数の最大値をかけて大きな値を出し，その値を`-2`で除していくことにより，正負の幅広い範囲の値をテストできるようにしました．

また，戻り値は，一つでも`.true.`が返るとテストが失敗するように，前の値の戻り値と`.or.`を取るようにしています．本来は，`retval`を論理型の配列として，`all(retval .eqv. .false.)`で判定する方が好ましいのですが．

```Fortran
integer(int32) :: i
real(real32) :: x

retval = .false.

call random_number(x)
x = x*huge(x)
do i = 1, 200
    retval = is_nan(x) .or. retval
    x = -x/2.
end do
```

<details><summary>test_is_nan_real32.f90</summary><div>

```Fortran:test\test_is_nan_real32.f90
program test_is_nan_real32
    use, intrinsic :: iso_fortran_env
    use, intrinsic :: ieee_arithmetic
    use :: non_number
    implicit none

    character, parameter :: TAB = achar(int(z'09'))

    call returns_true_for_fp32_number_that_is_nan()
    call returns_false_for_fp32_number_that_is_not_nan()
contains
    subroutine returns_true_for_fp32_number_that_is_nan()
        implicit none
        logical :: retval

        print '(A)', "is_nan returns true for fp32 number that is nan"

        retval = is_nan(ieee_value(0., ieee_quiet_nan))
        if (retval .eqv. .true.) then
            print '(A)', TAB//"True"
        else
            print '(A)', TAB//"False"
            error stop
        end if
    end subroutine returns_true_for_fp32_number_that_is_nan

    subroutine returns_false_for_fp32_number_that_is_not_nan()
        implicit none
        logical :: retval

        print '(A)', "is_nan returns false for fp32 number that is not nan"

        block
            integer(int32) :: i
            real(real32) :: x

            retval = .false.

            call random_number(x)
            x = x*huge(x)
            do i = 1, 200
                retval = is_nan(x) .or. retval
                x = -x/2.
            end do
        end block

        if (retval .eqv. .false.) then
            print '(A)', TAB//"True"
        else
            print '(A)', TAB//"False"
            error stop
        end if
    end subroutine returns_false_for_fp32_number_that_is_not_nan
end program test_is_nan_real32
```

</div></details>

<details><summary>test_is_nan_real64.f90</summary><div>

```Fortran:test\test_is_nan_real64.f90
program test_is_nan_real64
    use, intrinsic :: iso_fortran_env
    use, intrinsic :: ieee_arithmetic
    use :: non_number
    implicit none

    character, parameter :: TAB = achar(int(z'09'))

    call returns_true_for_fp64_number_that_is_nan
    call returns_false_for_fp64_number_that_is_not_nan()
contains
    subroutine returns_true_for_fp64_number_that_is_nan()
        implicit none
        logical :: retval

        print '(A)', "is_nan returns true for fp64 number that is nan"

        retval = is_nan(ieee_value(0d0, ieee_quiet_nan))
        if (retval .eqv. .true.) then
            print '(A)', TAB//"True"
        else
            print '(A)', TAB//"False"
            error stop
        end if
    end subroutine returns_true_for_fp64_number_that_is_nan

    subroutine returns_false_for_fp64_number_that_is_not_nan()
        implicit none
        logical :: retval

        print '(A)', "is_nan returns false for fp64 number that is not nan"

        block
            integer(int32) :: i
            real(real64) :: x

            retval = .false.

            call random_number(x)
            x = x*huge(x)
            do i = 1, 500
                retval = is_nan(x) .or. retval
                x = -x/20d0
            end do
        end block

        if (retval .eqv. .false.) then
            print '(A)', TAB//"True"
        else
            print '(A)', TAB//"False"
            error stop
        end if
    end subroutine returns_false_for_fp64_number_that_is_not_nan
end program test_is_nan_real64
```

</div></details>

### テストの実行
`fpm build`を実行してもテストはビルドされません．テストのビルドは，`fpm test`でテストを実行する際に行われます．

テストのビルドと実行を分けたい場合には，`fpm test --list`を利用します．`fpm test --list`は，プロジェクトに用意されたテストの一覧を確認するコマンドですが，テストの一覧を作成するためにビルドされるという挙動を利用して，ビルドと実行を分けています．

`fpm test --list`を実行すると，テストがビルドされた後，2個のテスト`test_is_nan_real32`, `test_is_nan_real64`が表示されます．

```
D:\project\non_number> fpm test --list
 + gfortran -c test\test_is_nan_real32.f90  -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single -J build\gfortran_2A42023B310FA28D -Ibuild\gfortran_2A42023B310FA28D -o build\gfortran_2A42023B310FA28D\non_number\test_test_is_nan_real32.f90.o
 + gfortran -c test\test_is_nan_real64.f90  -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single -J build\gfortran_2A42023B310FA28D -Ibuild\gfortran_2A42023B310FA28D -o build\gfortran_2A42023B310FA28D\non_number\test_test_is_nan_real64.f90.o
 + mkdir build\gfortran_2A42023B310FA28D\test\
 + gfortran  -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single  build\gfortran_2A42023B310FA28D\non_number\test_test_is_nan_real32.f90.o build\gfortran_2A42023B310FA28D\non_number\libnon_number.a -o build\gfortran_2A42023B310FA28D\test\test_is_nan_real32.exe
 + gfortran  -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single  build\gfortran_2A42023B310FA28D\non_number\test_test_is_nan_real64.f90.o build\gfortran_2A42023B310FA28D\non_number\libnon_number.a -o build\gfortran_2A42023B310FA28D\test\test_is_nan_real64.exe
 Matched names:
test_is_nan_real32      test_is_nan_real64
```

テストのビルドが完了したら，`fpm test`でテストを実行します．

```console
D:\project\non_number> fpm test
is_nan returns true for fp32 number that is nan
        True
is_nan returns false for fp32 number that is not nan
        True
is_nan returns true for fp64 number that is nan
        True
is_nan returns false for fp64 number that is not nan
        True
```

テストを選択して実行するには，`--target`を利用します．

```console
:\project\non_number> fpm test --target test_is_nan_real32
is_nan returns true for fp32 number that is nan
        True
is_nan returns false for fp32 number that is not nan
        True

D:\project\non_number> fpm test --target test_is_nan_real64
is_nan returns true for fp64 number that is nan
        True
is_nan returns false for fp64 number that is not nan
        True
```

## ローカルに作成したfpmプロジェクトの参照
ライブラリ`non_number`を作成し，テストを実行して実装の正しさを確認しました．テストの中で戻り値の判定を計4回書いていました．これは良い実装ではないので，戻り値の判定をテストの外に切り出すことにします．

### checkプロジェクト
切り出した際に`non_number`と連携しやすくするために，別のfpmプロジェクトとして，`non_number`プロジェクトのローカルに構築します．

fpmの新規プロジェクトの作成は挙動がよく判らないところがあります．例えば，プロジェクトの下に新しいプロジェクトを作成しようとすると，必ずプロジェクトルートに作られます．

下記の実行例では，`non_number`ディレクトリに下に`util`ディレクトリを作成し，その中にfpmプロジェクト`check`を作成しようとしました．しかし，`check`は`non_number`ディレクトリ直下に作られてしまいました．

```console
D:\project\non_number> mkdir util

D:\project\non_number> cd util

D:\project\non_number\util> fpm new check --lib
fpm: Entering directory 'D:\project\non_number'
 + mkdir check
 + cd check
 + mkdir check\src
 + git init check
Initialized empty Git repository in D:/project/non_number/check/.git/
fpm: Leaving directory 'D:\project\non_number'
```

既存プロジェクトの下にサブディレクトリを切ってプロジェクトを作成するには，プロジェクト名にサブディレクトリ名を含めて新規作成を行います．このとき，パスの区切りは`/`です．

```console
D:\project\non_number>fpm new util/check --lib
 + mkdir util\check
 + cd util/check
 + mkdir util\check\src
 + git init util/check
Initialized empty Git repository in D:/project/non_number/util/check/.git/
```

```
.
├── README.md
├── build\
├── fpm.toml
├── src
│   └── non_number.f90
├── test
│   ├── test_is_nan_real32.f90
│   └── test_is_nan_real64.f90
└── util
    └── check
        ├── README.md
        ├── fpm.toml
        └── src
            └── check.f90
```

```Fortran:util\check\src\check.f90
module util_check
    implicit none
    private
    public :: check

    character, public, parameter :: TAB = achar(int(z'09'))

contains
    subroutine check(condition)
        implicit none
        logical, intent(in) :: condition

        if (condition) then
            print '(A)', TAB//"True"
        else
            print '(A)', TAB//"False"
            error stop
        end if
    end subroutine check
end module util_check
```

```toml:util\check\fpm.toml
name = "check"
version = "0.1.0"
license = "MIT"
author = "Implicit None"
copyright = "Copyright 2021, Implicit None"

[build]
auto-executables = true
auto-tests = true
auto-examples = true

[install]
library = false
```

テストも修正します．モジュールを`use`し，重複している定数を削除し，結果の判定をしている箇所をサブルーチン呼出しに置き換えます．

<details><summary>test_is_nan_real32.f90</summary><div>

```Fortran:test\test_is_nan_real32.f90
program test_is_nan_real32
    use, intrinsic :: iso_fortran_env
    use, intrinsic :: ieee_arithmetic
    use :: non_number
    use :: util_check
    implicit none

    call returns_true_for_fp32_number_that_is_nan()
    call returns_false_for_fp32_number_that_is_not_nan()
contains
    subroutine returns_true_for_fp32_number_that_is_nan()
        implicit none
        logical :: retval

        print '(A)', "is_nan returns true for fp32 number that is nan"

        retval = is_nan(ieee_value(0., ieee_quiet_nan))

        call check(retval .eqv. .true.)
    end subroutine returns_true_for_fp32_number_that_is_nan

    subroutine returns_false_for_fp32_number_that_is_not_nan()
        implicit none
        logical :: retval

        print '(A)', "is_nan returns false for fp32 number that is not nan"

        block
            integer(int32) :: i
            real(real32) :: x

            retval = .false.

            call random_number(x)
            x = x*huge(x)
            do i = 1, 200
                retval = is_nan(x) .or. retval
                x = -x/2.
            end do
        end block

        call check(retval .eqv. .false.)
    end subroutine returns_false_for_fp32_number_that_is_not_nan
end program test_is_nan_real32
```

</div></details>

<details><summary>test_is_nan_real64.f90</summary><div>

```Fortran:test\test_is_nan_real64.f90
program test_is_nan_real64
    use, intrinsic :: iso_fortran_env
    use, intrinsic :: ieee_arithmetic
    use :: non_number
    use :: util_check
    implicit none

    call returns_true_for_fp64_number_that_is_nan
    call returns_false_for_fp64_number_that_is_not_nan()
contains
    subroutine returns_true_for_fp64_number_that_is_nan()
        implicit none
        logical :: retval

        print '(A)', "is_nan returns true for fp64 number that is nan"

        retval = is_nan(ieee_value(0d0, ieee_quiet_nan))
        call check(retval .eqv. .true.)
    end subroutine returns_true_for_fp64_number_that_is_nan

    subroutine returns_false_for_fp64_number_that_is_not_nan()
        implicit none
        logical :: retval

        print '(A)', "is_nan returns false for fp64 number that is not nan"

        block
            integer(int32) :: i
            real(real64) :: x

            retval = .false.

            call random_number(x)
            x = x*huge(x)
            do i = 1, 500
                retval = is_nan(x) .or. retval
                x = -x/20d0
            end do
        end block

        call check(retval .eqv. .false.)
    end subroutine returns_false_for_fp64_number_that_is_not_nan
end program test_is_nan_real64
```

</div></details>


### ローカルプロジェクトの参照
ローカルにおかれたfpmプロジェクトを参照するには，プロジェクトのマニフェスト`fpm.toml`に`[dependencies]`の項目を設け，そこにプロジェクト名と場所を記述します．

```toml:fpm.toml
name = "non_number"
version = "0.1.0"
license = "MIT"
author = "Implicit None"
copyright = "Copyright 2021, Implicit None"

[build]
auto-executables = true
auto-tests = true
auto-examples = true
external-modules = ["stdlib_stats"]

[install]
library = false

[dependencies]
check = {path = "util/check"}
```

もう一度ビルドして実行したところ，正しく動作しているようです．本来は`check`プロジェクトでもテストをしなければなりませんが，都合により省略します．

```console
D:\project\non_number> fpm test --list
 + mkdir build\gfortran_2A42023B310FA28D\test\
 + gfortran  -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single  build\gfortran_2A42023B310FA28D\non_number\test_test_is_nan_real32.f90.o build\gfortran_2A42023B310FA28D\non_number\libnon_number.a -o build\gfortran_2A42023B310FA28D\test\test_is_nan_real32.exe
 + gfortran -c test\test_is_nan_real64.f90  -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single -J build\gfortran_2A42023B310FA28D -Ibuild\gfortran_2A42023B310FA28D -o build\gfortran_2A42023B310FA28D\non_number\test_test_is_nan_real64.f90.o
 + gfortran  -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single  build\gfortran_2A42023B310FA28D\non_number\test_test_is_nan_real64.f90.o build\gfortran_2A42023B310FA28D\non_number\libnon_number.a -o build\gfortran_2A42023B310FA28D\test\test_is_nan_real64.exe
 Matched names:
test_is_nan_real32      test_is_nan_real64

D:\project\non_number> fpm test
is_nan returns true for fp32 number that is nan
        True
is_nan returns false for fp32 number that is not nan
        True
is_nan returns true for fp64 number that is nan
        True
is_nan returns false for fp64 number that is not nan
        True
```

### 依存関係の正確な記述
上で作成した`util_check`モジュールは，`non_number`モジュール内では参照せず，テストでのみ参照していました．

テストのみが必要とするfpmプロジェクトを参照する設定として，`[test.dependencies]`が用意されています．

`fpm.toml`の`[dependencies]`を削除し，`[test.dependencies]`の設定を記述してみます．

```toml:fpm.toml
name = "non_number"
version = "0.1.0"
license = "MIT"
author = "Implicit None"
copyright = "Copyright 2021, Implicit None"

[build]
auto-executables = true
auto-tests = true
auto-examples = true

[install]
library = false

[test.dependencies]
check = {path = "util/check"}
```

しかし，この設定でビルドし直しても，`util_check`モジュールが参照できないというエラーが出て，ビルドできません．

```console
D:\project\non_number> rmdir /S build
build、よろしいですか (Y/N)? Y

D:\project\non_number> fpm build
 + mkdir build\dependencies
 + mkdir build\gfortran_2A42023B310FA28D
 + mkdir build\gfortran_2A42023B310FA28D\non_number\
 + gfortran -c .\.\src\non_number.f90  -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single -J build\gfortran_2A42023B310FA28D -Ibuild\gfortran_2A42023B310FA28D -o build\gfortran_2A42023B310FA28D\non_number\src_non_number.f90.o
 + ar -rs build\gfortran_2A42023B310FA28D\non_number\libnon_number.a @build\gfortran_2A42023B310FA28D\non_number\libnon_number.a.resp
ar: creating build\gfortran_2A42023B310FA28D\non_number\libnon_number.a

D:\project\non_number> fpm test --list
<ERROR>*cmd_run*:targets error:Unable to find source for module dependency: "util_check" used by "test\test_is_nan_real32.f90"
STOP 1
```

設定ファイルの書き方の記事でも言及しましたが，テストのみが必要とするプロジェクトを記述するには，少なくとも一つはテスト設定を書く必要があります．

```toml:fpm.toml
name = "non_number"
version = "0.1.0"
license = "MIT"
author = "Implicit None"
copyright = "Copyright 2021, Implicit None"

[build]
auto-executables = true
auto-tests = true
auto-examples = true

[install]
library = false

[[test]]
name = "test_is_nan_real32"
source-dir = "test"
main = "test_is_nan_real32.f90"

[test.dependencies]
check = {path = "util/check"}
```

ここでは，単精度実数用の`is_nan`に対するテストのみを指定していますが，この設定があれば倍精度実数用の`is_nan`もビルドされるようになります．これはTOMLの書式の都合でしょうが，改善してほしいところです．

```console
D:\project\non_number> fpm test --list
 + gfortran -c .\util/check\src\check.f90  -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single -J build\gfortran_2A42023B310FA28D -Ibuild\gfortran_2A42023B310FA28D -o build\gfortran_2A42023B310FA28D\non_number\util_check_src_check.f90.o
 + ar -rs build\gfortran_2A42023B310FA28D\non_number\libnon_number.a @build\gfortran_2A42023B310FA28D\non_number\libnon_number.a.resp
 + gfortran -c test\test_is_nan_real32.f90  -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single -J build\gfortran_2A42023B310FA28D -Ibuild\gfortran_2A42023B310FA28D -o build\gfortran_2A42023B310FA28D\non_number\test_test_is_nan_real32.f90.o
 + gfortran -c test\test_is_nan_real64.f90  -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single -J build\gfortran_2A42023B310FA28D -Ibuild\gfortran_2A42023B310FA28D -o build\gfortran_2A42023B310FA28D\non_number\test_test_is_nan_real64.f90.o
 + mkdir build\gfortran_2A42023B310FA28D\test\
 + gfortran  -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single  build\gfortran_2A42023B310FA28D\non_number\test_test_is_nan_real32.f90.o build\gfortran_2A42023B310FA28D\non_number\libnon_number.a -o build\gfortran_2A42023B310FA28D\test\test_is_nan_real32.exe
 + gfortran  -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single  build\gfortran_2A42023B310FA28D\non_number\test_test_is_nan_real64.f90.o build\gfortran_2A42023B310FA28D\non_number\libnon_number.a -o build\gfortran_2A42023B310FA28D\test\test_is_nan_real64.exe
 Matched names:
test_is_nan_real32      test_is_nan_real64

D:\project\non_number> fpm test
is_nan returns true for fp32 number that is nan
        True
is_nan returns false for fp32 number that is not nan
        True
is_nan returns true for fp64 number that is nan
        True
is_nan returns false for fp64 number that is not nan
        True
```

## プロジェクトのデモ
### デモの作成
ライブラリの作成方法を示すデモを作成しておくと，ライブラリを利用するユーザの助けになります．

既存のfpmプロジェクトにデモを追加するには，テストを追加したの同様に，`--backfill`オプション付きで`fpm new`を実行します．

```console
D:\project\non_number> cd ..

D:\project> fpm new non_number --example --backfill
backfilling non_number
 + cd non_number
<INFO>   non_number\README.md already exists. Not overwriting
 + mkdir non_number\example
<INFO>   non_number\fpm.toml already exists. Not overwriting
 + git init non_number
Reinitialized existing Git repository in D:/project/non_number/.git/
fpm: Leaving directory 'D:'
```

`example`ディレクトリが追加されました．

```
.
├── README.md
├── build\
├── example
│   └── demo.f90
├── fpm.toml
├── src\
├── test\
└── util
    └── check\
```

デモの作成については，テストと同じです．単一のファイルに書くというルールはありません．今後，複数のデモを追加することを想定して，既定のファイル名`demo.f90`ではなく`demo_is_nan.f90`を用いる事にします．

```
.
├── README.md
├── build\
├── example
│   └── demo_is_nan.f90
├── fpm.toml
├── src\
├── test\
└── util
    └── check\
```

デモとして，配列の平均値`mean`に長さ0の配列を渡した際に発生する`NaN`を捕まえる処理を実装しました．

<details><summary>demo_is_nan.f90</summary><div>

```Fortran:example\demo_is_nan.f90
program demo_is_nan
    use, intrinsic :: iso_fortran_env
    use :: non_number
    use :: util_check
    implicit none

    character(*), parameter :: fmt = '(A,*(g0:,","))'

    real(real32), allocatable :: x(:)
    real(real32) :: x_mean

    block
        integer(int32) :: i
        x = [(i, i=1, 10)]
        x_mean = mean(x)

        print fmt, "vals = ", x
        print fmt, "mean = ", x_mean
    end block

    block
        x = [real(real32) ::]
        x_mean = mean(x)

        if (.not. is_nan(x_mean)) then
            print *, TAB//"value error: x_mean is nan"
        end if
    end block

contains
    real(real32) function mean(x)
        implicit none
        real(real32), intent(in) :: x(:)

        mean = sum(x)/size(x)
    end function mean
end program demo_is_nan
```

</div></details>

### デモの実行
デモはテストとは異なり，`fpm build`でビルドされます．

```console
D:\project\non_number> fpm build
 + gfortran -c example\demo_is_nan.f90  -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single -J build\gfortran_2A42023B310FA28D -Ibuild\gfortran_2A42023B310FA28D -o build\gfortran_2A42023B310FA28D\non_number\example_demo_is_nan.f90.o
 + mkdir build\gfortran_2A42023B310FA28D\example\
 + gfortran  -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single  build\gfortran_2A42023B310FA28D\non_number\example_demo_is_nan.f90.o build\gfortran_2A42023B310FA28D\non_number\libnon_number.a -o build\gfortran_2A42023B310FA28D\example\demo_is_nan.exe
```

実行は，`--example`オプション付きで`fpm run`を実行します．

```console
D:\project\non_number> fpm run --example
vals = 1.00000000,2.00000000,3.00000000,4.00000000,5.00000000,6.00000000,7.00000000,8.00000000,9.00000000,10.0000000
mean = 5.50000000
 value error: x_mean is nan
```

デモの一覧を確認するには，`fpm run --example --list`を実行します．デモを選択して実行するには，`--target`を利用します．

```console
D:\project\non_number> fpm run --example --list
 Matched names:
demo_is_nan
```

## オンラインのfpmプロジェクトの参照

関数`mean`はFortranの標準ライブラリstdlibに実装されているので，わざわざ作る必要はありません．stdlibはgithubにリポジトリが存在するので，それを参照します．参照するには，プロジェクトのマニフェスト`fpm.toml`に`[dependencies]`の項目を設け，そこにプロジェクト名と場所を記述します．

```toml:fpm.toml
name = "non_number"
version = "0.1.0"
license = "MIT"
author = "Implicit None"
copyright = "Copyright 2021, Implicit None"

[build]
auto-executables = true
auto-tests = true
auto-examples = true

[install]
library = false

[dependencies]
stdlib = { git="https://github.com/fortran-lang/stdlib", branch="stdlib-fpm" }

[[test]]
name = "test_is_nan_real32"
source-dir = "test"
main = "test_is_nan_real32.f90"

[test.dependencies]
check = {path = "util/check"}
```

`demo_is_nan.f90`に`use :: stdlib_stats`を追記し，ソース内の`mean`の定義を削除します．

`fpm build`を実行すると，githubからstdlibが取得され，同時にビルド・リンクが行われます．

```console
D:\project\non_number>fpm build
Initialized empty Git repository in D:/project/non_number/build/dependencies/stdlib/.git/
remote: Enumerating objects: 91, done.
remote: Counting objects: 100% (91/91), done.
remote: Compressing objects: 100% (83/83), done.
remote: Total 91 (delta 21), reused 43 (delta 7), pack-reused 0
Unpacking objects: 100% (91/91), 202.57 KiB | 1.07 MiB/s, done.
From https://github.com/fortran-lang/stdlib
 * branch            stdlib-fpm -> FETCH_HEAD
:（中略）
 + gfortran  -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single  build\gfortran_2A42023B310FA28D\non_number\example_demo_is_nan.f90.o build\gfortran_2A42023B310FA28D\non_number\libnon_number.a -o build\gfortran_2A42023B310FA28D\example\demo_is_nan.exe

D:\project\non_number> fpm run --example --target demo_is_nan
vals = 1.00000000,2.00000000,3.00000000,4.00000000,5.00000000,6.00000000,7.00000000,8.00000000,9.00000000,10.0000000
mean = 5.50000000
 value error: x_mean is nan
```

### 依存関係の正確な記述
stdlibは，`non_number`モジュール内でもテストでも参照せず，`example`でのみ参照していました．

デモのみが必要とするfpmプロジェクトを参照する設定として，`[example.dependencies]`が用意されています．`[dependencies]`の代わりに`[example.dependencies]`を記述するのですが，これもテストと同じで，デモのみが必要とするプロジェクトを記述するには，少なくとも一つはデモ設定を書く必要があります．

```toml:fpm.toml
name = "non_number"
version = "0.1.0"
license = "MIT"
author = "Implicit None"
copyright = "Copyright 2021, Implicit None"

[build]
auto-executables = true
auto-tests = true
auto-examples = true

[install]
library = false

[example.dependencies]
stdlib = { git="https://github.com/fortran-lang/stdlib", branch="stdlib-fpm" }

[[test]]
name = "test_is_nan_real32"
source-dir = "test"
main = "test_is_nan_real32.f90"

[test.dependencies]
check = {path = "util/check"}
```

```console
D:\project\non_number> rmdir /S build
build、よろしいですか (Y/N)? Y

D:\project\non_number> fpm build
 + mkdir build\dependencies
<ERROR>*cmd_build*:target error:Unable to find source for module dependency: "stdlib_stats" used by "example\demo_is_nan.f90"
STOP 1
```

デモの設定を追記してビルドすると，ビルドに成功します．

```toml:fpm.toml
name = "non_number"
version = "0.1.0"
license = "MIT"
author = "Implicit None"
copyright = "Copyright 2021, Implicit None"

[build]
auto-executables = true
auto-tests = true
auto-examples = true

[install]
library = false

[[example]]
name = "demo_is_nan"
source-dir = "example"
main = "demo_is_nan.f90"

[example.dependencies]
stdlib = { git="https://github.com/fortran-lang/stdlib", branch="stdlib-fpm" }

[[test]]
name = "test_is_nan_real32"
source-dir = "test"
main = "test_is_nan_real32.f90"

[test.dependencies]
check = {path = "util/check"}
```

```console
D:\project\non_number> fpm build
 + mkdir build\dependencies
Initialized empty Git repository in D:/project/non_number/build/dependencies/stdlib/.git/
remote: Enumerating objects: 91, done.
remote: Counting objects: 100% (91/91), done.
remote: Compressing objects: 100% (83/83), done.
remote: Total 91 (delta 21), reused 43 (delta 7), pack-reused 0
Unpacking objects: 100% (91/91), 202.57 KiB | 1.12 MiB/s, done.
From https://github.com/fortran-lang/stdlib
 * branch            stdlib-fpm -> FETCH_HEAD
:（中略）
 + gfortran  -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single  build\gfortran_2A42023B310FA28D\non_number\example_demo_is_nan.f90.o build\gfortran_2A42023B310FA28D\non_number\libnon_number.a -o build\gfortran_2A42023B310FA28D\example\demo_is_nan.exe

D:\project\non_number> fpm run --example --target demo_is_nan
vals = 1.00000000,2.00000000,3.00000000,4.00000000,5.00000000,6.00000000,7.00000000,8.00000000,9.00000000,10.0000000
mean = 5.50000000
 value error: x_mean is nan
```

## インストール済みライブラリの参照
先ほどは，githubにあるstdlibを参照しましたが，既にインストールしている場合もあります．

その場合は，`[build]`の項目で`link`および`external-modules`を設定します．

```toml:fpm.toml
name = "non_number"
version = "0.1.0"
license = "MIT"
author = "Implicit None"
copyright = "Copyright 2021, Implicit None"

[build]
auto-executables = true
auto-tests = true
auto-examples = true
external-modules = ["stdlib_stats"]
link = "stdlib"

[install]
library = false

[[test]]
name = "test_is_nan_real32"
source-dir = "test"
main = "test_is_nan_real32.f90"

[test.dependencies]
check = {path = "util/check"}
```

ライブラリおよびモジュール（`.mod`）の置き場所にパスが通っている場合は，ビルドの際にオプションを追加する必要はありません．

```console
D:\project\non_number> rmdir /S build
build、よろしいですか (Y/N)? Y

D:\project\non_number> fpm build
 + mkdir build\dependencies
 + mkdir build\gfortran_2A42023B310FA28D
 + mkdir build\gfortran_2A42023B310FA28D\non_number\
 + gfortran -c .\.\src\non_number.f90  -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single -J build\gfortran_2A42023B310FA28D -Ibuild\gfortran_2A42023B310FA28D -o build\gfortran_2A42023B310FA28D\non_number\src_non_number.f90.o
 + gfortran -c .\util/check\src\check.f90  -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single -J build\gfortran_2A42023B310FA28D -Ibuild\gfortran_2A42023B310FA28D -o build\gfortran_2A42023B310FA28D\non_number\util_check_src_check.f90.o
 + ar -rs build\gfortran_2A42023B310FA28D\non_number\libnon_number.a @build\gfortran_2A42023B310FA28D\non_number\libnon_number.a.resp
ar: creating build\gfortran_2A42023B310FA28D\non_number\libnon_number.a
 + gfortran -c example\demo_is_nan.f90  -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single -J build\gfortran_2A42023B310FA28D -Ibuild\gfortran_2A42023B310FA28D -o build\gfortran_2A42023B310FA28D\non_number\example_demo_is_nan.f90.o
 + mkdir build\gfortran_2A42023B310FA28D\example\
 + gfortran  -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single  build\gfortran_2A42023B310FA28D\non_number\example_demo_is_nan.f90.o build\gfortran_2A42023B310FA28D\non_number\libnon_number.a -lstdlib -o build\gfortran_2A42023B310FA28D\example\demo_is_nan.exe

D:\project\non_number> fpm run --example --target demo_is_nan
vals = 1.00000000,2.00000000,3.00000000,4.00000000,5.00000000,6.00000000,7.00000000,8.00000000,9.00000000,10.0000000
mean = 5.50000000
 value error: x_mean is nan
```

### 正確な依存関係の記述
インストールされたstdlibをリンクしましたが，ログを見ると，`non_number`の静的ライブラリにstdlibがリンクされています．

```console
build\gfortran_2A42023B310FA28D\non_number\libnon_number.a -lstdlib -o
```

しかし，`non_number`はstdlibを必要としておらず，リンクが必要なのは，デモ（`demo_is_nan.exe`）だけでした．リンクの設定`link`は，`[[example]]`や`[[test]]`にも記述できるので，これを利用する事でリンクするターゲットを正確に設定できます．ただし，`external-modules`は`[build]`にしか記述できません．

```toml:fpm.toml
name = "non_number"
version = "0.1.0"
license = "MIT"
author = "Implicit None"
copyright = "Copyright 2021, Implicit None"

[build]
auto-executables = true
auto-tests = true
auto-examples = true
external-modules = ["stdlib_stats"]

[install]
library = false

[[example]]
name = "demo_is_nan"
source-dir = "example"
main = "demo_is_nan.f90"
link = "stdlib"

[[test]]
name = "test_is_nan_real32"
source-dir = "test"
main = "test_is_nan_real32.f90"

[test.dependencies]
check = {path = "util/check"}
```

`[[example]]`に`link`の設定を移動してビルドすると，`fpm build`のログの最後1行で，`demo_is_nan.exe`のリンクの際にstdlibがリンクされていることを確認できます．


```console
D:\project\non_number> rmdir /S build
build、よろしいですか (Y/N)? Y

D:\project\non_number> fpm build
 + mkdir build\dependencies
 + mkdir build\gfortran_2A42023B310FA28D
 + mkdir build\gfortran_E231ED6BEC2C0EC6
 + mkdir build\gfortran_2A42023B310FA28D\non_number\
 + gfortran -c .\.\src\non_number.f90  -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single -J build\gfortran_2A42023B310FA28D -Ibuild\gfortran_2A42023B310FA28D -o build\gfortran_2A42023B310FA28D\non_number\src_non_number.f90.o
 + gfortran -c .\util/check\src\check.f90  -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single -J build\gfortran_2A42023B310FA28D -Ibuild\gfortran_2A42023B310FA28D -o build\gfortran_2A42023B310FA28D\non_number\util_check_src_check.f90.o
 + ar -rs build\gfortran_2A42023B310FA28D\non_number\libnon_number.a @build\gfortran_2A42023B310FA28D\non_number\libnon_number.a.resp
ar: creating build\gfortran_2A42023B310FA28D\non_number\libnon_number.a
 + gfortran -c example\demo_is_nan.f90  -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single -J build\gfortran_2A42023B310FA28D -Ibuild\gfortran_2A42023B310FA28D -o build\gfortran_2A42023B310FA28D\non_number\example_demo_is_nan.f90.o
 + mkdir build\gfortran_E231ED6BEC2C0EC6\example\
 + gfortran  -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single  build\gfortran_2A42023B310FA28D\non_number\example_demo_is_nan.f90.o -lstdlib build\gfortran_2A42023B310FA28D\non_number\libnon_number.a -o build\gfortran_E231ED6BEC2C0EC6\example\demo_is_nan.exe

D:\project\non_number> fpm run --example --target demo_is_nan
vals = 1.00000000,2.00000000,3.00000000,4.00000000,5.00000000,6.00000000,7.00000000,8.00000000,9.00000000,10.0000000
mean = 5.50000000
 value error: x_mean is nan
```

### パスの通っていないライブラリを参照する
先ほどは，システムにインストールされ，パスが通っているライブラリを参照しました．しかし，プロジェクトによっては，プロジェクトのルートに`lib`や`include`ディレクトリを作成し，そこにライブラリおよびモジュールを置く場合もあります．この場合は，`lib`や`include`ディレクトリにパスを通すことは希で，ディレクトリを指定してビルドを行います．

例えば下記のようにライブラリとモジュールファイルを置いた場合は，fpmでビルドする際に，`--flag`および`--link-flag`を用いて，コンパイラおよびリンカに渡すオプションを明記します．

```
.
├── README.md
├── example\
├── fpm.toml
├── include
│   └── stdlib_stats.mod
├── lib
│   └── libstdlib.a
├── src\
├── test\
└── util
    └── check\
```

```console
D:\project\non_number>rmdir /S build
build、よろしいですか (Y/N)? Y

D:\project\non_number>fpm build --flag "-Iinclude" --link-flag "-Llib -lstdlib"
 + mkdir build\dependencies
 + mkdir build\gfortran_D959645BECF235A9
 + mkdir build\gfortran_0C5EEBEEBACDEC93
 + mkdir build\gfortran_D959645BECF235A9\non_number\
 + gfortran -c .\.\src\non_number.f90  -Iinclude -I.\.\include -J build\gfortran_D959645BECF235A9 -Ibuild\gfortran_D959645BECF235A9 -o build\gfortran_D959645BECF235A9\non_number\src_non_number.f90.o
 + gfortran -c .\util/check\src\check.f90  -Iinclude -I.\.\include -J build\gfortran_D959645BECF235A9 -Ibuild\gfortran_D959645BECF235A9 -o build\gfortran_D959645BECF235A9\non_number\util_check_src_check.f90.o
 + ar -rs build\gfortran_D959645BECF235A9\non_number\libnon_number.a @build\gfortran_D959645BECF235A9\non_number\libnon_number.a.resp
ar: creating build\gfortran_D959645BECF235A9\non_number\libnon_number.a
 + gfortran -c example\demo_is_nan.f90  -Iinclude -I.\.\include -J build\gfortran_D959645BECF235A9 -Ibuild\gfortran_D959645BECF235A9 -o build\gfortran_D959645BECF235A9\non_number\example_demo_is_nan.f90.o
 + mkdir build\gfortran_0C5EEBEEBACDEC93\example\
 + gfortran  -Iinclude -I.\.\include  -Llib -lstdlib build\gfortran_D959645BECF235A9\non_number\example_demo_is_nan.f90.o -lstdlib build\gfortran_D959645BECF235A9\non_number\libnon_number.a -o build\gfortran_0C5EEBEEBACDEC93\example\demo_is_nan.exe
```

ログからわかるように，fpmは，プロジェクトルートの`include`を標準でインクルードディレクトリとして扱うオプションを付与している（`-Iinclude -I.\.\include`となってインクルードディレクトリの指定が2回現れている）ので，`--flag "-Iinclude"`は必要ありません．

インクルードディレクトリの名前を変更するには，ライブラリ設定`[library]`の`include-dir`で名前を指定します．

コンパイラオプション付きでビルドした場合，デモやテストを実行するときにも同じオプションが必要です．

## インストールの設定
ビルドした`non_number`のインストールもfpmで可能です．fpmは，標準ではアプリケーション（実行ファイル）のインストールしかしてくれませんが，`[install]`の項目で`library`を設定すると，ライブラリおよびモジュールをインストールしてくれるようになります．

```toml:fpm.toml
name = "non_number"
version = "0.1.0"
license = "MIT"
author = "Implicit None"
copyright = "Copyright 2021, Implicit None"

[build]
auto-executables = true
auto-tests = true
auto-examples = true
external-modules = ["stdlib_stats"]

[install]
library = true

[[example]]
name = "demo_is_nan"
source-dir = "example"
main = "demo_is_nan.f90"
link = "stdlib"

[[test]]
name = "test_is_nan_real32"
source-dir = "test"
main = "test_is_nan_real32.f90"

[test.dependencies]
check = {path = "util/check"}
```

# 参照fpmプロジェクトのコンパイラオプションの指定
fpmは，現状ではマニフェスト`fpm.toml`にコンパイラオプションを記述できません．一方で，ビルド時に`--flag`で指定したコンパイラオプションは，参照しているfpmプロジェクトのビルドにも適用されます．そのため，参照しているライブラリのビルドにオプションが必要な場合は，ビルドの際にまとめて指定します．

fpmはまだ発展途上なので，プリプロセスを多用するような複雑なプロジェクトはまだ作らない方がよいでしょう．他のビルドツールを用いて複雑なビルド設定を構築しておき，条件を限定したfpmプロジェクト用のソースを作成するのも，現状ではやむなしです．

# マニフェスト作成の現状の方針
fpmを利用する事で，プロジェクトの構築が非常に楽になりました．しかし，まだまだ発展途上であるため，煩わしいところもあります．

煩わしさを低減するために，著者らのマニフェスト（`fpm.toml`）作成の方針を紹介します．

## ディレクトリ名は標準（`app`, `src`, `test`, `example`）から変更しない

- ディレクトリ名を変更すると設定の煩わしさが跳ね上がる．

## 外部ライブラリを参照する場合は，可能な限りfpmプロジェクトをオンラインから取得する

- fpmプロジェクトを参照すれば，`external-modules`や`link`の設定やを記述する必要がなくなる．
- プロジェクトをビルドするための環境構築が必要なくなり，ビルドや配布が簡単になる．
- fpmプロジェクトでないライブラリでも，複雑ではない場合はfpmプロジェクトに変換して利用する．
    - githubリポジトリの場合は，forkしてfpmプロジェクトのブランチを作成する．
    - 労力に見合った恩恵がある．
- 参照するライブラリが大規模でビルドに時間がかかる場合は，予めビルドしてローカルにインストールする．
    - 多用途で他のプロジェクトからも利用できるライブラリの場合は，プロジェクトと異なる場所に置いてパスを通しておく．
    - 単一のプロジェクトでしか使わない場合は，`fpm install`を用いてプロジェクトのルートにコピーする．

## 参照するfpmプロジェクトは`[dependencies]`にまとめて書く

- 依存関係を正確に表現するために，`[executable.dependencies]`, `[test.dependencies]`, `[example.dependencies]`は利用できるが，利用するために他の設定を書く必要があって煩わしい．
- 作成するアプリケーションやライブラリが，所属組織外で広く使われることを想定している場合は，依存関係を正確に記述する．

## 外部ライブラリのリンクの設定は`[build]`にまとめて書く

- リンクの設定の記述に，`[[executable]]`, `[[test]]`, `[[example]]`を利用できるが，利用するために他の設定を書く必要があって煩わしい．
- `external-modules`は`[build]`にしか書けないので，`link`の設定もそれほどき気を遣わなくてもよい．
- 作成するアプリケーションやライブラリが，所属組織外で広く使われることを想定している場合は，依存関係を正確に記述する．