This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch, libgfortran RFC] Installation script for OpenCoarrays to enable multi-image gfortran


The attached patch introduces an installation script and support structure to
build OpenCoarrays using mpich, allowing multi-image gfortran, (latest Fortran
standards).

This patch is preliminary and intended to allow testing and comments to start.

I would like to get this into gcc 7 release as a manually invoked script. Later,
in gcc 8, I would like to modify such that it is automatically invoked right
after gfortran and libgfortran are installed, ie end of make install. (assuming
this approach is acceptable to the community)

The manual script is invoked with libgfortran as the current working directory
and passing to it the location of the just installed gfortran installation
directory. This is done to ensure OpenCoarrays uses the just installed gfortran
and gcc for compilation. A typical invocation is:

	mk-multi-image/mk-multi-image.sh --install-prefix /home/jerry/dev/usr

At least on Fedora 25, one must use 'module load mpi' before invoking the script
to set things up to find an existing mpich installation. The intent will be to
build mpich if it is not found by the script.

The script uses portions of Bash 3 Boilerplate which are under MIT license.
These are separated out into the use-case subdirectory.

The OpenCoarrays tarball is downloaded from the github repository, sha256sum
checked, unpacked, and built in a temporary folder. The boiler plate provides
quite a few options for setting installation parameters.

The build requires cmake/make and runs tests using ctest. There are currently 4
coarray test failures that are known issues being actively worked.

The installation places libcaf_mpi.a in the install-prefix lib directory and
executables, caf and cafrun, in the bin directory.

TODO:

1. Change name of 'use-case' directory to 'utilities' to clarify its function.

2. Set tracked versus untracked downloads before release of the script.
Currently this is set to false to avoid artificially inflating download
statistics on github during testing. Simplify the code for this
tracked/untracked feature.

3. Move the usage text file into the 'utility' directory.

4. Address both lib and lib64 versions of the library and where they are installed.

5 Test and refine the finding and using/building mpich. We used mpich only as a
first implementation. Our intent will be to add other alternative communication
libraries in the future.  (Will be testing on a Cray machine and others as made
available)

4. Resolve any issues/comments identified during this RFC phase.

Your comments are welcome. This is a first step in full integration of
multi-image coarrays into gfortran.

Regards,

