#----------------------------------*-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-2023 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" ] && [ -n "$WM_PROJECT_DIR" ] then WM_DIR="$WM_PROJECT_DIR/wmake" fi [ -n "$WM_DIR" ] && export WM_DIR #------------------------------------------------------------------------------ # Check environment variables checkEnv() { local check failed # Possibly redundant check for WM_DIR for check in WM_PROJECT_DIR WM_DIR WM_OPTIONS do eval test -n "\$$check" || failed="$failed $check" done if [ -n "$failed" ] then echo "$Script error: OpenFOAM environment variable(s) not set" 1>&2 echo " $failed" 1>&2 exit 1 fi } # (api) from WM_DIR/rules/General/general # - extract WM_VERSION = OPENFOAM= getApiOpenFOAM() { local rulesFile="$WM_DIR/rules/General/general" local value if [ -n "$WM_DIR" ] && [ -f "$rulesFile" ] then value="$(sed -ne 's@^ *WM_VERSION *= *OPENFOAM=\([0-9][0-9]*\).*@\1@p' "$rulesFile" 2>/dev/null)" fi if [ -n "$value" ] then echo "$value" else echo "Could not extract OpenFOAM API value" 1>&2 return 1 fi } # Set FOAM_MODULE_PREFIX according to # - absolute/relative path # - predefined type (u,user | g,group | o,openfoam) setModulePrefix() { export FOAM_MODULE_PREFIX="$1" case "$FOAM_MODULE_PREFIX" in # Prefix: user (u | user) FOAM_MODULE_PREFIX="${FOAM_USER_LIBBIN%/*}" ;; # Prefix: group (g | group) FOAM_MODULE_PREFIX="${FOAM_SITE_LIBBIN%/*}" ;; # Prefix: openfoam (other) (o | openfoam) FOAM_MODULE_PREFIX="${FOAM_LIBBIN%/*}" ;; # Prefix: false | none (ie, 'disabled') (false | none) FOAM_MODULE_PREFIX=false ;; # Prefix: directory (absolute or relative) (*) : "${FOAM_MODULE_PREFIX:=/usr/local}" # Fallback (autoconf-like) # Require absolute path [ "${FOAM_MODULE_PREFIX#/}" != "${FOAM_MODULE_PREFIX}" ] || \ FOAM_MODULE_PREFIX="${PWD}/${FOAM_MODULE_PREFIX}" ;; esac # Avoid potential conflicts unset FOAM_MODULE_APPBIN FOAM_MODULE_LIBBIN echo "Module prefix = ${FOAM_MODULE_PREFIX:-[]}" 1>&2 } #------------------------------------------------------------------------------ # 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: # - FOAM_BUILDROOT, WM_PROJECT_DIR, WM_OPTIONS findObjectDir() { local project="$(expandPath "$WM_PROJECT_DIR")" local absdir="$(expandPath "${1:-.}")" local appDir relativeDir objectsDir # Treat project/ builds as out-of-source relativeDir="${absdir#${project}/}" if [ "$relativeDir" != "$absdir" ] then if [ -n "$FOAM_BUILDROOT" ] && [ -w "$FOAM_BUILDROOT" ] then objectsDir="${FOAM_BUILDROOT}/build/${WM_OPTIONS}/${relativeDir}" elif [ -w "$WM_PROJECT_DIR" ] then objectsDir="${WM_PROJECT_DIR}/build/${WM_OPTIONS}/${relativeDir}" fi fi # Default (local) build directory if [ -z "$objectsDir" ] then if [ -d "$absdir/Make" ] then objectsDir="${absdir}/Make/${WM_OPTIONS}" else relativeDir="$absdir" appDir=. [ -d Make ] || appDir=$(findTarget .) || exit 1 # Fatal absdir=$(expandPath "$appDir"/.) relativeDir="${relativeDir#${absdir}}" objectsDir="${appDir}/Make/${WM_OPTIONS}${relativeDir}" fi fi 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) # compile into MPI-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 # - targetType # # Requires that WM_MPLIB contain an "MPI" string # # Has very simple option handling (bool options only!) that allow # things like "wmakeLibMpi -debug -no-openmp" etc. # wmakeLibMpi() { local libName local wmakeCmd="wmake" # Very simple option handling (bool options only!) while [ "$#" -gt 0 ] do case "$1" in (- | --) # Stop option parsing shift break ;; (-*) # Any bool option wmakeCmd="$wmakeCmd $1" ;; (*) break # Done ;; esac shift done 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 "$wmakeCmd $targetType${targetType:+ }(mpi=$WM_MPLIB:$FOAM_MPI)" $wmakeCmd $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() { 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}/%%" } fi #------------------------------------------------------------------------------