Development Tools and Configuration
January 16, 2025 ยท View on GitHub
This guide explains the development tools and configurations used in this project for Modern Fortran development.
Remember that all tooling and configurations mentioned are optional and customisable.
- Initial Setup
- Visual Studio Code
- Language Server
- Code Formatting
- Automated Checks
- Package Management
- Best Practices
Initial Setup
-
Install VS Code Extensions:
- Open Extensions (CTRL + Shift + X) and search for "Modern Fortran".
- Install other recommended extensions from the "Recommended" tab (see .vscode/extensions.json).
-
Create a directory for generated modules:
- Create a directory named
.generated_modulesto house allfortlslinter module and object files. This directory will be hidden from VS Code's Explorer (see .vscode/settings.json).
- Create a directory named
-
Review and amend configurations:
- "Modern Fortran" can accommodate several different configurations for the linter, including
gfortranandifort,fprettifyorfindent, etc.
- "Modern Fortran" can accommodate several different configurations for the linter, including
Visual Studio Code
Configuration
The workspace configuration file .vscode/settings.json is automatically used when the workspace is opened. It includes global and Fortran-related settings. Global settings can be moved to the user settings file if needed. To do this:
Ctrl + Shift + Pin VS Code.- Type
Preferences: Open User Settings (JSON)and press Enter. - Copy them (only global settings) across from
.vscode/settings.jsonand uncomment them.
Especially python.venvFolders is important so that VS Code always activates your virtual environment when a project directory is opened. This makes sure all tooling is in the path for "Modern Fortran" to use.
Extensions
To install extensions:
- Open the "Extensions" tab (
Ctrl/Cmd + Shift + X). - Search for the extensions by name.
- Install
- Optionally: enable them by workspace to minimize performance degradation by selecting "Enable (Workspace)" from the dropdown menu.
Alternatively, recommended extensions will appear on the "Recommended" tab, courtesy of .vscode/extensions.json.
Recommended Extensions
Modern Fortran: Provides Fortran language support, syntax highlighting, Language Server support, Debugging, DiagnosticsMarkdown all-in-one: Markdown syntax highlighting and moreGit History: In-editor Git functionalityGitlens: In-editor Git functionalityEven Better TOML: TOML files syntax highlightingEditorConfig For VSCode: Uses.editorconfigto resolve the configuration for that particular file and applies any relevant editor settings.
Language Server
The Fortran Language Server (fortls) provides advanced IDE functionality, and is used by the Modern Fortran extension:
Features
- Intelligent code completion and suggestions
- Hover information for variables, functions, and modules
- Go to definition and find references
- Symbol detection across your project
- Real-time error detection and diagnostics
Configuration
Settings can be found in:
- VS Code settings file (
.vscode/settings.json) fortlsconfig file (.fortls)
The .fortls config takes precedence where settings overlap.
Linting
The "Modern Fortran" extension supports multiple compilers for linting:
- GNU's
gfortran - Intel's
ifortandifx - NAG's
nagfor
The linter provides real-time feedback on:
- Syntax errors
- Variable usage and initialization
- Type mismatches
- Array bounds
- Procedure interfaces
- Common programming mistakes
fortitude linter
fortitude is a new, rust-based, Fortran linter being actively developed.
It has been integrated in pre-commit, so it will run automatically when commiting or pushing. Included configuration in fpm.toml.
To run independently, simply invoke: fortitude check to check all Fortran files present (or add the path to a Fortran file).
Code Formatting
fprettify
fprettify provides comprehensive formatting capabilities:
- Consistent indentation
- Space padding around operators
- Case normalization for keywords
- Line continuation style
- Comment alignment
Configuration
The formatting configuration is customized through .fprettify.rc in the project root.
Known Issues
fprettify configuration does not work correctly in VS Code Modern Fortran with --case 1 1 1 1. As a workaround, pre-commit is set to run the formatter with the config file.
Automated Checks
Pre-commit Hooks
Pre-commit hooks run automatically before git commit and git push to ensure code quality:
Setup
pre-commit install # Install hooks
pre-commit uninstall # Uninstall hooks
Bypass Temporarily
SKIP test-fpm git commit -m "Commit message.." # ignore specific hook
Testing
Testing is handled through fpm test:
- Runs automatically via pre-commit hooks
- Can be run manually:
fpm test - Uses gfortran in debug mode by default
Compile Checks
fpm build provides compile-time checking:
- Debug mode (default):
fpm build(--profile debugis implied) - Release mode:
fpm build --profile release
Package Management
fpm (Fortran Package Manager)
fpm handles project structure and dependencies:
- Builds the project:
fpm build - Runs tests:
fpm test - Executes the program:
fpm run - Manages dependencies through
fpm.toml
Response file usage
fpm supports response files (.rsp) that store commonly used command-line options. These files allow you to create reusable build configurations and simplify complex command-line invocations. The syntax uses @ to reference a response file:
fpm @debug_gcc # Use gfortran debug configuration
fpm @debug_gcc --verbose # Same as above but with verbose output
fpm @installgcc-opt # Install with gfortran optimizations
You can also append additional flags to response file configurations:
# Add specific vectorization flags
fpm @installgcc-opt --flag "-g -mprefer-vector-width=512 -fno-omit-frame-pointer"
# Enable vectorizer verbose output
fpm @installgcc-opt --flag "-ftree-vectorizer-verbose=2"
# Redirect compiler warnings or errors to a file
fpm @debug_gcc --verbose >> warnings.out
Response files are particularly useful for:
- Storing complex compiler configurations
- Switching between debug and release builds
- Managing different optimization levels
- Maintaining consistent build settings across team members
Build, Run, Install Commands
When using build, run, or install, the target binary is hashed based on the compiler flags. This means that if you install with different flags than what was used to build, you might end up with a mismatched target. To avoid this:
- Use consistent
--flagand--profileoptions between builds, runs, and installs - Once you've settled on a specific configuration (compiler, flags, etc.), create an alias in your
.rspfile that mirrors said configuration - Remember to commit the changes so that the configuration is reflected in the repository
For example, in the .rsp file:
@installgcc-opt
option install --compiler gfortran --profile release --prefix $PWD --flag "-O3 -flto -march=native -fPIC -funroll-loops"
will ensure the installed target always matches the specified configuration you've tested and verified.
Accessing Binaries
buildcompiles the program underbuild/<compiler><hash>. Manually finding the final binary works but is bothersomeruninvokesbuildand parses the possible targets.fpm run <target>will compile and run the<target>binaryinstallinvokesbuild, then installs the binary under<PREFIX>/bin.<PREFIX>can be set through--prefix <dir>. For example,fpm install --prefix $PWDwill install the target in the root directory, underbin/
Recommended: Using fpm install --prefix keeps the binary in one place: ./bin/<target>. Run scripts don't have to be modified every time and the binary can be installed/replaced with the appropriate response alias as needed.
Python Dependencies
All Fortran tools provided in the template are Python packages, and they are managed through the pyproject.toml configuration file.
- Runtime dependencies:
pip install . - Development dependencies:
pip install .[dev]
UV Package Manager
uv is a modern Python package manager, written in Rust. It replaces venv, virtualenv, poetry, anaconda (for projects that don't need binaries), and other tools.
Installation
Available as a standalone script (always review such scripts before running!) or through other sources. More information in the documentation.
To update: uv self update
Usage
uv is a drop-in replacement for pip. Choose one or the other for each virtual environment, as they are not interchangeable.
# Create a virtual environment
uv venv .venv # defaults to .venv but can be changed
source .venv/bin/activate
uv pip install . # Install runtime dependencies
uv pip install .[dev] # Install development dependencies
Best Practices
- Enable the language server for intelligent code analysis
- Configure at least one linter for catching errors early
- Use automatic formatting to maintain consistent code style
- Utilize "Go to Definition" and "Find References" for code navigation
- Review hover information to understand symbol usage
- Run tests before commits using pre-commit hooks
- Use debug builds during development, release builds for deployment
- Edit, commit, and use aliases from
fpm.rspfor a reproducible compilation