6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

fpm (Fortran Package Manager)をBuilder兼Runnerとして利用する(続き1)

Last updated at Posted at 2020-12-12

fortran-langはFortran-lang Community Projectsの成果を記事にする際に用いているタグです.

概要

前の記事で紹介したfpm (Fortran Package Manager)が,Prototype版からver. 0.1.2になったので使ってみました.

大きな変化は

  • バイナリが提供されるようになってインストール方法が変わった.
  • プロジェクトを作れるようになった.
  • 複数のプロジェクトをまとめてビルドできるようになった.

くらいだと思われます.

追記:
バージョン0.5.0での使い方を別記事にまとめました.

環境

  • Ubuntu 18.04 (WSL)
  • fpm version 0.1.2
  • gfortran 8.4.0
  • Haskell stack 2.5.1
  • git 2.17.1

fpmのインストール

fpm verion 0.1.0からは,Windows,Linux,MacOS向けのバイナリが提供されるようになりました.
fpmのリポジトリのリリースページから,必要なバイナリをダウンロードし,適当なフォルダにコピーすればインストールは完了です.

本記事では,Prototype版に合わせて,~/.local/binにコピーしています.

前の記事でも紹介したように,fpmはHaskell-stackを使ってビルドする必要がありました.これまでと同様に,リポジトリをcloneしてstackを使ってビルドすることも可能です.

手順はfpmのGithubリポジトリに書いてあります.

  1. fpmのリポジトリをクローン
  2. Haskell版のfpmをビルド
  3. Haskell版fpmでFortran版のfpmをビルド
  4. Fortran版fpmを適当なディレクトリにコピー

少々変わったインストール手順ですし,上記の環境で試したところ,ビルドしたfpmが正常に動作しませんでした.Windows, Linux, MacOSを利用している場合は,素直にバイナリをダウンロードすることをお薦めします.

fpmによるプロジェクト管理

プロジェクトの作成

fpmで新しいプロジェクトを作成するには,

fpm new プロジェクト名

を実行します.プロジェクト名は,各人で置き換えてください.

コマンドを実行すると,実行したディレクトリ以下にプロジェクト名のディレクトリが作成され,いくつかのファイルとサブディレクトリが作成されます1

$ fpm new sample
 + mkdir -p sample
 + cd sample
 + mkdir -p sample/src
 + mkdir -p sample/test
 + mkdir -p sample/app
 + git init sample
Initialized empty Git repository in コマンドを実行したディレクトリ/sample/.git/
プロジェクト名
├── app
│   └── main.f90
├── src
│   └── プロジェクト名.f90
├── test
│   └── main.f90
├── fpm.toml
├── README.md
└── .gitignore

fpmの公式によると,apptestディレクトリは,オプションを利用した場合に作成されるらしいのですが,現状では何のオプションを付けなくても作成されました.

自動で作成されたソースファイルを見ると,テストは投げやりですが,それ以外はそれなりに形になっています.

app/main.f90
program main
  use sample, only: say_hello
  implicit none

  call say_hello()
end program main
src/sample.f90
module sample
  implicit none
  private

  public :: say_hello
contains
  subroutine say_hello
    print *, "Hello, sample!"
  end subroutine say_hello
end module sample
test/main.f90
program main
implicit none

print *, "Put some tests in here!"
end program main

README.mdの中身は,非常に簡素です.

# sample
My cool new project!

一方,プロジェクトを管理するfpm.tomlファイルには,色々な情報が書かれています.簡単なプログラムであれば,最初に作られたfpm.tomlのヘッダ部分(名前やバージョンなど)を編集するだけで十分でしょう.

name = "sample"
version = "0.1.0"
license = "license"
author = "Jane Doe"
maintainer = "jane.doe@example.com"
copyright = "2020 Jane Doe"


[library]
source-dir="src"

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

[[executable]]
name="sample"
source-dir="app"
main="main.f90"

fpm.tomlの項目の並びが[library][[executable]]となっていることが気になった方もいるのではないでしょうか?

Prototype版から,fpmは用途に応じて3通りのパッケージングの方法を提供しています.

  • アプリケーション(実行ファイルのみを生成)
  • ライブラリ(静的ライブラリのみを生成)
  • アプリケーションとライブラリ

また,appディレクトリを作成するには--with-executableが必要だという公式の記述から,fpmはライブラリ作成を基本としている(必要があれば実行ファイルも作成できる)のだと考えられます.

プロジェクトのビルド

fpmでプロジェクトをビルドするには,プロジェクトのディレクトリ(fpm.tomlがあるディレクトリ)で,

fpm build

を実行するだけです.

$ fpm build
 + mkdir -p build/gfortran_debug/sample
 + mkdir -p build/gfortran_debug/test/
 + gfortran -c test/main.f90 -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fbounds-check -fcheck-array-temporaries -fbacktrace -fcoarray=single  -J build/gfortran_debug/sample -I build/gfortran_debug/sample -o build/gfortran_debug/test/main.f90.o
 + gfortran -c ./src/sample.f90 -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fbounds-check -fcheck-array-temporaries -fbacktrace -fcoarray=single  -J build/gfortran_debug/sample -I build/gfortran_debug/sample -o build/gfortran_debug/sample/sample.f90.o
 + ar -rs build/gfortran_debug/sample/libsample.a build/gfortran_debug/sample/sample.f90.o
