Skip to content

Filesystem path manipulation Fortran library, based on C++17 filesystem with fallback to plain C++. For Linux, macOS, Windows.

License

Notifications You must be signed in to change notification settings

scivision/fortran-filesystem

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Ffilesystem: for Fortran using C++17 and libc

DOI ci ci_windows oneapi-linux ci_fpm ci_meson

Platform independent (Linux, macOS, Windows, Cygwin, WSL, BSD, ...) Fortran filesystem "Ffilesystem" path manipulation library. Ffilesystem core functions are implemented in C++17 using <string_view>. If available, C++ standard library <filesystem> is used. Otherwise, plain C++ code is used with the C standard library to access filesystem and system parameters. Ffilesystem uses C++ std::string and (optional) Fortran character. UTF-8 encoding allows for multibyte characters in paths. Ffilesystem header ffilesystem.h can be used from C and C++ project code--see example.

The optional Fortran interface is built by default. Ffilesystem brings full filesystem functionality to Fortran.

The language standards must be at least:

  • C++17 standard library STL
  • (optional) Fortran 2003

Ffilesystem works with popular C++ STL and C standard library implementations including: glibc, newlib, musl, Cosmopolitan universal binaries, macOS universal binaries, BSD libc, Microsoft CRT, among others. On Linux, symbol _DEFAULT_SOURCE is defined if needed to enable C standard library functions.

Inspired by (and benchmarked against) Python pathlib. Important Ffilesystem functions are benchmarked to help improve performance. Advanced / conceptual development takes place in ffilesystem-concepts.

Compiler support

Ffilesystem supports compilers including:

  • GCC ≥ 7 (gcc/g++, gfortran)
  • LLVM Clang ≥ 9 (clang/clang++, flang or gfortran)
  • Intel oneAPI ≥ 2023.1 (icx, icpx, ifx)
  • Intel Classic ≥ 2021.9 (icpc, ifort)
  • AMD AOCC (clang/clang++, flang)
  • NVIDIA HPC SDK (nvc++, nvfortran)
  • Visual Studio (C/C++)
  • Cray: using Cray compilers alone (cc, CC, ftn) or using GCC or Intel backend

To help debug with older compilers, disable C++ <filesystem>:

cmake -Bbuild -Dffilesystem_cpp=off

libstdc++

Some systems have broken, obsolete, or incompatible libstdc++.

Intel: If Intel compiler linker errors use GCC >= 9.1. This can be done by setting environment variable CXXFLAGS to the top level GCC >= 9.1 directory. Set environment variable CXXFLAGS for Intel GCC toolchain like:

export CXXFLAGS=--gcc-toolchain=/opt/rh/gcc-toolset-10/root/usr/

which can be determined like:

scl enable gcc-toolset-10 "which g++"

Build

Ffilesystem can be built with CMake or Fortran Package Manager (FPM).

"libffilesystem.a" is the library binary built that contains the Fortran "filesystem" module--it is the only binary you need to use in your project.

Please see the API docs for extensive list of functions/subroutines.

Use any one of these methods to build Ffilesystem:

CMake:

cmake -B build
cmake --build build
# optional
ctest --test-dir build

The default library with CMake is static; to build shared library:

cmake -B build -DBUILD_SHARED_LIBS=on
...

Meson:

meson setup build
meson compile -C build
# optional
meson test -C build

The default library with Meson is shared; to build static library:

meson setup -Ddefault_library=static build
...

Fortran Package Manager (FPM):

fpm build

GNU Make:

make

We provide Fortran REPL "filesystem_cli" and C++ REPL "fs_cli" for interactive testing of Ffilesystem routines.

Build options

Fortran "filesystem" module contains OPTIONAL (enabled by default) Fortran type "path_t" that contains properties and methods. The "path_t" type uses getter and setter procedure to access the path as a string character(:), allocatable.

use filesystem, only : path_t

type(path_t) :: p

p = path_t("my/path")  !< setter

print *, "path: ", p%path() !< getter

The CMake and Meson scripts detect if Fortran 2003 type is available and enable path_t by default. To manually enable / disable path_t with CMake set command option cmake -DHAVE_F03TYPE=1 or cmake -DHAVE_F03TYPE=0 respectively.

By default stat() is used on non-Windows systems to get file information. On glibc systems, statx() may be used if available by setting build option

cmake -Dffilesystem_statx=true -Bbuild

# or

meson setup -Dstatx=true build

Self test

The optional self-tests provide reasonable coverage of the Ffilesystem library. Several of the tests use argv[0] as a test file. We are aware of the shortcomings of argv[0] to get the executable name. We provide the function fs_exepath() to get the executable path reliably.

Usage from other projects

The example directory contains a use pattern from external projects. One can either cmake --install build ffilesystem or use CMake ExternalProject or FetchContent from the other project. To find ffilesystem in your CMake project:

find_package(ffilesystem CONFIG REQUIRED)

CMake package variables ffilesystem_cpp and ffilesystem_fortran indicate whether ffilesystem was built with C++ <filesystem> and/or Fortran support.

ffilesystem.cmake would be included from the other project to find or build Ffilesystem automatically. It provides the appropriate imported targets for shared or static builds, including Windows DLL handling.

Notes

GCC 6.x and older aren't supported due to lack of C++17 string_view support.

Possible future features

Use statx() if available to inquire if a file is encrypted or compressed, etc.

Other C++ filesystem libraries

Ffilesystem emphasizes simplicity and reasonable performance and reliability for scientific computing, particularly on HPC systems. A highly performance-oriented C++ low-level no TOCTOU filesystem library is LLFIO.

Other implementations of C++ filesystem include:

Other Fortran filesystem libraries

Other Fortran libraries that provide interfaces to filesystems include the following. Generally they have noticeably fewer functions than Ffilesystem. They typically implement many functions in Fortran, where with Ffilesystem we implement in C++ or C++ <filesystem> if available. Ffilesystem Fortran code is optional, and is just a thin wrapper around the C++ functions.


There is no "is_musl()" function due to MUSL designers not providing a MUSL feature macro.

Windows long paths

Like Microsoft STL, Ffilesystem is not designed for UNC paths. We recommend using a UNC path to a mapped drive letter. Windows long paths are not implemented due to limitations.

C++ filesystem discussion

Security research led to TOCTOU-related patches to the C++ filesystem library in various C++ standard library implementations noted in that discussion. Ffilesystem does NOT use remove_all, which was the TOCTOU concern addressed above.

Since the underlying C++ filesystem is not thread-safe, race conditions can occur if multiple threads are accessing the same filesystem object regardless of the code language used in the Ffilesystem library.

About

Filesystem path manipulation Fortran library, based on C++17 filesystem with fallback to plain C++. For Linux, macOS, Windows.

Topics

Resources

License

Code of conduct

Stars

Watchers

Forks