ThirdPartyFunctions 12 KB
Newer Older
Henry's avatar
Henry committed
1
2
3
4
#---------------------------------*- sh -*-------------------------------------
# =========                 |
# \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
#  \\    /   O peration     |
5
#   \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
6
#    \\/     M anipulation  | Copyright (C) 2016-2017 OpenCFD Ltd.
Henry's avatar
Henry committed
7
8
#------------------------------------------------------------------------------
# License
Mark Olesen's avatar
Mark Olesen committed
9
10
#     This file is part of OpenFOAM, licensed under GNU General Public License
#     <http://www.gnu.org/licenses/>.
Henry's avatar
Henry committed
11
12
13
14
15
#
# File
#     etc/tools/ThirdPartyFunctions
#
# Description
16
#     Various functions used in building ThirdParty packages
Henry's avatar
Henry committed
17
18
19
20
21
#
#     Define the standard buildBASE and installBASE for the platform
#     Define WM_NCOMPPROCS always.
#------------------------------------------------------------------------------

22
23
# The normal locations for source, build and installation (prefix-dir)
sourceBASE=$WM_THIRD_PARTY_DIR
Henry's avatar
Henry committed
24
25
26
buildBASE=$WM_THIRD_PARTY_DIR/build/$WM_ARCH$WM_COMPILER
installBASE=$WM_THIRD_PARTY_DIR/platforms/$WM_ARCH$WM_COMPILER

27
unset BUILD_SUFFIX
28
29
30
31
32
33
34
35
#------------------------------------------------------------------------------
# Force use of gcc/g++
useGcc()
{
    export CC=gcc    # Use gcc/g++
    export CXX=g++
}

36
37
38
39
40
41
42
43
44
45
46
47
48
# Scan arguments for a '-gcc' option, forcing gcc/g++ when found
useGccFlag()
{
    for i
    do
        if [ "$i" = "-gcc" ]
        then
            useGcc
            break
        fi
    done
}

49
50
51
# Return <mpicc> by default or <mpiicc> if possible for INTELMPI.
# Cray doesn't have <mpicc>, but its <cc> manages mpi paths directly.
# NOTE: could further refine based on $CC or $WM_CC, but not yet needed
52
53
whichMpicc()
{
54
    local mpicc=$(command -v mpicc)
55
56
    case "$WM_MPLIB" in
    (INTELMPI)
57
58
59
60
        mpicc=$(command -v mpiicc)  # Intel <mpiicc> available?
        ;;
    (CRAY-MPI*)
        : ${mpicc:=cc}              # Cray <cc> if there is no <mpicc>
61
62
        ;;
    esac
63
    echo "${mpicc:-mpicc}"
64
65
}

66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#------------------------------------------------------------------------------
# Some functions as per OpenFOAM etc/config.sh/functions

unset -f _foamAddLib _foamAddMan _foamAddPath   # Get settings only
unset -f _foamEtc

