基于 Fortran 包管理器 fpm 文档, 总结功能及基本用法 [目前尚有诸多不完善, 文档不全]
introduction
Fortran 包管理器 fpm (Fortran Package Manager) 主要目的是简化 Fortran 程序或库的构建与分发, 主要功能包括
- 项目创建:使用
fpm new
命令可以快速创建一个新的 Fortran 项目
- 依赖管理:fpm 支持本地和在线注册表, 可以轻松管理项目的依赖项
- 构建和测试:fpm 可以自动构建项目, 并运行可执行文件、测试和示例
- 发布和分发:通过
fpm publish
命令, 可以将项目发布到注册表中, 供其他 Fortran 项目使用
- 配置选项:支持启用和禁用语言特性, 如隐式类型和默认源码形式
Fortran 包管理器官方文档 (https://fpm.fortran-lang.org//index.html), 中文文档 (https://fpm.fortran-lang.cn/tutorial/hello-fpm.html)
install
安装可以直接下载发行包或使用 conda, 此处采用前者, 下载地址 (https://github.com/fortran-lang/fpm/releases)
1 2
| wget https://github.com/fortran-lang/fpm/releases/download/v0.10.1/fpm-0.10.1-linux-x86_64 -P ~/Environment/Fortran/bin wget https://github.com/fortran-lang/fpm/releases/download/v0.10.1/fpm-0.10.1-linux-x86_64.sha256 -P ~/Environment/Fortran/bin
|
以.sha256结尾的链接提供加密哈希, 可以使用这些哈希来验证二进制文件的下载是否成功
1 2 3 4
| $ openssl sha256 -r fpm-0.10.1-linux-x86_64 2c0759e349fb8c91fc6d4cbc1c355f52cfd1dd15589273550327daf6e7f9932c *fpm-0.10.1-linux-x86_64 $ cat fpm-0.10.1-linux-x86_64.sha256 2c0759e349fb8c91fc6d4cbc1c355f52cfd1dd15589273550327daf6e7f9932c fpm-0.10.1-linux-x86_64
|
添加可执行权限和软链接
1 2
| chmod +x fpm-0.10.1-linux-x86_64 ln -s ~/Environment/Fortran/bin/fpm-0.10.1-linux-x86_64 ~/Environment/Fortran/bin/fpm
|
通过 Environment Modules
工具管理
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| proc ModulesHelp {} { puts stderr "Program: fpm $::version" puts stderr "Description: A Fortran package manager and build system" puts stderr "Home Page: https://github.com/fortran-lang/fpm" puts stderr "License: MIT" puts stderr "OS Type: Linux" puts stderr {} } set version 0.10.1 set prefix /home/user/Environment/Fortran module-whatis "Fortran package manager and build system" setenv FPM_HOME $prefix prepend-path PATH $prefix/bin
|
Command
fpm 包含以下指令
Command |
Function |
fpm new project |
Compile the packages into the “build/” directory |
fpm build |
create git repository in the fpm standard layout |
fpm test |
run tests |
fpm run --example |
Run the local package binaries. |
fpm clean |
Delete directories in the “build/” directory |
fpm update |
Update the project dependencies |
fpm publish |
Publish package to the registry |
fpm install |
installs the executables locally, NOT RECOMMEND |
这里主要关心如何通过 fpm 构建程序并测试
layout
通过 fpm new test
创建新项目结构如下
1 2 3 4 5 6 7 8 9
| test ├── app │ └── main.f90 ├── fpm.toml ├── README.md ├── src │ └── test.f90 └── test └── check.f90
|
执行 fpm build
创建 build
目录结构如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| build ├── cache.toml ├── dependencies ├── gfortran_50F62D7499E64B65 │ └── test │ ├── libtest.a │ └── libtest.a.log ├── gfortran_87E2AE0597D39913 │ ├── test │ │ ├── app_main.f90.o │ │ ├── app_main.f90.o.digest │ │ ├── app_main.f90.o.log │ │ ├── src_test.f90.o │ │ ├── src_test.f90.o.digest │ │ └── src_test.f90.o.log │ └── test.mod └── gfortran_E167FD2A985B468F ├── app │ ├── test │ └── test.log └── test ├── check └── check.log
|
不同路径及文件功能
File |
Description |
app/main.f90 |
Fortran program |
fpm.toml |
manifest |
src/test.f90 |
Fortran subroutine |
test/check.f90 |
test program |
build |
compile path |
build/cache.toml |
compile cache |
build/dependencies |
dependencies library |
gfortran_5** |
build static library |
libtest.a |
static library |
libtest.a.log |
log file of static library |
gfortran_8** |
compile file |
**.f90.o |
object file |
**.f90.o.digest |
digest(hash) file used to skip compilation of unmodified sources |
**.f90.o.log |
log file of object file |
test.mod |
module file |
gfortran_E** |
build executable |
app |
executable folder |
test |
binary executable |
test.log |
log file of binary executable |
check |
binary executable for test |
check.log |
log file of test |
manifest
每个项目的 fpm.toml 文件称为清单 (manifest), 使用TOML格式编写, 详细内容参考 (https://fpm.fortran-lang.org/zh_CN/spec/manifest.html)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| [library] source-dir = "src" include-dir = ["include", "third_party/include"]
[build] auto-executables = true auto-tests = true auto-examples = true module-naming = false link = ["z", "blas", "lapack"] external-modules = ["netcdf", "h5lt"]
[install] library = false
[fortran] implicit-typing = false implicit-external = false source-form = "free"
[dependencies] stdlib = "*" [dependencies.toml-f] git = "https://github.com/toml-f/toml-f" branch = "main" rev = "2f5eaba864ff630ba0c3791126a3f811b6e437f3" [dependencies] my-package.namespace = "my-namespace" example-package.v = "1.0.0" [dependencies] my-utils = { path = "utils" }
[preprocess] cpp.suffixes = ["F90", "f90"] cpp.directories = ["src/feature1", "src/models"] cpp.macros = ["FOO", "BAR"]
[preprocess] [preprocess.cpp] suffixes = ["F90", "f90"] directories = ["src/feature1", "src/models"] macros = ["FOO", "BAR"]
[preprocess] [preprocess.fypp]
[[executable]] name = "app-name" source-dir = "app" main = "program.f90" executable = [ { name = "a-prog" }, { name = "app-tool", source-dir = "tool" }, ] [executable.dependencies] helloff = { git = "https://gitlab.com/fun/helloff.git" }
[[test]] name = "test-name" source-dir = "test" main = "check.F90" [test.dependencies] helloff = { git = "https://gitlab.com/fun/helloff.git" }
|