Forgex v3.5: Moved CLI Tool to New Repository

Author: Amasaki Shinobu(雨崎しのぶ)

Twitter: @amasaki203

Posted on: 2024-09-02 JST

Abstract

Forgex—Fortran Regular Expression—version 3.5 has been released. In this release, Forgex command line tool (forgex-cli) has been moved to a new repository as Forgex-CLI on GitHub.

None of the Forgex APIs have changed.

Details

Source Code Bloat

Since the release of Forgex v3.2, the lines of code in the source files across the entire project have reached 9,000. Most of the increase comes from code that constructs the forgex-cli executable file, which is used for debugging, testing, and benchmarking. This has resulted in compilation times roughly twice as long as before. This situation is problematic for me as a developer and for most users who only need the library.

C code

Additionally, a module included in forgex-cli that measures execution time was also an issue. This module required different handling depending on the OS to achieve the time resolution needed for measurements. On Windows, it invokes system calls for high-resolution timing, but on other OSes, successful builds require the following stub code written in C.

// This file is a stub to building on Unix-like systems.
#if defined(_WIN32) || defined(_WIN64)
#else
#include <stdbool.h>
bool QueryPerformanceCounter(long long PerformanceCount_count) {
return false;
}
bool QueryPerformanceFrequency(long long Frequency_countPerSec) {
return false;
}
#endif

This required using system calls on Windows and corresponding stub functions with the same name on other systems, necessitating the use of the C preprocessor’s functionality. I tried to write the stub in Fortran to avoid relying on C code, but GNU Fortran compiler’s predefined macros provided insufficient for this purpose.

Below is a list of predefined macros provided by GNU Fortran v13.1.0 in MinGW-W64 on Windows 10:

PS> touch foo.f90
PS> gfortran -cpp -E -dM .\foo.f90
# 1 ".\\foo.f90"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 ".\\foo.f90"

#define __ATOMIC_ACQUIRE 2
#define __CHAR_BIT__ 8
#define __FLOAT_WORD_ORDER__ __ORDER_LITTLE_ENDIAN__
#define __ORDER_LITTLE_ENDIAN__ 1234
#define __ORDER_PDP_ENDIAN__ 3412
#define __GFC_REAL_10__ 1
#define __FINITE_MATH_ONLY__ 0
#define __GNUC_PATCHLEVEL__ 0
#define __GFC_INT_2__ 1
#define __SIZEOF_INT__ 4
#define __SIZEOF_POINTER__ 8
#define __GFORTRAN__ 1
#define __GFC_REAL_16__ 1
#define __STDC_HOSTED__ 0
#define __NO_MATH_ERRNO__ 1
#define __SIZEOF_FLOAT__ 4
#define __pic__ 1
#define _LANGUAGE_FORTRAN 1
#define __SIZEOF_LONG__ 4
#define __GFC_INT_8__ 1
#define _REENTRANT 1
#define __SIZEOF_SHORT__ 2
#define __GNUC__ 13
#define __SIZEOF_LONG_DOUBLE__ 16
#define __BIGGEST_ALIGNMENT__ 16
#define __ATOMIC_RELAXED 0
#define __GFC_INT_1__ 1
#define __ORDER_BIG_ENDIAN__ 4321
#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
#define __SIZEOF_SIZE_T__ 8
#define __PIC__ 1
#define __SIZEOF_DOUBLE__ 8
#define __ATOMIC_CONSUME 1
#define __GNUC_MINOR__ 1
#define __GFC_INT_16__ 1
#define __ATOMIC_SEQ_CST 5
#define __SIZEOF_LONG_LONG__ 8
#define __ATOMIC_ACQ_REL 4
#define __ATOMIC_RELEASE 3
#define __VERSION__ "13.1.0"

Unlike the C compiler, these macros (WIN32, WIN64, _WIN32, and _WIN64) are not defined in the Fortran compiler. Therefore, it is advisable not to use these macros to determine the OS. For more detailed information on preprocessor usage in Fortran, refer to Reference 3. The discussion in Reference 3 provided valuable insights for me.

My Decision

Due to the reasons mentioned above, I decided to move the Forgex command line tool to a separate repository. forgex-cli will now be provided at the following repository link:

https://github.com/ShinobuAmasaki/forgex-cli

This choice has the following advantages over providing command line tool bundled with Forgex:

  • It keeps the repository lightweight.
  • Users who don’t need the CLI tool need not compile its files.
  • It ensures that the only compiler required for the Forgex repository is Fortran.

However, there are also some disadvantages:

  • It is necessary to manage two repositories.
  • It takes more effort to synchronize source code during development.
  • The documentation of Forgex’s functionalities generated by FORD may become scattered.

After considering these issues, I have concluded that, for the time being, I will accept the disadvantages of the latter in favor of the benefits of the former.

It is possible to build the package for each OS using CMake functions or command line arguments of the Fortran Package Manager (FPM). However, from the viewpoint of providing libraries that can be easily used with FPM, I will opt for separate repositories, at least until FPM can provide platform-specific builds in a more transparent manner (i.e. by specifying them in the manifest file fpm.toml).

Conclusion

While it is a useful command line tool for my purposes, I have concluded that Forgex should not ship forgex-cli with its repository. The minimal amount of C code that was introduced in Forgex v3.2 has been relocated to Forgex-CLI, and Forgex is once again a pure Fortran repository. As the developer of both projects, I believe the benefits outweigh the extra effort required to maintain a separate repository.

References

  1. ShinobuAmasaki/forgex | GitHub.com
  2. ShinobuAmasaki/forgex-cli | GitHub.com
  3. Problem using ‘C’ preprocessor with gfortran | Fortran-lang Discourse