|
| 1 | +# Module name requirements |
| 2 | + |
| 3 | +:::{note} |
| 4 | +Module naming requirements only apply to packages which are uploaded to a fpm registry; by default, no naming rules are enforced for local fpm projects. |
| 5 | +::: |
| 6 | + |
| 7 | +:::{note} |
| 8 | +TL;DR Always prefix all your module names with a standardized package prefix. |
| 9 | +- A default prefix (package name + double underscore: `my_package__*`) is always reserved by the registry |
| 10 | +- A custom prefix (no-symbols + single underscore: `mypkg_*`) can be specified, but it is subject to not being reserved in the registry yet. |
| 11 | +- Set default (`module-naming=true`) or custom (`module-naming="mypfx"`) prefix in `fpm.toml` `[build]`. |
| 12 | +::: |
| 13 | + |
| 14 | +The Fortran language does not support namespaces. This means that all public names (modules, but also global subroutines and functions) must be unique in the build space. |
| 15 | +Any build that contains duplicate names will fail because it is impossible to resolve a name to a unique object. |
| 16 | +For this reason, fpm by default requires all packages to comply with simple naming conventions that apply to both the package name and its modules. |
| 17 | + |
| 18 | + |
| 19 | +## Fortran names: general rules |
| 20 | + |
| 21 | +As of Fortran 2003 onward, valid Fortran names need to comply with the following rules: |
| 22 | + |
| 23 | +- Up to 63 characters long; |
| 24 | +- Letters are case insensitive; |
| 25 | +- Must begin with a letter; |
| 26 | +- Only alphanumeric characters (letters, numbers) and underscores `_` are allowed. |
| 27 | + |
| 28 | +*Examples of invalid Fortran names:* |
| 29 | + |
| 30 | +```{code-block} fortran |
| 31 | + 1_package ! Begins with # |
| 32 | + package$ ! Contains invalid symbol |
| 33 | + _package ! Does not begin with letter |
| 34 | + my package ! Contains space |
| 35 | +``` |
| 36 | + |
| 37 | +*Examples of valid Fortran names:* |
| 38 | + |
| 39 | +```{code-block} fortran |
| 40 | + my_module ! Case insensitive: all versions valid, |
| 41 | + My_Module ! but resolving to the same object |
| 42 | + MY_MODULE |
| 43 | + MyModule |
| 44 | + mypackage |
| 45 | + package_module ! Underscores allowed |
| 46 | + my_package_123 |
| 47 | +``` |
| 48 | + |
| 49 | +## fpm registry names: rules for packages and modules |
| 50 | + |
| 51 | +To reduce the chance of name collisions, any Fortran module name in a package must begin with a unique prefix. |
| 52 | +Two options are offered. |
| 53 | + |
| 54 | +### Default Module names |
| 55 | + |
| 56 | +The default option is always valid for all packages, as it is uniquely bound to the package name. It features a fortrannized package name, followed by a double underscore, with these rules: |
| 57 | + |
| 58 | +1. Must begin with their package name; |
| 59 | +2. The ``default separator`` `__` between the package name chunk and what follows must be used; |
| 60 | +3. Neither the module nor the package name shall contain the default separator sequence elsewhere. |
| 61 | + |
| 62 | +:::{note} |
| 63 | +The default separator is a *double* underscore, single underscores are allowed anywhere except at the end of a package name. |
| 64 | +::: |
| 65 | + |
| 66 | +*Valid enforced module names* |
| 67 | + |
| 68 | +When the naming conventions are enforced, these are example modules in a package named `my_pkg` to illustrate the rules: |
| 69 | + |
| 70 | +```{code-block} fortran |
| 71 | +
|
| 72 | + module my_pkg ! Global API |
| 73 | + module my_pkg__1 ! We can now number them |
| 74 | + module my_pkg__123 |
| 75 | + module my_pkg__core |
| 76 | + module my_pkg__utils |
| 77 | + module my_pkg__with_very_long_name |
| 78 | +``` |
| 79 | + |
| 80 | +*Invalid enforced module names* |
| 81 | + |
| 82 | +Considering the same package `my_pkg`, the following names will be invalid according to the naming rules: |
| 83 | + |
| 84 | +```{code-block} fortran |
| 85 | +
|
| 86 | + module my_pkg__ ! Nothing follows the separator |
| 87 | + module my_pkg__1__2 ! Separator must be unique |
| 88 | + module my_pkg__90123456789012345678901234567890123456789012345678901234 ! 64 chars: too long |
| 89 | + module my_pkg__util$ ! non-Fortran name |
| 90 | +``` |
| 91 | + |
| 92 | +### Custom Module names |
| 93 | + |
| 94 | +Optionally, one can specify a custom prefix for the package's modules. The custom prefix must be: |
| 95 | + |
| 96 | +1. A valid Fortran name; |
| 97 | +2. Alphanumeric only characters (no spaces, symbols, dashes, underscores allowed). |
| 98 | + |
| 99 | +Different from the default option, a custom prefix needs to be validated by the registry, which keeps a |
| 100 | +list of unique custom prefixes to prevent name collisions. |
| 101 | + |
| 102 | +Module names with the custom prefix are followed by a ``single underscore`` `_`, which makes this option more flexible and backward compatible with existing packages. |
| 103 | +When a custom module prefix is specified, the default one is still available. Considering for example a package named `date-time`, with chosen prefix `dt`, the following are all valid module names: |
| 104 | + |
| 105 | +```{code-block} fortran |
| 106 | +
|
| 107 | + module date_time ! Same as package name |
| 108 | + module dt ! Same as custom prefix |
| 109 | + module date_time__utils ! use standard naming -> double underscore |
| 110 | + module dt_utils ! custom prefix -> single underscore |
| 111 | + module dt_123 ! custom prefix |
| 112 | + module dt_1 |
| 113 | + module dt__1 ! also valid |
| 114 | +``` |
| 115 | + |
| 116 | +### Package names |
| 117 | + |
| 118 | +All packages in FPM registries must have unique names, hence they must abide to the following rules |
| 119 | + |
| 120 | +1. All package names shall be valid Fortran names; |
| 121 | +2. Dash characters (`-`) are also allowed, and are treated by fpm as underscores; |
| 122 | +3. Package names may contain uppercase and lowercase characters, but their unique identification is made case insensitive; |
| 123 | +4. No duplicate package names are allowed within the same namespace. |
| 124 | + |
| 125 | +*Examples of valid package names:* |
| 126 | + |
| 127 | +```{code-block} fortran |
| 128 | + my_package ! 1 underscore allowed |
| 129 | + My_Package ! same as the former |
| 130 | + mypackage123 ! Numbers OK |
| 131 | + my-package ! Will be read by fpm as "my_package" |
| 132 | +``` |
| 133 | + |
| 134 | +*Examples of invalid package names:* |
| 135 | + |
| 136 | +```fortran |
| 137 | + my__package ! Contains package__module separator |
| 138 | + package__ ! Contains separator |
| 139 | + package_ ! Ends with underscore |
| 140 | + my pac$age ! Spaces and all symbols besides `_` not allowed |
| 141 | + _my_package ! Does not begin with letter |
| 142 | + 123package ! Does not begin with letter |
| 143 | +``` |
| 144 | + |
| 145 | +## Manifest Settings |
| 146 | + |
| 147 | +:::{note} |
| 148 | +Key facts: |
| 149 | +- FPM does not apply naming requirements by default. If you want them, enable them in `fpm.toml` |
| 150 | +- FPM registries mandatorily require them. Ensure `fpm.toml` enables them. |
| 151 | +- Enable standard prefix with `module-naming=true`, custom prefix with `module-naming="prefixname"`. |
| 152 | +::: |
| 153 | + |
| 154 | +Module naming requirements can be enabled in `fpm.toml` under the `build` section, using the boolean flag `module-naming`. |
| 155 | +By default, `module-naming = false`, so no registry name enforcing is checked during the build. |
| 156 | + |
| 157 | +*Example:* |
| 158 | + |
| 159 | +```{code-block} toml |
| 160 | +:emphasize-lines: 5 |
| 161 | +[build] |
| 162 | +auto-executables = true |
| 163 | +auto-examples = false |
| 164 | +auto-tests = false |
| 165 | +module-naming = true # Use default naming convention |
| 166 | +external-modules = "netcdf" |
| 167 | +``` |
| 168 | + |
| 169 | +```{code-block} toml |
| 170 | +:emphasize-lines: 5 |
| 171 | +[build] |
| 172 | +auto-executables = true |
| 173 | +auto-examples = false |
| 174 | +auto-tests = false |
| 175 | +module-naming = "tomlf" # Use custom prefix, "tomlf" |
| 176 | +external-modules = "netcdf" |
| 177 | +``` |
| 178 | + |
| 179 | +## Guidelines |
| 180 | + |
| 181 | +:::{note} |
| 182 | +These are non-mandatory styling suggestions to improve code readability and uniformity. |
| 183 | +::: |
| 184 | + |
| 185 | +It's recommended that the public API of each package is contained in a top-level module, whose name is same as the package name. |
| 186 | +For example, assuming a package ``DateTime`` deals with time and date in Fortran, one could have several modules deal with parts of it: |
| 187 | + |
| 188 | +```{code-block} fortran |
| 189 | + module datetime__dates ; end module |
| 190 | + module datetime__time ; end module |
| 191 | + module datetime__julian; end module |
| 192 | +``` |
| 193 | + |
| 194 | +and a unique public API that's contained in the top-level module: |
| 195 | + |
| 196 | +```{code-block} fortran |
| 197 | + module datetime |
| 198 | + use datetime__dates, only: [...] |
| 199 | + use datetime__time, only: [...] |
| 200 | + use datetime__julian, only: [...] |
| 201 | + implicit none(type,external) |
| 202 | + private |
| 203 | +
|
| 204 | + ! Publish API |
| 205 | + public :: sub_1 |
| 206 | + public :: fun_123 |
| 207 | +
|
| 208 | + end module datetime |
| 209 | +``` |
| 210 | + |
| 211 | +## References |
| 212 | + |
| 213 | +[1] Metcalf, Reid, Cohen, "[Modern Fortran Explained](https://dl.acm.org/doi/book/10.5555/2090092)", Oxford University Press. |
| 214 | + |
| 215 | +[2] [Style Guide for Python Code](https://peps.python.org/pep-0008/#package-and-module-names) |
| 216 | + |
0 commit comments