Here is a shell script that I use to put various compile time environment strings info into my codes.
#!/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
This script now assumes a git repository, but previous versions have used svn, cvs, etc. I also notice that this version sidesteps the ifort bug for the intrinsics compiler_version()
and compiler_options()
. I have not tested lately, maybe those are fixed now in newer ifort/ifx.
On unix/posix machines, if the script is called cte_mod.sh, then it is invoked as
cte_mod.sh > cte_mod.F90
The output is a fortran file that can be compiled and linked with your code. There is an embedded main program that can be activated with the preprocessor macro -DEXE that you can use to test the module; this creates a one-file stand-alone program.
This is part of a larger program system, so you should change the line that defines the XcolverX string to something else:
XcolverX='Insert String Here'
I normally use make to build the codes that use this module, so within Makefile I define cte_mod.o as a dependency, and cte_mod.F90 as a .PHONY target. This forces a new cte_mod.F90 to be created and compiled every time a code is built, so the info is never out of date or inconsistent.