模块名称要求

备注

模块命名要求只适用于上传到fpm注册表的软件包;默认情况下,本地fpm项目不执行命名规则。

备注

如题,始终用一个标准化的包前缀来命名你的所有模块。

  • 一个默认的前缀(包名+双下划线:my_package__*)总是由注册表保留

  • 可以指定一个自定义的前缀(无符号+单下划线:mypkg_*),但它受制于还没有在注册表中被保留。

  • fpm.toml[build]中设置默认(module-naming=true)或自定义(module-naming="mypfx")前缀。

Fortran语言不支持命名空间。这意味着所有公共名称(模块,但也包括全局子程序和函数)在构建空间中必须是唯一的。任何包含重复名字的构建都会失败,因为不可能将一个名字解析为一个唯一的对象。出于这个原因,fpm默认要求所有的包都要遵守简单的命名规则,这些规则同时适用于包名和它的模块。

Fortran名称:一般规则

从Fortran 2003开始,有效的Fortran名称需要遵守以下规则:

  • 最长为63个字符;

  • 字母是不分大小写的;

  • 必须以字母作为开头;

  • 只允许使用字母数字字符(字母、数字)和下划线_

无效的Fortran名称的例子:

  1_package         ! Begins with #
  package$          ! Contains invalid symbol
  _package          ! Does not begin with letter
  my package        ! Contains space

有效的Fortran名称的例子:

  my_module         ! Case insensitive: all versions valid,
  My_Module         ! but resolving to the same object
  MY_MODULE
  MyModule
  mypackage
  package_module    ! Underscores allowed
  my_package_123

fpm注册表名称:软件包和模块的规则

为了减少名称冲突的机会,包中的任何Fortran模块名称必须以唯一的前缀开始。提供了两个选项。

默认模块名称

默认选项对所有软件包都是有效的,因为它与软件包名称唯一绑定。它的特点是一个transannized软件包名称,后面是一个双下划线,有这些规则:

  1. 必须以其包装名称开头;

  2. 必须在软件包名称块和后面的内容之间使用默认的分隔符 __

  3. 模块和包的名称都不应该在其他地方包含默认的分隔符序列。

备注

默认的分隔符是下划线,单下划线可以在任何地方使用,除了在包名的末尾。

有效的执行模块名称

当命名规则被强制执行时,这些是在一个名为my_pkg的包中的例子模块,以说明规则:

   module my_pkg        ! Global API
   module my_pkg__1     ! We can now number them
   module my_pkg__123
   module my_pkg__core
   module my_pkg__utils
   module my_pkg__with_very_long_name

无效的执行模块名称

考虑到同一个软件,my_pkg,根据命名规则,以下名称将是无效的:

   module my_pkg__      ! Nothing follows the separator
   module my_pkg__1__2  ! Separator must be unique
   module my_pkg__90123456789012345678901234567890123456789012345678901234 ! 64 chars: too long
   module my_pkg__util$ ! non-Fortran name

自定义模块名称

可以选择为包的模块指定一个自定义前缀。该自定义前缀必须是:

  1. 一个有效的Fortran名称;

  2. 只有字母数字字符(不允许有空格、符号、破折号、下划线)。

与默认选项不同的是,自定义前缀需要经过注册表的验证,注册表保留了一个唯一的自定义前缀列表,以防止名称碰撞。

带有自定义前缀的模块名称后面有一个单下划线 _,这使得这个选项更加灵活,并向后兼容现有的软件包。当自定义模块前缀被指定时,默认的前缀仍然可用。例如,考虑到一个名为 date-time的包,并选择了前缀 dt,以下是所有有效的模块名称:

   module date_time        ! Same as package name
   module dt               ! Same as custom prefix
   module date_time__utils ! use standard naming -> double underscore
   module dt_utils         ! custom prefix -> single underscore
   module dt_123           ! custom prefix
   module dt_1
   module dt__1            ! also valid

包名称

FPM注册表中的所有软件包必须有唯一的名称,因此它们必须遵守以下规则

  1. 所有包的名称都应是有效的Fortran名称;

  2. 破折号字符(-)也是允许的,并被fpm当作下划线处理;

  3. 包的名称可以包含大写和小写字符,但它们的唯一标识是不分大小写的;

  4. 在同一命名空间内不允许有重复的包名。

有效软件包名称的例子:

   my_package     ! 1 underscore allowed
   My_Package     ! same as the former
   mypackage123   ! Numbers OK
   my-package     ! Will be read by fpm as "my_package"

无效的软件包名称的例子:

  my__package       ! Contains package__module separator
  package__         ! Contains separator
  package_          ! Ends with underscore
  my pac$age        ! Spaces and all symbols besides `_` not allowed
  _my_package       ! Does not begin with letter
  123package        ! Does not begin with letter

清单设置

备注

关键事实:

  • FPM默认不应用命名要求。如果你想要它们,请在fpm.toml中启用它们

  • FPM注册处强制要求它们。确保fpm.toml启用它们。

  • module-naming=true启用标准前缀,用module-naming="prefixname"启用自定义前缀。

模块命名要求可以在fpm.toml中的build部分启用,使用布尔标志module-naming。默认情况下,module-naming = false,所以在构建过程中不会检查注册表的名称强制。

例如:

[build]
auto-executables = true
auto-examples = false
auto-tests = false
module-naming = true          # Use default naming convention
external-modules = "netcdf"
[build]
auto-executables = true
auto-examples = false
auto-tests = false
module-naming = "tomlf"       # Use custom prefix, "tomlf"
external-modules = "netcdf"

准则

备注

这些是非强制性的风格建议,以提高代码的可读性和统一性。

我们建议每个包的公共API都包含在一个顶级模块中,其名称与包的名称相同。例如,假设一个包DateTime在Fortran中处理时间和日期,我们可以有几个模块来处理它的一部分:

   module datetime__dates ; end module
   module datetime__time  ; end module
   module datetime__julian; end module

和一个独特的公共API,它包含在顶层模块中:

   module datetime
      use datetime__dates, only: [...]
      use datetime__time, only: [...]
      use datetime__julian, only: [...]
      implicit none(type,external)
      private

      ! Publish API
      public :: sub_1
      public :: fun_123

   end module datetime

引用

[1] Metcalf, Reid, Cohen, “Modern Fortran Explained”, Oxford University Press.

[2] Style Guide for Python Code