Here is a shell script that I use to create a fortran file that has compile time information.
#!/bin/sh
# shell script to create a *.F90 file with embedded compile-time-environment information.
# output is written to stdout.
# usage: cte_mod.sh > cte_mod.F90
XgitX=`git log -1 --format=format:"%H"` # git hash for the current commit.
XdateX=`date`
XhostX=`hostname -s`
XunameX=`uname -sr` # -a is over 132 characters, so keep it short.
XuserX=`whoami`
XcolverX=`cat $COLUMBUS/doc/version`
cat <<EOF | sed \
-e s/XGITX/"$XgitX"/ \
-e s/XDATEX/"$XdateX"/ \
-e s/XHOSTX/"$XhostX"/ \
-e s/XUNAMEX/"$XunameX"/ \
-e s/XUSERX/"$XuserX"/ \
-e s/XCOLVERX/"$XcolverX"/
module cte_mod
! this module defines some compile time environment (cte) parameters.
use, intrinsic :: iso_fortran_env, only: compiler_version, compiler_options
implicit none
! the following constants are defined by the script cte_mod.sh.
character(len=*), parameter :: cte_git = 'XGITX' ! hash for the current git commit.
character(len=*), parameter :: cte_date = 'XDATEX' ! compile date and time.
character(len=*), parameter :: cte_host = 'XHOSTX' ! compile time hostname.
character(len=*), parameter :: cte_uname = 'XUNAMEX' ! OS info at compile time.
character(len=*), parameter :: cte_user = 'XUSERX' ! user name who compiled the code.
character(len=*), parameter :: cte_colver = 'XCOLVERX' ! COLUMBUS version.
#ifdef __INTEL_COMPILER
character(len=*), parameter :: cte_cver = 'ifort unknown version'
character(len=*), parameter :: cte_copt = 'ifort options unavailable'
#else
character(len=*), parameter :: cte_cver = compiler_version()
character(len=*), parameter :: cte_copt = compiler_options()
#endif
contains
subroutine cte_print( nlist )
! print out the entire list of cte* parameters to unit nlist.
implicit none
integer, intent(in) :: nlist
character(len=*), parameter :: cfmt='(2a)'
write(nlist,cfmt) 'cte_git = ', cte_git
write(nlist,cfmt) 'cte_date = ', cte_date
write(nlist,cfmt) 'cte_host = ', cte_host
write(nlist,cfmt) 'cte_uname = ', cte_uname
write(nlist,cfmt) 'cte_user = ', cte_user
write(nlist,cfmt) 'cte_colver = ', cte_colver
write(nlist,cfmt) 'cte_cver = ', cte_cver
write(nlist,cfmt) 'cte_copt = ', cte_copt
return
end subroutine cte_print
end module cte_mod
#ifdef EXE
! compile with -DEXE to create a stand-alone test program.
program cte_test
use, intrinsic :: iso_fortran_env, only: output_unit
use cte_mod
implicit none
call cte_print(output_unit)
end program cte_test
#endif
EOF
I use a makefile to create the file instead of fpm, but the same approach should also work there too. My makefle executes the command
cte_mod.sh > cte_mod.F90
In my case, I execute this command every time I create the executable by using a .PHONY target. I’m not sure how best to do that with fpm. Note that there is a little test driver program built into the cte.F90 file. Also note that the ifort compiler had a bug that prevented a couple of symbols from working, so there is a bypass. That bug might be fixed now, I don’t know.