# Source an etc file
_foamEtc()
{
    local file
    if [ $# -gt 0 ] && file=$($WM_PROJECT_DIR/bin/foamEtcFile "$@")
    then
        . $file
    fi
}

82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#------------------------------------------------------------------------------

#
# Set a suffix for the build
# - eg, for -mpi, or -mesa etc
#
setBuildSuffix()
{
    BUILD_SUFFIX="${1##-}"
    if [ -n "$BUILD_SUFFIX" ]
    then
        BUILD_SUFFIX="-${BUILD_SUFFIX}"
    else
        unset BUILD_SUFFIX
    fi
}


Henry's avatar
Henry committed
100
#
101
# Mostly building without wmake
Henry's avatar
Henry committed
102
# - disable wmakeScheduler variables
103
# - use max number of cores for building
Henry's avatar
Henry committed
104
105
#
unset WM_HOSTS WM_SCHEDULER
106
if [ -r /proc/cpuinfo ]
Henry's avatar
Henry committed
107
then
108
109
    WM_NCOMPPROCS=$(egrep "^processor" /proc/cpuinfo | wc -l)
else
Henry's avatar
Henry committed
110
111
    WM_NCOMPPROCS=1
fi
112
export WM_NCOMPPROCS
Henry's avatar
Henry committed
113
114
115


#
116
117
118
119
120
121
122
123
# If WM_CONTINUE_ON_ERROR not set activate the shell option "stop on error"
#
if [ -z "${WM_CONTINUE_ON_ERROR}" ]
then
    set -e
fi


124
125
126
127
128
129
130
131
132
133
134
# Report error and exit
die()
{
    exec 1>&2
    echo
    echo "Error: see '${0##*/} -help' for usage"
    while [ "$#" -ge 1 ]; do echo "    $1"; shift; done
    echo
    exit 1
}

135
136
137
138
139
140
141
142
143
144
145
146
147
# Test if it matches "*-none"
_foamIsNone()
{
    test "${1##*-}" = none
}

# Test if it matches "*-system"
_foamIsSystem()
{
    test "${1##*-}" = system
}


148
#
149
150
151
152
# Try to locate cmake according to the CMAKE_PATH.
#
# On success: return the resolved value as output.
# On failure: just report what is found in the path.
153
#
154
unset CMAKE_PATH # clear when first loaded
155
156
findCMake()
{
157
    local candidate foundExe
158
159
160

    if [ -n "$CMAKE_PATH" ]
    then
161
        # Check as directory
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
        if [ -d "$CMAKE_PATH" ]
        then
            for candidate in \
                $CMAKE_PATH/cmake \
                $CMAKE_PATH/bin/cmake \
            ;
            do
                if [ -f "$candidate" -a -x "$candidate" ]
                then
                    foundExe=$candidate
                    break
                fi
            done
        fi

177
        # Check as file, include ThirdParty installation in the search
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
        if [ -z "$foundExe" ]
        then
            for candidate in \
                $CMAKE_PATH \
                $installBASE/$CMAKE_PATH/bin/cmake \
                $installBASE/cmake-$CMAKE_PATH/bin/cmake \
            ;
            do
                if [ -f "$candidate" -a -x "$candidate" ]
                then
                    foundExe=$candidate
                    break
                fi
            done
        fi

        if [ -n "$foundExe" ]
        then
            # Use absolute path
            if [ "${foundExe#/}" = "$foundExe" ]
            then
                foundExe="$(cd ${foundExe%/cmake} 2>/dev/null && pwd)/cmake"
            fi
201
            echo "Using cmake=$foundExe" 1>&2
202
            echo $foundExe
203
204
205
206
207
208
209
210
211
212
            return 0
        else
            cat << NOT_FOUND 1>&2
'cmake' not found under specified CMAKE_PATH
    CMAKE_PATH=$CMAKE_PATH
reverting to using command from path
NOT_FOUND
        fi
    fi

213
214
215
216
    # Default to use the path. Resolve so we know what we are using.
    foundExe=$(command -v cmake 2> /dev/null) || foundExe=false
    echo "Using cmake=$foundExe" 1>&2
    echo $foundExe
217
218
219
220
221
}


#
# try to locate qmake according to the QMAKE_PATH
222
223
224
#
# On success: return the resolved value as output.
# On failure: just report what is found in the path.
225
#
226
unset QMAKE_PATH # clear when first loaded
227
228
findQtMake()
{
229
    local candidate foundExe
230
231
232

    if [ -n "$QMAKE_PATH" ]
    then
233
        # Check as directory
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
        if [ -d "$QMAKE_PATH" ]
        then
            for candidate in \
                $QMAKE_PATH/qmake \
                $QMAKE_PATH/bin/qmake \
            ;
            do
                if [ -f "$candidate" -a -x "$candidate" ]
                then
                    foundExe=$candidate
                    break
                fi
            done
        fi

249
        # Check as file, include ThirdParty installation in the search
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
        if [ -z "$foundExe" ]
        then
            for candidate in \
                $QMAKE_PATH \
                $installBASE/$QMAKE_PATH/bin/qmake \
                $installBASE/qt-$QMAKE_PATH/bin/qmake \
            ;
            do
                if [ -f "$candidate" -a -x "$candidate" ]
                then
                    foundExe=$candidate
                    break
                fi
            done
        fi

        if [ -n "$foundExe" ]
        then
            # Use absolute path
            if [ "${foundExe#/}" = "$foundExe" ]
            then
                foundExe="$(cd ${foundExe%/qmake} 2>/dev/null && pwd)/qmake"
            fi
273
            echo "Using qmake=$foundExe" 1>&2
274
            echo $foundExe
275
276
277
278
279
280
281
282
283
284
            return 0
        else
            cat << NOT_FOUND 1>&2
'qmake' not found under specified QMAKE_PATH
    QMAKE_PATH=$QMAKE_PATH
reverting to using command from path
NOT_FOUND
        fi
    fi

285
    # Default to use the path, try resolving (so we know what we are using)
286
287
288
    foundExe=$(command -v qmake 2> /dev/null) || foundExe=false
    echo "Using qmake=$foundExe" 1>&2
    echo $foundExe
289
290
291
}


292
#
293
# Set a new prefix=... in pkgconfig files
294
#
295
pkgconfigNewPrefix()
296
{
297
    local dir="${1%%/}"
298

299
    if [ -n "$dir" -a -d "$dir" ]
300
    then
301
302
303
304
305
306
307
308
309
310
311
312
313
314
        # Require absolute path, but use logical (not physical) location
        [ "${dir}" != "${dir#/}" ] || dir=$(cd $dir 2>/dev/null && /bin/pwd -L)
        # Strip sub-level
        case "$dir" in (*/pkgconfig) dir="${dir%/*}";; esac
        # Strip a level
        case "$dir" in (*/lib | */lib64 | */bin) dir="${dir%/*}";; esac
    fi

    # Verify that the prefix path is valid
    # Warning (not an error) - thus no special return code
    [ -n "$dir" -a -d "$dir" ] || {
        echo "Warning: invalid prefix directory: $dir" 1>&2
        return 0
    }
315

316
    echo "Set pkgconfig prefix : $dir"
317

318
319
320
321
322
323
    local nfiles
    for libdir in lib/pkgconfig lib64/pkgconfig
    do
        unset nfiles
        [ -d "$dir/$libdir" ] || continue
        for i in $dir/$libdir/*.pc
324
        do
325
            if [ -f "$i" -a ! -L "$i" ]
326
327
            then
                nfiles="x$nfiles"
328
                sed -i -e 's@^\(prefix=\).*$@\1'"$dir@" $i
329
330
            fi
        done
331
332
        echo "    $libdir/*.pc  (edited ${#nfiles})"
    done
333
334
335
336
}


#
337
338
339
340
341
# Adjust pkgconfig information to use '${prefix} where possible instead
# of directory paths.
#
# Adjusts includedir=, libdir=, -I/... and -L/... and
# any *_location= entries (QT)
342
343
344
#
pkgconfigAdjust()
{
345
    local dir="${1%%/}"
346

347
    if [ -n "$dir" -a -d "$dir" ]
348
    then
349
350
351
352
353
354
355
        # Require absolute path, but use logical (not physical) location
        [ "${dir}" != "${dir#/}" ] || dir=$(cd $dir 2>/dev/null && /bin/pwd -L)
        # Strip sub-level
        case "$dir" in (*/pkgconfig) dir="${dir%/*}";; esac
        # Strip a level
        case "$dir" in (*/lib | */lib64 | */bin) dir="${dir%/*}";; esac
    fi
356

357
358
359
360
361
362
    # Verify that the prefix path is valid
    # Warning (not an error) - thus no special return code
    [ -n "$dir" -a -d "$dir" ] || {
        echo "Warning: invalid prefix directory: $dir" 1>&2
        return 0
    }
363

364
365
366
367
368
369
370
371
    echo "Adjust pkgconfig locations : $dir"

    local nfiles
    for libdir in lib/pkgconfig lib64/pkgconfig
    do
        unset nfiles
        [ -d "$dir/$libdir" ] || continue
        for i in $dir/$libdir/*.pc
372
        do
373
            if [ -f "$i" -a ! -L "$i" ]
374
375
376
            then
                nfiles="x$nfiles"
                sed -i \
377
378
379
380
                    -e 's@^\(includedir=\)'"$dir/"'@\1${prefix}/@' \
                    -e 's@^\(libdir=\)'"$dir/"'@\1${prefix}/@'     \
                    -e 's@\(_location=\)'"$dir/"'@\1${prefix}/@'   \
                    -e 's@\(-[IL]\)'"$dir/"'@\1${prefix}/@g'       \
381
382
383
                    $i
            fi
        done
384
385
        echo "    $libdir/*.pc  (edited ${#nfiles})"
    done
386
387
388
}


389
390
#
# Download file $1 from url $2 into download/ directory
Henry's avatar
Henry committed
391
392
393
394
395
396
397
398
#
downloadFile()
{
    [ "$#" -eq 2 ] || {
        echo "downloadFile called with incorrect number of arguments $@"
        return 1
    }

399
400
    local file="$1"
    local url="$2"
Henry's avatar
Henry committed
401
402
403
404
405
406
407
408
409
410
411

    if [ ! -e download/$file ]
    then
        mkdir -p download
        echo "downloading $tarFile from $url"
        ( cd download && wget --no-check-certificate $url -O $file )
    fi
}


#
412
# Copy Make/{files,options} from etc/makeFiles/PACKAGE
Henry's avatar
Henry committed
413
414
#
# $1 = PACKAGE
415
# $2 = TARGET DIRECTORY (optional)
Henry's avatar
Henry committed
416
417
418
419
420
421
422
cpMakeFiles()
{
    [ "$#" -eq 1 -o "$#" -eq 2 ] || {
        echo "cpMakeFiles called with incorrect number of arguments $@"
        return 1
    }

423
424
    local pkg=$1
    local dst="${2:-.}"
Henry's avatar
Henry committed
425
426
    echo "cpMakeFiles" $pkg $dst

427
    wmakeFiles=$WM_THIRD_PARTY_DIR/etc/makeFiles/$pkg
Henry's avatar
Henry committed
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451

    for i in $(cd $wmakeFiles && find . -type f)
    do
        d=${i%/*}   # dirname
        b=${i##*/}   # basename

        mkdir -p $dst/$d/Make 2>/dev/null

        # NOTE the behaviour of '-nt' can cause problems
        #
        # - bash, ksh, /usr/bin/test
        #   True, if file1 exists and file2 does not
        #
        # - dash, zsh (and maybe others)
        #   False, if file1 or file2 does not exist
        #
        if [ ! -e $dst/$d/Make/$b -o $wmakeFiles/$i -nt $dst/$d/Make/$b ]
        then
            cp $wmakeFiles/$i $dst/$d/Make/$b
        fi
    done
}


452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
#
# Apply source-code patch if possible.
# Patches are taken from etc/patches/PACKAGE
#
# $1 = PACKAGE
# $2 = TARGET DIRECTORY (optional)
applyPatch()
{
    [ "$#" -eq 1 -o "$#" -eq 2 ] || {
        echo "applyPatch called with incorrect number of arguments ($#): $@"
        return 1
    }

    local pkg="$1"
    local dst="${2:-.}"

    local patch="$WM_THIRD_PARTY_DIR/etc/patches/$pkg"
    local sentinel="PATCHED_DURING_OPENFOAM_BUILD"

    if [ -r "$patch" ]
    then
    (
        cd $dst || exit 1
        if [ -f "$sentinel" ]
        then
            echo "patch for $pkg was already applied"
        else
            echo "apply patch for $pkg"
            touch "$sentinel"
481
            patch -b -l -p1 < $patch 2>&1 | tee $sentinel
482
483
484
485
486
487
488
        fi
    )
    else
        echo "no patch found for $pkg"
    fi
}

489
#------------------------------------------------------------------------------