Jerry
diff --git a/libgfortran/mk-multi-image/mk-multi-image.sh b/libgfortran/mk-multi-image/mk-multi-image.sh
new file mode 100755
index 0000000..def8032
--- /dev/null
+++ b/libgfortran/mk-multi-image/mk-multi-image.sh
@@ -0,0 +1,246 @@
+#!/usr/bin/env bash
+
+#  Copyright (C) 2017 Free Software Foundation, Inc.
+#  Contributed by Jerry DeLisle in collaboration with Damian Rousan.
+#
+# This file is part of the GNU Fortran runtime library (libgfortran).
+#
+# Libgfortran 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, or (at your option)
+# any later version.
+
+# Libgfortran 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.
+
+# Under Section 7 of GPL version 3, you are granted additional
+# permissions described in the GCC Runtime Library Exception, version
+# 3.1, as published by the Free Software Foundation.
+
+# You should have received a copy of the GNU General Public License and
+# a copy of the GCC Runtime Library Exception along with this program;
+# see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+# mk-multi-image.sh
+#
+# --- This script downloads and installs OpenCoarrays to directly support mult-image 
+#     execution in libgfortran. Execute this script the last step of the libgfortran 
+#     make install.
+
+# Portions of this script derive from or call sub-scripts of BASH3 Boilerplate. See
+# the B3B_USE_CASE subdirectory for the substantial portions of the Software and the
+# required permission notices of the MIT License (MIT).
+
+
+export LIBGFORTRAN_SRC_DIR="${LIBGFORTRAN_SRC_DIR:-${PWD%/}}"
+if [[ ! -d "${LIBGFORTRAN_SRC_DIR}/caf" ]]; then
+  echo "File not found: ${LIBGFORTRAN_SRC_DIR}/caf"
+  echo "Please run this script inside the libgfortran source directory or "
+  echo "set LIBGFORTRAN_SRC_DIR to the libgfortran source directory path."
+  exit 1
+fi
+export B3B_USE_CASE="${B3B_USE_CASE:-${LIBGFORTRAN_SRC_DIR}/mk-multi-image/use-case}"
+if [[ ! -f "${B3B_USE_CASE:-}/bootstrap.sh" ]]; then
+  echo "Please set B3B_USE_CASE to the bash3boilerplate use-case directory path."
+  exit 2
+else
+  source "${B3B_USE_CASE}/bootstrap.sh" "$@"
+fi
+
+# Set expected value of present flags that take no arguments
+export __flag_present=1
+
+function cleanup_before_exit () {
+  info "Cleaning up. Done"
+}
+trap cleanup_before_exit EXIT # The signal is specified here. Could be SIGINT, SIGTERM etc.
+
+# Validation (decide what's required for running this script and error out)
+[ -z "${LOG_LEVEL:-}" ] && emergency "Cannot continue without LOG_LEVEL. "
+
+if [[ "${arg_D}" == "${__flag_present}" || "${arg_L}" == "${__flag_present}" || "${arg_P}" == "${__flag_present}" ||  "${arg_U}" == "${__flag_present}" || ${arg_V}"" == "${__flag_present}" ]]; then 
+   print_debug_only=7
+   if [ "$(( LOG_LEVEL < print_debug_only ))" -ne 0 ]; then
+     debug "Supressing info and debug messages: -v present."
+     export LOG_LEVEL=5
+   fi
+fi
+
+# Print bootstrapped magic variables to STDERR when LOG_LEVEL is at
+# the default value (6) or above. 'info' is a B3B defined function.
+{
+info "__file: ${__file}"
+info "__dir: ${__dir}"
+info "__base: ${__base}"
+info "__os: ${__os}"
+info "__usage: ${__usage}"
+info "LOG_LEVEL: ${LOG_LEVEL}"
+
+info  "-d (--debug):              ${arg_d}"
+info  "-D (--print-downloader):   ${arg_D}"
+info  "-e (--verbose):            ${arg_e}"
+info  "-h (--help):               ${arg_h}"
+info  "-i (--install-prefix):     ${arg_i}"
+info  "-j (--num-threads):        ${arg_j}"
+info  "-l (--comm-library):       ${arg_l}"
+info  "-L (--print-comm-library): ${arg_L}"
+info  "-n (--no-color):           ${arg_n}"
+info  "-P (--print-path):         ${arg_P}"
+info  "-U (--print-url):          ${arg_U}"
+info  "-v (--version):            ${arg_v}"
+info  "-V (--print-version):      ${arg_V}"
+}
+
+communication_library=${arg_l}
+opencoarrays_version=${arg_v}
+install_prefix="${arg_i}"
+
+debug "\${communication_library}=${communication_library}"
+debug "\${opencoarrays_version}=${opencoarrays_version}"
+debug "\${install_prefix}=${install_prefix}"
+
+# Set the variable 'fetch' to invoke an available downloader utility.
+source ${B3B_USE_CASE}/set_or_print_downloader.sh
+set_or_print_downloader
+
+# If one of the above --print-* arguments is present, we print its value and exit normally.
+# Here we print with echo instead of a B3B function because the output might be used in an 
+# assignment to a variable in another script e.g., version=`mk-multi-image.sh -V`
+if [[ "${arg_V}" == "${__flag_present}" ]]; then
+  echo "${opencoarrays_version}"
+  exit 0
+fi
+if [[ "${arg_P}" == "${__flag_present}" ]]; then
+  echo "${install_prefix}"
+  exit 0
+fi
+if [[ "${arg_U}" == "${__flag_present}" ]]; then
+  echo "${opencoarrays_url}"
+  exit 0
+fi
+if [[ "${arg_L}" == "${__flag_present}" ]]; then
+  echo "${communication_library}"
+  exit 0
+fi
+if [[ "${arg_D}" == "${__flag_present}" ]]; then
+  echo "${fetch}"
+  exit 0
+fi
+
+compile="${1:-}"
+
+# Check to see if this script has been previously run by checking for the
+# directory ../libgfortran/caf/multi .
+if [[ -d caf/multi ]]; then
+  info "Changing directory to caf/multi"
+  cd caf/multi
+  info "Skipping build: caf/multi already exists."
+  # TODO: Add checks on downloaded files and whether already built
+  ls -a
+else
+  # caf/multi is a working directory into which source files will be
+  # downloaded and shasum signature checked before building.
+  info "caf/multi not found"
+  mkdir -p caf/multi
+  cd caf/multi
+  info "Created caf/multi."
+  # Set to true just before releasing (false avoids inflating
+  # OpenCoarrays download statistics)
+  tracked_download="false"
+  if [[ ${tracked_download} == "true"  ]]; then
+    tar_ball_prefix="OpenCoarrays-"
+    opencoarrays_tar_ball=${tar_ball_prefix:-}${opencoarrays_version}.tar.gz
+    opencoarrays_url=https://github.com/sourceryinstitute/opencoarrays/releases/download/${opencoarrays_version}/$opencoarrays_tar_ball
+  else
+    opencoarrays_tar_ball=${tar_ball_prefix:-}${opencoarrays_version}.tar.gz
+    opencoarrays_url=https://github.com/sourceryinstitute/opencoarrays/archive/$opencoarrays_tar_ball
+  fi
+
+  info "Downloading OpenCoarrays with the following command:"
+  info "${fetch} ${fetch_args[@]:-} \"${opencoarrays_url}\""
+  ${fetch} ${fetch_args[@]:-} "${opencoarrays_url}" 
+  if [[ ! -f ${opencoarrays_tar_ball} ]]; then
+    emergency "Downloaded file not found: ${opencoarrays_version}.tar.gz"
+  fi
+
+  # Get the signature file for verification of the tar ball.
+  if [[ $tracked_download == "true" ]]; then
+    digital_signature=opencoarrays-${opencoarrays_version}-SHA256.txt
+    digital_signature_url=https://github.com/sourceryinstitute/opencoarrays/releases/download/${opencoarrays_version}/"$digital_signature";
+    info "Downloading the digital signature with the following command:"
+    info "${fetch} ${fetch_args[@]:-} \"${digital_signature_url}\""
+    ${fetch} ${fetch_args[@]:-} "${digital_signature_url}"
+    sha256sum -c "$digital_signature" || emergency "Invalid digital signature"
+    if [[ ! -f "${digital_signature}" ]]; then
+      emergency "Downloaded file not found: ${digital_signature}"
+    fi
+  fi
+
+  # At this point we have a clean download, extract it.
+  info "Unpacking OpenCoarrays with the following command:"
+  info "tar xvzf ${tar_ball_prefix:-}${opencoarrays_version}.tar.gz"
+  if [[ $tracked_download == "true" ]]; then
+    tar -xvzf ${tar_ball_prefix:-}${opencoarrays_version}.tar.gz
+  else
+    tar -xvzf ${opencoarrays_version}.tar.gz
+  fi
+
+  # Confirm that it extracted ito the expected sub-directory and go
+  # there.
+  if [[ $tracked_download == "true" ]]; then
+    echo ping
+    if [[ ! -d OpenCoarrays-${opencoarrays_version} ]]; then
+      emergency "Uncompressed directory not found: OpenCoarrays-${opencoarrays_version}"
+    fi
+    cd OpenCoarrays-${opencoarrays_version}
+  else
+    echo pong
+    if [[ ! -d opencoarrays-${opencoarrays_version} ]]; then
+      emergency "Uncompressed directory not found: opencoarrays-${opencoarrays_version}"
+    fi
+    cd opencoarrays-${opencoarrays_version}
+  fi
+
+  # Create a directory to build in and go there.
+  if [[ -d build ]]; then
+    rm -rf build
+  fi
+  mkdir -p build
+  cd build
+  pwd
+
+  # Look for an installed mpich package. Some users may need to
+  # use 'module load mpi' or similar before invoking this script.
+  if ! type mpif90 >& /dev/null; then
+    info "mpif90 not found. Attempting to install MPICH"
+    ./install.sh --package mpich
+  fi
+  if ! type cmake >& /dev/null; then
+    info "cmake not found. Attempting to install CMake"
+    ./install.sh --package cmake
+    CMAKE=`./install.sh --print-path cmake`/bin/cmake
+  else
+    CMAKE=cmake
+  fi
+
+  # The user must ensure the desired or just-built gcc and gfortran
+  # reside in the directory specified by ${install_prefix}. Invoke cmake
+  # to build OpenCoarrays.
+  CC="${install_prefix}"/bin/gcc FC="${install_prefix}"/bin/gfortran "$CMAKE" .. -DCMAKE_INSTALL_PREFIX=${install_prefix}
+  num_threads=$arg_j
+  make -j ${num_threads}
+
+  # Run tests ...
+  ctest || true
+  
+  # Install. This will place lib_caf.a in the install_prefix/lib
+  # directory and the executables, caf and cafrun, in install_prefix/bin. 
+  source "${B3B_USE_CASE}"/set_SUDO_if_needed_to_write_to_directory.sh
+  set_SUDO_if_needed_to_write_to_directory "${install_prefix}"
+  ${SUDO:-} make install
+fi
+
+# End of mk-multi-image.sh
diff --git a/libgfortran/mk-multi-image/mk-multi-image.sh-usage b/libgfortran/mk-multi-image/mk-multi-image.sh-usage
new file mode 100644
index 0000000..2c83a41
--- /dev/null
+++ b/libgfortran/mk-multi-image/mk-multi-image.sh-usage
@@ -0,0 +1,13 @@
+  -d --debug                 Enable debug mode.
+  -D --print-downloader      Print download program to be used on this platform.
+  -e --verbose               Enable verbose mode, print script as it is executed.
+  -h --help                  Print this page.
+  -i --install-prefix [arg]  Install OpenCoarrays in specified path. Default="${PWD}"
+  -j --num-threads [arg]     Number of threads to use when invoking make. Default="1"
+  -n --no-color              Disable color output.
+  -P --print-path            Print installation directory for specified package.
+  -U --print-url             Print the URL for specified package.
+  -v --install-version [arg] Install OpenCoarrays version. Default="1.8.2"
+  -V --print-version         Print default OpenCoarrays version number.
+  -L --print-commlibrary     Print the chosen communicaiton library. 
+  -l --comm-library [arg]    Set communication library. Default="mpich"
diff --git a/libgfortran/mk-multi-image/use-case/LICENSE b/libgfortran/mk-multi-image/use-case/LICENSE
new file mode 100644
index 0000000..c12d473
--- /dev/null
+++ b/libgfortran/mk-multi-image/use-case/LICENSE
@@ -0,0 +1,35 @@
+# The MIT License (MIT)
+#
+# Copyright (c) 2014 Kevin van Zonneveld
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+#
+#  - https://github.com/kvz/bash3boilerplate
+#  - http://kvz.io/blog/2013/02/26/introducing-bash3boilerplate/
+#
+# Version: 2.0.0
+#
+# Authors:
+#
+#  - Kevin van Zonneveld (http://kvz.io)
+#  - Izaak Beekman (https://izaakbeekman.com/)
+#  - Alexander Rathai (Alexander.Rathai@gmail.com)
+#  - Dr. Damian Rouson (http://www.sourceryinstitute.org/) (documentation)
+#
diff --git a/libgfortran/mk-multi-image/use-case/bootstrap.sh b/libgfortran/mk-multi-image/use-case/bootstrap.sh
new file mode 100755
index 0000000..1b7fd85
--- /dev/null
+++ b/libgfortran/mk-multi-image/use-case/bootstrap.sh
@@ -0,0 +1,41 @@
+#!/usr/bin/env bash
+# BASH3 Boilerplate
+#
+#  bootstrap.sh
+#
+#  - Exports bash3boilerplate features and variables to the invoking script
+#  - Invokes functions containing commands extracted from the bash3boilerplate
+#    main.sh as part of a refactoring to facilitate wholesale reuse of main.sh's
+#    contents of without modification.
+#
+# Usage (as invoked in my-script.sh):
+#
+#   source bootstrap.sh "${@}"
+#
+# More info:
+#
+#  - https://github.com/kvz/bash3boilerplate
+#  - http://kvz.io/blog/2013/02/26/introducing-bash3boilerplate/
+#
+# Version: 2.1.0
+#
+# Authors:
+#
+#  - Kevin van Zonneveld (http://kvz.io)
+#  - Izaak Beekman (https://izaakbeekman.com/)
+#  - Alexander Rathai (Alexander.Rathai@gmail.com)
+#  - Dr. Damian Rouson (http://www.sourceryinstitute.org/) (documentation)
+#
+# Licensed under MIT
+# Copyright (c) 2013 Kevin van Zonneveld (http://kvz.io)
+
+# shellcheck source=./set_environment_and_color.sh
+source "${B3B_USE_CASE}"/set_environment_and_color.sh         # turn on errexit, nounset, pipefail, default log level
+# shellcheck source=./set_magic_variables.sh
+source "${B3B_USE_CASE}"/set_magic_variables.sh "$(caller 0)" # set __dir, __file, __filename, __base, __os
+# shellcheck source=./define_functions.sh
+source "${B3B_USE_CASE}"/define_functions.sh                  # help/usage function and debug/info output functions
+# shellcheck source=./parse_command_line.sh
+source "${B3B_USE_CASE}"/parse_command_line.sh "${@:-}"       # parse the command line
+# shellcheck source=./set_common_switches.sh
+source "${B3B_USE_CASE}"/set_common_switches.sh               # provide defaults for -h, -V, and -d
diff --git a/libgfortran/mk-multi-image/use-case/define_functions.sh b/libgfortran/mk-multi-image/use-case/define_functions.sh
new file mode 100644
index 0000000..48d94bd
--- /dev/null
+++ b/libgfortran/mk-multi-image/use-case/define_functions.sh
@@ -0,0 +1,105 @@
+# BASH3 Boilerplate
+#
+#  define_functions.sh
+#
+#  - Defines helper functions containing commands extracted from the
+#    bash3boilerplate main.sh as part of a refactoring to facilitate
+#    wholesale reuse of main.sh's contents of without modification.
+#
+# Usage (as invoked in bootstrap.sh):
+#
+#   source define_functions.sh
+#
+# More info:
+#
+#  - https://github.com/kvz/bash3boilerplate
+#  - http://kvz.io/blog/2013/02/26/introducing-bash3boilerplate/
+#
+# Version: 2.0.0
+#
+# Authors:
+#
+#  - Kevin van Zonneveld (http://kvz.io)
+#  - Izaak Beekman (https://izaakbeekman.com/)
+#  - Alexander Rathai (Alexander.Rathai@gmail.com)
+#  - Dr. Damian Rouson (http://www.sourceryinstitute.org/) (documentation)
+#
+#
+# Licensed under MIT
+# Copyright (c) 2013 Kevin van Zonneveld (http://kvz.io)
+
+### Functions
+#####################################################################
+
+# shellcheck disable=SC2034
+function _fmt ()      {
+  local color_debug="\x1b[35m"
+  local color_info="\x1b[32m"
+  local color_notice="\x1b[34m"
+  local color_warning="\x1b[33m"
+  local color_error="\x1b[31m"
+  local color_critical="\x1b[1;31m"
+  local color_alert="\x1b[1;33;41m"
+  local color_emergency="\x1b[1;4;5;33;41m"
+  local colorvar=color_$1
+
+  local color="${!colorvar:-$color_error}"
+  local color_reset="\x1b[0m"
+  if [ "${NO_COLOR}" = "true" ] || [[ "${TERM:-}" != "xterm"* ]] || [ -t 1 ]; then
+    # Don't use colors on pipes or non-recognized terminals
+    color=""; color_reset=""
+  fi
+  echo -e "$(date -u +"%Y-%m-%d %H:%M:%S UTC") ${color}$(printf "[%9s]" "${1}")${color_reset}";
+}
+
+# The block of single-line functions below all print to STDERR,
+# leaving STDOUT for piping machine readable information to other
+# software. Above each such function is a commented demonstration
+# of its usage.  Execution continues after an invocation of each
+# function, except the "emergency" function, which causes
+# termination with a non-zero exit status.
+
+# shellcheck disable=SC2015
+{
+# emergency "A \"panic\" condition usually affecting multiple apps/servers/sites. At this level it would usually notify all tech staff on call."
+function emergency () {                             echo "$(_fmt emergency) ${*}" 1>&2 || true; exit 1; }
+# alert "Should be corrected immediately, therefore notify staff who can fix the problem. An example would be the loss of a primary ISP connection."
+function alert ()     { [ "${LOG_LEVEL}" -ge 1 ] && echo "$(_fmt alert) ${*}" 1>&2 || true; }
+# critical "Should be corrected immediately, but indicates failure in a primary system, an example is a loss of a backup ISP connection."
+function critical ()  { [ "${LOG_LEVEL}" -ge 2 ] && echo "$(_fmt critical) ${*}" 1>&2 || true; }
+# error "Non-urgent failures, these should be relayed to developers or admins; each item must be resolved within a given time."
+function error ()     { [ "${LOG_LEVEL}" -ge 3 ] && echo "$(_fmt error) ${*}" 1>&2 || true; }
+# warning "Warning messages, not an error, but indication that an error will occur if action is not taken, e.g. file system 85% full - each item must be resolved within a given time. This is a debug message"
+function warning ()   { [ "${LOG_LEVEL}" -ge 4 ] && echo "$(_fmt warning) ${*}" 1>&2 || true; }
+# notice "Events that are unusual but not error conditions - might be summarized in an email to developers or admins to spot potential problems - no immediate action required."
+function notice ()    { [ "${LOG_LEVEL}" -ge 5 ] && echo "$(_fmt notice) ${*}" 1>&2 || true; }
+# info "Normal operational messages - may be harvested for reporting, measuring throughput, etc. - no action required."
+function info ()      { [ "${LOG_LEVEL}" -ge 6 ] && echo "$(_fmt info) ${*}" 1>&2 || true; }
+# debug "Info useful to developers for debugging the application, not useful during operations."
+function debug ()     { [ "${LOG_LEVEL}" -ge 7 ] && echo "$(_fmt debug) ${*}" 1>&2 || true; }
+}
+function suppress_debug_messages() { export LOG_LEVEL=6; }
+function suppress_info_debug_messages () { export LOG_LEVEL=5; }
+function suppress_notice_info_debug_messages () { export LOG_LEVEL=4; }
+
+function help () {
+  echo "" 1>&2
+  echo " ${*}" 1>&2
+  echo "" 1>&2
+  # shellcheck disable=SC2154
+  cat "${__usage}" 1>&2
+  echo "" 1>&2
+  exit 1
+}
+export -f help
+export -f emergency
+export -f alert
+export -f critical
+export -f error
+export -f warning
+export -f notice
+export -f info
+export -f debug
+export suppress_debug_messages
+export suppress_info_debug_messages
+export suppress_notice_info_debug_messages
diff --git a/libgfortran/mk-multi-image/use-case/parse_command_line.sh b/libgfortran/mk-multi-image/use-case/parse_command_line.sh
new file mode 100644
index 0000000..5aad347
--- /dev/null
+++ b/libgfortran/mk-multi-image/use-case/parse_command_line.sh
@@ -0,0 +1,127 @@
+# BASH3 Boilerplate
+#
+#  parse_command_line.sh
+#
+#  - Uses usage information defined in "${__usage}" to parse the command line.
+#  - Defines a function containing commands extracted from the bash3boilerplate
+#    main.sh as part of a refactoring to facilitate wholesale reuse of main.sh's
+#    contents of without modification.
+#
+# More info:
+#
+#  - https://github.com/kvz/bash3boilerplate
+#  - http://kvz.io/blog/2013/02/26/introducing-bash3boilerplate/
+#
+# Version: 2.0.0
+#
+# Authors:
+#
+#  - Kevin van Zonneveld (http://kvz.io)
+#  - Izaak Beekman (https://izaakbeekman.com/)
+#  - Alexander Rathai (Alexander.Rathai@gmail.com)
+#  - Dr. Damian Rouson (http://www.sourceryinstitute.org/) (documentation)
+#
+# Usage (as invoked in bootstraph.sh):
+#
+#   source parse_command_line.sh
+#   parse_command_line ${@:2}
+#
+# Licensed under MIT
+# Copyright (c) 2013 Kevin van Zonneveld (http://kvz.io)
+
+### Parse commandline options
+#####################################################################
+function parse_command_line(){
+# source this script and pass $@ as the argument
+
+# Translate usage string -> getopts arguments, and set $arg_<flag> defaults
+# shellcheck disable=SC2154
+while read -r line; do
+  # fetch single character version of option string
+  opt="$(echo "${line}" |awk '{print $1}' |sed -e 's#^-##')"
+
+  # fetch long version if present
+  long_opt="$(echo "${line}" |awk '/\-\-/ {print $2}' |sed -e 's#^--##')"
+  long_opt_mangled="$(sed 's#-#_#g' <<< "$long_opt")"
+
+  # map long name back to short name
+  varname="short_opt_${long_opt_mangled}"
+  eval "${varname}=\"${opt}\""
+
+  # check if option takes an argument
+  varname="has_arg_${opt}"
+  if ! echo "${line}" |egrep '\[.*\]' >/dev/null 2>&1; then
+    init="0" # it's a flag. init with 0
+    eval "${varname}=0"
+  else
+    opt="${opt}:" # add : if opt has arg
+    init=""  # it has an arg. init with ""
+    eval "${varname}=1"
+  fi
+  opts="${opts:-}${opt}"
+
+  varname="arg_${opt:0:1}"
+  if ! echo "${line}" |egrep '\. Default=' >/dev/null 2>&1; then
+    eval "${varname}=\"${init}\""
+  else
+    match="$(sed 's#^.*Default=\(\)#\1#g' <<< "${line}")"
+    eval "${varname}=\"${match}\""
+  fi
+done < "${__usage}"
+
+
+# Allow long options like --this
+opts="${opts}-:"
+
+# Reset in case getopts has been used previously in the shell.
+OPTIND=1
+
+# start parsing command line
+set +o nounset # unexpected arguments will cause unbound variables
+               # to be dereferenced
+# Overwrite $arg_<flag> defaults with the actual CLI options
+while getopts "${opts}" opt; do
+  [ "${opt}" = "?" ] && help "Invalid use of script: ${*} "
+
+  if [ "${opt}" = "-" ]; then
+    # OPTARG is long-option-name or long-option=value
+    if [[ "${OPTARG}" =~ .*=.* ]]; then
+      # --key=value format
+      long=${OPTARG/=*/}
+      long_mangled="$(sed 's#-#_#g' <<< "$long")"
+      # Set opt to the short option corresponding to the long option
+      eval "opt=\"\${short_opt_${long_mangled}}\""
+      OPTARG=${OPTARG#*=}
+    else
+      # --key value format
+      # Map long name to short version of option
+      long_mangled="$(sed 's#-#_#g' <<< "$OPTARG")"
+      eval "opt=\"\${short_opt_${long_mangled}}\""
+      # Only assign OPTARG if option takes an argument
+      eval "OPTARG=\"\${@:OPTIND:\${has_arg_${opt}}}\""
+      # shift over the argument if argument is expected
+      ((OPTIND+=has_arg_${opt}))
+    fi
+    # we have set opt/OPTARG to the short value and the argument as OPTARG if it exists
+  fi
+  varname="arg_${opt:0:1}"
+  default="${!varname}"
+
+  value="${OPTARG}"
+  if [ -z "${OPTARG}" ] && [ "${default}" = "0" ]; then
+    value="1"
+  fi
+
+  eval "${varname}=\"${value}\""
+  debug "cli arg ${varname} = ($default) -> ${!varname}"
+done
+
+set -o nounset # no more unbound variable references expected
+
+shift $((OPTIND-1))
+
+# shellcheck disable=SC2015
+[ "${1:-}" = "--" ] && shift || true
+}
+export -f parse_command_line # make function available to subshells
+parse_command_line "${@:-}"  # invoke parsing function and allow for empty argument list
diff --git a/libgfortran/mk-multi-image/use-case/set_SUDO_if_needed_to_write_to_directory.sh b/libgfortran/mk-multi-image/use-case/set_SUDO_if_needed_to_write_to_directory.sh
new file mode 100644
index 0000000..5218211
--- /dev/null
+++ b/libgfortran/mk-multi-image/use-case/set_SUDO_if_needed_to_write_to_directory.sh
@@ -0,0 +1,34 @@
+# Define the sudo command to be used if the installation path requires administrative permissions
+set_SUDO_if_needed_to_write_to_directory()
+{
+  if [[ $# != "1" ]]; then
+    emergency "set_SUDO_if_needed_to_write_to_directory takes exactly one argument"
+  else
+    directory_to_create=$1
+  fi
+  if [[ -z "${LD_LIBRARY_PATH:-}" ]]; then
+     info "\${LD_LIBRARY_PATH} is empty. Try setting it if the compiler encounters linking problems."
+  fi
+  SUDO_COMMAND="sudo env LD_LIBRARY_PATH=${LD_LIBRARY_PATH:-} PATH=${PATH:-}"
+  info "Checking whether the directory ${directory_to_create} exists... "
+  if [[ -d "${directory_to_create}" ]]; then
+    info "yes"
+    info "Checking whether I have write permissions to ${directory_to_create} ... "
+    if [[ -w "${directory_to_create}" ]]; then
+      info "yes"
+    else
+      info "no"
+      SUDO="${SUDO_COMMAND}"
+    fi
+  else
+    info "no"
+    info "Checking whether I can create ${directory_to_create} ... "
+    if mkdir -p "${directory_to_create}" >& /dev/null; then
+      info "yes."
+    else
+      info "no."
+      # shellcheck disable=SC2034
+      SUDO="${SUDO_COMMAND}"
+    fi
+  fi
+}
diff --git a/libgfortran/mk-multi-image/use-case/set_common_switches.sh b/libgfortran/mk-multi-image/use-case/set_common_switches.sh
new file mode 100644
index 0000000..4271ff7
--- /dev/null
+++ b/libgfortran/mk-multi-image/use-case/set_common_switches.sh
@@ -0,0 +1,52 @@
+# BASH3 Boilerplate
+#
+#  set_common_switches.sh
+#
+#  - Sets variables that are useful in conjunction with other bash3boilerplate features
+#  - Contains commands extracted from the bash3boilerplate main.sh as part of a refactoring
+#    to facilitate wholesale reuse of main.sh's contents of without modification.
+#
+# Usage (as invoked in bootstrap.sh):
+#
+#  source set_common_switches.sh
+#
+# More info:
+#
+#  - https://github.com/kvz/bash3boilerplate
+#  - http://kvz.io/blog/2013/02/26/introducing-bash3boilerplate/
+#
+# Version: 2.0.0
+#
+# Authors:
+#
+#  - Kevin van Zonneveld (http://kvz.io)
+#  - Izaak Beekman (https://izaakbeekman.com/)
+#  - Alexander Rathai (Alexander.Rathai@gmail.com)
+#  - Dr. Damian Rouson (http://www.sourceryinstitute.org/) (documentation)
+#
+# Licensed under MIT
+# Copyright (c) 2013 Kevin van Zonneveld (http://kvz.io)
+
+### Switches (like -d for debugmode, -h for showing helppage)
+#####################################################################
+
+# shellcheck disable=SC2154
+{
+# debug mode
+if [ "${arg_d}" = "1" ]; then
+  set -o xtrace
+  LOG_LEVEL="7"
+  export LOG_LEVEL
+fi
+
+# verbose mode
+if [ "${arg_e}" = "1" ]; then
+  set -o verbose
+fi
+
+# help mode
+if [ "${arg_h}" = "1" ]; then
+  # Help exists with code 1
+  help "Help using ${0}"
+fi
+}
diff --git a/libgfortran/mk-multi-image/use-case/set_environment_and_color.sh b/libgfortran/mk-multi-image/use-case/set_environment_and_color.sh
new file mode 100644
index 0000000..40a413b
--- /dev/null
+++ b/libgfortran/mk-multi-image/use-case/set_environment_and_color.sh
@@ -0,0 +1,44 @@
+# BASH3 Boilerplate
+#
+#  set_environment_and_color.sh
+#
+#  - Sets variables that control the behavior of the invoking script.
+#  - Contains commands extracted from the bash3boilerplate main.sh as
+#    part of a refactoring to facilitate wholesale reuse of main.sh's
+#    contents of without modification.
+#
+# Usage (as invoked in bootstrap.sh):
+#
+#  source set_environment_and_color.sh
+#
+# More info:
+#
+#  - https://github.com/kvz/bash3boilerplate
+#  - http://kvz.io/blog/2013/02/26/introducing-bash3boilerplate/
+#
+# Version: 2.0.0
+#
+# Authors:
+#
+#  - Kevin van Zonneveld (http://kvz.io)
+#  - Izaak Beekman (https://izaakbeekman.com/)
+#  - Alexander Rathai (Alexander.Rathai@gmail.com)
+#  - Dr. Damian Rouson (http://www.sourceryinstitute.org/) (documentation)
+#
+# Licensed under MIT
+# Copyright (c) 2013 Kevin van Zonneveld (http://kvz.io)
+
+# Exit on error. Append ||true if you expect an error.
+# `set` is safer than relying on a shebang like `#!/bin/bash -e` because that is neutralized
+# when someone runs your script as `bash yourscript.sh`
+set -o errexit
+set -o nounset
+
+# Bash will remember & return the highest exitcode in a chain of pipes.
+# This way you can catch the error in case mysqldump fails in `mysqldump |gzip`
+set -o pipefail
+# set -o xtrace
+
+# Environment variables and their defaults
+LOG_LEVEL="${LOG_LEVEL:-6}" # 7 = debug -> 0 = emergency
+NO_COLOR="${NO_COLOR:-}"    # true = disable color. otherwise autodetected
diff --git a/libgfortran/mk-multi-image/use-case/set_magic_variables.sh b/libgfortran/mk-multi-image/use-case/set_magic_variables.sh
new file mode 100644
index 0000000..50d74dd
--- /dev/null
+++ b/libgfortran/mk-multi-image/use-case/set_magic_variables.sh
@@ -0,0 +1,46 @@
+# BASH3 Boilerplate
+#
+#  set_magic_variables.sh
+#
+#  - Sets the variables __dir, __file, __filename, __base, and __os
+#  - Defines a function containing commands extracted from the bash3boilerplate
+#    main.sh as part of a refactoring to facilitate wholesale reuse of main.sh's
+#    contents of without modification.
+#
+#  Usage (as invoked in bootstrap.sh):
+#
+#    source set_magic_variables.sh "$(caller 0)"
+#
+# More info:
+#
+#  - https://github.com/kvz/bash3boilerplate
+#  - http://kvz.io/blog/2013/02/26/introducing-bash3boilerplate/
+#
+# Version: 2.1.0
+#
+# Authors:
+#
+#  - Kevin van Zonneveld (http://kvz.io)
+#  - Izaak Beekman (https://izaakbeekman.com/)
+#  - Alexander Rathai (Alexander.Rathai@gmail.com)
+#  - Dr. Damian Rouson (http://www.sourceryinstitute.org/) (documentation)
+#
+# Licensed under MIT
+# Copyright (c) 2013 Kevin van Zonneveld (http://kvz.io)
+
+# shellcheck disable=SC2016
+[ -z "${1}" ] && echo 'Usage: source set_magic_variables.sh "$(caller 0)"'
+# shellcheck disable=SC2034
+function set_magic_variables(){
+  text_after_final_space="${1##* }"
+  __dir="$(cd "$(dirname "${text_after_final_space}")" && pwd)"
+  __file="${__dir}/$(basename "${text_after_final_space}")"
+  __filename="$(basename "${text_after_final_space}")"
+  __base="$(basename "${__file}" .sh)"
+  __os="Linux"
+  if [[ "${OSTYPE:-}" == "darwin"* ]]; then
+    __os="OSX"
+  fi
+  __usage="${__usage:-${__file}-usage}"
+}
+set_magic_variables "${@}"
diff --git a/libgfortran/mk-multi-image/use-case/set_or_print_downloader.sh b/libgfortran/mk-multi-image/use-case/set_or_print_downloader.sh
new file mode 100644
index 0000000..ef0ad11
--- /dev/null
+++ b/libgfortran/mk-multi-image/use-case/set_or_print_downloader.sh
@@ -0,0 +1,23 @@
+# shellcheck disable=SC2154
+set_or_print_downloader()
+{
+  # Choose the first available download mechanism, prioritizing first robustness:
+  info "Checking available download mechanisms: curl, wget."
+
+  if type curl &> /dev/null; then
+    fetch=curl
+    fetch_args=("-LO" "-u" "anonymous:")
+  elif type wget &> /dev/null; then
+    fetch=wget
+    fetch_args=("")
+  else
+    tried="curl, wget"
+    emergency "No available download mechanism. Option tried: ${tried}"
+  fi
+
+  # If a printout of the download mechanism was requested, then print it and exit with normal status
+  if [[ "${arg_D}" == "${__flag_present}" ]]; then
+     printf "%s\n" "${fetch}"
+     exit 0
+  fi
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]