ar: build/gfortran_debug/sample/libsample.a を作成しています
 + mkdir -p build/gfortran_debug/app/
 + gfortran -c app/main.f90 -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fbounds-check -fcheck-array-temporaries -fbacktrace -fcoarray=single  -J build/gfortran_debug/sample -I build/gfortran_debug/sample -o build/gfortran_debug/app/main.f90.o
 + gfortran  -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fbounds-check -fcheck-array-temporaries -fbacktrace -fcoarray=single  -J build/gfortran_debug/sample -I build/gfortran_debug/sample build/gfortran_debug/app/main.f90.o build/gfortran_debug/sample/libsample.a  -o build/gfortran_debug/app/sample
 + gfortran  -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fbounds-check -fcheck-array-temporaries -fbacktrace -fcoarray=single  -J build/gfortran_debug/sample -I build/gfortran_debug/sample build/gfortran_debug/test/main.f90.o build/gfortran_debug/sample/libsample.a  -o build/gfortran_debug/test/runTests

プロジェクトディレクトリ直下にbuildディレクトリが作成され,その下にgfortran_debugディレクトリが作られます.gfortran_debug以下には,プロジェクトディレクトリと同じディレクトリapp, sample(プロジェクト名), testが作られ,コンパイル時に作成されたオブジェクトファイルなどが置かれます.
また,sampleには,静的ライブラリlibsample.aが作成されます.

リリース版をビルドする際は,--releaseオプションを付けてビルドします.

$ fpm build --release
 + mkdir -p build/gfortran_release/sample
 + mkdir -p build/gfortran_release/test/
 + gfortran -c test/main.f90 -O3 -Wimplicit-interface -fPIC -fmax-errors=1 -ffast-math -funroll-loops -fcoarray=single  -J build/gfortran_release/sample -I build/gfortran_release/sample -o build/gfortran_release/test/main.f90.o
 + gfortran -c ./src/sample.f90 -O3 -Wimplicit-interface -fPIC -fmax-errors=1 -ffast-math -funroll-loops -fcoarray=single  -J build/gfortran_release/sample -I build/gfortran_release/sample -o build/gfortran_release/sample/sample.f90.o
 + ar -rs build/gfortran_release/sample/libsample.a build/gfortran_release/sample/sample.f90.o
ar: build/gfortran_release/sample/libsample.a を作成しています
 + mkdir -p build/gfortran_release/app/
 + gfortran -c app/main.f90 -O3 -Wimplicit-interface -fPIC -fmax-errors=1 -ffast-math -funroll-loops -fcoarray=single  -J build/gfortran_release/sample -I build/gfortran_release/sample -o build/gfortran_release/app/main.f90.o
 + gfortran  -O3 -Wimplicit-interface -fPIC -fmax-errors=1 -ffast-math -funroll-loops -fcoarray=single  -J build/gfortran_release/sample -I build/gfortran_release/sample build/gfortran_release/app/main.f90.o build/gfortran_release/sample/libsample.a  -o build/gfortran_release/app/sample
 + gfortran  -O3 -Wimplicit-interface -fPIC -fmax-errors=1 -ffast-math -funroll-loops -fcoarray=single  -J build/gfortran_release/sample -I build/gfortran_release/sample build/gfortran_release/test/main.f90.o build/gfortran_release/sample/libsample.a  -o build/gfortran_release/test/runTests

--releaseオプションの有無でコンパイルオプションが変わっていることが確認できます.
オブジェクトファイルなどは,build\gfortran_releaseディレクトリ以下に置かれます.

実行

ビルドしたプログラムは,fpm runで実行します.

$ fpm run
 + build/gfortran_debug/app/sample 
 Hello, sample!

テストは,fpm testで実行します.

$ fpm test
 + build/gfortran_debug/test/runTests 
 Put some tests in here!

fpm付属のサンプル

fpmのリポジトリには,fpmプロジェクトのサンプルがいくつか存在します.
そのうち,確認しておいた方がよい例を表にまとめました.

サンプル 理由
hello_world 最小のプロジェクト
hello_complex 複数のテストや実行ファイルを含むプロジェクト
hello_fpm hello_complexを参照した,プロジェクト同士の連携の例
circular_example circular_testを循環参照
circular_test circular_exampleを循環参照
submodules サブモジュールを使用する例
link_executable 外部ライブラリとの連携
with_c C言語を含むプロジェクトの例
with_makefile makefileの使用例(Fortran版fpmでは動作しない)

まとめ

Prototype版から進化したfpmを使ってみました.
目に見えて大きく変わったということはありませんが,できる事も増えて,着実に良くなっています.

まだ,外部コマンドとの連携や,コンパイルオプションの変更,gfortran以外のコンパイラの利用はできないみたいですが,今後に期待します.

近いうちに,もう1本fpmに関する記事を投稿する予定です.
投稿しました.(2020 Dec. 13rd)

  1. 当然gitで管理するんだろう?という圧を感じます.

6
2
1

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
6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?