#----------------------------------*-sh-*-------------------------------------- # ========= | # \\ / F ield | OpenFOAM: The Open Source CFD Toolbox # \\ / O peration | # \\ / A nd | www.openfoam.com # \\/ M anipulation | #------------------------------------------------------------------------------ # Copyright (C) 2015-2016 OpenFOAM Foundation # Copyright (C) 2018-2020 OpenCFD Ltd. #------------------------------------------------------------------------------ # License # This file is part of OpenFOAM, distributed under GPL-3.0-or-later. # # Script # wmakeFunctions # # Description # Support functions for wmake infrastructure. # For example, check environment, find .dep and .o files, various # wrappers when making libraries. # #------------------------------------------------------------------------------ # Ensure these variables are always defined MakeDir=Make : "${Script:=wmakeFunctions}" # Environment defaults if [ -z "$WM_DIR" ] then WM_DIR="$WM_PROJECT_DIR/wmake" export WM_DIR fi #------------------------------------------------------------------------------ # Check environment variables checkEnv() { local check failed # Default for WM_DIR already provided above for check in WM_PROJECT_DIR WM_OPTIONS do eval test -n "\$$check" || failed="$failed $check" done [ -z "$failed" ] || { echo "$Script error: Environment variable(s) not set" 1>&2 echo " $failed" 1>&2 exit 1 } } # Return the absolute (physical) path for a directory or # for a file's parent directory # expandPath dirName # expandPath fileName # # Output: # - the expanded path name expandPath() { if [ -d "$1" ] then (cd "$1" && pwd -P) elif [ -n "$1" ] then (cd $(dirname "$1") && pwd -P) else pwd -P fi } # Find the target directory, which contains a Make/ directory # search upwards in its parent directories, but stopping # when it hits the project root, home, or the file-system root # # findTarget dirName # # Output: # - the relative target directory # # Global variables used: # - WM_PROJECT_DIR, HOME findTarget() { local project=$(expandPath $WM_PROJECT_DIR) local home=$(expandPath $HOME) local reldir="${1:-.}" local absdir=$(expandPath $reldir) while [ -n "$absdir" ] do case "$absdir" in ($project | $home | /) break ;; esac if [ -d "$reldir/Make" ] then echo "$reldir" return 0 else # Check parent directory absdir="${absdir%/*}" reldir="$reldir/.." fi done echo "Error: no Make directory for $(expandPath $1)" 1>&2 echo 1>&2 return 1 } # Change to 'MakeDir' parent # - uses 'MakeDir' for its input # # Side-effects: # - unsets targetType cdSource() { local dir if [ ! -d "$MakeDir" ] then echo "$Script: '$MakeDir' directory does not exist in $PWD" 1>&2 echo " Searching up directories tree for Make directory" 1>&2 dir=$(findTarget .) || exit 1 # Fatal cd $dir 2>/dev/null || { echo "$Script error: could not change to directory '$dir'" 1>&2 exit 1 } unset targetType fi [ -r $MakeDir/files ] || { echo "$Script error: file '$MakeDir/files' does not exist in $PWD" 1>&2 exit 1 } } # Find the object directory # findObjectDir dirName # findObjectDir fileName # # Output: # - the objectsDir # # Global variables used: # - WM_PROJECT_DIR, WM_OPTIONS findObjectDir() { local project=$(expandPath $WM_PROJECT_DIR) local absdir=$(expandPath ${1:-.}) local objectsDir case "$absdir" in ("$project"/*) local buildPath=$WM_PROJECT_DIR/build/${WM_OPTIONS} objectsDir=$buildPath$(echo $absdir | sed s%$project%% ) ;; (*) local path=$absdir local appDir=. [ -d Make ] || appDir=$(findTarget .) || exit 1 # Fatal absdir=$(expandPath $appDir/.) objectsDir=$appDir/Make/${WM_OPTIONS}$(echo $path | sed s%$absdir%% ) ;; esac echo "$objectsDir" } # Find the object directory and remove it # removeObjectDir dirName # removeObjectDir fileName # # Output: # - NONE # # Global variables used: # - WM_PROJECT_DIR, WM_OPTIONS removeObjectDir() { local objectsDir=$(findObjectDir ${1:-.}) if [ -d "$objectsDir" ] then rm -rf "$objectsDir" 2>/dev/null fi } # Save build/configure parameter information (dependency) into sentinel file # # 1 - sentinelFile # 2... build/configure parameters # storeDependency() { local sentinel="$1" local depend shift if [ -n "$sentinel" ] then mkdir -p "$(dirname "$sentinel")" echo '# Build/configure parameters' >| "$sentinel" for depend do echo "-- $depend" done >> "$sentinel" fi return 0 } # Check sentinel file(s) to handle changed build/configure parameters # such as paraview / vtk version changes # # 1 - sourceDir # 2... build/configure parameters # # The additional test for "CMakeCache.txt" helps for cmake projects and # has no adverse affect for others # sameDependency() { local sourceDir="$1" shift local objectsDir local compare=0 # Where generated files are stored objectsDir=$(findObjectDir "$sourceDir") || exit 1 # Fatal local sentinel="$objectsDir/ConfigParameters" if [ -f "$sentinel" ] then # Create an .update version for comparison storeDependency "${sentinel}.update" $@ cmp "${sentinel}" "${sentinel}.update" >/dev/null 2>&1 compare=$? if [ "$compare" -ne 0 ] then echo "build/configure parameters changed between builds" 1>&2 ## cat "${sentinel}.update" 1>&2 fi else # No sentinel file: First time, or failed compilation? if [ -f "$objectsDir/CMakeCache.txt" ] then echo "previous build was incomplete" 1>&2 compare=1 fi fi echo "$sentinel" return "$compare" } # Build a mpi-versioned library (targetType) # - use sentinel file(s) to handle paraview version changes # compile into qualified directory # use sentinel file(s) to handle version changes # 1 - libName # 2... build/configure information # # Global variables used: # - WM_OPTIONS, WM_MPLIB, FOAM_MPI # # Requires that WM_MPLIB contain an "MPI" string wmakeLibMpi() { local libName="$1" shift case "$WM_MPLIB" in (*MPI* | *mpi*) ( WM_OPTIONS="$WM_OPTIONS$WM_MPLIB" # Where generated files are stored objectsDir="$(findObjectDir "$libName")" || exit 1 # Fatal # Something changed sentinel=$(sameDependency "$libName" "MPLIB=$WM_MPLIB" "MPI=$FOAM_MPI" $@) || \ wclean "$libName" echo "wmake $targetType $libName (mpi=$WM_MPLIB)" wmake $targetType "$libName" && \ storeDependency "$sentinel" "MPLIB=$WM_MPLIB" "MPI=$FOAM_MPI" $@ ) ;; esac } # Clean an mpi-versioned library # # Global variables used: # - WM_OPTIONS, WM_MPLIB # # Requires that WM_MPLIB contain an "MPI" string wcleanLibMpi() { case "$WM_MPLIB" in (*MPI* | *mpi*) ( WM_OPTIONS="$WM_OPTIONS$WM_MPLIB" for libName do wclean "$libName" done ) ;; esac } #------------------------------------------------------------------------------ # depToSource depFile # # Output: # - the sourceFile corresponding to depFile # # Global variables used: # - WM_OPTIONS # - WM_MPLIB if [ -n "$BASH_VERSION" ] then depToSource() { local sourceFile=${1%.dep} sourceFile="${sourceFile/build\/${WM_OPTIONS}\//}" sourceFile="${sourceFile/build\/${WM_OPTIONS}${WM_MPLIB}\//}" sourceFile="${sourceFile/Make\/${WM_OPTIONS}\//}" sourceFile="${sourceFile/Make\/${WM_OPTIONS}${WM_MPLIB}\//}" echo "$sourceFile" } else depToSource() { local sourceFile=$(echo ${1%.dep} | \ sed -e s%build/${WM_OPTIONS}/%% \ -e s%build/${WM_OPTIONS}${WM_MPLIB}/%% \ -e s%Make/${WM_OPTIONS}/%% \ -e s%Make/${WM_OPTIONS}${WM_MPLIB}/%% ) echo "$sourceFile" } fi #------------------------------------------------------------------------------