#!/bin/sh
#------------------------------------------------------------------------------
# ========= |
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
# \\ / O peration |
# \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
# \\/ M anipulation |
#-------------------------------------------------------------------------------
# License
# This file is part of OpenFOAM.
#
# OpenFOAM is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with OpenFOAM. If not, see .
#
# Script
# wmake
#
# Description
# General, easy to use make system for multi-platform development
# with support for local and network parallel compilation.
#
# This updated wmake supports out-of-tree object and dependency files to
# avoid the clutter which accumulates in the source-tree with the original
# wmake system. Now when building the OpenFOAM package both the object and
# dependency files are now located in a tree with the same structure as the
# source tree but in the platforms/$WM_OPTIONS sub-directory of
# $WM_PROJECT_DIR.
#
# When building user libraries and applications which are not located in the
# OpenFOAM source-tree the object and dependency files are located in a tree
# with the same structure as the source tree but in the Make/$WM_OPTIONS
# sub-directory.
#
# The disadvantage of the out-of-tree compilation is that the dependency
# files are harder to find but are sometimes useful to study which header
# files are included. For those who need access to the dependency files the
# new wdep script is provided to locate them. See the wdep script header or
# run:
# wdep -h
#
# See also
# wmakeLnInclude, wmakeLnIncludeAll, wdep, wrmdep, wrmo,
# wclean, wcleanPlatform, wcleanLnIncludeAll
#
#------------------------------------------------------------------------------
Script=${0##*/}
usage() {
exec 1>&2
while [ "$#" -ge 1 ]; do echo "$1"; shift; done
cat<&2
exit 1
}
done
# When compiling anything but a standalone exe WM_PROJECT and WM_PROJECT_DIR
# must be set
[ "$1" = exe -o \( "$WM_PROJECT" -a "$WM_PROJECT_DIR" \) ] || {
echo "$Script error:" 1>&2
echo " environment variable \$WM_PROJECT or " \
"\$WM_PROJECT_DIR not set" 1>&2
echo " while building project library" 1>&2
exit 1
}
#------------------------------------------------------------------------------
# Setup parallel compilation
#------------------------------------------------------------------------------
# Set WM_NCOMPPROCS automatically when both WM_HOSTS and WM_SCHEDULER are set
if [ -z "$WM_NCOMPPROCS" -a -n "$WM_HOSTS" -a -n "$WM_SCHEDULER" ]
then
WM_NCOMPPROCS=$(wmakeScheduler -count)
[ $? -eq 0 ] || unset WM_NCOMPPROCS
fi
if [ "$WM_NCOMPPROCS" ]
then
if [ "$WM_NCOMPPROCS" -gt 1 -a ! "$MAKEFLAGS" ]
then
lockDir=$HOME/.$WM_PROJECT/.wmake
if [ -d $lockDir ]
then
rm -f $lockDir/*
else
mkdir -p $lockDir
fi
make="$make --no-print-directory -j "$WM_NCOMPPROCS
fi
fi
#------------------------------------------------------------------------------
# Check arguments and change to the directory in which to run wmake
#------------------------------------------------------------------------------
unset dir targetType
MakeDir=Make
if [ $# -ge 1 ]
then
if [ -d "$1" ]
then
dir=$1
else
targetType=$1
fi
# Specified directory name:
[ $# -ge 2 ] && dir=$2
# Specified alternative name for the Make sub-directory:
[ $# -ge 3 ] && MakeDir=$3
if [ "$dir" ]
then
cd $dir 2>/dev/null || {
echo "$Script error: could not change to directory '$dir'" 1>&2
exit 1
}
fi
fi
#------------------------------------------------------------------------------
# Recurse the source tree to compile "all" targets
#------------------------------------------------------------------------------
if [ "$all" = "all" ]
then
if [ -e Allwmake ]
then
./Allwmake
exit $?
else
# Find all the sub-directories containing a 'Make' directory
FOAM_APPS=$(\
for d in *; \
do [ -d "$d" -a "$d" != Optional -a "$d" != Make ] \
&& echo "$d"; \
done | xargs \
)
if [ ! "$FOAM_APPS" = "" ]
then
# Compile all applications in sub-directories
$make ${WM_CONTINUE_ON_ERROR:+-k} \
-f $WM_DIR/makefiles/apps \
TARGET="$targetType" FOAM_APPS="$FOAM_APPS"
fi
# If the current directory contains a 'Make' directory continue
# otherwise exit
if [ ! -d $MakeDir ]
then
exit $?
fi
fi
fi
#------------------------------------------------------------------------------
# Search up the directory tree for the Make sub-directory,
# check the existance of the 'files' file and build there if present
#------------------------------------------------------------------------------
unset dir
expandPath()
{
dir=$(dirname $1)
cwd=$PWD
cd $dir
exPath=$PWD
cd $cwd
}
findTarget()
{
expandPath $1
if [ "$exPath" = "$WM_PROJECT_DIR" \
-o "$exPath" = "$HOME" \
-o "$exPath" = "/" \
]
then
echo "$Script error: could not find Make directory" 1>&2
elif [ -d "$1/Make" ]; then
echo " Found target directory " $1
dir=$1
else
findTarget "$1/.."
fi
}
if [ ! -d $MakeDir ]
then
echo "$Script: '$MakeDir' directory does not exist in $PWD" 1>&2
echo " Searching up directories tree for Make directory"
findTarget .
targetType=
if [ "$dir" ]
then
cd $dir 2>/dev/null || {
echo "$Script error: could not change to directory '$dir'" 1>&2
exit 1
}
fi
fi
[ -r $MakeDir/files ] || {
echo "$Script error: file '$MakeDir/files' does not exist in $PWD" 1>&2
exit 1
}
#------------------------------------------------------------------------------
# Transform options
#------------------------------------------------------------------------------
# Transform no option to "libso" if that looks appropriate or remove it
# so that the call to make builds the application
if [ "$targetType" = "" ]
then
unset targetType
if grep -e '^ *LIB *=' "$MakeDir/files" >/dev/null 2>&1
then
targetType=libso
fi
fi
#------------------------------------------------------------------------------
# Spawn a sub-shell and unset MAKEFLAGS in that sub-shell to avoid
# files and options being built in parallel
#------------------------------------------------------------------------------
objectsDir=$MakeDir/$WM_OPTIONS
if echo $PWD | grep "$WM_PROJECT_DIR"
then
platformPath=$WM_PROJECT_DIR/platforms/${WM_OPTIONS}
objectsDir=$platformPath$(echo $PWD | sed s%$WM_PROJECT_DIR%% )
fi
(
unset MAKEFLAGS
mkdir -p $objectsDir
# Pre-build the $WM_OPTIONS/options file
# which is included when building the $WM_OPTIONS/files file
$make -s -f $WM_DIR/makefiles/files MAKE_DIR=$MakeDir \
OBJECTS_DIR=$objectsDir $objectsDir/options
$make -s -f $WM_DIR/makefiles/files MAKE_DIR=$MakeDir \
OBJECTS_DIR=$objectsDir
)
#------------------------------------------------------------------------------
# Check the $objectsDir/sourceFiles file was created successfully
#------------------------------------------------------------------------------
[ -r $objectsDir/sourceFiles ] || {
echo "$Script error: file '$objectsDir/sourceFiles'" \
"could not be created in $PWD" 1>&2
exit 1
}
#------------------------------------------------------------------------------
# Make the dependency files
#------------------------------------------------------------------------------
# For libraries create lnInclude ...
case "$targetType" in
lib | libo | libso | dep )
# ... but only if 'LIB' is declared in 'Make/files'
if grep -e '^ *LIB *=' "$MakeDir/files" >/dev/null 2>&1
then
$make -s -f $WM_DIR/makefiles/general MAKE_DIR=$MakeDir \
OBJECTS_DIR=$objectsDir lnInclude
fi
;;
esac
#------------------------------------------------------------------------------
# Make the dependency files or object files and link
#------------------------------------------------------------------------------
exec $make -f $WM_DIR/makefiles/general MAKE_DIR=$MakeDir \
OBJECTS_DIR=$objectsDir $targetType
#------------------------------------------------------------------------------
# Cleanup local variables and functions
#------------------------------------------------------------------------------
unset Script usage expandPath findTarget
#------------------------------------------------------------------------------