[metview] 01/01: Upstream release 4.8.0

Alastair McKinstry mckinstry at moszumanska.debian.org
Mon Nov 28 17:08:16 UTC 2016


This is an automated email from the git hooks/post-receive script.

mckinstry pushed a commit to tag upstream/4.8.0
in repository metview.

commit 5835dfd1378d6b6da9d20afd256ed1b1b64295fa
Author: Alastair McKinstry <mckinstry at debian.org>
Date:   Mon Nov 28 17:03:51 2016 +0000

    Upstream release 4.8.0
---
 CMakeLists.txt                                     |   4 +-
 VERSION.cmake                                      |   4 +-
 VERSION.cmake.orig                                 |  11 --
 bin/ecbuild                                        |   4 +-
 cmake/CheckFortranCompilerFlag.cmake               |  37 ----
 cmake/CheckFortranSourceCompiles.cmake             |  94 ----------
 cmake/FindAEC.cmake                                |  31 ++--
 cmake/{contrib => }/FindFFTW.cmake                 |   6 -
 cmake/FindGeoTIFF.cmake                            |  64 ++++---
 cmake/FindMKL.cmake                                |   7 +-
 cmake/FindOpenJPEG.cmake                           |  54 +++---
 cmake/VERSION.cmake                                |   4 +-
 cmake/compiler_flags/Cray_C.cmake                  |  11 +-
 cmake/compiler_flags/Cray_CXX.cmake                |  11 +-
 cmake/compiler_flags/Cray_Fortran.cmake            |  12 +-
 .../CMakeCheckCompilerFlagCommonPatterns.cmake     |  33 ++++
 cmake/contrib/CheckFortranCompilerFlag.cmake       |  72 +++++---
 cmake/contrib/CheckFortranSourceCompiles.cmake     | 133 +++++++++-----
 cmake/contrib/FindNetCDF4.cmake                    |   4 +-
 .../contrib/GreatCMakeCookOff/AddCPP11Flags.cmake  |   5 +-
 .../GreatCMakeCookOff/CheckCXX11Features.cmake     | 125 ++++++-------
 cmake/ecbuild_add_executable.cmake                 |  64 +------
 cmake/ecbuild_add_fortran_flags.cmake              |  11 +-
 cmake/ecbuild_add_library.cmake                    | 102 ++++-------
 cmake/ecbuild_add_option.cmake                     |  74 ++++----
 cmake/ecbuild_add_test.cmake                       |  82 ++++++---
 cmake/ecbuild_bundle.cmake                         |   8 +-
 cmake/ecbuild_check_cxx11.cmake                    | 158 +++++++++--------
 cmake/ecbuild_check_fortran.cmake                  | 126 +++++++++++++
 cmake/ecbuild_check_fortran_source_return.cmake    |  13 +-
 cmake/ecbuild_check_functions.cmake                |   9 +
 cmake/ecbuild_compiler_flags.cmake                 | 154 +++++++++++++---
 cmake/ecbuild_config.h.in                          |   6 +
 cmake/ecbuild_declare_project.cmake                |  47 +++--
 cmake/ecbuild_define_paths.cmake                   |  23 ++-
 cmake/ecbuild_download_resource.cmake              |   1 +
 cmake/ecbuild_find_omp.cmake                       |   4 +-
 cmake/ecbuild_find_python.cmake                    | 149 +++++++++-------
 cmake/ecbuild_generate_fortran_interfaces.cmake    |   2 +-
 cmake/ecbuild_get_cxx11_flags.cmake                |   9 +-
 cmake/ecbuild_get_test_data.cmake                  |  15 +-
 cmake/ecbuild_install_project.cmake                |  58 +++---
 cmake/ecbuild_log.cmake                            |  23 ++-
 cmake/ecbuild_pkgconfig.cmake                      |   2 +-
 cmake/ecbuild_print_summary.cmake                  |   8 +-
 cmake/ecbuild_remove_fortran_flags.cmake           |   5 +-
 cmake/ecbuild_separate_sources.cmake               |  24 +--
 cmake/ecbuild_source_flags.cmake                   |   6 +-
 cmake/ecbuild_system.cmake                         |   2 +
 cmake/ecbuild_target_flags.cmake                   |  91 ++++++++++
 cmake/ecbuild_use_package.cmake                    |   1 +
 cmake/fortran_features/CheckFortranFeatures.cmake  | 167 ++++++++++++++++++
 cmake/fortran_features/c_size_t.F90                |   8 +
 cmake/fortran_features/c_sizeof.F90                |   3 +
 cmake/fortran_features/derivedtype_interface.F90   |  54 ++++++
 cmake/fortran_features/derivedtype_io.F90          |  42 +++++
 cmake/fortran_features/finalization.F90            | 141 +++++++++++++++
 cmake/fortran_features/submodules.F90              |  35 ++++
 share/ecbuild/toolchains/ecmwf-XC30-Cray.cmake     |  21 +--
 share/ecbuild/toolchains/ecmwf-XC30-GNU.cmake      |  14 +-
 share/ecbuild/toolchains/ecmwf-XC30-Intel.cmake    |  14 +-
 ...wf-XC30-Intel.cmake => ichec-fionn-Intel.cmake} |  30 ++--
 share/metview/etc/GeoViewDef.orig                  | 132 --------------
 share/metview/etc/MAXISDef                         |  25 ++-
 share/metview/etc/MAXISRules                       |  13 ++
 share/metview/etc/ecmwf.def                        |   1 +
 src/Desktop/MvQColourLine.cc                       |  11 +-
 src/Desktop/MvQGeoHelp.cc                          |   2 +
 src/Macro/grib.cc                                  |  81 +++++++--
 src/Macro/misc.cc                                  |  14 +-
 src/Macro/mlist.cc                                 | 102 ++++++++---
 src/Macro/mvector.cc                               | 195 ++++++++++++++++++---
 src/libMarsClient/expand.c                         |  10 +-
 src/libMarsClient/tools.c                          |   7 +-
 src/libMvQtGui/MvQAbout.cc                         |   6 +-
 test/macros/CMakeLists.txt                         |   6 +
 test/macros/fieldsets.mv                           |  51 ++++++
 test/macros/lists.mv                               |  36 ++++
 test/macros/vectors.mv                             |  78 +++++++++
 79 files changed, 2218 insertions(+), 1084 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 87b67ef..8431d1a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -235,7 +235,7 @@ endif()
 
 # ecbuild_use_package( PROJECT eckit VERSION 0.3 REQUIRED )
 
-ecbuild_add_option( FEATURE ECCODES DESCRIPTION "" DEFAULT OFF )
+ecbuild_add_option( FEATURE ECCODES DESCRIPTION "" DEFAULT ON )
 
 if( HAVE_ECCODES )
   ecbuild_use_package( PROJECT eccodes VERSION 0.14 REQUIRED )
@@ -243,8 +243,10 @@ if( HAVE_ECCODES )
   set( GRIB_API_LIBRARIES    ${ECCODES_LIBRARIES} )
   set( GRIB_API_DEFINITIONS  ${ECCODES_DEFINITIONS} )
   set( grib_api_BASE_DIR     ${eccodes_BASE_DIR} )
+  add_definitions(-DGRIB_HANDLING_PACKAGE=ecCodes)
 else()
   ecbuild_use_package( PROJECT grib_api VERSION 1.13.0 REQUIRED )
+  add_definitions(-DGRIB_HANDLING_PACKAGE=GRIB_API)
 endif()
 
 
diff --git a/VERSION.cmake b/VERSION.cmake
index 8b237ab..71e10d3 100644
--- a/VERSION.cmake
+++ b/VERSION.cmake
@@ -1,5 +1,5 @@
 set(${PROJECT_NAME}_MAJOR_VERSION_STR    "4")
-set(${PROJECT_NAME}_MINOR_VERSION_STR    "7")
-set(${PROJECT_NAME}_REVISION_VERSION_STR "2")
+set(${PROJECT_NAME}_MINOR_VERSION_STR    "8")
+set(${PROJECT_NAME}_REVISION_VERSION_STR "0")
 
 set(${PROJECT_NAME}_VERSION_STR  "${${PROJECT_NAME}_MAJOR_VERSION_STR}.${${PROJECT_NAME}_MINOR_VERSION_STR}.${${PROJECT_NAME}_REVISION_VERSION_STR}")
diff --git a/VERSION.cmake.orig b/VERSION.cmake.orig
deleted file mode 100644
index 26351c4..0000000
--- a/VERSION.cmake.orig
+++ /dev/null
@@ -1,11 +0,0 @@
-<<<<<<< HEAD
-set(${PROJECT_NAME}_MAJOR_VERSION_STR    "5")
-set(${PROJECT_NAME}_MINOR_VERSION_STR    "0")
-set(${PROJECT_NAME}_REVISION_VERSION_STR "0")
-=======
-set(${PROJECT_NAME}_MAJOR_VERSION_STR    "4")
-set(${PROJECT_NAME}_MINOR_VERSION_STR    "7")
-set(${PROJECT_NAME}_REVISION_VERSION_STR "2")
->>>>>>> release/4.7.2
-
-set(${PROJECT_NAME}_VERSION_STR  "${${PROJECT_NAME}_MAJOR_VERSION_STR}.${${PROJECT_NAME}_MINOR_VERSION_STR}.${${PROJECT_NAME}_REVISION_VERSION_STR}")
diff --git a/bin/ecbuild b/bin/ecbuild
index 0ee4b13..da2d7b9 100755
--- a/bin/ecbuild
+++ b/bin/ecbuild
@@ -368,9 +368,9 @@ cmake_version_sufficient=""
 
 # Check that version $1 satisfies $2
 # CMake versions have no more than 4 fields
-# (adapted from http://stackoverflow.com/a/25731924/396967)
+# Version sort (sort -V) is not available on all platforms
 version_gte() {
-    [  "$2" = "$(echo -e "$1\n$2" | sort -t '.' -k 1,1 -k 2,2 -k 3,3 -k 4,4 -g | head -n1)" ]
+  [ "$2" = "$(echo -e "$1\n$2" | sort -t '.' -k 1,1 -k 2,2 -k 3,3 -k 4,4 -g | head -n1)" ]
 }
 
 # Use already built CMake if any
diff --git a/cmake/CheckFortranCompilerFlag.cmake b/cmake/CheckFortranCompilerFlag.cmake
deleted file mode 100644
index 5408691..0000000
--- a/cmake/CheckFortranCompilerFlag.cmake
+++ /dev/null
@@ -1,37 +0,0 @@
-# - Check whether the CXX compiler supports a given flag.
-# CHECK_CXX_COMPILER_FLAG(FLAG VARIABLE)
-#
-#  FLAG - the compiler flag
-#  VARIABLE - variable to store the result
-
-# Copyright (c) 2006, Alexander Neundorf, <neundorf at kde.org>
-#
-# Redistribution and use is allowed according to the terms of the BSD license.
-# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
-
-
-INCLUDE(CheckFortranSourceCompiles)
-
-MACRO (CHECK_FORTRAN_COMPILER_FLAG _FLAG _RESULT)
-   SET(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}")
-   SET(CMAKE_REQUIRED_DEFINITIONS "${_FLAG}")
-   CHECK_FORTRAN_SOURCE_COMPILES("program main\nend program\n" ${_RESULT}
-     # Some compilers do not fail with a bad flag
-     FAIL_REGEX "command line option .* is valid for .* but not for C\\\\+\\\\+" # GNU
-     FAIL_REGEX "unrecognized .*option"                     # GNU
-     FAIL_REGEX "unknown .*option"                          # Clang
-     FAIL_REGEX "invalid value"                             # Clang
-     FAIL_REGEX "ignoring unknown option"                   # MSVC
-     FAIL_REGEX "warning D9002"                             # MSVC, any lang
-     FAIL_REGEX "option.*not supported"                     # Intel
-     FAIL_REGEX "invalid argument .*option"                 # Intel
-     FAIL_REGEX "ignoring option .*argument required"       # Intel
-     FAIL_REGEX "[Uu]nknown option"                         # HP
-     FAIL_REGEX "[Ww]arning: [Oo]ption"                     # SunPro
-     FAIL_REGEX "command option .* is not recognized"       # XL
-     FAIL_REGEX "not supported in this configuration; ignored"       # AIX
-     FAIL_REGEX "File with unknown suffix passed to linker" # PGI
-     FAIL_REGEX "WARNING: unknown flag:"                    # Open64
-     )
-   SET (CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}")
-ENDMACRO (CHECK_FORTRAN_COMPILER_FLAG)
diff --git a/cmake/CheckFortranSourceCompiles.cmake b/cmake/CheckFortranSourceCompiles.cmake
deleted file mode 100644
index d3dc968..0000000
--- a/cmake/CheckFortranSourceCompiles.cmake
+++ /dev/null
@@ -1,94 +0,0 @@
-# - Check if given Fortran source compiles and links into an executable
-# CHECK_FORTRAN_SOURCE_COMPILES(<code> <var> [FAIL_REGEX <fail-regex>])
-#  <code>       - source code to try to compile, must define 'main'
-#  <var>        - variable to store whether the source code compiled
-#  <fail-regex> - fail if test output matches this regex
-# The following variables may be set before calling this macro to
-# modify the way the check is run:
-#
-#  CMAKE_REQUIRED_FLAGS = string of compile command line flags
-#  CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
-#  CMAKE_REQUIRED_INCLUDES = list of include directories
-#  CMAKE_REQUIRED_LIBRARIES = list of libraries to link
-
-#=============================================================================
-# Copyright 2005-2009 Kitware, Inc.
-# Fortran version, 2013, James Tappin
-#
-# Distributed under the OSI-approved BSD License (the "License");
-# see accompanying file Copyright.txt for details.
-#
-# This software is distributed WITHOUT ANY WARRANTY; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-# See the License for more information.
-#=============================================================================
-# (To distribute this file outside of CMake, substitute the full
-#  License text for the above reference.)
-
-
-
-macro(CHECK_FORTRAN_SOURCE_COMPILES SOURCE VAR)
-
-if( ${VAR} MATCHES "^${VAR}$" )
-    set(_FAIL_REGEX)
-    set(_key)
-    foreach(arg ${ARGN})
-      if("${arg}" MATCHES "^(FAIL_REGEX)$")
-        set(_key "${arg}")
-      elseif(_key)
-        list(APPEND _${_key} "${arg}")
-      else()
-        ecbuild_critical("Unknown argument:\n  ${arg}\n")
-      endif()
-    endforeach()
-    set(MACRO_CHECK_FUNCTION_DEFINITIONS
-      "-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
-    if(CMAKE_REQUIRED_LIBRARIES)
-      set(CHECK_FORTRAN_SOURCE_COMPILES_ADD_LIBRARIES
-        LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
-    else()
-      set(CHECK_FORTRAN_SOURCE_COMPILES_ADD_LIBRARIES)
-    endif()
-    if(CMAKE_REQUIRED_INCLUDES)
-      set(CHECK_FORTRAN_SOURCE_COMPILES_ADD_INCLUDES
-        "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
-    else()
-      set(CHECK_FORTRAN_SOURCE_COMPILES_ADD_INCLUDES)
-    endif()
-    file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.f90"
-      "${SOURCE}\n")
-
-    ecbuild_debug("Performing Test ${VAR}")
-    try_compile(${VAR}
-      ${CMAKE_BINARY_DIR}
-      ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.f90
-      COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
-      ${CHECK_FORTRAN_SOURCE_COMPILES_ADD_LIBRARIES}
-      CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
-      "${CHECK_FORTRAN_SOURCE_COMPILES_ADD_INCLUDES}"
-      OUTPUT_VARIABLE OUTPUT)
-
-    foreach(_regex ${_FAIL_REGEX})
-      if("${OUTPUT}" MATCHES "${_regex}")
-        set(${VAR} 0)
-      endif()
-    endforeach()
-
-    if(${VAR})
-      set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
-      ecbuild_debug("Performing Test ${VAR} - Success")
-      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
-        "Performing Fortran SOURCE FILE Test ${VAR} succeded with the following output:\n"
-        "${OUTPUT}\n"
-        "Source file was:\n${SOURCE}\n")
-    else()
-      ecbuild_debug("Performing Test ${VAR} - Failed")
-      set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
-      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
-        "Performing Fortran SOURCE FILE Test ${VAR} failed with the following output:\n"
-        "${OUTPUT}\n"
-        "Source file was:\n${SOURCE}\n")
-    endif()
-  endif()
-endmacro()
-
diff --git a/cmake/FindAEC.cmake b/cmake/FindAEC.cmake
index 767544f..717b2b5 100644
--- a/cmake/FindAEC.cmake
+++ b/cmake/FindAEC.cmake
@@ -3,24 +3,31 @@
 # This software is licensed under the terms of the Apache Licence Version 2.0
 # which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
 # In applying this licence, ECMWF does not waive the privileges and immunities
-# granted to it by virtue of its status as an intergovernmental organisation nor
-# does it submit to any jurisdiction.
+# granted to it by virtue of its status as an intergovernmental organisation
+# nor does it submit to any jurisdiction.
 
 # - Try to find AEC (Adaptive Entropy Coding library)
 # See https://www.dkrz.de/redmine/projects/aec/wiki
 
 # Once done this will define
-#  AEC_FOUND - System has AEC
+#  AEC_FOUND        - System has AEC
 #  AEC_INCLUDE_DIRS - The AEC include directories
-#  AEC_LIBRARIES - The libraries needed to use AEC
-
-if( DEFINED AEC_PATH )
-    find_path( AEC_INCLUDE_DIR szlib.h    PATHS ${AEC_PATH}/include PATH_SUFFIXES aec NO_DEFAULT_PATH )
-    find_library( AEC_LIBRARY  NAMES aec  PATHS ${AEC_PATH}/lib     PATH_SUFFIXES aec NO_DEFAULT_PATH )
-endif()
-
-find_path( AEC_INCLUDE_DIR szlib.h PATH_SUFFIXES aec )
-find_library( AEC_LIBRARY NAMES aec PATH_SUFFIXES aec )
+#  AEC_LIBRARIES    - The libraries needed to use AEC
+#
+# The following paths will be searched with priority if set in CMake or env
+#
+#  AEC_DIR          - prefix path of the AEC installation
+#  AEC_PATH         - prefix path of the AEC installation
+
+find_path( AEC_INCLUDE_DIR szlib.h
+           PATHS ${AEC_DIR} ${AEC_PATH} ENV AEC_DIR ENV AEC_PATH
+           PATH_SUFFIXES include include/aec NO_DEFAULT_PATH )
+find_path( AEC_INCLUDE_DIR szlib.h PATH_SUFFIXES include include/aec )
+
+find_library( AEC_LIBRARY  NAMES aec
+              PATHS ${AEC_DIR} ${AEC_PATH} ENV AEC_DIR ENV AEC_PATH
+              PATH_SUFFIXES lib lib64 lib/aec lib64/aec NO_DEFAULT_PATH )
+find_library( AEC_LIBRARY NAMES aec PATH_SUFFIXES lib lib64 lib/aec lib64/aec )
 
 set( AEC_LIBRARIES    ${AEC_LIBRARY} )
 set( AEC_INCLUDE_DIRS ${AEC_INCLUDE_DIR} )
diff --git a/cmake/contrib/FindFFTW.cmake b/cmake/FindFFTW.cmake
similarity index 96%
rename from cmake/contrib/FindFFTW.cmake
rename to cmake/FindFFTW.cmake
index 5ef46df..b76afa5 100644
--- a/cmake/contrib/FindFFTW.cmake
+++ b/cmake/FindFFTW.cmake
@@ -56,12 +56,6 @@
 #
 ##############################################################################
 
-#============================================#
-#                                            #
-#    From Eigen3, modified by W Deconinck    #
-#                                            #
-#============================================#
-
 if( (NOT FFTW_ROOT) AND EXISTS $ENV{FFTW_ROOT} )
   set( FFTW_ROOT ${FFTW_ROOT} )
 endif()
diff --git a/cmake/FindGeoTIFF.cmake b/cmake/FindGeoTIFF.cmake
index 83c868c..126bc46 100644
--- a/cmake/FindGeoTIFF.cmake
+++ b/cmake/FindGeoTIFF.cmake
@@ -1,38 +1,46 @@
-###############################################################################
+# (C) Copyright 1996-2016 ECMWF.
 #
-# CMake module to search for GeoTIFF library
-#
-# On success, the macro sets the following variables:
-# GEOTIFF_FOUND       = if the library found
-# GEOTIFF_LIBRARIES   = full path to the library
-# GEOTIFF_INCLUDE_DIR = where to find the library headers 
-# also defined, but not for general use are
-# GEOTIFF_LIBRARY, where to find the PROJ.4 library.
-#
-# Copyright (c) 2009 Mateusz Loskot <mateusz at loskot.net>
+# This software is licensed under the terms of the Apache Licence Version 2.0
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
+# granted to it by virtue of its status as an intergovernmental organisation
+# nor does it submit to any jurisdiction.
+
+# - Try to find the GeoTIFF includes and library
+# This module defines
 #
-# Module source: http://github.com/mloskot/workshop/tree/master/cmake/
+#  GEOTIFF_FOUND         - System has GeoTIFF
+#  GEOTIFF_INCLUDE_DIRS  - the GeoTIFF include directories
+#  GEOTIFF_LIBRARIES     - the libraries needed to use GeoTIFF
 #
-# Redistribution and use is allowed according to the terms of the BSD license.
-# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+# The following paths will be searched with priority if set in CMake or env
 #
-###############################################################################
+#  GEOTIFF_DIR   - root folder of the GeoTIFF installation
+#  GEOTIFF_PATH  - root folder of the GeoTIFF installation
 
-SET(GEOTIFF_NAMES geotiff)
+find_path( GEOTIFF_INCLUDE_DIR geotiff.h
+           PATHS ${GEOTIFF_PATH} ENV GEOTIFF_PATH
+                 ${GEOTIFF_DIR}  ENV GEOTIFF_DIR
+           PATH_SUFFIXES include include/libgeotiff
+           NO_DEFAULT_PATH )
+find_path( GEOTIFF_INCLUDE_DIR  openjpeg.h
+           PATH_SUFFIXES include include/libgeotiff )
 
+find_library( GEOTIFF_LIBRARY NAMES geotiff
+              PATHS ${GEOTIFF_PATH} ENV GEOTIFF_PATH
+                    ${GEOTIFF_DIR}  ENV GEOTIFF_DIR
+              PATH_SUFFIXES lib lib64
+              NO_DEFAULT_PATH )
+find_library( GEOTIFF_LIBRARY NAMES geotiff )
 
-    FIND_PATH(GEOTIFF_INCLUDE_DIR geotiff.h PATH_PREFIXES geotiff 
-         PATHS /usr/local/include/libgeotiff /usr/include/libgeotiff)
+set( GEOTIFF_LIBRARIES    ${GEOTIFF_LIBRARY} )
+set( GEOTIFF_INCLUDE_DIRS ${GEOTIFF_INCLUDE_DIR} )
 
-    FIND_LIBRARY(GEOTIFF_LIBRARY NAMES ${GEOTIFF_NAMES})
+include(FindPackageHandleStandardArgs)
 
-
-IF(GEOTIFF_FOUND)
-  SET(GEOTIFF_LIBRARIES ${GEOTIFF_LIBRARY})
-ENDIF()
-
-# Handle the QUIET and REQUIRED arguments and set GEOTIFF_FOUND to TRUE
+# handle the QUIETLY and REQUIRED arguments and set GEOTIFF_FOUND to TRUE
 # if all listed variables are TRUE
-# Note: capitalisation of the package name must be the same as in the file name
-INCLUDE(FindPackageHandleStandardArgs)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(GEOTiff DEFAULT_MSG GEOTIFF_LIBRARY GEOTIFF_INCLUDE_DIR)
+find_package_handle_standard_args( GeoTIFF DEFAULT_MSG
+                                   GEOTIFF_LIBRARY GEOTIFF_INCLUDE_DIR )
+
+mark_as_advanced( GEOTIFF_INCLUDE_DIR GEOTIFF_LIBRARY )
diff --git a/cmake/FindMKL.cmake b/cmake/FindMKL.cmake
index 1123234..5941179 100644
--- a/cmake/FindMKL.cmake
+++ b/cmake/FindMKL.cmake
@@ -15,6 +15,7 @@
 #
 # The following paths will be searched with priority if set in CMake or env
 #
+#  MKLROOT           - root directory of the MKL installation
 #  MKL_PATH          - root directory of the MKL installation
 #  MKL_ROOT          - root directory of the MKL installation
 
@@ -34,9 +35,9 @@ else()
 
 endif()
 
-# Search with priority for MKL_ROOT and MKL_PATH if set in CMake or env
+# Search with priority for MKLROOT, MKL_PATH and MKL_ROOT if set in CMake or env
 find_path(MKL_INCLUDE_DIR mkl.h
-          PATHS ${MKL_PATH} ${MKL_ROOT} ENV MKL_PATH MKL_ROOT
+          PATHS ${MKLROOT} ${MKL_PATH} ${MKL_ROOT} ENV MKLROOT ENV MKL_PATH ENV MKL_ROOT
           PATH_SUFFIXES include NO_DEFAULT_PATH)
 find_path(MKL_INCLUDE_DIR mkl.h
           PATH_SUFFIXES include)
@@ -53,8 +54,6 @@ if( MKL_INCLUDE_DIR ) # use include dir to find libs
     set( __libsfx "" )
   endif()
 
-  message( STATUS "ICC_LIB_PATH ${ICC_LIB_PATH}" )
-
   find_library( MKL_LIB_INTEL         NAMES mkl_intel${__libsfx} PATHS ${MKL_LIB_PATH} )
   find_library( ${__mkl_lib_par}      NAMES ${__mkl_lib_name} PATHS ${MKL_LIB_PATH} )
   find_library( MKL_LIB_CORE          NAMES mkl_core PATHS ${MKL_LIB_PATH} )
diff --git a/cmake/FindOpenJPEG.cmake b/cmake/FindOpenJPEG.cmake
index 805f091..c660238 100644
--- a/cmake/FindOpenJPEG.cmake
+++ b/cmake/FindOpenJPEG.cmake
@@ -1,33 +1,45 @@
 # (C) Copyright 1996-2016 ECMWF.
-# 
+#
 # This software is licensed under the terms of the Apache Licence Version 2.0
-# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. 
-# In applying this licence, ECMWF does not waive the privileges and immunities 
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
 # granted to it by virtue of its status as an intergovernmental organisation nor
 # does it submit to any jurisdiction.
 
-# - Try to find the OpenJPEG includes and library
+# - Try to find the OpenJPEG includes and library (version 1.5.x or 2.1.x)
 # This module defines
+#
 #  OPENJPEG_FOUND         - System has OpenJPEG
 #  OPENJPEG_INCLUDE_DIRS  - the OpenJPEG include directories
 #  OPENJPEG_LIBRARIES     - the libraries needed to use OpenJPEG
 #
-# also defined internally:
-#  OPENJPEG_LIBRARY, where to find the OpenJPEG library.
-#  OPENJPEG_INCLUDE_DIR, where to find the openjpeg.h header
-
-IF( NOT DEFINED OPENJPEG_PATH AND NOT "$ENV{OPENJPEG_PATH}" STREQUAL "" )
-  SET( OPENJPEG_PATH "$ENV{OPENJPEG_PATH}" )
-ENDIF()
-
-# TODO: This only works for OpenJPEG v1.x.y and not for v2 which has a different API, library name etc
-if( DEFINED OPENJPEG_PATH )
-        find_path(OPENJPEG_INCLUDE_DIR openjpeg.h PATHS ${OPENJPEG_PATH}/include PATH_SUFFIXES openjpeg  NO_DEFAULT_PATH)
-        find_library(OPENJPEG_LIBRARY  openjpeg   PATHS ${OPENJPEG_PATH}/lib     PATH_SUFFIXES openjpeg  NO_DEFAULT_PATH)
-endif()
-
-find_path(OPENJPEG_INCLUDE_DIR  openjpeg.h PATH_SUFFIXES openjpeg )
-find_library( OPENJPEG_LIBRARY  openjpeg   PATH_SUFFIXES openjpeg )
+# The following paths will be searched with priority if set in CMake or env
+#
+#  OPENJPEG_DIR   - root folder of the OpenJPEG installation
+#  OPENJPEG_PATH  - root folder of the OpenJPEG installation
+
+# Note: OpenJPEG has a version-specific subdirectory in the include
+# e.g. include/openjpeg-2.0 or include/openjpeg-2.1.
+# Only version 1.5.x and 2.1.x are supported.
+# The library name is different for 1.x (libopenjpeg) and 2.x (libopenjp2).
+
+set( _suff include include/openjpeg include/openjpeg-1.5 include/openjpeg-2.1 )
+find_path( OPENJPEG_INCLUDE_DIR openjpeg.h
+           PATHS ${OPENJPEG_PATH} ENV OPENJPEG_PATH
+                 ${OPENJPEG_DIR}  ENV OPENJPEG_DIR
+           PATH_SUFFIXES ${_suff}
+           NO_DEFAULT_PATH )
+find_path( OPENJPEG_INCLUDE_DIR  openjpeg.h
+           PATH_SUFFIXES ${_suff} )
+unset( _suff )
+
+find_library( OPENJPEG_LIBRARY NAMES openjpeg openjp2
+              PATHS ${OPENJPEG_PATH} ENV OPENJPEG_PATH
+                    ${OPENJPEG_DIR}  ENV OPENJPEG_DIR
+              PATH_SUFFIXES lib lib/openjpeg
+              NO_DEFAULT_PATH )
+find_library( OPENJPEG_LIBRARY NAMES openjpeg openjp2
+              PATH_SUFFIXES lib lib/openjpeg )
 
 set( OPENJPEG_LIBRARIES    ${OPENJPEG_LIBRARY} )
 set( OPENJPEG_INCLUDE_DIRS ${OPENJPEG_INCLUDE_DIR} )
@@ -39,4 +51,4 @@ include(FindPackageHandleStandardArgs)
 find_package_handle_standard_args(OpenJPEG  DEFAULT_MSG
                                   OPENJPEG_LIBRARY OPENJPEG_INCLUDE_DIR)
 
-mark_as_advanced(OPENJPEG_INCLUDE_DIR OPENJPEG_LIBRARY )
+mark_as_advanced( OPENJPEG_INCLUDE_DIR OPENJPEG_LIBRARY )
diff --git a/cmake/VERSION.cmake b/cmake/VERSION.cmake
index ff7b93b..d9d8705 100644
--- a/cmake/VERSION.cmake
+++ b/cmake/VERSION.cmake
@@ -1,7 +1,7 @@
 set( ECBUILD_MAJOR_VERSION "2" )
-set( ECBUILD_MINOR_VERSION "3" )
+set( ECBUILD_MINOR_VERSION "5" )
 set( ECBUILD_PATCH_VERSION "0" )
 
-set( ECBUILD_VERSION_STR  "2.3.0" )
+set( ECBUILD_VERSION_STR  "2.5.0" )
 
 set( ECBUILD_MACRO_VERSION "${ECBUILD_MAJOR_VERSION}.${ECBUILD_MINOR_VERSION}" )
diff --git a/cmake/compiler_flags/Cray_C.cmake b/cmake/compiler_flags/Cray_C.cmake
index 76779f9..f487cf4 100644
--- a/cmake/compiler_flags/Cray_C.cmake
+++ b/cmake/compiler_flags/Cray_C.cmake
@@ -6,9 +6,8 @@
 # granted to it by virtue of its status as an intergovernmental organisation
 # nor does it submit to any jurisdiction.
 
-set( CMAKE_C_FLAGS_ALL            "-hlist=amid"                                                                    CACHE STRING "Common flags for all build-types" FORCE )
-set( CMAKE_C_FLAGS_RELEASE        "${CMAKE_C_FLAGS_ALL} -O3 -hfp3 -hscalar3 -hvector3 -DNDEBUG"                    CACHE STRING "Release C flags"                  FORCE )
-set( CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_ALL} -O2 -hfp1 -Gfast -DNDEBUG"                                 CACHE STRING "Release-with-debug-info C flags"  FORCE )
-set( CMAKE_C_FLAGS_PRODUCTION     "${CMAKE_C_FLAGS_ALL} -O2 -hfp1 -G2"                                             CACHE STRING "Production C flags"               FORCE )
-set( CMAKE_C_FLAGS_BIT            "${CMAKE_C_FLAGS_ALL} -O2 -hfp1 -G2 -hflex_mp=conservative -hadd_paren -DNDEBUG" CACHE STRING "Bit-reproducible C flags"         FORCE )
-set( CMAKE_C_FLAGS_DEBUG          "${CMAKE_C_FLAGS_ALL} -O0 -G0"                                                   CACHE STRING "Debug Cflags"                     FORCE )
+set( CMAKE_C_FLAGS_RELEASE        "-O3 -hfp3 -hscalar3 -hvector3 -DNDEBUG"        CACHE STRING "Release C flags"                  FORCE )
+set( CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -hfp1 -Gfast -DNDEBUG"                     CACHE STRING "Release-with-debug-info C flags"  FORCE )
+set( CMAKE_C_FLAGS_PRODUCTION     "-O2 -hfp1 -G2"                                 CACHE STRING "Production C flags"               FORCE )
+set( CMAKE_C_FLAGS_BIT            "-O2 -hfp1 -G2 -hflex_mp=conservative -DNDEBUG" CACHE STRING "Bit-reproducible C flags"         FORCE )
+set( CMAKE_C_FLAGS_DEBUG          "-O0 -G0"                                       CACHE STRING "Debug Cflags"                     FORCE )
diff --git a/cmake/compiler_flags/Cray_CXX.cmake b/cmake/compiler_flags/Cray_CXX.cmake
index d599bff..a2a6632 100644
--- a/cmake/compiler_flags/Cray_CXX.cmake
+++ b/cmake/compiler_flags/Cray_CXX.cmake
@@ -6,9 +6,8 @@
 # granted to it by virtue of its status as an intergovernmental organisation
 # nor does it submit to any jurisdiction.
 
-set( CMAKE_CXX_FLAGS_ALL            "-hlist=amid"                                                                      CACHE STRING "Common flags for all build-types"  FORCE )
-set( CMAKE_CXX_FLAGS_RELEASE        "${CMAKE_CXX_FLAGS_ALL} -O3 -hfp3 -hscalar3 -hvector3 -DNDEBUG"                    CACHE STRING "Release C++ flags"                 FORCE )
-set( CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_ALL} -O2 -hfp1 -Gfast -DNDEBUG"                                 CACHE STRING "Release-with-debug-info C++ flags" FORCE )
-set( CMAKE_CXX_FLAGS_PRODUCTION     "${CMAKE_CXX_FLAGS_ALL} -O2 -hfp1 -G2"                                             CACHE STRING "Production C++ flags"              FORCE )
-set( CMAKE_CXX_FLAGS_BIT            "${CMAKE_CXX_FLAGS_ALL} -O2 -hfp1 -G2 -hflex_mp=conservative -hadd_paren -DNDEBUG" CACHE STRING "Bit-reproducible C++ flags"        FORCE )
-set( CMAKE_CXX_FLAGS_DEBUG          "${CMAKE_CXX_FLAGS_ALL} -O0 -G0"                                                   CACHE STRING "Debug CXX flags"                   FORCE )
+set( CMAKE_CXX_FLAGS_RELEASE        "-O3 -hfp3 -hscalar3 -hvector3 -DNDEBUG"        CACHE STRING "Release C++ flags"                 FORCE )
+set( CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -hfp1 -Gfast -DNDEBUG"                     CACHE STRING "Release-with-debug-info C++ flags" FORCE )
+set( CMAKE_CXX_FLAGS_PRODUCTION     "-O2 -hfp1 -G2"                                 CACHE STRING "Production C++ flags"              FORCE )
+set( CMAKE_CXX_FLAGS_BIT            "-O2 -hfp1 -G2 -hflex_mp=conservative -DNDEBUG" CACHE STRING "Bit-reproducible C++ flags"        FORCE )
+set( CMAKE_CXX_FLAGS_DEBUG          "-O0 -G0"                                       CACHE STRING "Debug CXX flags"                   FORCE )
diff --git a/cmake/compiler_flags/Cray_Fortran.cmake b/cmake/compiler_flags/Cray_Fortran.cmake
index b2c23de..34b96e4 100644
--- a/cmake/compiler_flags/Cray_Fortran.cmake
+++ b/cmake/compiler_flags/Cray_Fortran.cmake
@@ -7,9 +7,9 @@
 # nor does it submit to any jurisdiction.
 
 # -emf activates .mods and uses lower case
-set( CMAKE_Fortran_FLAGS_ALL            "-emf"                                                                                 CACHE STRING "Common flags for all build-types"      FORCE )
-set( CMAKE_Fortran_FLAGS_RELEASE        "${CMAKE_Fortran_FLAGS_ALL} -O3 -hfp3 -hscalar3 -hvector3 -DNDEBUG"                    CACHE STRING "Release Fortran flags"                 FORCE )
-set( CMAKE_Fortran_FLAGS_RELWITHDEBINFO "${CMAKE_Fortran_FLAGS_ALL} -O2 -hfp1 -Gfast -DNDEBUG"                                 CACHE STRING "Release-with-debug-info Fortran flags" FORCE )
-set( CMAKE_Fortran_FLAGS_PRODUCTION     "${CMAKE_Fortran_FLAGS_ALL} -O2 -hfp1 -G2"                                             CACHE STRING "Production Fortran flags"              FORCE )
-set( CMAKE_Fortran_FLAGS_BIT            "${CMAKE_Fortran_FLAGS_ALL} -O2 -hfp1 -G2 -hflex_mp=conservative -hadd_paren -DNDEBUG" CACHE STRING "Bit-reproducible Fortran flags"        FORCE )
-set( CMAKE_Fortran_FLAGS_DEBUG          "${CMAKE_Fortran_FLAGS_ALL} -O0 -G0"                                                   CACHE STRING "Debug Fortran flags"                   FORCE )
+# -rmoid produces a listing file
+set( CMAKE_Fortran_FLAGS_RELEASE        "-emf -rmoid -O3 -hfp3 -hscalar3 -hvector3 -DNDEBUG"                    CACHE STRING "Release Fortran flags"                 FORCE )
+set( CMAKE_Fortran_FLAGS_RELWITHDEBINFO "-emf -rmoid -O2 -hfp1 -Gfast -DNDEBUG"                                 CACHE STRING "Release-with-debug-info Fortran flags" FORCE )
+set( CMAKE_Fortran_FLAGS_PRODUCTION     "-emf -rmoid -O2 -hfp1 -G2"                                             CACHE STRING "Production Fortran flags"              FORCE )
+set( CMAKE_Fortran_FLAGS_BIT            "-emf -rmoid -O2 -hfp1 -G2 -hflex_mp=conservative -hadd_paren -DNDEBUG" CACHE STRING "Bit-reproducible Fortran flags"        FORCE )
+set( CMAKE_Fortran_FLAGS_DEBUG          "-emf -rmoid -O0 -G0"                                                   CACHE STRING "Debug Fortran flags"                   FORCE )
diff --git a/cmake/contrib/CMakeCheckCompilerFlagCommonPatterns.cmake b/cmake/contrib/CMakeCheckCompilerFlagCommonPatterns.cmake
new file mode 100644
index 0000000..1b5178d
--- /dev/null
+++ b/cmake/contrib/CMakeCheckCompilerFlagCommonPatterns.cmake
@@ -0,0 +1,33 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+
+# Do NOT include this module directly into any of your code. It is meant as
+# a library for Check*CompilerFlag.cmake modules. It's content may change in
+# any way between releases.
+
+macro (CHECK_COMPILER_FLAG_COMMON_PATTERNS _VAR)
+   set(${_VAR}
+     FAIL_REGEX "[Uu]nrecogni[sz]ed .*option"               # GNU, NAG
+     FAIL_REGEX "unknown .*option"                          # Clang
+     FAIL_REGEX "optimization flag .* not supported"        # Clang
+     FAIL_REGEX "unknown argument ignored"                  # Clang (cl)
+     FAIL_REGEX "ignoring unknown option"                   # MSVC, Intel
+     FAIL_REGEX "warning D9002"                             # MSVC, any lang
+     FAIL_REGEX "option.*not supported"                     # Intel
+     FAIL_REGEX "invalid argument .*option"                 # Intel
+     FAIL_REGEX "ignoring option .*argument required"       # Intel
+     FAIL_REGEX "ignoring option .*argument is of wrong type" # Intel
+     FAIL_REGEX "[Uu]nknown option"                         # HP
+     FAIL_REGEX "[Ww]arning: [Oo]ption"                     # SunPro
+     FAIL_REGEX "command option .* is not recognized"       # XL
+     FAIL_REGEX "command option .* contains an incorrect subargument" # XL
+     FAIL_REGEX "not supported in this configuration. ignored"       # AIX
+     FAIL_REGEX "File with unknown suffix passed to linker" # PGI
+     FAIL_REGEX "[Uu]nknown switch"                         # PGI
+     FAIL_REGEX "WARNING: unknown flag:"                    # Open64
+     FAIL_REGEX "Incorrect command line option:"            # Borland
+     FAIL_REGEX "Warning: illegal option"                   # SunStudio 12
+     FAIL_REGEX "[Ww]arning: Invalid suboption"             # Fujitsu
+   )
+endmacro ()
diff --git a/cmake/contrib/CheckFortranCompilerFlag.cmake b/cmake/contrib/CheckFortranCompilerFlag.cmake
index 6a35c8e..8519fcc 100644
--- a/cmake/contrib/CheckFortranCompilerFlag.cmake
+++ b/cmake/contrib/CheckFortranCompilerFlag.cmake
@@ -1,25 +1,53 @@
-# File taken from CMake Bug Report: http://public.kitware.com/Bug/print_bug_page.php?bug_id=12459
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
 
-# - Check whether the Fortan compiler supports a given flag.
-# CHECK_FORTRAN_COMPILER_FLAG(<flag> <var>)
-#  <flag> - the compiler flag
-#  <var>  - variable to store the result
-# This internally calls the check_fortran_source_compiles macro.  See help
-# for CheckFortranSourceCompiles for a listing of variables that can
-# modify the build.
+#.rst:
+# CheckFortranCompilerFlag
+# ------------------------
+#
+# Check whether the Fortran compiler supports a given flag.
+#
+# CHECK_Fortran_COMPILER_FLAG(<flag> <var>)
+#
+# ::
+#
+#   <flag> - the compiler flag
+#   <var>  - variable to store the result
+#            Will be created as an internal cache variable.
+#
+# This internally calls the check_fortran_source_compiles macro and
+# sets CMAKE_REQUIRED_DEFINITIONS to <flag>.  See help for
+# CheckFortranSourceCompiles for a listing of variables that can
+# otherwise modify the build.  The result only tells that the compiler
+# does not give an error message when it encounters the flag.  If the
+# flag has any effect or even a specific one is beyond the scope of
+# this module.
 
-INCLUDE(CheckFortranSourceCompiles)
+include(CheckFortranSourceCompiles)
+include(CMakeCheckCompilerFlagCommonPatterns)
 
-MACRO (CHECK_FORTRAN_COMPILER_FLAG _FLAG _RESULT)
-   SET(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}")
-   SET(CMAKE_REQUIRED_DEFINITIONS "${_FLAG}")
-   CHECK_FORTRAN_SOURCE_COMPILES("end" ${_RESULT}
-     # Some compilers do not fail with a bad flag
-     FAIL_REGEX "unrecognized .*option"                     # GNU
-     FAIL_REGEX "ignoring unknown option"                   # MSVC
-     FAIL_REGEX "[Uu]nknown option"                         # HP
-     FAIL_REGEX "[Ww]arning: [Oo]ption"                     # SunPro
-     FAIL_REGEX "command option .* is not recognized"       # XL
-     )
-   SET (CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}")
-ENDMACRO (CHECK_FORTRAN_COMPILER_FLAG)
+macro (CHECK_Fortran_COMPILER_FLAG _FLAG _RESULT)
+  set(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}")
+  set(CMAKE_REQUIRED_DEFINITIONS "${_FLAG}")
+
+  # Normalize locale during test compilation.
+  set(_CheckFortranCompilerFlag_LOCALE_VARS LC_ALL LC_MESSAGES LANG)
+  foreach(v ${_CheckFortranCompilerFlag_LOCALE_VARS})
+    set(_CheckFortranCompilerFlag_SAVED_${v} "$ENV{${v}}")
+    set(ENV{${v}} C)
+  endforeach()
+  CHECK_COMPILER_FLAG_COMMON_PATTERNS(_CheckFortranCompilerFlag_COMMON_PATTERNS)
+  CHECK_Fortran_SOURCE_COMPILES("       program test\n       stop\n       end program" ${_RESULT}
+    # Some compilers do not fail with a bad flag
+    FAIL_REGEX "command line option .* is valid for .* but not for Fortran" # GNU
+    ${_CheckFortranCompilerFlag_COMMON_PATTERNS}
+    )
+  foreach(v ${_CheckFortranCompilerFlag_LOCALE_VARS})
+    set(ENV{${v}} ${_CheckFortranCompilerFlag_SAVED_${v}})
+    unset(_CheckFortranCompilerFlag_SAVED_${v})
+  endforeach()
+  unset(_CheckFortranCompilerFlag_LOCALE_VARS)
+  unset(_CheckFortranCompilerFlag_COMMON_PATTERNS)
+
+  set (CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}")
+endmacro ()
diff --git a/cmake/contrib/CheckFortranSourceCompiles.cmake b/cmake/contrib/CheckFortranSourceCompiles.cmake
index 500aee6..c42254c 100644
--- a/cmake/contrib/CheckFortranSourceCompiles.cmake
+++ b/cmake/contrib/CheckFortranSourceCompiles.cmake
@@ -1,61 +1,106 @@
-# File taken from CMake Bug Report: http://public.kitware.com/Bug/print_bug_page.php?bug_id=12459
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
 
-# - Check if the source code provided in the SOURCE argument compiles.
-# CHECK_FORTRAN_SOURCE_COMPILES(SOURCE VAR)
-# - macro which checks if the source code compiles
-#  SOURCE   - source code to try to compile
-#  VAR      - variable to store whether the source code compiled
+#.rst:
+# CheckFortranSourceCompiles
+# --------------------------
 #
-# The following variables may be set before calling this macro to
-# modify the way the check is run:
+# Check if given Fortran source compiles and links into an executable::
 #
-#  CMAKE_REQUIRED_FLAGS = string of compile command line flags
-#  CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
-#  CMAKE_REQUIRED_INCLUDES = list of include directories
-#  CMAKE_REQUIRED_LIBRARIES = list of libraries to link
+#   CHECK_Fortran_SOURCE_COMPILES(<code> <var> [FAIL_REGEX <fail-regex>]
+#                                 [SRC_EXT <ext>])
+#
+# The arguments are:
+#
+# ``<code>``
+#   Source code to try to compile.  It must define a PROGRAM entry point.
+# ``<var>``
+#   Variable to store whether the source code compiled.
+#   Will be created as an internal cache variable.
+# ``FAIL_REGEX <fail-regex>``
+#   Fail if test output matches this regex.
+# ``SRC_EXT <ext>``
+#   Use source extension ``.<ext>`` instead of the default ``.F``.
+#
+# The following variables may be set before calling this macro to modify
+# the way the check is run::
+#
+#   CMAKE_REQUIRED_FLAGS = string of compile command line flags
+#   CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
+#   CMAKE_REQUIRED_INCLUDES = list of include directories
+#   CMAKE_REQUIRED_LIBRARIES = list of libraries to link
+#   CMAKE_REQUIRED_QUIET = execute quietly without messages
 
-MACRO(CHECK_FORTRAN_SOURCE_COMPILES SOURCE VAR)
-  IF("${VAR}" MATCHES "^${VAR}$")
-    SET(MACRO_CHECK_FUNCTION_DEFINITIONS
+macro(CHECK_Fortran_SOURCE_COMPILES SOURCE VAR)
+  if(NOT DEFINED "${VAR}")
+    set(_FAIL_REGEX)
+    set(_SRC_EXT)
+    set(_key)
+    foreach(arg ${ARGN})
+      if("${arg}" MATCHES "^(FAIL_REGEX|SRC_EXT)$")
+        set(_key "${arg}")
+      elseif(_key)
+        list(APPEND _${_key} "${arg}")
+      else()
+        message(FATAL_ERROR "Unknown argument:\n  ${arg}\n")
+      endif()
+    endforeach()
+    if(NOT _SRC_EXT)
+      set(_SRC_EXT F)
+    endif()
+    set(MACRO_CHECK_FUNCTION_DEFINITIONS
       "-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
-    IF(CMAKE_REQUIRED_LIBRARIES)
-      SET(CHECK_FORTRAN_SOURCE_COMPILES_ADD_LIBRARIES
-        "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
-    ELSE(CMAKE_REQUIRED_LIBRARIES)
-      SET(CHECK_FORTRAN_SOURCE_COMPILES_ADD_LIBRARIES)
-    ENDIF(CMAKE_REQUIRED_LIBRARIES)
-    IF(CMAKE_REQUIRED_INCLUDES)
-      SET(CHECK_FORTRAN_SOURCE_COMPILES_ADD_INCLUDES
+    if(CMAKE_REQUIRED_LIBRARIES)
+      set(CHECK_Fortran_SOURCE_COMPILES_ADD_LIBRARIES
+        LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
+    else()
+      set(CHECK_Fortran_SOURCE_COMPILES_ADD_LIBRARIES)
+    endif()
+    if(CMAKE_REQUIRED_INCLUDES)
+      set(CHECK_Fortran_SOURCE_COMPILES_ADD_INCLUDES
         "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
-    ELSE(CMAKE_REQUIRED_INCLUDES)
-      SET(CHECK_FORTRAN_SOURCE_COMPILES_ADD_INCLUDES)
-    ENDIF(CMAKE_REQUIRED_INCLUDES)
-    FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.f90"
+    else()
+      set(CHECK_Fortran_SOURCE_COMPILES_ADD_INCLUDES)
+    endif()
+    file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.${_SRC_EXT}"
       "${SOURCE}\n")
 
-    MESSAGE(STATUS "Performing Test ${VAR}")
-    TRY_COMPILE(${VAR}
+    if(NOT CMAKE_REQUIRED_QUIET)
+      message(STATUS "Performing Test ${VAR}")
+    endif()
+    try_compile(${VAR}
       ${CMAKE_BINARY_DIR}
-      ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.f90
+      ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.${_SRC_EXT}
       COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+      ${CHECK_Fortran_SOURCE_COMPILES_ADD_LIBRARIES}
       CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
-      "${CHECK_FORTRAN_SOURCE_COMPILES_ADD_LIBRARIES}"
-      "${CHECK_FORTRAN_SOURCE_COMPILES_ADD_INCLUDES}"
+      "${CHECK_Fortran_SOURCE_COMPILES_ADD_INCLUDES}"
       OUTPUT_VARIABLE OUTPUT)
-    IF(${VAR})
-      SET(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
-      MESSAGE(STATUS "Performing Test ${VAR} - Success")
-      FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
-        "Performing Fortran SOURCE FILE Test ${VAR} succeded with the following output:\n"
+
+    foreach(_regex ${_FAIL_REGEX})
+      if("${OUTPUT}" MATCHES "${_regex}")
+        set(${VAR} 0)
+      endif()
+    endforeach()
+
+    if(${VAR})
+      set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
+      if(NOT CMAKE_REQUIRED_QUIET)
+        message(STATUS "Performing Test ${VAR} - Success")
+      endif()
+      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+        "Performing Fortran SOURCE FILE Test ${VAR} succeeded with the following output:\n"
         "${OUTPUT}\n"
         "Source file was:\n${SOURCE}\n")
-    ELSE(${VAR})
-      MESSAGE(STATUS "Performing Test ${VAR} - Failed")
-      SET(${VAR} 0 CACHE INTERNAL "Test ${VAR}")
-      FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+    else()
+      if(NOT CMAKE_REQUIRED_QUIET)
+        message(STATUS "Performing Test ${VAR} - Failed")
+      endif()
+      set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
+      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
         "Performing Fortran SOURCE FILE Test ${VAR} failed with the following output:\n"
         "${OUTPUT}\n"
         "Source file was:\n${SOURCE}\n")
-    ENDIF(${VAR})
-  ENDIF("${VAR}" MATCHES "^${VAR}$")
-ENDMACRO(CHECK_FORTRAN_SOURCE_COMPILES)
+    endif()
+  endif()
+endmacro()
diff --git a/cmake/contrib/FindNetCDF4.cmake b/cmake/contrib/FindNetCDF4.cmake
index 6bba4e0..70e54af 100644
--- a/cmake/contrib/FindNetCDF4.cmake
+++ b/cmake/contrib/FindNetCDF4.cmake
@@ -149,11 +149,11 @@ else()
     set( NETCDF_F90_INCLUDE_NAMES netcdf.mod typesizes.mod ${NETCDF_C_INCLUDE_NAMES} )
 
     set( NETCDF_C_LIBRARY_NAMES netcdf)
-    set( NETCDF_CXX_LIBRARY_NAMES netcdf_c++ ${NETCDF_C_LIBRARY_NAMES} )
+    set( NETCDF_CXX_LIBRARY_NAMES netcdf_c++ netcdf_c++4 ${NETCDF_C_LIBRARY_NAMES} )
     set( NETCDF_FORTRAN_LIBRARY_NAMES netcdff ${NETCDF_C_LIBRARY_NAMES})
     set( NETCDF_F90_LIBRARY_NAMES ${NETCDF_FORTRAN_LIBRARY_NAMES} )
 
-    set( NETCDF_REQUIRED netcdf.h netcdfcpp.h netcdf.mod typesizes.mod netcdf netcdff netcdf_c++)
+    set( NETCDF_REQUIRED netcdf.h netcdfcpp.h netcdf.mod typesizes.mod netcdf netcdff netcdf_c++ netcdf_c++4)
 
     foreach( LANGUAGE ${NETCDF_LANGUAGE_BINDINGS} )
         ecbuild_debug("FindNetCDF4: looking for ${LANGUAGE} language bindings")
diff --git a/cmake/contrib/GreatCMakeCookOff/AddCPP11Flags.cmake b/cmake/contrib/GreatCMakeCookOff/AddCPP11Flags.cmake
index 2a11e04..ac7f456 100644
--- a/cmake/contrib/GreatCMakeCookOff/AddCPP11Flags.cmake
+++ b/cmake/contrib/GreatCMakeCookOff/AddCPP11Flags.cmake
@@ -29,6 +29,7 @@ endif(CMAKE_VERSION VERSION_LESS 2.8.9)
 
 check_cxx_compiler_flag(-std=c++11 has_std_cpp11)
 check_cxx_compiler_flag(-std=c++0x has_std_cpp0x)
+check_cxx_compiler_flag(-hstd=c++11 has_hstd_cpp11)
 if(MINGW) 
   check_cxx_compiler_flag(-std=gnu++11 has_std_gnupp11)
   check_cxx_compiler_flag(-std=gnu++0x has_std_gnupp0x)
@@ -37,10 +38,12 @@ if(has_std_gnupp11)
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
 elseif(has_std_gnupp0x)
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++0x")
-elseif(has_std_cpp11) 
+elseif(has_std_cpp11)
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
 elseif(has_std_cpp0x)
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
+elseif(has_hstd_cpp11)
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -hstd=c++11")
 endif(has_std_gnupp11)
 
 if(MSVC) 
diff --git a/cmake/contrib/GreatCMakeCookOff/CheckCXX11Features.cmake b/cmake/contrib/GreatCMakeCookOff/CheckCXX11Features.cmake
index 71fa610..593b62f 100644
--- a/cmake/contrib/GreatCMakeCookOff/CheckCXX11Features.cmake
+++ b/cmake/contrib/GreatCMakeCookOff/CheckCXX11Features.cmake
@@ -1,14 +1,14 @@
 # Checks for C++11 features
-# 
+#
 # USAGE: There are two functions
 #
-# cxx11_find_all_features(OUTPUT_VARIABLE) 
+# cxx11_find_all_features(OUTPUT_VARIABLE)
 # This function returns a variable with all possible features.
 #
 # cxx11_feature_check([feature feature] [REQUIRED [feature feature]])
 # If no arguments are provided, then checks all available features
 # Features appeacing before REQUIRED are optional.
-# If arguments are provided and those features are available, sets 
+# If arguments are provided and those features are available, sets
 # the variable HAS_CXX11_FEATURENAME, where FEATURENAME is the input in capital letters.
 # Fails if required feature are not available
 #
@@ -17,65 +17,66 @@
 # Original script by Rolf Eike Beer
 # Modifications by Andreas Weis
 # Further Modifications by RSDT at UCL
+# Adapted to ecBuild by Florian Rathgeber <florian.rathgeber at ecmwf.int>
 
 set(CPP11_FEATURE_CHECK_DIR ${CMAKE_CURRENT_LIST_DIR}/cpp11 CACHE INTERNAL "c++11 file directory")
 
 MACRO(cxx11_check_single_feature FEATURE_NAME FEATURE_NUMBER RESULT_VAR)
-	IF (NOT DEFINED ${RESULT_VAR})
+  IF (NOT DEFINED ${RESULT_VAR})
     SET(_bindir "${CMAKE_BINARY_DIR}/cxx11_feature_tests/cxx11_${FEATURE_NAME}")
 
-		IF (${FEATURE_NUMBER})
+    IF (${FEATURE_NUMBER})
       SET(_SRCFILE_BASE ${CPP11_FEATURE_CHECK_DIR}/${FEATURE_NAME}-N${FEATURE_NUMBER})
-			SET(_LOG_NAME "\"${FEATURE_NAME}\" (N${FEATURE_NUMBER})")
-		ELSE (${FEATURE_NUMBER})
+      SET(_LOG_NAME "\"${FEATURE_NAME}\" (N${FEATURE_NUMBER})")
+    ELSE (${FEATURE_NUMBER})
       SET(_SRCFILE_BASE ${CPP11_FEATURE_CHECK_DIR}/${FEATURE_NAME})
-			SET(_LOG_NAME "\"${FEATURE_NAME}\"")
-		ENDIF (${FEATURE_NUMBER})
-		MESSAGE(STATUS "Checking C++11 support for ${_LOG_NAME}")
-
-		SET(_SRCFILE "${_SRCFILE_BASE}.cpp")
-		SET(_SRCFILE_FAIL "${_SRCFILE_BASE}_fail.cpp")
-		SET(_SRCFILE_FAIL_COMPILE "${_SRCFILE_BASE}_fail_compile.cpp")
-
-		IF (CROSS_COMPILING)
-			try_compile(${RESULT_VAR} "${_bindir}" "${_SRCFILE}")
-			IF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
-				try_compile(${RESULT_VAR} "${_bindir}_fail" "${_SRCFILE_FAIL}")
-			ENDIF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
-		ELSE (CROSS_COMPILING)
-			try_run(_RUN_RESULT_VAR _COMPILE_RESULT_VAR
-					"${_bindir}" "${_SRCFILE}")
-			IF (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR)
-				SET(${RESULT_VAR} TRUE)
-			ELSE (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR)
-				SET(${RESULT_VAR} FALSE)
-			ENDIF (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR)
-			IF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
-				try_run(_RUN_RESULT_VAR _COMPILE_RESULT_VAR
-						"${_bindir}_fail" "${_SRCFILE_FAIL}")
-				IF (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR)
-					SET(${RESULT_VAR} TRUE)
-				ELSE (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR)
-					SET(${RESULT_VAR} FALSE)
-				ENDIF (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR)
-			ENDIF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
-		ENDIF (CROSS_COMPILING)
-		IF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL_COMPILE})
-			try_compile(_TMP_RESULT "${_bindir}_fail_compile" "${_SRCFILE_FAIL_COMPILE}")
-			IF (_TMP_RESULT)
-				SET(${RESULT_VAR} FALSE)
-			ELSE (_TMP_RESULT)
-				SET(${RESULT_VAR} TRUE)
-			ENDIF (_TMP_RESULT)
-		ENDIF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL_COMPILE})
-
-		IF (${RESULT_VAR})
-			MESSAGE(STATUS "Checking C++11 support for ${_LOG_NAME} -- works")
-		ELSE (${RESULT_VAR})
-			MESSAGE(STATUS "Checking C++11 support for ${_LOG_NAME} -- not supported")
-		ENDIF (${RESULT_VAR})
-		SET(${RESULT_VAR} ${${RESULT_VAR}} CACHE INTERNAL "C++11 support for ${_LOG_NAME}")
-	ENDIF (NOT DEFINED ${RESULT_VAR})
+      SET(_LOG_NAME "\"${FEATURE_NAME}\"")
+    ENDIF (${FEATURE_NUMBER})
+    ecbuild_info("Checking C++11 support for ${_LOG_NAME}")
+
+    SET(_SRCFILE "${_SRCFILE_BASE}.cpp")
+    SET(_SRCFILE_FAIL "${_SRCFILE_BASE}_fail.cpp")
+    SET(_SRCFILE_FAIL_COMPILE "${_SRCFILE_BASE}_fail_compile.cpp")
+
+    IF (CROSS_COMPILING)
+      try_compile(${RESULT_VAR} "${_bindir}" "${_SRCFILE}")
+      IF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
+        try_compile(${RESULT_VAR} "${_bindir}_fail" "${_SRCFILE_FAIL}")
+      ENDIF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
+    ELSE (CROSS_COMPILING)
+      try_run(_RUN_RESULT_VAR _COMPILE_RESULT_VAR
+          "${_bindir}" "${_SRCFILE}")
+      IF (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR)
+        SET(${RESULT_VAR} TRUE)
+      ELSE (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR)
+        SET(${RESULT_VAR} FALSE)
+      ENDIF (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR)
+      IF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
+        try_run(_RUN_RESULT_VAR _COMPILE_RESULT_VAR
+            "${_bindir}_fail" "${_SRCFILE_FAIL}")
+        IF (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR)
+          SET(${RESULT_VAR} TRUE)
+        ELSE (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR)
+          SET(${RESULT_VAR} FALSE)
+        ENDIF (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR)
+      ENDIF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
+    ENDIF (CROSS_COMPILING)
+    IF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL_COMPILE})
+      try_compile(_TMP_RESULT "${_bindir}_fail_compile" "${_SRCFILE_FAIL_COMPILE}")
+      IF (_TMP_RESULT)
+        SET(${RESULT_VAR} FALSE)
+      ELSE (_TMP_RESULT)
+        SET(${RESULT_VAR} TRUE)
+      ENDIF (_TMP_RESULT)
+    ENDIF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL_COMPILE})
+
+    IF (${RESULT_VAR})
+      ecbuild_info("Checking C++11 support for ${_LOG_NAME} -- works")
+    ELSE (${RESULT_VAR})
+      ecbuild_info("Checking C++11 support for ${_LOG_NAME} -- not supported")
+    ENDIF (${RESULT_VAR})
+    SET(${RESULT_VAR} ${${RESULT_VAR}} CACHE INTERNAL "C++11 support for ${_LOG_NAME}")
+  ENDIF (NOT DEFINED ${RESULT_VAR})
 ENDMACRO(cxx11_check_single_feature)
 
 # Find list of all features
@@ -138,12 +139,12 @@ macro(_figure_out_cxx11_feature current_feature)
       list(REMOVE_ITEM ALL_FEATURE_FILES ${filename})
     endif()
   endforeach()
-  
+
   list(LENGTH ALL_FEATURE_FILES NFILES)
   if(NOT ${NFILES} EQUAL 1)
-    message(FATAL_ERROR "[c++11] Expected to find only one feature. Found ${NFILES} -- ${ALL_FEATURE_FILES}.")
+    ecbuild_critical("[c++11] Expected to find only one feature. Found ${NFILES} -- ${ALL_FEATURE_FILES}.")
   endif(NOT ${NFILES} EQUAL 1)
-  
+
   # Now we know which file corresponds to option.
   get_filename_component(basename ${ALL_FEATURE_FILES} NAME_WE)
   # If has feature number, extract it
@@ -165,18 +166,18 @@ function(cxx11_feature_check)
   # Parses input to this function.
   parse_input_features("${ALL_CPP11_FEATURES}" OPTIONALS REQUIRED ERRORS ${ARGN})
   if(NOT ${ERRORS} STREQUAL "")
-    message(STATUS "[c++11] The following features are unknown: ${ERRORS}.")
+    ecbuild_info("[c++11] The following features are unknown: ${ERRORS}.")
   endif()
 
   # MinGW has not implemented std::random_device fully yet. Unfortunately, this can only be detected
   # by running a program which tries to call std::random_device. However that generates an error that
-  # is *not* caught by CMake's try_run. 
+  # is *not* caught by CMake's try_run.
   if(MSYS)
     list(REMOVE_ITEM OPTIONALS "random_device")
     list(FIND REQUIRED "random_device" feature_was_found)
     if(NOT feature_was_found EQUAL "-1")
-      message(FATAL_ERROR "[c++1] MSYS does not implement Random devices fully.\n"
-                          "       It cannot be required on this system.")
+      ecbuild_critical("[c++1] MSYS does not implement Random devices fully.\n"
+                       "       It cannot be required on this system.")
     endif()
   endif()
 
@@ -190,7 +191,7 @@ function(cxx11_feature_check)
     _figure_out_cxx11_feature(${current_feature})
     set(VARNAME HAS_CXX11_${UPPER_OPTIONAL})
     if(NOT ${VARNAME})
-      message(FATAL_ERROR "[c++11] Required feature ${current_feature} is not available.")
+      ecbuild_critical("[c++11] Required feature ${current_feature} is not available.")
     endif(NOT ${VARNAME})
   endforeach(current_feature ${REQUIRED})
 
diff --git a/cmake/ecbuild_add_executable.cmake b/cmake/ecbuild_add_executable.cmake
index 4572832..424059e 100644
--- a/cmake/ecbuild_add_executable.cmake
+++ b/cmake/ecbuild_add_executable.cmake
@@ -26,7 +26,7 @@
 #                           [ PERSISTENT <file1> [<file2> ...] ]
 #                           [ GENERATED <file1> [<file2> ...] ]
 #                           [ DEPENDS <target1> [<target2> ...] ]
-#                           [ CONDITION <condition1> [<condition2> ...] ]
+#                           [ CONDITION <condition> ]
 #                           [ NOINSTALL ]
 #                           [ VERSION <version> | AUTO_VERSION ]
 #                           [ CFLAGS <flag1> [<flag2> ...] ]
@@ -232,66 +232,10 @@ macro( ecbuild_add_executable )
     #   ecbuild_debug_var( ${_PAR_TARGET}_h_srcs )
     #   ecbuild_debug_var( ${_PAR_TARGET}_c_srcs )
     #   ecbuild_debug_var( ${_PAR_TARGET}_cxx_srcs )
-    #   ecbuild_debug_var( ${_PAR_TARGET}_f_srcs )
+    #   ecbuild_debug_var( ${_PAR_TARGET}_fortran_srcs )
 
-    # add local flags
-
-    if( ${_PAR_TARGET}_c_srcs )
-
-      if( ECBUILD_SOURCE_FLAGS )
-        ecbuild_source_flags( ${_PAR_TARGET}_C_SOURCE_FLAGS
-                              ${_PAR_TARGET}_c
-                              "${_PAR_CFLAGS}"
-                              "${${_PAR_TARGET}_c_srcs}" )
-
-        ecbuild_debug("ecbuild_add_executable(${_PAR_TARGET}): setting source file C flags from ${${_PAR_TARGET}_C_SOURCE_FLAGS}")
-        include( ${${_PAR_TARGET}_C_SOURCE_FLAGS} )
-
-      elseif( DEFINED _PAR_CFLAGS )
-
-        ecbuild_debug("ecbuild_add_executable(${_PAR_TARGET}): use C flags ${_PAR_CFLAGS}")
-        set_source_files_properties( ${${_PAR_TARGET}_c_srcs}   PROPERTIES COMPILE_FLAGS "${_PAR_CFLAGS}" )
-
-      endif()
-    endif()
-
-    if( ${_PAR_TARGET}_cxx_srcs )
-
-      if( ECBUILD_SOURCE_FLAGS )
-        ecbuild_source_flags( ${_PAR_TARGET}_CXX_SOURCE_FLAGS
-                              ${_PAR_TARGET}_cxx
-                              "${_PAR_CXXFLAGS}"
-                              "${${_PAR_TARGET}_cxx_srcs}" )
-
-        ecbuild_debug("ecbuild_add_executable(${_PAR_TARGET}): setting source file CXX flags from ${${_PAR_TARGET}_CXX_SOURCE_FLAGS}")
-        include( ${${_PAR_TARGET}_CXX_SOURCE_FLAGS} )
-
-      elseif( DEFINED _PAR_CXXFLAGS )
-
-        ecbuild_debug("ecbuild_add_executable(${_PAR_TARGET}): use C++ flags ${_PAR_CFLAGS}")
-        set_source_files_properties( ${${_PAR_TARGET}_cxx_srcs} PROPERTIES COMPILE_FLAGS "${_PAR_CXXFLAGS}" )
-
-      endif()
-    endif()
-
-    if( ${_PAR_TARGET}_f_srcs )
-
-      if( ECBUILD_SOURCE_FLAGS )
-        ecbuild_source_flags( ${_PAR_TARGET}_Fortran_SOURCE_FLAGS
-                              ${_PAR_TARGET}_f
-                              "${_PAR_FFLAGS}"
-                              "${${_PAR_TARGET}_f_srcs}" )
-
-        ecbuild_debug("ecbuild_add_executable(${_PAR_TARGET}): setting source file Fortran flags from ${${_PAR_TARGET}_Fortran_SOURCE_FLAGS}")
-        include( ${${_PAR_TARGET}_Fortran_SOURCE_FLAGS} )
-
-      elseif( DEFINED _PAR_FFLAGS )
-
-        ecbuild_debug("ecbuild_add_executable(${_PAR_TARGET}): use Fortran flags ${_PAR_CFLAGS}")
-        set_source_files_properties( ${${_PAR_TARGET}_f_srcs}  PROPERTIES COMPILE_FLAGS "${_PAR_FFLAGS}" )
-
-      endif()
-    endif()
+    # Override compilation flags on a per source file basis
+    ecbuild_target_flags( ${_PAR_TARGET} "${_PAR_CFLAGS}" "${_PAR_CXXFLAGS}" "${_PAR_FFLAGS}" )
 
     # define VERSION if requested
     if( DEFINED _PAR_VERSION )
diff --git a/cmake/ecbuild_add_fortran_flags.cmake b/cmake/ecbuild_add_fortran_flags.cmake
index 17b9bf2..0d3b544 100644
--- a/cmake/ecbuild_add_fortran_flags.cmake
+++ b/cmake/ecbuild_add_fortran_flags.cmake
@@ -64,7 +64,14 @@ macro( ecbuild_add_fortran_flags m_fortran_flags )
 
       math( EXPR N_FortranFLAG '${N_FortranFLAG}+1' )
 
-      if( NOT ECBUILD_TRUST_FLAGS )
+      if( ECBUILD_TRUST_FLAGS )
+        set( _flag_ok 1 )
+      # Due to a bug in CMake < 3.0, check_fortran_compiler_flag ALWAYS fails with ifort
+      # see https://cmake.org/Bug/view.php?id=14507
+      elseif( CMAKE_MAJOR_VERSION LESS 3 AND CMAKE_Fortran_COMPILER_ID MATCHES "Intel" )
+        set( _flag_ok 1 )
+        ecbuild_warn( "Not testing Fortran flags due to a bug in CMake < 3.0 with ifort" )
+      else()
         if( DEFINED _PAR_NAME )
           check_fortran_compiler_flag( ${_flags} ${_PAR_NAME} )
           set( _flag_ok ${${_PAR_NAME}} )
@@ -72,8 +79,6 @@ macro( ecbuild_add_fortran_flags m_fortran_flags )
           check_fortran_compiler_flag( ${_flags} Fortran_FLAG_TEST_${N_FortranFLAG} )
           set( _flag_ok ${Fortran_FLAG_TEST_${N_FortranFLAG}} )
         endif()
-      else()
-        set( _flag_ok 1 )
       endif()
 
       if( _flag_ok )
diff --git a/cmake/ecbuild_add_library.cmake b/cmake/ecbuild_add_library.cmake
index 48602a4..a7f8001 100644
--- a/cmake/ecbuild_add_library.cmake
+++ b/cmake/ecbuild_add_library.cmake
@@ -29,13 +29,14 @@
 #                        [ PERSISTENT <file1> [<file2> ...] ]
 #                        [ GENERATED <file1> [<file2> ...] ]
 #                        [ DEPENDS <target1> [<target2> ...] ]
-#                        [ CONDITION <condition1> [<condition2> ...] ]
+#                        [ CONDITION <condition> ]
 #                        [ NOINSTALL ]
 #                        [ HEADER_DESTINATION <path> ]
 #                        [ INSTALL_HEADERS LISTED|ALL ]
 #                        [ INSTALL_HEADERS_LIST <header1> [<header2> ...] ]
 #                        [ INSTALL_HEADERS_REGEX <pattern> ]
 #                        [ VERSION <version> | AUTO_VERSION ]
+#                        [ SOVERSION <soversion> | AUTO_SOVERSION ]
 #                        [ CFLAGS <flag1> [<flag2> ...] ]
 #                        [ CXXFLAGS <flag1> [<flag2> ...] ]
 #                        [ FFLAGS <flag1> [<flag2> ...] ]
@@ -123,10 +124,16 @@
 #   regular expression to match extra headers to install
 #
 # VERSION : optional, AUTO_VERSION or LIBS_VERSION is used if not specified
-#   version to use as library version
+#   build version of the library
 #
 # AUTO_VERSION : optional, ignored if VERSION is specified
-#   automatically version the library with the package version
+#   use MAJOR.MINOR package version as build version of the library
+#
+# SOVERSION : optional, AUTO_SOVERSION or LIBS_SOVERSION is used if not specified
+#   ABI version of the library
+#
+# AUTO_SOVERSION : optional, ignored if SOVERSION is specified
+#   use MAJOR package version as ABI version of the library
 #
 # CFLAGS : optional
 #   list of C compiler flags to use for all C source files
@@ -147,8 +154,8 @@
 
 function( ecbuild_add_library_impl )
 
-  set( options NOINSTALL AUTO_VERSION )
-  set( single_value_args TARGET TYPE COMPONENT INSTALL_HEADERS INSTALL_HEADERS_REGEX LINKER_LANGUAGE HEADER_DESTINATION VERSION OUTPUT_NAME )
+  set( options NOINSTALL AUTO_VERSION AUTO_SOVERSION )
+  set( single_value_args TARGET TYPE COMPONENT INSTALL_HEADERS INSTALL_HEADERS_REGEX LINKER_LANGUAGE HEADER_DESTINATION VERSION SOVERSION OUTPUT_NAME )
   set( multi_value_args  SOURCES SOURCES_GLOB SOURCES_EXCLUDE_REGEX OBJECTS TEMPLATES LIBS INCLUDES PRIVATE_INCLUDES PUBLIC_INCLUDES DEPENDS PERSISTENT DEFINITIONS INSTALL_HEADERS_LIST CFLAGS CXXFLAGS FFLAGS GENERATED CONDITION )
 
   cmake_parse_arguments( _PAR "${options}" "${single_value_args}" "${multi_value_args}"  ${_FIRST_ARG} ${ARGN} )
@@ -330,19 +337,32 @@ function( ecbuild_add_library_impl )
 
     # define VERSION if requested
     if( DEFINED _PAR_VERSION )
-      ecbuild_debug("ecbuild_add_library(${_PAR_TARGET}): set version to ${_PAR_VERSION}")
+      ecbuild_debug("ecbuild_add_library(${_PAR_TARGET}): set build version to ${_PAR_VERSION}")
       set_target_properties( ${_PAR_TARGET} PROPERTIES VERSION "${_PAR_VERSION}" )
     else()
       if( _PAR_AUTO_VERSION OR LIBS_VERSION MATCHES "[Aa][Uu][Tt][Oo]")
-        ecbuild_debug("ecbuild_add_library(${_PAR_TARGET}): set version to ${${PNAME}_MAJOR_VERSION}.${${PNAME}_MINOR_VERSION} (auto)")
+        ecbuild_debug("ecbuild_add_library(${_PAR_TARGET}): set build version to ${${PNAME}_MAJOR_VERSION}.${${PNAME}_MINOR_VERSION} (auto)")
         set_target_properties( ${_PAR_TARGET} PROPERTIES VERSION "${${PNAME}_MAJOR_VERSION}.${${PNAME}_MINOR_VERSION}" )
-      endif()
-      if( LIBS_VERSION AND NOT LIBS_VERSION MATCHES "[Aa][Uu][Tt][Oo]" )
-        ecbuild_debug("ecbuild_add_library(${_PAR_TARGET}): set version to ${LIBS_VERSION}")
+      elseif( DEFINED LIBS_VERSION )
+        ecbuild_debug("ecbuild_add_library(${_PAR_TARGET}): set build version to ${LIBS_VERSION}")
         set_target_properties( ${_PAR_TARGET} PROPERTIES VERSION "${LIBS_VERSION}" )
       endif()
     endif()
 
+    # define SOVERSION if requested
+    if( DEFINED _PAR_SOVERSION )
+      ecbuild_debug("ecbuild_add_library(${_PAR_TARGET}): set ABI version to ${_PAR_SOVERSION}")
+      set_target_properties( ${_PAR_TARGET} PROPERTIES SOVERSION "${_PAR_SOVERSION}" )
+    else()
+      if( _PAR_AUTO_SOVERSION OR LIBS_SOVERSION MATCHES "[Aa][Uu][Tt][Oo]")
+        ecbuild_debug("ecbuild_add_library(${_PAR_TARGET}): set ABI version to ${${PNAME}_MAJOR_VERSION} (auto)")
+        set_target_properties( ${_PAR_TARGET} PROPERTIES SOVERSION "${${PNAME}_MAJOR_VERSION}" )
+      elseif( DEFINED LIBS_SOVERSION )
+        ecbuild_debug("ecbuild_add_library(${_PAR_TARGET}): set ABI version to ${LIBS_SOVERSION}")
+        set_target_properties( ${_PAR_TARGET} PROPERTIES SOVERSION "${LIBS_SOVERSION}" )
+      endif()
+    endif()
+
     # filter sources
 
     if( _PAR_SOURCES )
@@ -352,66 +372,10 @@ function( ecbuild_add_library_impl )
     #   ecbuild_debug_var( ${_PAR_TARGET}_h_srcs )
     #   ecbuild_debug_var( ${_PAR_TARGET}_c_srcs )
     #   ecbuild_debug_var( ${_PAR_TARGET}_cxx_srcs )
-    #   ecbuild_debug_var( ${_PAR_TARGET}_f_srcs )
-
-    # add local flags
-
-    if( ${_PAR_TARGET}_c_srcs )
-
-      if( ECBUILD_SOURCE_FLAGS )
-        ecbuild_source_flags( ${_PAR_TARGET}_C_SOURCE_FLAGS
-                              ${_PAR_TARGET}_c
-                              "${_PAR_CFLAGS}"
-                              "${${_PAR_TARGET}_c_srcs}" )
-
-        ecbuild_debug("ecbuild_add_library(${_PAR_TARGET}): setting source file C flags from ${${_PAR_TARGET}_C_SOURCE_FLAGS}")
-        include( ${${_PAR_TARGET}_C_SOURCE_FLAGS} )
-
-      elseif( DEFINED _PAR_CFLAGS )
-
-        ecbuild_debug("ecbuild_add_library(${_PAR_TARGET}): use C flags ${_PAR_CFLAGS}")
-        set_source_files_properties( ${${_PAR_TARGET}_c_srcs}   PROPERTIES COMPILE_FLAGS "${_PAR_CFLAGS}" )
-
-      endif()
-    endif()
+    #   ecbuild_debug_var( ${_PAR_TARGET}_fortran_srcs )
 
-    if( ${_PAR_TARGET}_cxx_srcs )
-
-      if( ECBUILD_SOURCE_FLAGS )
-        ecbuild_source_flags( ${_PAR_TARGET}_CXX_SOURCE_FLAGS
-                              ${_PAR_TARGET}_cxx
-                              "${_PAR_CXXFLAGS}"
-                              "${${_PAR_TARGET}_cxx_srcs}" )
-
-        ecbuild_debug("ecbuild_add_library(${_PAR_TARGET}): setting source file CXX flags from ${${_PAR_TARGET}_CXX_SOURCE_FLAGS}")
-        include( ${${_PAR_TARGET}_CXX_SOURCE_FLAGS} )
-
-      elseif( DEFINED _PAR_CXXFLAGS )
-
-        ecbuild_debug("ecbuild_add_library(${_PAR_TARGET}): use C++ flags ${_PAR_CFLAGS}")
-        set_source_files_properties( ${${_PAR_TARGET}_cxx_srcs} PROPERTIES COMPILE_FLAGS "${_PAR_CXXFLAGS}" )
-
-      endif()
-    endif()
-
-    if( ${_PAR_TARGET}_f_srcs )
-
-      if( ECBUILD_SOURCE_FLAGS )
-        ecbuild_source_flags( ${_PAR_TARGET}_Fortran_SOURCE_FLAGS
-                              ${_PAR_TARGET}_f
-                              "${_PAR_FFLAGS}"
-                              "${${_PAR_TARGET}_f_srcs}" )
-
-        ecbuild_debug("ecbuild_add_library(${_PAR_TARGET}): setting source file Fortran flags from ${${_PAR_TARGET}_Fortran_SOURCE_FLAGS}")
-        include( ${${_PAR_TARGET}_Fortran_SOURCE_FLAGS} )
-
-      elseif( DEFINED _PAR_FFLAGS )
-
-        ecbuild_debug("ecbuild_add_library(${_PAR_TARGET}): use Fortran flags ${_PAR_CFLAGS}")
-        set_source_files_properties( ${${_PAR_TARGET}_f_srcs}  PROPERTIES COMPILE_FLAGS "${_PAR_FFLAGS}" )
-
-      endif()
-    endif()
+    # Override compilation flags on a per source file basis
+    ecbuild_target_flags( ${_PAR_TARGET} "${_PAR_CFLAGS}" "${_PAR_CXXFLAGS}" "${_PAR_FFLAGS}" )
 
     if( DEFINED _PAR_GENERATED )
       ecbuild_debug("ecbuild_add_library(${_PAR_TARGET}): mark as generated ${_PAR_GENERATED}")
diff --git a/cmake/ecbuild_add_option.cmake b/cmake/ecbuild_add_option.cmake
index 8261bd4..fd8076e 100644
--- a/cmake/ecbuild_add_option.cmake
+++ b/cmake/ecbuild_add_option.cmake
@@ -19,8 +19,8 @@
 #                       [ DESCRIPTION <description> ]
 #                       [ PURPOSE <purpose> ]
 #                       [ REQUIRED_PACKAGES <package1> [<package2> ...] ]
-#                       [ CONDITION <condition1> [<condition2> ...] ]
-#                       [ ADVANCED ] )
+#                       [ CONDITION <condition> ]
+#                       [ ADVANCED ] [ NO_TPL ] )
 #
 # Options
 # -------
@@ -66,6 +66,9 @@
 # ADVANCED : optional
 #   mark the feature as advanced
 #
+# NO_TPL : optional
+#   do not add any ``REQUIRED_PACKAGES`` to the list of third party libraries
+#
 # Usage
 # -----
 #
@@ -84,7 +87,7 @@
 
 macro( ecbuild_add_option )
 
-  set( options ADVANCED )
+  set( options ADVANCED NO_TPL )
   set( single_value_args FEATURE DEFAULT DESCRIPTION TYPE PURPOSE )
   set( multi_value_args  REQUIRED_PACKAGES CONDITION )
 
@@ -129,17 +132,16 @@ macro( ecbuild_add_option )
     set( _${_p_FEATURE}_condition TRUE )
   endif()
 
-  # check if user provided value
-
-  get_property( _in_cache CACHE ENABLE_${_p_FEATURE} PROPERTY VALUE )
+  # Check if user explicitly enabled/disabled the feature in cache
+  get_property( _in_cache CACHE ENABLE_${_p_FEATURE} PROPERTY VALUE SET )
 
   # A feature set to REQUIRE is always treated as explicitly enabled
   if( ENABLE_${_p_FEATURE} MATCHES "REQUIRE" )
     set( ENABLE_${_p_FEATURE} ON CACHE BOOL "" FORCE )
     ecbuild_debug("ecbuild_add_option(${_p_FEATURE}): ENABLE_${_p_FEATURE} was required")
     set( ${_p_FEATURE}_user_provided_input 1 CACHE BOOL "" FORCE )
-  elseif( NOT "${ENABLE_${_p_FEATURE}}" STREQUAL "" AND _in_cache )
-    ecbuild_debug("ecbuild_add_option(${_p_FEATURE}): ENABLE_${_p_FEATURE} was found in cache")
+  elseif( NOT ENABLE_${_p_FEATURE} STREQUAL "" AND _in_cache )
+    ecbuild_debug("ecbuild_add_option(${_p_FEATURE}): ENABLE_${_p_FEATURE}=${ENABLE_${_p_FEATURE}} was found in cache")
     set( ${_p_FEATURE}_user_provided_input 1 CACHE BOOL "" )
   else()
     ecbuild_debug("ecbuild_add_option(${_p_FEATURE}): ENABLE_${_p_FEATURE} not found in cache")
@@ -159,13 +161,9 @@ macro( ecbuild_add_option )
                           TYPE ${_p_TYPE}
                           PURPOSE "${_p_PURPOSE}" )
 
-  ecbuild_debug("ecbuild_add_option(${_p_FEATURE}): ENABLE_${_p_FEATURE} = ${ENABLE_${_p_FEATURE}}")
-  set( _do_search ${ENABLE_${_p_FEATURE}} )
-  if( _p_FEATURE STREQUAL "OMP" )
-    set( _do_search TRUE )
-  endif()
+  ecbuild_debug("ecbuild_add_option(${_p_FEATURE}): ENABLE_${_p_FEATURE}=${ENABLE_${_p_FEATURE}}")
 
-  if( _do_search  )
+  if( ENABLE_${_p_FEATURE} )
     ecbuild_debug("ecbuild_add_option(${_p_FEATURE}): feature enabled")
 
     set( HAVE_${_p_FEATURE} 1 )
@@ -196,6 +194,7 @@ macro( ecbuild_add_option )
         string( TOUPPER ${pkgname} pkgUPPER )
         string( TOLOWER ${pkgname} pkgLOWER )
 
+        set( __help_msg "Provide ${pkgname} location with -D${pkgUPPER}_PATH=/..." )
         if( ${pkgname}_FOUND OR ${pkgUPPER}_FOUND OR ${pkgLOWER}_FOUND )
 
           ecbuild_debug("ecbuild_add_option(${_p_FEATURE}): ${pkgname} has already been found")
@@ -205,7 +204,7 @@ macro( ecbuild_add_option )
 
           if( pkgproject )
 
-            ecbuild_debug("ecbuild_add_option(${_p_FEATURE}): searching for ecbuild project ${pkgname}")
+            ecbuild_debug("ecbuild_add_option(${_p_FEATURE}): searching for ecbuild project ${pkgname} - ecbuild_use_package( ${pkglist} )")
             ecbuild_use_package( ${pkglist} )
 
           else()
@@ -213,7 +212,7 @@ macro( ecbuild_add_option )
             if( pkgname STREQUAL "MPI" )
               set( _find_args ${pkglist} )
               list( REMOVE_ITEM _find_args "MPI" )
-              ecbuild_debug("ecbuild_add_option(${_p_FEATURE}): searching for MPI")
+              ecbuild_debug("ecbuild_add_option(${_p_FEATURE}): searching for MPI - ecbuild_find_mpi( ${_find_args} )")
               ecbuild_find_mpi( ${_find_args} )
             elseif( pkgname STREQUAL "OMP" )
               set( _find_args ${pkglist} )
@@ -221,20 +220,21 @@ macro( ecbuild_add_option )
               if( NOT ENABLE_${_p_FEATURE} )
                 list( APPEND _find_args STUBS )
               endif()
-              ecbuild_debug("ecbuild_add_option(${_p_FEATURE}): searching for OpenMP")
+              ecbuild_debug("ecbuild_add_option(${_p_FEATURE}): searching for OpenMP - ecbuild_find_omp( ${_find_args} )")
               ecbuild_find_omp( ${_find_args} )
             elseif( pkgname STREQUAL "Python" OR pkgname STREQUAL "PYTHON" )
               set( _find_args ${pkglist} )
               list( REMOVE_ITEM _find_args ${pkgname} )
-              ecbuild_debug("ecbuild_add_option(${_p_FEATURE}): searching for Python")
+              ecbuild_debug("ecbuild_add_option(${_p_FEATURE}): searching for Python - ecbuild_find_python( ${_find_args} )")
               ecbuild_find_python( ${_find_args} )
+              set( __help_msg "Specify the location of the Python interpreter with -DPYTHON_EXECUTABLE=/..." )
             elseif( pkgname STREQUAL "LEXYACC" )
               set( _find_args ${pkglist} )
               list( REMOVE_ITEM _find_args ${pkgname} )
-              ecbuild_debug("ecbuild_add_option(${_p_FEATURE}): searching for lex-yacc")
+              ecbuild_debug("ecbuild_add_option(${_p_FEATURE}): searching for lex-yacc - ecbuild_find_lexyacc( ${_find_args} )")
               ecbuild_find_lexyacc( ${_find_args} )
             else()
-              ecbuild_debug("ecbuild_add_option(${_p_FEATURE}): searching for package ${pkgname}")
+              ecbuild_debug("ecbuild_add_option(${_p_FEATURE}): searching for package ${pkgname} - find_package( ${pkglist} )")
               find_package( ${pkglist} )
             endif()
 
@@ -242,14 +242,6 @@ macro( ecbuild_add_option )
 
         endif()
 
-        # if found append to list of third-party libraries (to be forward to other packages )
-        if( ${pkgname}_FOUND OR ${pkgUPPER}_FOUND OR ${pkgLOWER}_FOUND )
-
-          list( APPEND ${PROJECT_NAME_CAPS}_TPLS ${pkgname} )
-          list( REMOVE_DUPLICATES ${PROJECT_NAME_CAPS}_TPLS )
-
-        endif()
-
         # ecbuild_debug_var( ${pkgname}_FOUND  )
         # ecbuild_debug_var( ${pkgLOWER}_FOUND )
         # ecbuild_debug_var( ${pkgUPPER}_FOUND )
@@ -258,8 +250,17 @@ macro( ecbuild_add_option )
 
         if( ${pkgname}_FOUND OR ${pkgUPPER}_FOUND OR ${pkgLOWER}_FOUND )
           ecbuild_info( "Found package ${pkgname} required for feature ${_p_FEATURE}" )
+
+          # append to list of third-party libraries (to be forward to other packages )
+          # unless the NO_TPL option was given
+          if( NOT _p_NO_TPL )
+            ecbuild_debug("ecbuild_add_option(${_p_FEATURE}): appending ${pkgname} to ${PROJECT_NAME_CAPS}_TPLS")
+            list( APPEND ${PROJECT_NAME_CAPS}_TPLS ${pkgname} )
+            list( REMOVE_DUPLICATES ${PROJECT_NAME_CAPS}_TPLS )
+          endif()
+
         else()
-          ecbuild_info( "Could not find package ${pkgname} required for feature ${_p_FEATURE} -- Provide ${pkgname} location with -D${pkgUPPER}_PATH=/..." )
+          ecbuild_info( "Could NOT find package ${pkgname} required for feature ${_p_FEATURE} -- ${__help_msg}" )
           set( HAVE_${_p_FEATURE} 0 )
           list( APPEND _failed_to_find_packages ${pkgname} )
         endif()
@@ -279,15 +280,16 @@ macro( ecbuild_add_option )
     else() # if user provided input and we cannot satisfy FAIL otherwise WARN
 
       if( ${_p_FEATURE}_user_provided_input )
-        if( _${_p_FEATURE}_condition )
-          ecbuild_critical( "Feature ${_p_FEATURE} cannot be enabled -- following required packages weren't found: ${_failed_to_find_packages}" )
-        else()
+        if( NOT _${_p_FEATURE}_condition )
           string(REPLACE ";" " " _condition_msg "${_p_CONDITION}")
           ecbuild_critical( "Feature ${_p_FEATURE} cannot be enabled -- following condition was not met: ${_condition_msg}" )
+        else()
+          ecbuild_critical( "Feature ${_p_FEATURE} cannot be enabled -- following required packages weren't found: ${_failed_to_find_packages}" )
         endif()
       else()
-        if( _${_p_FEATURE}_condition )
-          ecbuild_info( "Feature ${_p_FEATURE} was not enabled (also not requested) -- following condition was not met: ${_p_CONDITION}" )
+        if( NOT _${_p_FEATURE}_condition )
+          string(REPLACE ";" " " _condition_msg "${_p_CONDITION}")
+          ecbuild_info( "Feature ${_p_FEATURE} was not enabled (also not requested) -- following condition was not met: ${_condition_msg}" )
         else()
           ecbuild_info( "Feature ${_p_FEATURE} was not enabled (also not requested) -- following required packages weren't found: ${_failed_to_find_packages}" )
         endif()
@@ -297,13 +299,13 @@ macro( ecbuild_add_option )
 
     endif()
 
-  else( _do_search )
+  else()
 
     ecbuild_debug("ecbuild_add_option(${_p_FEATURE}): feature disabled")
     set( HAVE_${_p_FEATURE} 0 )
     ecbuild_set_feature( ${_p_FEATURE} ENABLED OFF )
 
-  endif( _do_search )
+  endif()
 
 
   if( ${_p_ADVANCED} )
diff --git a/cmake/ecbuild_add_test.cmake b/cmake/ecbuild_add_test.cmake
index 2097683..1dcf2c6 100644
--- a/cmake/ecbuild_add_test.cmake
+++ b/cmake/ecbuild_add_test.cmake
@@ -19,6 +19,7 @@
 #                     [ OBJECTS <obj1> [<obj2> ...] ]
 #                     [ COMMAND <executable> ]
 #                     [ TYPE EXE|SCRIPT|PYTHON ]
+#                     [ LABELS <label1> [<label2> ...] ]
 #                     [ ARGS <argument1> [<argument2> ...] ]
 #                     [ RESOURCES <file1> [<file2> ...] ]
 #                     [ TEST_DATA <file1> [<file2> ...] ]
@@ -33,7 +34,7 @@
 #                     [ GENERATED <file1> [<file2> ...] ]
 #                     [ DEPENDS <target1> [<target2> ...] ]
 #                     [ TEST_DEPENDS <target1> [<target2> ...] ]
-#                     [ CONDITION <condition1> [<condition2> ...] ]
+#                     [ CONDITION <condition> ]
 #                     [ ENVIRONMENT <variable1> [<variable2> ...] ]
 #                     [ WORKING_DIRECTORY <path> ]
 #                     [ CFLAGS <flag1> [<flag2> ...] ]
@@ -63,6 +64,22 @@
 #   :SCRIPT: run command or script, default if COMMAND is provided
 #   :PYTHON: run a Python script (requires the Python interpreter to be found)
 #
+# LABELS : optional
+#   list of labels to assign to the test
+#
+#   The project name in lower case is always added as a label. Additional
+#   labels are assigned depending on the type of test:
+#
+#   :executable: for type ``EXE``
+#   :script:     for type ``SCRIPT``
+#   :python:     for type ``PYTHON``
+#   :boost:      uses Boost unit test
+#   :mpi:        if ``MPI`` is set
+#   :openmp:     if ``OMP`` is set
+#
+#   This allows selecting tests to run via ``ctest -L <regex>`` or tests
+#   to exclude via ``ctest -LE <regex>``.
+#
 # ARGS : optional
 #   list of arguments to pass to TARGET or COMMAND when running the test
 #
@@ -76,9 +93,9 @@
 #   use the Boost Unit Test Framework
 #
 # MPI : optional
-#   number of MPI tasks to use.
+#   Run with MPI using the given number of MPI tasks.
 #
-#   If greater than 1, and MPI is not available, the test is disabled.
+#   If greater than 1, and ``MPIEXEC`` is not available, the test is disabled.
 #
 # OMP : optional
 #   number of OpenMP threads per MPI task to use.
@@ -138,7 +155,7 @@ macro( ecbuild_add_test )
 
   set( options           BOOST )
   set( single_value_args TARGET ENABLED COMMAND TYPE LINKER_LANGUAGE MPI OMP WORKING_DIRECTORY )
-  set( multi_value_args  SOURCES OBJECTS LIBS INCLUDES TEST_DEPENDS DEPENDS ARGS
+  set( multi_value_args  SOURCES OBJECTS LIBS INCLUDES TEST_DEPENDS DEPENDS LABELS ARGS
                          PERSISTENT DEFINITIONS RESOURCES TEST_DATA CFLAGS
                          CXXFLAGS FFLAGS GENERATED CONDITION ENVIRONMENT )
 
@@ -150,21 +167,31 @@ macro( ecbuild_add_test )
 
   set( _TEST_DIR ${CMAKE_CURRENT_BINARY_DIR} )
 
-  # Check for MPI
-  if(_PAR_MPI)
-    if( (_PAR_MPI GREATER 1) AND ( (NOT MPI_FOUND) OR (NOT MPIEXEC) ) )
-      ecbuild_debug("ecbuild_add_test(${_PAR_TARGET}): ${_PAR_MPI} MPI ranks requested but MPI not available - disabling test")
+  # Undocumented flag for disabling all MPI tests for test environment without suitable MPI(EXEC)
+  if( _PAR_MPI AND ECBUILD_DISABLE_MPI_TESTS )
+    ecbuild_debug("ecbuild_add_test(${_PAR_TARGET}): ECBUILD_DISABLE_MPI_TESTS set - disabling test")
+    set( _PAR_ENABLED 0 )
+  elseif( _PAR_MPI )
+    # Check for MPIEXEC if it not set
+    find_program( MPIEXEC NAMES mpiexec mpirun lamexec srun
+                  DOC "Executable for running MPI programs." )
+    if( MPIEXEC )
+      set(MPIEXEC_NUMPROC_FLAG "-np" CACHE STRING "Flag used by MPI to specify the number of processes for MPIEXEC")
+      ecbuild_debug("ecbuild_add_test(${_PAR_TARGET}): Running using ${MPIEXEC} on ${_PAR_MPI} MPI rank(s)")
+      set( _PAR_LABELS mpi ${_PAR_LABELS} )
+    elseif( _PAR_MPI GREATER 1 )
+      ecbuild_debug("ecbuild_add_test(${_PAR_TARGET}): ${_PAR_MPI} MPI ranks requested but MPIEXEC not available - disabling test")
       set( _PAR_ENABLED 0 )
-    elseif( (_PAR_MPI EQUAL 1) AND (NOT MPI_FOUND) )
-      ecbuild_debug("ecbuild_add_test(${_PAR_TARGET}): 1 MPI rank requested but MPI not available - disabling MPI")
-      set( _PAR_MPI 0 )
     else()
-      ecbuild_debug("ecbuild_add_test(${_PAR_TARGET}): Running using ${_PAR_MPI} MPI rank(s)")
+      ecbuild_debug("ecbuild_add_test(${_PAR_TARGET}): 1 MPI rank requested but MPIEXEC not available - running sequentially")
+      set( _PAR_MPI 0 )
     endif()
   endif()
 
   # Check for OMP
-  if( NOT DEFINED _PAR_OMP )
+  if( DEFINED _PAR_OMP )
+    set( _PAR_LABELS openmp ${_PAR_LABELS} )
+  else()
     set( _PAR_OMP 1 )
   endif()
   list( APPEND _PAR_ENVIRONMENT "OMP_NUM_THREADS=${_PAR_OMP}" )
@@ -181,11 +208,13 @@ macro( ecbuild_add_test )
   # command implies script
   if( DEFINED _PAR_COMMAND )
     set( _PAR_TYPE "SCRIPT" )
+    set( _PAR_LABELS script ${_PAR_LABELS} )
   endif()
 
   # default of TYPE
   if( NOT _PAR_TYPE AND DEFINED _PAR_TARGET )
     set( _PAR_TYPE "EXE" )
+    set( _PAR_LABELS executable ${_PAR_LABELS} )
     if( NOT _PAR_SOURCES )
       ecbuild_critical("The call to ecbuild_add_test() defines a TARGET without SOURCES.")
     endif()
@@ -194,6 +223,7 @@ macro( ecbuild_add_test )
   if( _PAR_TYPE MATCHES "PYTHON" )
     if( PYTHONINTERP_FOUND )
       set( _PAR_COMMAND ${PYTHON_EXECUTABLE} )
+      set( _PAR_LABELS python ${_PAR_LABELS} )
     else()
       ecbuild_warn( "Requested a python test but python interpreter not found - disabling test\nPYTHON_EXECUTABLE: [${PYTHON_EXECUTABLE}]" )
       set( _PAR_ENABLED 0 )
@@ -233,6 +263,7 @@ macro( ecbuild_add_test )
   if( _PAR_BOOST AND ENABLE_TESTS AND _${_PAR_TARGET}_condition )
 
     if( HAVE_BOOST_UNIT_TEST )
+      set( _PAR_LABELS boost ${_PAR_LABELS} )
       if( BOOST_UNIT_TEST_FRAMEWORK_HEADER_ONLY )
         include_directories( ${ECBUILD_BOOST_HEADER_DIRS} )
         include_directories( ${Boost_INCLUDE_DIRS}  ) # temporary until we ship Boost Unit Test with ecBuild
@@ -322,25 +353,14 @@ macro( ecbuild_add_test )
       # filter sources
       ecbuild_separate_sources( TARGET ${_PAR_TARGET} SOURCES ${_PAR_SOURCES} )
 
-      # add local flags
-      if( DEFINED _PAR_CFLAGS )
-        ecbuild_debug("ecbuild_add_test(${_PAR_TARGET}): use C flags ${_PAR_CFLAGS}")
-        set_source_files_properties( ${${_PAR_TARGET}_c_srcs}   PROPERTIES COMPILE_FLAGS "${_PAR_CFLAGS}" )
-      endif()
-      if( DEFINED _PAR_CXXFLAGS )
-        ecbuild_debug("ecbuild_add_test(${_PAR_TARGET}): use C++ flags ${_PAR_CFLAGS}")
-        set_source_files_properties( ${${_PAR_TARGET}_cxx_srcs} PROPERTIES COMPILE_FLAGS "${_PAR_CXXFLAGS}" )
-      endif()
-      if( DEFINED _PAR_FFLAGS )
-        ecbuild_debug("ecbuild_add_test(${_PAR_TARGET}): use Fortran flags ${_PAR_CFLAGS}")
-        set_source_files_properties( ${${_PAR_TARGET}_f_srcs}   PROPERTIES COMPILE_FLAGS "${_PAR_FFLAGS}" )
-      endif()
+      # Override compilation flags on a per source file basis
+      ecbuild_target_flags( ${_PAR_TARGET} "${_PAR_CFLAGS}" "${_PAR_CXXFLAGS}" "${_PAR_FFLAGS}" )
+
       if( DEFINED _PAR_GENERATED )
         ecbuild_debug("ecbuild_add_test(${_PAR_TARGET}): mark as generated ${_PAR_GENERATED}")
         set_source_files_properties( ${_PAR_GENERATED} PROPERTIES GENERATED 1 )
       endif()
 
-
       # modify definitions to compilation ( -D... )
       get_property( _target_defs TARGET ${_PAR_TARGET} PROPERTY COMPILE_DEFINITIONS )
 
@@ -405,7 +425,7 @@ macro( ecbuild_add_test )
 
     # Wrap with MPIEXEC
     if( _PAR_MPI )
-      
+
       set( MPIEXEC_TASKS ${MPIEXEC_NUMPROC_FLAG} ${_PAR_MPI} )
       if( DEFINED MPIEXEC_NUMTHREAD_FLAG )
         set( MPIEXEC_THREADS ${MPIEXEC_NUMTHREAD_FLAG} ${_PAR_OMP} )
@@ -442,6 +462,12 @@ macro( ecbuild_add_test )
 
       endif()
 
+      # Add lower case project name to custom test labels
+      set( _PAR_LABELS ${PROJECT_NAME_LOWCASE} ${_PAR_LABELS} )
+      list( REMOVE_DUPLICATES _PAR_LABELS )
+      ecbuild_debug("ecbuild_add_test(${_PAR_TARGET}): assign labels ${_PAR_LABELS}")
+      set_property( TEST ${_PAR_TARGET} APPEND PROPERTY LABELS "${_PAR_LABELS}" )
+
       if( DEFINED _PAR_ENVIRONMENT )
         set_property( TEST ${_PAR_TARGET} APPEND PROPERTY ENVIRONMENT "${_PAR_ENVIRONMENT}" )
       endif()
diff --git a/cmake/ecbuild_bundle.cmake b/cmake/ecbuild_bundle.cmake
index 83b0bba..aee900c 100644
--- a/cmake/ecbuild_bundle.cmake
+++ b/cmake/ecbuild_bundle.cmake
@@ -20,7 +20,9 @@ include(ecbuild_git)
 # =========================
 #
 # Initialise the ecBuild environment for a bundle. *Must* be called *before*
-# any call to ecbuild_bundle.
+# any call to ``ecbuild_bundle``. ::
+#
+#   ecbuild_bundle_initialize()
 #
 ##############################################################################
 
@@ -159,7 +161,9 @@ endmacro()
 # =======================
 #
 # Finalise the ecBuild environment for a bundle. *Must* be called *after* the
-# last call to ecbuild_bundle.
+# last call to ``ecbuild_bundle``. ::
+#
+#   ecbuild_bundle_finalize()
 #
 ##############################################################################
 
diff --git a/cmake/ecbuild_check_cxx11.cmake b/cmake/ecbuild_check_cxx11.cmake
index 390462b..9552389 100644
--- a/cmake/ecbuild_check_cxx11.cmake
+++ b/cmake/ecbuild_check_cxx11.cmake
@@ -23,110 +23,116 @@
 # Options
 # -------
 #
-# FEATURES : optional, checks for all features if omitted
-#   list of features to check for
+# FEATURES : optional
+#   list of optional features to check for
 #
 # REQUIRED : optional
 #   list of required features to check for
 #
 # PRINT : optional
-#   print a summary of features check for, found and not found
+#   print a summary of features checked for, found and not found
+#
+# Note
+# ----
+#
+# If neither ``FEATURES`` nor ``REQUIRED`` are given, check for all features.
 #
 ##############################################################################
 
 function( ecbuild_check_cxx11 )
 
-	# parse parameters
+  # parse parameters
 
-	set( options PRINT )
-	set( single_value_args )
-	set( multi_value_args   FEATURES REQUIRED )
+  set( options PRINT )
+  set( single_value_args )
+  set( multi_value_args   FEATURES REQUIRED )
 
-	cmake_parse_arguments( _p "${options}" "${single_value_args}" "${multi_value_args}"  ${_FIRST_ARG} ${ARGN} )
+  cmake_parse_arguments( _p "${options}" "${single_value_args}" "${multi_value_args}"  ${_FIRST_ARG} ${ARGN} )
 
-	if(_PAR_UNPARSED_ARGUMENTS)
-		ecbuild_critical("Unknown keywords given to ecbuild_check_cxx11(): \"${_PAR_UNPARSED_ARGUMENTS}\"")
-	endif()
+  if(_PAR_UNPARSED_ARGUMENTS)
+    ecbuild_critical("Unknown keywords given to ecbuild_check_cxx11(): \"${_PAR_UNPARSED_ARGUMENTS}\"")
+  endif()
 
-	include( ${ECBUILD_MACROS_DIR}/contrib/GreatCMakeCookOff/CheckCXX11Features.cmake )
+  include( ${ECBUILD_MACROS_DIR}/contrib/GreatCMakeCookOff/CheckCXX11Features.cmake )
 
-	cxx11_find_all_features( ALL_FEATURES ) # list all available features to check
+  cxx11_find_all_features( ALL_FEATURES ) # list all available features to check
 
-	# Save CXX flags
-	set( CXX_FLAGS_SNASHOT ${CMAKE_CXX_FLAGS} )
+  # Save CXX flags
+  set( CXX_FLAGS_SNASHOT ${CMAKE_CXX_FLAGS} )
 
-	# Add C++11 flags
-	include( ${ECBUILD_MACROS_DIR}/ecbuild_get_cxx11_flags.cmake )
-	ecbuild_get_cxx11_flags( CXX11_FLAGS )
-	set( CMAKE_CXX_FLAGS "${CXX11_FLAGS} ${CMAKE_CXX_FLAGS}" )
+  # Add C++11 flags
+  include( ${ECBUILD_MACROS_DIR}/ecbuild_get_cxx11_flags.cmake )
+  ecbuild_get_cxx11_flags( CXX11_FLAGS )
+  ecbuild_debug( "ecbuild_check_cxx11: detected C++11 flag as ${CXX11_FLAGS}" )
+  set( CMAKE_CXX_FLAGS "${CXX11_FLAGS} ${CMAKE_CXX_FLAGS}" )
 
-	if( NOT _p_FEATURES AND NOT _p_REQUIRED ) # no input, then search for all features
+  if( NOT _p_FEATURES AND NOT _p_REQUIRED ) # no input, then search for all features
 
-		cxx11_feature_check()
+    cxx11_feature_check()
 
-	else()
+  else()
 
-		foreach( _f ${_p_FEATURES} )
-			cxx11_feature_check( ${_f} )
-		endforeach()
+    foreach( _f ${_p_FEATURES} )
+      cxx11_feature_check( ${_f} )
+    endforeach()
 
-		foreach( _f ${_p_REQUIRED} )
-			cxx11_feature_check( REQUIRED ${_f} )
-		endforeach()
+    foreach( _f ${_p_REQUIRED} )
+      cxx11_feature_check( REQUIRED ${_f} )
+    endforeach()
 
-	endif()
+  endif()
 
-	# Restore CXX flags
-	set( CMAKE_CXX_FLAGS ${CXX_FLAGS_SNAPSHOT} )
+  # Restore CXX flags
+  set( CMAKE_CXX_FLAGS ${CXX_FLAGS_SNAPSHOT} )
 
-	if( _p_FEATURES OR _p_REQUIRED )
-		set( CXX11_CHECKED_FEATURES ${_p_FEATURES} ${_p_REQUIRED} )
-	else()
-		set( CXX11_CHECKED_FEATURES ${ALL_FEATURES} )
-	endif()
+  if( _p_FEATURES OR _p_REQUIRED )
+    set( CXX11_CHECKED_FEATURES ${_p_FEATURES} ${_p_REQUIRED} )
+  else()
+    set( CXX11_CHECKED_FEATURES ${ALL_FEATURES} )
+  endif()
 
-	foreach( f ${CXX11_CHECKED_FEATURES} )
-		string( TOUPPER ${f} FEAT )
-		if( HAS_CXX11_${FEAT} )
-		   list( APPEND CXX11_SUPPORTED_FEATURES ${f} )
-		else()
-		   list( APPEND CXX11_NOT_SUPPORTED_FEATURES ${f} )
-		endif()
-	endforeach()
+  foreach( f ${CXX11_CHECKED_FEATURES} )
+    string( TOUPPER ${f} FEAT )
+    if( HAS_CXX11_${FEAT} )
+       list( APPEND CXX11_SUPPORTED_FEATURES ${f} )
+    else()
+       list( APPEND CXX11_NOT_SUPPORTED_FEATURES ${f} )
+    endif()
+  endforeach()
 
   if( CXX11_CHECKED_FEATURES )
     list( SORT CXX11_CHECKED_FEATURES )
-	endif()
-	if( CXX11_SUPPORTED_FEATURES )
-		list( SORT CXX11_SUPPORTED_FEATURES )
-	endif()
-	if( CXX11_NOT_SUPPORTED_FEATURES )
-		list( SORT CXX11_NOT_SUPPORTED_FEATURES )
-	endif()
-
-	set( CXX11_CHECKED_FEATURES       ${CXX11_CHECKED_FEATURES}       PARENT_SCOPE )
-	set( CXX11_SUPPORTED_FEATURES     ${CXX11_SUPPORTED_FEATURES}     PARENT_SCOPE )
-	set( CXX11_NOT_SUPPORTED_FEATURES ${CXX11_NOT_SUPPORTED_FEATURES} PARENT_SCOPE )
-
-	if( _p_PRINT )
-		if( CXX11_CHECKED_FEATURES )
-			join( CXX11_CHECKED_FEATURES " " CXX11_CHECKED_FEATURES_STR )
-			ecbuild_info( "Checked C++11 features: ${CXX11_CHECKED_FEATURES_STR}" )
-		else()
-			ecbuild_info( "Checked no C++11 features" )
-		endif()
-		if( CXX11_SUPPORTED_FEATURES )
-			join( CXX11_SUPPORTED_FEATURES " " CXX11_SUPPORTED_FEATURES_STR )
-			ecbuild_info( "Found C++11 features: ${CXX11_SUPPORTED_FEATURES_STR}" )
-		else()
-			ecbuild_info( "Found no C++11 features" )
-		endif()
-		if( CXX11_NOT_SUPPORTED_FEATURES )
-			join( CXX11_NOT_SUPPORTED_FEATURES " " CXX11_NOT_SUPPORTED_FEATURES_STR )
-			ecbuild_info( "Not found C++11 features: ${CXX11_NOT_SUPPORTED_FEATURES_STR}" )
-		else()
-			ecbuild_info( "Found all checked C++11 features" )
-		endif()
-	endif()
+  endif()
+  if( CXX11_SUPPORTED_FEATURES )
+    list( SORT CXX11_SUPPORTED_FEATURES )
+  endif()
+  if( CXX11_NOT_SUPPORTED_FEATURES )
+    list( SORT CXX11_NOT_SUPPORTED_FEATURES )
+  endif()
+
+  set( CXX11_CHECKED_FEATURES       ${CXX11_CHECKED_FEATURES}       PARENT_SCOPE )
+  set( CXX11_SUPPORTED_FEATURES     ${CXX11_SUPPORTED_FEATURES}     PARENT_SCOPE )
+  set( CXX11_NOT_SUPPORTED_FEATURES ${CXX11_NOT_SUPPORTED_FEATURES} PARENT_SCOPE )
+
+  if( _p_PRINT )
+    if( CXX11_CHECKED_FEATURES )
+      join( CXX11_CHECKED_FEATURES " " CXX11_CHECKED_FEATURES_STR )
+      ecbuild_info( "Checked C++11 features: ${CXX11_CHECKED_FEATURES_STR}" )
+    else()
+      ecbuild_info( "Checked no C++11 features" )
+    endif()
+    if( CXX11_SUPPORTED_FEATURES )
+      join( CXX11_SUPPORTED_FEATURES " " CXX11_SUPPORTED_FEATURES_STR )
+      ecbuild_info( "Found C++11 features: ${CXX11_SUPPORTED_FEATURES_STR}" )
+    else()
+      ecbuild_info( "Found no C++11 features" )
+    endif()
+    if( CXX11_NOT_SUPPORTED_FEATURES )
+      join( CXX11_NOT_SUPPORTED_FEATURES " " CXX11_NOT_SUPPORTED_FEATURES_STR )
+      ecbuild_info( "Not found C++11 features: ${CXX11_NOT_SUPPORTED_FEATURES_STR}" )
+    else()
+      ecbuild_info( "Found all checked C++11 features" )
+    endif()
+  endif()
 
 endfunction( ecbuild_check_cxx11 )
diff --git a/cmake/ecbuild_check_fortran.cmake b/cmake/ecbuild_check_fortran.cmake
new file mode 100644
index 0000000..5612134
--- /dev/null
+++ b/cmake/ecbuild_check_fortran.cmake
@@ -0,0 +1,126 @@
+# (C) Copyright 1996-2016 ECMWF.
+#
+# This software is licensed under the terms of the Apache Licence Version 2.0
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
+# granted to it by virtue of its status as an intergovernmental organisation
+# nor does it submit to any jurisdiction.
+
+##############################################################################
+#.rst:
+#
+# ecbuild_check_fortran
+# =====================
+#
+# Check for Fortran features. ::
+#
+#   ecbuild_check_fortran( [ FEATURES <feature1> [ <feature2> ... ] ]
+#                          [ REQUIRED <feature1> [ <feature2> ... ] ]
+#                          [ PRINT ] )
+#
+# Options
+# -------
+#
+# FEATURES : optional
+#   list of optional features to check for
+#
+# REQUIRED : optional
+#   list of required features to check for, fails if not detected
+#
+# PRINT : optional
+#   print a summary of features checked for, found and not found
+#
+# Note
+# ----
+#
+# If neither ``FEATURES`` nor ``REQUIRED`` are given, check for all features.
+#
+##############################################################################
+
+function( ecbuild_check_fortran )
+
+  # parse parameters
+
+  set( options PRINT )
+  set( single_value_args )
+  set( multi_value_args   FEATURES REQUIRED )
+
+  cmake_parse_arguments( _p "${options}" "${single_value_args}" "${multi_value_args}"  ${_FIRST_ARG} ${ARGN} )
+
+  if(_PAR_UNPARSED_ARGUMENTS)
+    ecbuild_critical("Unknown keywords given to ecbuild_check_fortran(): \"${_PAR_UNPARSED_ARGUMENTS}\"")
+  endif()
+
+  include( ${ECBUILD_MACROS_DIR}/fortran_features/CheckFortranFeatures.cmake )
+
+  fortran_find_all_features( ALL_FEATURES ) # list all available features to check
+
+  if( NOT _p_FEATURES AND NOT _p_REQUIRED ) # no input, then search for all features
+
+    fortran_feature_check()
+
+  else()
+
+    foreach( _f ${_p_FEATURES} )
+      fortran_feature_check( ${_f} )
+    endforeach()
+
+    foreach( _f ${_p_REQUIRED} )
+      fortran_feature_check( REQUIRED ${_f} )
+    endforeach()
+
+  endif()
+
+  if( _p_FEATURES OR _p_REQUIRED )
+    set( Fortran_CHECKED_FEATURES ${_p_FEATURES} ${_p_REQUIRED} )
+  else()
+    set( Fortran_CHECKED_FEATURES ${ALL_FEATURES} )
+  endif()
+
+  foreach( f ${Fortran_CHECKED_FEATURES} )
+    string( TOUPPER ${f} FEAT )
+    if( HAS_Fortran_${FEAT} )
+       list( APPEND Fortran_SUPPORTED_FEATURES ${f} )
+       set( EC_HAVE_Fortran_${FEAT} 1 PARENT_SCOPE )
+    else()
+       list( APPEND Fortran_NOT_SUPPORTED_FEATURES ${f} )
+       set( EC_HAVE_Fortran_${FEAT} 0 PARENT_SCOPE )
+    endif()
+  endforeach()
+
+  if( Fortran_CHECKED_FEATURES )
+    list( SORT Fortran_CHECKED_FEATURES )
+  endif()
+  if( Fortran_SUPPORTED_FEATURES )
+    list( SORT Fortran_SUPPORTED_FEATURES )
+  endif()
+  if( Fortran_NOT_SUPPORTED_FEATURES )
+    list( SORT Fortran_NOT_SUPPORTED_FEATURES )
+  endif()
+
+  set( Fortran_CHECKED_FEATURES       ${Fortran_CHECKED_FEATURES}       PARENT_SCOPE )
+  set( Fortran_SUPPORTED_FEATURES     ${Fortran_SUPPORTED_FEATURES}     PARENT_SCOPE )
+  set( Fortran_NOT_SUPPORTED_FEATURES ${Fortran_NOT_SUPPORTED_FEATURES} PARENT_SCOPE )
+
+  if( _p_PRINT )
+    if( Fortran_CHECKED_FEATURES )
+      join( Fortran_CHECKED_FEATURES " " Fortran_CHECKED_FEATURES_STR )
+      ecbuild_info( "Checked Fortran features: ${Fortran_CHECKED_FEATURES_STR}" )
+    else()
+      ecbuild_info( "Checked no Fortran features" )
+    endif()
+    if( Fortran_SUPPORTED_FEATURES )
+      join( Fortran_SUPPORTED_FEATURES " " Fortran_SUPPORTED_FEATURES_STR )
+      ecbuild_info( "Found Fortran features: ${Fortran_SUPPORTED_FEATURES_STR}" )
+    else()
+      ecbuild_info( "Found no Fortran features" )
+    endif()
+    if( Fortran_NOT_SUPPORTED_FEATURES )
+      join( Fortran_NOT_SUPPORTED_FEATURES " " Fortran_NOT_SUPPORTED_FEATURES_STR )
+      ecbuild_info( "Not found Fortran features: ${Fortran_NOT_SUPPORTED_FEATURES_STR}" )
+    else()
+      ecbuild_info( "Found all checked Fortran features" )
+    endif()
+  endif()
+
+endfunction( ecbuild_check_fortran )
diff --git a/cmake/ecbuild_check_fortran_source_return.cmake b/cmake/ecbuild_check_fortran_source_return.cmake
index 6b007df..175f4ef 100644
--- a/cmake/ecbuild_check_fortran_source_return.cmake
+++ b/cmake/ecbuild_check_fortran_source_return.cmake
@@ -52,7 +52,6 @@
 
 macro( ecbuild_check_fortran_source_return SOURCE )
 
-    ecbuild_warn( "This macro ecbuild_check_fortran_source has never been tested" )
     set( options )
     set( single_value_args VAR  OUTPUT )
     set( multi_value_args  INCLUDES LIBS DEFINITIONS )
@@ -93,15 +92,15 @@ macro( ecbuild_check_fortran_source_return SOURCE )
         if( __add_libs )
             set(CHECK_Fortran_SOURCE_COMPILES_ADD_INCLUDES "-DINCLUDE_DIRECTORIES:STRING=${__add_incs}")
         endif()
-    
+
         # write the source file
-    
-        file( WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/test_${_PAR_VAR}.f" "${SOURCE}\n" )
+
+        file( WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/test_${_PAR_VAR}.F90" "${SOURCE}\n" )
 
         ecbuild_debug( "Performing Test ${_PAR_VAR}" )
         try_run( ${_PAR_VAR}_EXITCODE ${_PAR_VAR}_COMPILED
           ${CMAKE_BINARY_DIR}
-          ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/test_${_PAR_VAR}.f
+          ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/test_${_PAR_VAR}.F90
           COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
           CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
           -DCMAKE_SKIP_RPATH:BOOL=${CMAKE_SKIP_RPATH}
@@ -142,9 +141,9 @@ macro( ecbuild_check_fortran_source_return SOURCE )
     
           ecbuild_debug("Performing Test ${_PAR_VAR} - Failed")
           file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log 
-            "Performing C SOURCE FILE Test ${_PAR_VAR} failed with the following compile output:\n"
+            "Performing Fortran SOURCE FILE Test ${_PAR_VAR} failed with the following compile output:\n"
             "${compile_OUTPUT}\n" 
-            "Performing C SOURCE FILE Run ${_PAR_VAR} failed with the following run output:\n"
+            "Performing Fortran SOURCE FILE Run ${_PAR_VAR} failed with the following run output:\n"
             "${run_OUTPUT}\n" 
             "Return value: ${${_PAR_VAR}_EXITCODE}\n"
             "Source file was:\n${SOURCE}\n")
diff --git a/cmake/ecbuild_check_functions.cmake b/cmake/ecbuild_check_functions.cmake
index 88526b5..73f5cb5 100644
--- a/cmake/ecbuild_check_functions.cmake
+++ b/cmake/ecbuild_check_functions.cmake
@@ -169,6 +169,15 @@ if( ENABLE_OS_FUNCTIONS_TEST )
 #    ecbuild_debug_var(EC_HAVE_PROCFS)
 #    ecbuild_debug_var(EC_HAVE_PROCFS_OUTPUT)
 
+    #### check support for DL library #############
+
+    ecbuild_cache_check_include_files( dlfcn.h  EC_HAVE_DLFCN_H )
+
+    cmake_push_check_state(RESET)
+    set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_DL_LIBS} )
+    ecbuild_cache_check_c_source_compiles( "#define _GNU_SOURCE\n#include <dlfcn.h>\nint main(){ void* addr; Dl_info info; dladdr(addr, &info); }\n" EC_HAVE_DLADDR )
+    cmake_pop_check_state()
+
 endif()
 
 
diff --git a/cmake/ecbuild_compiler_flags.cmake b/cmake/ecbuild_compiler_flags.cmake
index b97eb2c..0e3fe1e 100644
--- a/cmake/ecbuild_compiler_flags.cmake
+++ b/cmake/ecbuild_compiler_flags.cmake
@@ -12,7 +12,7 @@
 # ecbuild_compiler_flags
 # ======================
 #
-# Set default compiler flags for a given language. ::
+# Set compiler specific default compilation flags for a given language. ::
 #
 #   ecbuild_compiler_flags( <lang> )
 #
@@ -35,53 +35,171 @@
 
 macro( ecbuild_compiler_flags _lang )
 
+  # Set compiler and language specific default flags - OVERWRITES variables in CMake cache
   if( CMAKE_${_lang}_COMPILER_LOADED )
-
-    ecbuild_debug( "try include ${ECBUILD_MACROS_DIR}/compiler_flags/${CMAKE_${_lang}_COMPILER_ID}_${_lang}.cmake ")
-
+    ecbuild_debug( "ecbuild_compiler_flags(${_lang}): try include ${ECBUILD_MACROS_DIR}/compiler_flags/${CMAKE_${_lang}_COMPILER_ID}_${_lang}.cmake ")
     include( ${ECBUILD_MACROS_DIR}/compiler_flags/${CMAKE_${_lang}_COMPILER_ID}_${_lang}.cmake OPTIONAL )
-
-    ecbuild_debug_var( CMAKE_${_lang}_FLAGS )
-
-    foreach( _btype NONE DEBUG BIT PRODUCTION RELEASE RELWITHDEBINFO )
-      ecbuild_debug_var( CMAKE_${_lang}_FLAGS_${_btype} )
-    endforeach()
-
   endif()
 
+  # Apply user or toolchain specified compilation flag overrides (NOT written to cache)
+
   foreach( _btype NONE DEBUG BIT PRODUCTION RELEASE RELWITHDEBINFO )
     if( DEFINED ECBUILD_${_lang}_FLAGS_${_btype} )
+      ecbuild_debug( "ecbuild_compiler_flags(${_lang}): overriding CMAKE_${_lang}_FLAGS_${_btype} with ${ECBUILD_${_lang}_FLAGS_${_btype}}")
       set( CMAKE_${_lang}_FLAGS_${_btype} ${ECBUILD_${_lang}_FLAGS_${_btype}} )
     endif()
     mark_as_advanced( CMAKE_${_lang}_FLAGS_${_btype} )
   endforeach()
 
   if( DEFINED ECBUILD_${_lang}_FLAGS )
+    ecbuild_debug( "ecbuild_compiler_flags(${_lang}): overriding CMAKE_${_lang}_FLAGS with ${ECBUILD_${_lang}_FLAGS}")
     set( CMAKE_${_lang}_FLAGS "${ECBUILD_${_lang}_FLAGS}" )
   endif()
 
   mark_as_advanced( CMAKE_${_lang}_FLAGS )
 
   if( DEFINED ECBUILD_${_lang}_LINK_FLAGS )
+    ecbuild_debug( "ecbuild_compiler_flags(${_lang}): overriding CMAKE_${_lang}_LINK_FLAGS with ${ECBUILD_${_lang}_LINK_FLAGS}")
     set( CMAKE_${_lang}_LINK_FLAGS "${ECBUILD_${_lang}_LINK_FLAGS}" )
   endif()
 
   mark_as_advanced( CMAKE_${_lang}_LINK_FLAGS )
 
+  ecbuild_debug_var( CMAKE_${_lang}_FLAGS )
+  foreach( _btype NONE DEBUG BIT PRODUCTION RELEASE RELWITHDEBINFO )
+    ecbuild_debug_var( CMAKE_${_lang}_FLAGS_${_btype} )
+  endforeach()
+
 endmacro()
 
-#-----------------------------------------------------------------------------------------------------------------------
+##############################################################################
+#.rst:
+#
+# Using custom compilation flags
+# ==============================
+#
+# If compilation flags need to be controlled on a per source file basis,
+# ecBuild supports defining custom rules in a CMake or JSON file.
+#
+# When using this approach, *default compilation flags are NOT loaded*!
+#
+# Overriding compilation flags on a per source file basis using CMake rules
+# -------------------------------------------------------------------------
+#
+# Compiler flags can be overridden on a per source file basis by setting the
+# CMake variable ``ECBUILD_COMPILE_FLAGS`` to the *full path* of a CMake file
+# defining the override rules. If set, ``<PNAME>_ECBUILD_COMPILE_FLAGS``
+# takes precendence and ``ECBUILD_COMPILE_FLAGS`` is ignored, allowing for
+# rules that only apply to a subproject (e.g. in a bundle).
+#
+# Flags can be overridden in 3 different ways:
+#
+# 1.  By defining project specific flags for a language and (optionally)
+#     build type e.g. ::
+#
+#       set(<PNAME>_Fortran_FLAGS "...") # common flags for all build types
+#       set(<PNAME>_Fortran_FLAGS_DEBUG "...") # only for DEBUG build type
+#
+# 2.  By defining source file specific flags which are *combined* with the
+#     project and target specific flags ::
+#
+#       set_source_files_properties(<source>
+#         PROPERTIES COMPILE_FLAGS "..."  # common flags for all build types
+#                    COMPILE_FLAGS_DEBUG "...") # only for DEBUG build type
+#
+# 3.  By defining source file specific flags which *override* the project and
+#     target specific flags ::
+#
+#       set_source_files_properties(<source>
+#         PROPERTIES OVERRIDE_COMPILE_FLAGS "..."
+#                    OVERRIDE_COMPILE_FLAGS_DEBUG "...")
+#
+# See ``examples/override-compile-flags`` in the ecBuild source tree for a
+# complete example using this technique.
+#
+# Overriding compilation flags on a per source file basis using JSON rules
+# ------------------------------------------------------------------------
+#
+# Compiler flags can be overridden on a per source file basis by setting the
+# CMake variable ``ECBUILD_SOURCE_FLAGS`` to the *full path* of a JSON file
+# defining the override rules. If set, ``<PNAME>_ECBUILD_SOURCE_FLAGS``
+# takes precendence and ``ECBUILD_SOURCE_FLAGS`` is ignored, allowing for
+# rules that only apply to a subproject (e.g. in a bundle).
+#
+# The JSON file lists shell glob patterns and the rule to apply to each source
+# file matching the pattern, defined as an array ``[op, flag1, ...]``
+# containing an operator followed by one or more flags. Valid operators are:
+#
+# :+: Add the flags to the default compilation flags for matching files
+# :=: Set the flags for matching files, disregarding default compilation flags
+# :/: Remove the flags from the default compilation flags for matching files
+#
+# Rules can be nested to e.g. only apply to a subdirectory by setting the rule
+# to a dictionary, which will only apply to source files matching its pattern.
+#
+# An example JSON file demonstrating different rule types is given below: ::
+#
+#   {
+#     "*"       : [ "+", "-g0" ],
+#     "*.cxx"   : [ "+", "-cxx11" ],
+#     "*.f90"   : [ "+", "-pipe" ],
+#     "foo.c"   : [ "+", "-O0" ],
+#     "foo.cc"  : [ "+", "-O2", "-pipe" ],
+#     "bar/*": {
+#       "*.f90" : [ "=", "-O1" ]
+#     },
+#     "baz/*": {
+#       "*.f90" : [ "/", "-pipe" ],
+#       "*.f90" : [ "/", "-O2" ],
+#       "*.f90" : [ "+", "-O3" ]
+#     }
+#   }
+#
+# See ``examples/override-compile-flags`` in the ecBuild source tree for a
+# complete example using this technique.
+#
+##############################################################################
 
-### OVERRIDE Compiler FLAGS (we override because CMake forcely defines them) -- see ecbuild_compiler_flags() macro
+# Custom (project specific) compilation flags enabled?
+foreach( _flags COMPILE SOURCE )
+  if( ${PROJECT_NAME_CAPS}_ECBUILD_${_flags}_FLAGS )
+    if ( ECBUILD_${_flags}_FLAGS )
+      ecbuild_debug( "Override ECBUILD_${_flags}_FLAGS (${ECBUILD_${_flags}_FLAGS}) with ${PROJECT_NAME} specific flags (${${PROJECT_NAME_CAPS}_ECBUILD_${_flags}_FLAGS})" )
+    else()
+      ecbuild_debug( "Use ${PROJECT_NAME} specific ECBUILD_${_flags}_FLAGS (${${PROJECT_NAME_CAPS}_ECBUILD_${_flags}_FLAGS})" )
+    endif()
+    set( ECBUILD_${_flags}_FLAGS ${${PROJECT_NAME_CAPS}_ECBUILD_${_flags}_FLAGS} )
+  endif()
+  # Ensure ECBUILD_${_flags}_FLAGS is a valid file path
+  if( DEFINED ECBUILD_${_flags}_FLAGS AND NOT EXISTS ${ECBUILD_${_flags}_FLAGS} )
+    ecbuild_warn( "ECBUILD_${_flags}_FLAGS points to non-existent file ${ECBUILD_${_flags}_FLAGS} and will be ignored" )
+    unset( ECBUILD_${_flags}_FLAGS )
+    unset( ECBUILD_${_flags}_FLAGS CACHE )
+  endif()
+endforeach()
+if( ECBUILD_COMPILE_FLAGS )
+  include( "${ECBUILD_COMPILE_FLAGS}" )
+endif()
 
 foreach( _lang C CXX Fortran )
   if( CMAKE_${_lang}_COMPILER_LOADED )
-    ecbuild_compiler_flags( ${_lang} )
+
+    # Clear default compilation flags potentially inherited from parent scope
+    # when using custom compilation flags
+    if( ECBUILD_SOURCE_FLAGS OR ECBUILD_COMPILE_FLAGS )
+      set(CMAKE_${_lang}_FLAGS "")
+      foreach(_btype ALL RELEASE RELWITHDEBINFO PRODUCTION BIT DEBUG)
+        set(CMAKE_${_lang}_FLAGS_${_btype} "")
+      endforeach()
+    # Load default compilation flags only if custom compilation flags not enabled
+    else()
+      ecbuild_compiler_flags( ${_lang} )
+    endif()
+
   endif()
 endforeach()
 
-### OVERRIDE Linker FLAGS per object type (we override because CMake forcely defines them)
-
+# Apply user or toolchain specified linker flag overrides per object type (NOT written to cache)
 foreach( _btype NONE DEBUG BIT PRODUCTION RELEASE RELWITHDEBINFO )
 
   foreach( _obj EXE SHARED MODULE )
@@ -91,7 +209,3 @@ foreach( _btype NONE DEBUG BIT PRODUCTION RELEASE RELWITHDEBINFO )
   endforeach()
 
 endforeach()
-
-#-----------------------------------------------------------------------------------------------------------------------
-
-mark_as_advanced( CMAKE_C_FLAGS_BIT )
diff --git a/cmake/ecbuild_config.h.in b/cmake/ecbuild_config.h.in
index dd8e9cd..df9eb91 100644
--- a/cmake/ecbuild_config.h.in
+++ b/cmake/ecbuild_config.h.in
@@ -129,6 +129,12 @@
 #cmakedefine EC_ATTRIBUTE_CONSTRUCTOR_INITS_ARGV
 #cmakedefine EC_HAVE_PROCFS
 
+
+/* --- dl library support --- */
+
+#cmakedefine EC_HAVE_DLFCN_H
+#cmakedefine EC_HAVE_DLADDR
+
 /* --- c compiler support --- */
 
 #cmakedefine EC_HAVE_C_INLINE
diff --git a/cmake/ecbuild_declare_project.cmake b/cmake/ecbuild_declare_project.cmake
index 1c2e93b..c95e8e3 100644
--- a/cmake/ecbuild_declare_project.cmake
+++ b/cmake/ecbuild_declare_project.cmake
@@ -28,24 +28,27 @@
 # :<PNAME>_MINOR_VERSION:  minor version number
 # :<PNAME>_PATCH_VERSION:  patch version number
 # :INSTALL_BIN_DIR:        relative install directory for executables
-#                          (default: ``bin``)
 # :INSTALL_LIB_DIR:        relative install directory for libraries
-#                          (default: ``lib``)
 # :INSTALL_INCLUDE_DIR:    relative install directory for include files
-#                          (default: ``include``)
 # :INSTALL_DATA_DIR:       relative install directory for data
-#                          (default: ``share/<project_name>``)
 # :INSTALL_CMAKE_DIR:      relative install directory for CMake files
-#                          (default: ``share/<project_name>/cmake``)
+#
+# Customising install locations
+# -----------------------------
 #
 # The relative installation directories of components can be customised by
 # setting the following CMake variables on the command line or in cache:
 #
-# :<PNAME>_INSTALL_BIN_DIR:     directory for installing executables
-# :<PNAME>_INSTALL_LIB_DIR:     directory for installing libraries
-# :<PNAME>_INSTALL_INCLUDE_DIR: directory for installing include files
-# :<PNAME>_INSTALL_DATA_DIR:    directory for installing data
-# :<PNAME>_INSTALL_CMAKE_DIR:   directory for installing CMake files
+# :INSTALL_BIN_DIR:        directory for installing executables
+#                          (default: ``bin``)
+# :INSTALL_LIB_DIR:        directory for installing libraries
+#                          (default: ``lib``)
+# :INSTALL_INCLUDE_DIR:    directory for installing include files
+#                          (default: ``include``)
+# :INSTALL_DATA_DIR:       directory for installing data
+#                          (default: ``share/<project_name>``)
+# :INSTALL_CMAKE_DIR:      directory for installing CMake files
+#                          (default: ``share/<project_name>/cmake``)
 #
 # Using *relative* paths is recommended, which are interpreted relative to the
 # ``CMAKE_INSTALL_PREFIX``. Using absolute paths makes the build
@@ -109,11 +112,22 @@ macro( ecbuild_declare_project )
 
   # install dirs for this project
 
-  set( INSTALL_BIN_DIR bin )
-  set( INSTALL_LIB_DIR lib )
-  set( INSTALL_INCLUDE_DIR include )
-  set( INSTALL_DATA_DIR share/${PROJECT_NAME} )
-  set( INSTALL_CMAKE_DIR share/${PROJECT_NAME}/cmake )
+  # Use defaults unless values are already present in cache
+  if( NOT INSTALL_BIN_DIR )
+    set( INSTALL_BIN_DIR bin )
+  endif()
+  if( NOT INSTALL_LIB_DIR )
+    set( INSTALL_LIB_DIR lib )
+  endif()
+  if( NOT INSTALL_INCLUDE_DIR )
+    set( INSTALL_INCLUDE_DIR include )
+  endif()
+  if( NOT INSTALL_DATA_DIR )
+    set( INSTALL_DATA_DIR share/${PROJECT_NAME} )
+  endif()
+  if( NOT INSTALL_CMAKE_DIR )
+    set( INSTALL_CMAKE_DIR share/${PROJECT_NAME}/cmake )
+  endif()
 
   mark_as_advanced( INSTALL_BIN_DIR )
   mark_as_advanced( INSTALL_LIB_DIR )
@@ -121,10 +135,11 @@ macro( ecbuild_declare_project )
   mark_as_advanced( INSTALL_DATA_DIR )
   mark_as_advanced( INSTALL_CMAKE_DIR )
 
-  # overrides of install dirs
+  # overrides of install dirs (deprecated in ecBuild 2.4.0)
 
   foreach( p LIB BIN INCLUDE DATA CMAKE )
     if( ${PNAME}_INSTALL_${p}_DIR )
+      ecbuild_deprecate( "Use of ${PNAME}_INSTALL_${p}_DIR is deprecated and will be removed in a future release. Use INSTALL_${p}_DIR instead." )
       set( INSTALL_${p}_DIR ${${PNAME}_INSTALL_${p}_DIR} )
     endif()
   endforeach()
diff --git a/cmake/ecbuild_define_paths.cmake b/cmake/ecbuild_define_paths.cmake
index 856903d..6584b26 100644
--- a/cmake/ecbuild_define_paths.cmake
+++ b/cmake/ecbuild_define_paths.cmake
@@ -1,8 +1,8 @@
 # (C) Copyright 1996-2016 ECMWF.
-# 
+#
 # This software is licensed under the terms of the Apache Licence Version 2.0
-# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. 
-# In applying this licence, ECMWF does not waive the privileges and immunities 
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
 # granted to it by virtue of its status as an intergovernmental organisation nor
 # does it submit to any jurisdiction.
 
@@ -15,17 +15,22 @@ file( MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/lib )
 
 # setup library building rpaths (both in build dir and then when installed)
 
-set( CMAKE_INSTALL_RPATH_USE_LINK_PATH   TRUE  ) # add the automatic parts to RPATH which point to dirs outside build tree
+# add the automatic parts to RPATH which point to dirs outside build tree
+set( CMAKE_INSTALL_RPATH_USE_LINK_PATH   TRUE  )
 
 # use RPATHs for the build tree
 set( CMAKE_SKIP_BUILD_RPATH              FALSE  )
 
-if( ENABLE_RELATIVE_RPATHS )
-    # when building, use the install RPATH immedietly
-	set( CMAKE_BUILD_WITH_INSTALL_RPATH      TRUE  )
+# If INSTALL_LIB_DIR is set to anything other than lib, the relative install
+# RPATH is wrong in the build tree
+if( ENABLE_RELATIVE_RPATHS AND (NOT INSTALL_LIB_DIR OR INSTALL_LIB_DIR STREQUAL "lib") )
+  # when building, use the install RPATH immediately (we don't want to relink)
+  set( CMAKE_BUILD_WITH_INSTALL_RPATH      TRUE  )
+  ecbuild_debug( "Building with install RPATH" )
 else()
-    # when building, don't use the install RPATH yet, but later on when installing
-    set( CMAKE_BUILD_WITH_INSTALL_RPATH      FALSE  ) 
+  # when building, don't use the install RPATH yet, but later on when installing
+  set( CMAKE_BUILD_WITH_INSTALL_RPATH      FALSE  )
+  ecbuild_debug( "Not building with install RPATH, need to relink when installing" )
 endif()
 
 # Always include srcdir and builddir in include path
diff --git a/cmake/ecbuild_download_resource.cmake b/cmake/ecbuild_download_resource.cmake
index 3b2f90e..5d394f5 100644
--- a/cmake/ecbuild_download_resource.cmake
+++ b/cmake/ecbuild_download_resource.cmake
@@ -25,6 +25,7 @@ function( ecbuild_download_resource _p_OUT _p_URL )
   if( NOT EXISTS ${_p_OUT} )
 
     find_program( CURL_PROGRAM curl )
+    mark_as_advanced(CURL_PROGRAM)
     if( CURL_PROGRAM )
       execute_process( COMMAND ${CURL_PROGRAM} --silent --show-error --fail --output ${_p_OUT} ${_p_URL}
                        WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} RESULT_VARIABLE CMD_RESULT )
diff --git a/cmake/ecbuild_find_omp.cmake b/cmake/ecbuild_find_omp.cmake
index 47c05c2..914da24 100644
--- a/cmake/ecbuild_find_omp.cmake
+++ b/cmake/ecbuild_find_omp.cmake
@@ -30,7 +30,7 @@ macro( lookup_omp_flags )
   #ifdef _OPENMP
     #pragma omp parallel
     {
-      int id = omp_get_thread_num();
+      (void)omp_get_thread_num();
     }
     return 0;
   #else
@@ -53,7 +53,7 @@ macro( lookup_omp_flags )
     #pragma omp parallel
     {
       // This pragma should have passed compilation
-      int id = 0;
+      (void)0;
     }
     return 0;
   #endif
diff --git a/cmake/ecbuild_find_python.cmake b/cmake/ecbuild_find_python.cmake
index 0273951..d3cf377 100644
--- a/cmake/ecbuild_find_python.cmake
+++ b/cmake/ecbuild_find_python.cmake
@@ -28,6 +28,10 @@
 # NO_LIBS : optional
 #   only search for the Python interpreter, not the libraries
 #
+# Unless ``NO_LIBS`` is set, the ``python-config`` utility, if found, is used
+# to determine the Python include directories, libraries and link line. Set the
+# CMake variable ``PYTHON_NO_CONFIG`` to use CMake's FindPythonLibs instead.
+#
 # Output variables
 # ----------------
 #
@@ -62,38 +66,34 @@ function( ecbuild_find_python )
     if(_p_UNPARSED_ARGUMENTS)
       ecbuild_critical("Unknown keywords given to ecbuild_find_python(): \"${_p_UNPARSED_ARGUMENTS}\"")
     endif()
+    if( _p_REQUIRED )
+      set( _p_REQUIRED REQUIRED )
+    else()
+      unset( _p_REQUIRED )
+    endif()
 
     # find python executable
 
-    find_package( PythonInterp )
-
-    if( NOT PYTHONINTERP_FOUND AND _p_REQUIRED )
-        ecbuild_error( "Failed to find any Python interpreter (REQUIRED)" )
+    # Search first without specifying the version, since doing so gives preference to the specified
+    # version even though a never version of the interpreter may be available
+    find_package( PythonInterp ${_p_REQUIRED} )
+
+    # If no suitable version was found, search again with the version specified
+    if( PYTHONINTERP_FOUND AND _p_VERSION )
+      if( _p_VERSION VERSION_GREATER "${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}.${PYTHON_VERSION_PATCH}" )
+        ecbuild_debug( "ecbuild_find_python: Found Python interpreter version ${PYTHON_VERSION_STRING} at ${PYTHON_EXECUTABLE}, however version ${_p_VERSION} is required. Searching again..." )
+        unset( PYTHONINTERP_FOUND )
+        unset( PYTHON_EXECUTABLE )
+        unset( PYTHON_EXECUTABLE CACHE )
+        unset( PYTHON_VERSION_MAJOR )
+        unset( PYTHON_VERSION_MINOR )
+        unset( PYTHON_VERSION_PATCH )
+        unset( PYTHON_VERSION_STRING )
+        find_package( PythonInterp "${_p_VERSION}" ${_p_REQUIRED} )
+      endif()
     endif()
 
-    # find python version
-    # execute_process( COMMAND ${PYTHON_EXECUTABLE} -V ERROR_VARIABLE _version  RESULT_VARIABLE _return ERROR_STRIP_TRAILING_WHITESPACE)
-    # if( NOT _return )
-    #    string(REGEX REPLACE ".*([0-9]+)\\.([0-9]+)\\.([0-9]+)" "\\1.\\2.\\3" PYTHON_VERSION ${_version} )
-    # endif()
-    # endif()
-
-    # ecbuild_debug( "Python version ${PYTHON_VERSION_STRING}" )
-    # ecbuild_debug_var(PYTHON_VERSION_MAJOR)
-    # ecbuild_debug_var(PYTHON_VERSION_MINOR)
-    # ecbuild_debug_var(PYTHON_VERSION_PATCH)
-
-    if( PYTHONINTERP_FOUND AND DEFINED _p_VERSION )
-        if( _p_VERSION VERSION_GREATER "${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}.${PYTHON_VERSION_PATCH}" )
-            set( PYTHONINTERP_FOUND 0 )
-            set( PYTHON_EXECUTABLE "PYTHON_EXECUTABLE-NOTFOUND" )
-            if( _p_REQUIRED )
-                ecbuild_critical( "Required python version at least ${_p_VERSION} but found only ${PYTHON_VERSION_STRING}" )
-            else()
-                ecbuild_warn( "Looking for python version at least ${_p_VERSION} but found only ${PYTHON_VERSION_STRING}\nMarking Python as NOTFOUND" )
-            endif()
-        endif()
-    endif()
+    set( __required_vars PYTHONINTERP_FOUND )
 
     if( PYTHONINTERP_FOUND )
         ecbuild_debug( "ecbuild_find_python: Found Python interpreter version ${PYTHON_VERSION_STRING} at ${PYTHON_EXECUTABLE}" )
@@ -104,15 +104,24 @@ function( ecbuild_find_python )
             execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())" OUTPUT_VARIABLE PYTHON_SITE_PACKAGES OUTPUT_STRIP_TRAILING_WHITESPACE)
         endif()
         ecbuild_debug( "ecbuild_find_python: PYTHON_SITE_PACKAGES=${PYTHON_SITE_PACKAGES}" )
-
     endif()
+
     if( PYTHONINTERP_FOUND AND NOT _p_NO_LIBS )
+        list( APPEND __required_vars PYTHONLIBS_FOUND PYTHON_LIBS_WORKING )
+
         # find python config
 
         if( PYTHON_EXECUTABLE AND EXISTS ${PYTHON_EXECUTABLE}-config )
             set(PYTHON_CONFIG_EXECUTABLE ${PYTHON_EXECUTABLE}-config CACHE PATH "" FORCE)
         else()
-            find_program( PYTHON_CONFIG_EXECUTABLE NAMES python-config python-config${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR} )
+            get_filename_component( __python_bin_dir ${PYTHON_EXECUTABLE} PATH )
+            find_program( PYTHON_CONFIG_EXECUTABLE
+                          NO_CMAKE_PATH NO_CMAKE_SYSTEM_PATH
+                          NO_CMAKE_ENVIRONMENT_PATH NO_SYSTEM_ENVIRONMENT_PATH
+                          HINTS ${__python_bin_dir}
+                          NAMES python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}-config
+                                python${PYTHON_VERSION_MAJOR}-config
+                                python-config )
         endif()
 
         ecbuild_debug_var( PYTHON_CONFIG_EXECUTABLE )
@@ -122,31 +131,58 @@ function( ecbuild_find_python )
         # The OpenBSD python packages have python-config's
         # that don't reliably report linking flags that will work.
 
-        if( PYTHON_CONFIG_EXECUTABLE AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD" )
+        if( PYTHON_CONFIG_EXECUTABLE AND NOT ( PYTHON_NO_CONFIG OR ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD" ) )
             ecbuild_debug( "ecbuild_find_python: Searching for Python include directories and libraries using ${PYTHON_CONFIG_EXECUTABLE}" )
 
-            execute_process(COMMAND "${PYTHON_CONFIG_EXECUTABLE}" --ldflags
-                            OUTPUT_VARIABLE PYTHON_LIBRARIES
-                            OUTPUT_STRIP_TRAILING_WHITESPACE
-                            ERROR_QUIET)
+            if( NOT PYTHON_LIBRARY )
+              execute_process(COMMAND "${PYTHON_CONFIG_EXECUTABLE}" --prefix
+                              OUTPUT_VARIABLE PYTHON_PREFIX
+                              OUTPUT_STRIP_TRAILING_WHITESPACE
+                              ERROR_QUIET)
+
+              execute_process(COMMAND "${PYTHON_CONFIG_EXECUTABLE}" --ldflags
+                              OUTPUT_VARIABLE PYTHON_LIBRARY
+                              OUTPUT_STRIP_TRAILING_WHITESPACE
+                              ERROR_QUIET)
+
+              # Prepend -L and and set the RPATH to the lib directory under the
+              # Python install prefix unless it is a standard system prefix path
+              if( PYTHON_LIBRARY AND PYTHON_PREFIX AND NOT CMAKE_SYSTEM_PREFIX_PATH MATCHES ${PYTHON_PREFIX} )
+                set( PYTHON_LIBRARY "-L${PYTHON_PREFIX}/lib -Wl,-rpath,${PYTHON_PREFIX}/lib ${PYTHON_LIBRARY}" )
+              endif()
+
+              set( PYTHON_INCLUDE_DIR "${PYTHON_INCLUDE_DIR}" CACHE PATH
+                   "Path to where Python.h is found" FORCE )
+            endif()
+
+            if(DEFINED PYTHON_INCLUDE_PATH AND NOT DEFINED PYTHON_INCLUDE_DIR)
+              set( PYTHON_INCLUDE_DIR "${PYTHON_INCLUDE_PATH}" CACHE PATH
+                   "Path to where Python.h is found" FORCE )
+            elseif( NOT PYTHON_INCLUDE_DIR )
+              execute_process(COMMAND "${PYTHON_CONFIG_EXECUTABLE}" --includes
+                              OUTPUT_VARIABLE PYTHON_INCLUDE_DIR
+                              OUTPUT_STRIP_TRAILING_WHITESPACE
+                              ERROR_QUIET)
 
-            execute_process(COMMAND "${PYTHON_CONFIG_EXECUTABLE}" --includes
-                            OUTPUT_VARIABLE PYTHON_INCLUDE_DIRS
-                            OUTPUT_STRIP_TRAILING_WHITESPACE
-                            ERROR_QUIET)
+              string(REGEX REPLACE "^[-I]" "" PYTHON_INCLUDE_DIR "${PYTHON_INCLUDE_DIR}")
+              string(REGEX REPLACE "[ ]-I" " " PYTHON_INCLUDE_DIR "${PYTHON_INCLUDE_DIR}")
 
-            string(REGEX REPLACE "^[-I]" "" PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIRS}")
-            string(REGEX REPLACE "[ ]-I" " " PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIRS}")
+              separate_arguments(PYTHON_INCLUDE_DIR)
+              set( PYTHON_INCLUDE_DIR "${PYTHON_INCLUDE_DIR}" CACHE PATH
+                   "Path to where Python.h is found" FORCE )
 
-            separate_arguments(PYTHON_INCLUDE_DIRS)
+            endif()
+
+            set(PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIR}")
+            set(PYTHON_LIBRARIES "${PYTHON_LIBRARY}")
+
+            find_package_handle_standard_args( PythonLibs DEFAULT_MSG
+                                               PYTHON_INCLUDE_DIRS PYTHON_LIBRARIES )
 
         else() # revert to finding pythonlibs the standard way (cmake macro)
-            ecbuild_debug( "ecbuild_find_python: Searching for Python include directories and libraries using find_package(PythonLibs)" )
+            ecbuild_debug( "ecbuild_find_python: Searching for Python include directories and libraries using find_package( PythonLibs ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}.${PYTHON_VERSION_PATCH} ${_p_REQUIRED} )" )
 
-            find_package(PythonLibs)
-            if( PYTHON_INCLUDE_PATH AND NOT PYTHON_INCLUDE_DIRS )
-              set(PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_PATH}")
-            endif()
+            find_package( PythonLibs "${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}.${PYTHON_VERSION_PATCH}" ${_p_REQUIRED} )
 
         endif()
 
@@ -159,25 +195,18 @@ function( ecbuild_find_python )
             try_compile( PYTHON_LIBS_WORKING ${CMAKE_CURRENT_BINARY_DIR}
                          ${__test_python}
                          CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${PYTHON_INCLUDE_DIRS}"
-                         LINK_LIBRARIES ${PYTHON_LIBRARIES} )
-
-            # set output variables
-
-            find_package_handle_standard_args( PythonLibs DEFAULT_MSG
-                                               PYTHON_INCLUDE_DIRS PYTHON_LIBRARIES PYTHON_LIBS_WORKING )
-            ecbuild_debug( "ecbuild_find_python: PYTHON_INCLUDE_DIRS=${PYTHON_INCLUDE_DIRS}" )
-            ecbuild_debug( "ecbuild_find_python: PYTHON_LIBRARIES=${PYTHON_LIBRARIES}" )
-
-        endif()
+                         LINK_LIBRARIES ${PYTHON_LIBRARIES}
+                         OUTPUT_VARIABLE __try_compile_output )
+            if( NOT PYTHON_LIBS_WORKING )
+              ecbuild_debug( "ecbuild_find_python: trying to link executable with Python libraries failed\n${__try_compile_output}" )
+            endif()
 
-        # Also set PYTHON_FOUND and Python_FOUND for compatibility with ecbuild_add_option
-        if( PYTHONLIBS_FOUND )
-          set( PYTHON_FOUND 1 )
-          set( Python_FOUND 1 )
         endif()
 
     endif()
 
+    find_package_handle_standard_args( Python DEFAULT_MSG ${__required_vars} )
+
     ecbuild_debug_var( PYTHONINTERP_FOUND )
     ecbuild_debug_var( PYTHON_FOUND )
     ecbuild_debug_var( PYTHON_EXECUTABLE )
diff --git a/cmake/ecbuild_generate_fortran_interfaces.cmake b/cmake/ecbuild_generate_fortran_interfaces.cmake
index d586248..93c7414 100644
--- a/cmake/ecbuild_generate_fortran_interfaces.cmake
+++ b/cmake/ecbuild_generate_fortran_interfaces.cmake
@@ -12,7 +12,7 @@
 # ecbuild_generate_fortran_interfaces
 # ===================================
 #
-# Generates interfaces form the Fortran source files. ::
+# Generates interfaces from the Fortran source files. ::
 #
 #   ecbuild_generate_fortran_interfaces()
 #
diff --git a/cmake/ecbuild_get_cxx11_flags.cmake b/cmake/ecbuild_get_cxx11_flags.cmake
index 47d0e1a..a97fe11 100644
--- a/cmake/ecbuild_get_cxx11_flags.cmake
+++ b/cmake/ecbuild_get_cxx11_flags.cmake
@@ -23,7 +23,7 @@ function( ecbuild_get_cxx11_flags CXX11_FLAGS )
 
   include(CheckCXXCompilerFlag)
 
-  # On older cmake versions + newer compilers, 
+  # On older cmake versions + newer compilers,
   # the given version of CheckCXXCompilerFlags does not quite work.
   if(CMAKE_VERSION VERSION_LESS 2.8.9)
     macro (CHECK_CXX_COMPILER_FLAG _FLAG _RESULT)
@@ -52,7 +52,8 @@ function( ecbuild_get_cxx11_flags CXX11_FLAGS )
 
   check_cxx_compiler_flag(-std=c++11 has_std_cpp11)
   check_cxx_compiler_flag(-std=c++0x has_std_cpp0x)
-  if(MINGW) 
+  check_cxx_compiler_flag(-hstd=c++11 has_hstd_cpp11)
+  if(MINGW)
     check_cxx_compiler_flag(-std=gnu++11 has_std_gnupp11)
     check_cxx_compiler_flag(-std=gnu++0x has_std_gnupp0x)
   endif(MINGW)
@@ -60,7 +61,9 @@ function( ecbuild_get_cxx11_flags CXX11_FLAGS )
     set(${CXX11_FLAGS} "-std=gnu++11" PARENT_SCOPE)
   elseif(has_std_gnupp0x)
     set(${CXX11_FLAGS} "-std=gnu++0x" PARENT_SCOPE)
-  elseif(has_std_cpp11) 
+  elseif(has_hstd_cpp11)
+    set(${CXX11_FLAGS} "-hstd=c++11" PARENT_SCOPE)
+  elseif(has_std_cpp11)
     set(${CXX11_FLAGS} "-std=c++11" PARENT_SCOPE)
   elseif(has_std_cpp0x)
     set(${CXX11_FLAGS} "-std=c++0x" PARENT_SCOPE)
diff --git a/cmake/ecbuild_get_test_data.cmake b/cmake/ecbuild_get_test_data.cmake
index c19a760..42185f1 100644
--- a/cmake/ecbuild_get_test_data.cmake
+++ b/cmake/ecbuild_get_test_data.cmake
@@ -20,6 +20,7 @@ function( _download_test_data _p_NAME _p_DIRNAME )
   #endif()
 
   find_program( CURL_PROGRAM curl )
+  mark_as_advanced(CURL_PROGRAM)
 
   if( CURL_PROGRAM )
 
@@ -240,6 +241,7 @@ endfunction(ecbuild_get_test_data)
 #   ecbuild_get_test_multidata( NAMES <name1> [ <name2> ... ]
 #                               TARGET <target>
 #                               [ DIRNAME <dir> ]
+#                               [ LABELS <label1> [<label2> ...] ]
 #                               [ EXTRACT ]
 #                               [ NOCHECK ] )
 #
@@ -257,6 +259,14 @@ endfunction(ecbuild_get_test_data)
 # DIRNAME : optional, defaults to <project>/<relative path to current dir>
 #   directory in which the test data resides
 #
+# LABELS : optional
+#   list of labels to assign to the test
+#
+#   Lower case project name and ``download_data`` are always added as labels.
+#
+#   This allows selecting tests to run via ``ctest -L <regex>`` or tests
+#   to exclude via ``ctest -LE <regex>``.
+#
 # EXTRACT : optional
 #   extract downloaded files (supported archives: tar, zip, tar.gz, tar.bz2)
 #
@@ -302,7 +312,7 @@ function( ecbuild_get_test_multidata )
 
     set( options EXTRACT NOCHECK )
     set( single_value_args TARGET DIRNAME )
-    set( multi_value_args  NAMES )
+    set( multi_value_args  NAMES LABELS )
 
     cmake_parse_arguments( _p "${options}" "${single_value_args}" "${multi_value_args}"  ${_FIRST_ARG} ${ARGN} )
 
@@ -385,6 +395,9 @@ endfunction()\n\n" )
 
     if( ENABLE_TESTS )
       add_test(  NAME ${_p_TARGET} COMMAND ${CMAKE_COMMAND} -P ${_script} )
+      set( _p_LABELS ${PROJECT_NAME_LOWCASE} download_data ${_p_LABELS} )
+      list( REMOVE_DUPLICATES _p_LABELS )
+      set_property( TEST ${_p_TARGET} APPEND PROPERTY LABELS "${_p_LABELS}" )
     endif()
 
 endfunction(ecbuild_get_test_multidata)
diff --git a/cmake/ecbuild_install_project.cmake b/cmake/ecbuild_install_project.cmake
index 2ba472e..5e26bea 100644
--- a/cmake/ecbuild_install_project.cmake
+++ b/cmake/ecbuild_install_project.cmake
@@ -233,6 +233,18 @@ macro( ecbuild_install_project )
         endif()
     endforeach()
 
+    # Deduplicate TPL includes, libs and definitions
+    # The same TPL may indirectly be pulled in multiple times!
+    if( ${PNAME}_TPL_INCLUDE_DIRS )
+      list( REMOVE_DUPLICATES ${PNAME}_TPL_INCLUDE_DIRS )
+    endif()
+    if( ${PNAME}_TPL_LIBRARIES )
+      list( REMOVE_DUPLICATES ${PNAME}_TPL_LIBRARIES )
+    endif()
+    if( ${PNAME}_TPL_DEFINITIONS )
+      list( REMOVE_DUPLICATES ${PNAME}_TPL_DEFINITIONS )
+    endif()
+
     # Generate the project .cmake config files
     # All variables here must be (sub)project specific in order to work within bundles
     if ( NOT ECBUILD_SKIP_${PNAME}_EXPORT )
@@ -278,8 +290,6 @@ macro( ecbuild_install_project )
            set( CONF_TPL_LIBRARIES ${${PNAME}_TPL_LIBRARIES} )
         endif()
 
-        # project-config.cmake @ build tree
-
         set( CONF_TPLS ${${PNAME}_TPLS} )
 
         set( CONF_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}" "${PROJECT_BINARY_DIR}" )
@@ -288,18 +298,11 @@ macro( ecbuild_install_project )
         endif()
 
         set( CONF_TPL_INCLUDE_DIRS "" )
-        foreach( _tpl ${${PNAME}_TPLS} )
-            string( TOUPPER ${_tpl} TPL )
-            if( ${_tpl}_INCLUDE_DIRS )
-                list( APPEND CONF_TPL_INCLUDE_DIRS ${${_tpl}_INCLUDE_DIRS} )
-            elseif( ${_tpl}_INCLUDE_DIR )
-                list( APPEND CONF_TPL_INCLUDE_DIRS ${${_tpl}_INCLUDE_DIR} )
-            elseif( ${TPL}_INCLUDE_DIRS )
-                list( APPEND CONF_TPL_INCLUDE_DIRS ${${TPL}_INCLUDE_DIRS} )
-            elseif( ${TPL}_INCLUDE_DIR )
-                list( APPEND CONF_TPL_INCLUDE_DIRS ${${TPL}_INCLUDE_DIR} )
-            endif()
-        endforeach()
+        if( ${PNAME}_TPL_INCLUDE_DIRS )
+            set( CONF_TPL_INCLUDE_DIRS ${${PNAME}_TPL_INCLUDE_DIRS} )
+        endif()
+
+        # Generate <project>-import.cmake (if it exists)
 
         set( CONF_IMPORT_FILE "${LNAME}-import.cmake" )
 
@@ -323,11 +326,17 @@ macro( ecbuild_install_project )
           ecbuild_debug( "No ${CONF_IMPORT_FILE} found in ${PROJECT_SOURCE_DIR}" )
         endif()
 
+        # Generate <project>-config.cmake for use from the build tree
+
         set( _lname_config "${PROJECT_BINARY_DIR}/${LNAME}-config.cmake")
 
+        # Include directories (may) reference source and build tree and the
+        # config file is marked as coming from a build tree
         set( _is_build_dir_export ON )
         configure_file( "${_template_config}" "${_lname_config}" @ONLY )
 
+        # Generate <project>-config.cmake.tpls (if there are any TPLs)
+
         file( REMOVE ${_lname_config}.tpls.in )
 
         foreach( _tpl ${${PNAME}_TPLS} )
@@ -360,28 +369,13 @@ macro( ecbuild_install_project )
             install( FILES "${_lname_config}.tpls" DESTINATION "${INSTALL_CMAKE_DIR}" )
         endif()
 
-        # project-config.cmake @ install tree
+        # Generate <project>-config.cmake for use in the install tree
 
+        # Compute path to the include dir relative to the project's CMake dir
+        # where <project>-config.cmake is installed to
         file( RELATIVE_PATH REL_INCLUDE_DIR "${${PNAME}_FULL_INSTALL_CMAKE_DIR}" "${${PNAME}_FULL_INSTALL_INCLUDE_DIR}" )
         set( CONF_INCLUDE_DIRS "\${${PNAME}_CMAKE_DIR}/${REL_INCLUDE_DIR}" )
 
-        set( CONF_TPL_INCLUDE_DIRS "" )
-        foreach( _tpl ${${PNAME}_TPLS} )
-            string( TOUPPER ${_tpl} TPL )
-            if( ${TPL}_FULL_INSTALL_INCLUDE_DIR )
-                 list( APPEND CONF_TPL_INCLUDE_DIRS "\${${PNAME}_CMAKE_DIR}/${REL_INCLUDE_DIR}" )
-            endif()
-            if( ${_tpl}_INCLUDE_DIRS )
-                list( APPEND CONF_TPL_INCLUDE_DIRS ${${_tpl}_INCLUDE_DIRS} )
-            elseif( ${_tpl}_INCLUDE_DIR )
-                list( APPEND CONF_TPL_INCLUDE_DIRS ${${_tpl}_INCLUDE_DIR} )
-            elseif( ${TPL}_INCLUDE_DIRS )
-                list( APPEND CONF_TPL_INCLUDE_DIRS ${${TPL}_INCLUDE_DIRS} )
-            elseif( ${TPL}_INCLUDE_DIR )
-                list( APPEND CONF_TPL_INCLUDE_DIRS ${${TPL}_INCLUDE_DIR} )
-            endif()
-        endforeach()
-
         set( _is_build_dir_export OFF )
         configure_file( "${_template_config}" "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${LNAME}-config.cmake" @ONLY )
         install( FILES "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${LNAME}-config.cmake" DESTINATION "${INSTALL_CMAKE_DIR}" )
diff --git a/cmake/ecbuild_log.cmake b/cmake/ecbuild_log.cmake
index ec99495..32a1398 100644
--- a/cmake/ecbuild_log.cmake
+++ b/cmake/ecbuild_log.cmake
@@ -20,7 +20,9 @@
 # :ecbuild_warn:      logs a ``WARNING`` message if log level <= ``WARN``
 # :ecbuild_error:     logs a ``SEND_ERROR`` message if log level <= ``ERROR``
 # :ecbuild_critical:  logs a ``FATAL_ERROR`` message if log level <= ``CRITICAL``
-# :ecbuild_deprecate: logs a ``DEPRECATION`` message
+# :ecbuild_deprecate: logs a ``DEPRECATION`` message as a warning
+#                     enable CMAKE_ERROR_DEPRECATED to raise an error instead
+#                     disable CMAKE_WARN_DEPRECATED to hide deprecations
 #
 # Furthermore there are auxilliary functions for outputting CMake variables,
 # CMake lists and environment variables if the log level is ``DEBUG``:
@@ -50,10 +52,6 @@
 # ECBUILD_NO_COLOUR : bool
 #   if set, does not colour log output (by default log output is coloured)
 #
-# ECBUILD_NO_DEPRECATIONS : bool
-#   if set, does not output deprecation messages (only set this if you *really*
-#   know what you are doing!)
-#
 # Usage
 # -----
 #
@@ -64,7 +62,7 @@
 #
 ##############################################################################
 
-# Define colour escape sequences (https://stackoverflow.com/a/19578320/396967)
+# Define colour escape sequences (not available on Windows)
 if(NOT (WIN32 OR ECBUILD_NO_COLOUR))
   string(ASCII 27 Esc)
   set(ColourReset "${Esc}[m")
@@ -113,6 +111,9 @@ endif()
 if( NOT DEFINED ECBUILD_LOG_FILE )
   set( ECBUILD_LOG_FILE ${CMAKE_BINARY_DIR}/ecbuild.log )
 endif()
+if( NOT DEFINED CMAKE_ERROR_DEPRECATED AND NOT DEFINED CMAKE_WARN_DEPRECATED )
+  set( CMAKE_WARN_DEPRECATED ON )
+endif()
 
 ##############################################################################
 
@@ -167,7 +168,15 @@ endfunction( ecbuild_error )
 function( ecbuild_deprecate )
   string(REPLACE ";" " " MSG ${ARGV})
   ecbuild_log(DEPRECATION "${MSG}")
-  if( NOT ECBUILD_NO_DEPRECATIONS )
+  # DEPRECATION message type was only introduced in CMake 3.0, provide
+  # consistent behaviour for CMake < 3.0
+  if( CMAKE_VERSION VERSION_LESS 3.0 )
+    if( CMAKE_ERROR_DEPRECATED )
+      message(FATAL_ERROR "${BoldRed}DEPRECATION - ${MSG}${ColourReset}")
+    elseif( CMAKE_WARN_DEPRECATED )
+      message(WARNING "${Yellow}DEPRECATION - ${MSG}${ColourReset}")
+    endif()
+  else()
     message(DEPRECATION "${BoldRed}${MSG}${ColourReset}")
   endif()
 endfunction( ecbuild_deprecate )
diff --git a/cmake/ecbuild_pkgconfig.cmake b/cmake/ecbuild_pkgconfig.cmake
index 6f62977..d839a86 100644
--- a/cmake/ecbuild_pkgconfig.cmake
+++ b/cmake/ecbuild_pkgconfig.cmake
@@ -275,7 +275,7 @@ endfunction(ecbuild_pkgconfig_include)
 # ---------------
 #
 # The following CMake variables are used as default values for some of the
-# options listed above, where ``PNAME`` is the project name in upper case: ::
+# options listed above, where ``PNAME`` is the project name in upper case:
 #
 # :<PNAME>_LIBRARIES:    list of libraries to export
 # :<PNAME>_DESCRIPTION:  package description
diff --git a/cmake/ecbuild_print_summary.cmake b/cmake/ecbuild_print_summary.cmake
index 4cf05cc..6fc70d0 100644
--- a/cmake/ecbuild_print_summary.cmake
+++ b/cmake/ecbuild_print_summary.cmake
@@ -59,6 +59,11 @@ macro( ecbuild_print_summary )
     ecbuild_info( "build type       : [${CMAKE_BUILD_TYPE}]" )
     ecbuild_info( "timestamp        : [${EC_BUILD_TIMESTAMP}]" )
     ecbuild_info( "install prefix   : [${CMAKE_INSTALL_PREFIX}]" )
+    ecbuild_info( "  bin dir        : [${${PNAME}_FULL_INSTALL_BIN_DIR}]" )
+    ecbuild_info( "  lib dir        : [${${PNAME}_FULL_INSTALL_LIB_DIR}]" )
+    ecbuild_info( "  include dir    : [${${PNAME}_FULL_INSTALL_INCLUDE_DIR}]" )
+    ecbuild_info( "  data dir       : [${${PNAME}_FULL_INSTALL_DATA_DIR}]" )
+    ecbuild_info( "  cmake dir      : [${${PNAME}_FULL_INSTALL_CMAKE_DIR}]" )
     if( EC_LINK_DIR )
       ecbuild_info( "links prefix     : [${EC_LINK_DIR}]" )
     endif()
@@ -66,7 +71,8 @@ macro( ecbuild_print_summary )
 
     foreach( lang ${langs} )
       ecbuild_info( "${lang} -- ${CMAKE_${lang}_COMPILER_ID} ${CMAKE_${lang}_COMPILER_VERSION}"  )
-      ecbuild_info( "    compiler   : ${CMAKE_${lang}_COMPILER} ${CMAKE_${lang}_FLAGS} ${CMAKE_${lang}_FLAGS_${CMAKE_BUILD_TYPE_CAPS}}" )
+      ecbuild_info( "    compiler   : ${CMAKE_${lang}_COMPILER}" )
+      ecbuild_info( "    flags      : ${CMAKE_${lang}_FLAGS} ${CMAKE_${lang}_FLAGS_${CMAKE_BUILD_TYPE_CAPS}} ${${PNAME}_${lang}_FLAGS} ${${PNAME}_${lang}_FLAGS_${CMAKE_BUILD_TYPE_CAPS}}" )
       ecbuild_info( "    link flags : ${CMAKE_${lang}_LINK_FLAGS}" )
     endforeach()
 
diff --git a/cmake/ecbuild_remove_fortran_flags.cmake b/cmake/ecbuild_remove_fortran_flags.cmake
index 74c8832..3a80316 100644
--- a/cmake/ecbuild_remove_fortran_flags.cmake
+++ b/cmake/ecbuild_remove_fortran_flags.cmake
@@ -10,9 +10,9 @@
 #.rst:
 #
 # ecbuild_remove_fortran_flags
-# =========================
+# ============================
 #
-# Remove Fortran compiler flags from CMAKE_Fortran_FLAGS. ::
+# Remove Fortran compiler flags from ``CMAKE_Fortran_FLAGS``. ::
 #
 #   ecbuild_remove_fortran_flags( <flag1> [ <flag2> ... ] [ BUILD <build> ] )
 #
@@ -58,4 +58,3 @@ macro( ecbuild_remove_fortran_flags m_flags )
   unset( _flags )
 
 endmacro()
-
diff --git a/cmake/ecbuild_separate_sources.cmake b/cmake/ecbuild_separate_sources.cmake
index b56db63..00722ae 100644
--- a/cmake/ecbuild_separate_sources.cmake
+++ b/cmake/ecbuild_separate_sources.cmake
@@ -32,10 +32,11 @@
 # If any file of the following group of extensions is present in the list of
 # sources, the corresponding CMake variable is set:
 #
-# :<target>_h_srcs:   list of sources with extension .h, .hxx, .hh, .hpp, .H
-# :<target>_c_srcs:   list of sources with extension .c
-# :<target>_cxx_srcs: list of sources with extension .cc, .cxx, .cpp, .C
-# :<target>_f_srcs:   list of sources with extension .f, .F, .for, f77, .f90, .f95
+# :<target>_h_srcs:       source files with extension .h, .hxx, .hh, .hpp, .H
+# :<target>_c_srcs:       source files with extension .c
+# :<target>_cxx_srcs:     source files with extension .cc, .cxx, .cpp, .C
+# :<target>_fortran_srcs: source files with extension .f, .F, .for, f77, .f90,
+#                                                     .f95, .F77, .F90, .F95
 #
 ##############################################################################
 
@@ -60,32 +61,33 @@ macro( ecbuild_separate_sources )
 	endif()
 
 	foreach( src ${_PAR_SOURCES} )
-		if(${src} MATCHES "(\\.h|\\.hxx|\\.hh|\\.hpp|\\.H)")
+		if(${src} MATCHES "(\\.h$|\\.hxx$|\\.hh$|\\.hpp$|\\.H$)")
 			list( APPEND ${_PAR_TARGET}_h_srcs ${src} )
 		endif()
 	endforeach()
 
 	foreach( src ${_PAR_SOURCES} )
-		if(${src} MATCHES "(\\.c)")
+		if(${src} MATCHES "(\\.c$)")
 			list( APPEND ${_PAR_TARGET}_c_srcs ${src} )
 		endif()
 	endforeach()
 
 	foreach( src ${_PAR_SOURCES} )
-		if(${src} MATCHES "(\\.cc|\\.cxx|\\.cpp|\\.C)")
+		if(${src} MATCHES "(\\.cc$|\\.cxx$|\\.cpp$|\\.C$)")
 			list( APPEND ${_PAR_TARGET}_cxx_srcs ${src} )
 		endif()
 	endforeach()
 
 	foreach( src ${_PAR_SOURCES} )
-		if(${src} MATCHES "(\\.f|\\.F|\\.for|\\.f77|\\.f90|\\.f95)")
-			list( APPEND ${_PAR_TARGET}_f_srcs ${src} )
+		if(${src} MATCHES "(\\.f$|\\.F$|\\.for$|\\.f77$|\\.f90$|\\.f95$|\\.f03$|\\.f08$|\\.F77$|\\.F90$|\\.F95$|\\.F03$|\\.F08$)")
+			list( APPEND ${_PAR_TARGET}_fortran_srcs ${src} )
 		endif()
 	endforeach()
+	set_source_files_properties( ${${_PAR_TARGET}_fortran_srcs} PROPERTIES LANGUAGE Fortran )
 
 #    ecbuild_debug_var( ${_PAR_TARGET}_h_srcs )
 #    ecbuild_debug_var( ${_PAR_TARGET}_c_srcs )
 #    ecbuild_debug_var( ${_PAR_TARGET}_cxx_srcs )
-#    ecbuild_debug_var( ${_PAR_TARGET}_f_srcs )
+#    ecbuild_debug_var( ${_PAR_TARGET}_fortran_srcs )
 
-endmacro( ecbuild_separate_sources  )
+endmacro( ecbuild_separate_sources )
diff --git a/cmake/ecbuild_source_flags.cmake b/cmake/ecbuild_source_flags.cmake
index 2414765..a281f1d 100644
--- a/cmake/ecbuild_source_flags.cmake
+++ b/cmake/ecbuild_source_flags.cmake
@@ -23,8 +23,12 @@ function( ecbuild_source_flags OUT TARGET DEFAULT_FLAGS SOURCES )
   endif()
   execute_process( COMMAND ${PYTHON_EXECUTABLE} ${__gen_source_flags}
                            ${ECBUILD_SOURCE_FLAGS} ${OUTFILE} "${DEFAULT_FLAGS}"
-                           ${SOURCES} "${__debug}" )
+                           ${SOURCES} "${__debug}"
+                   RESULT_VARIABLE __res )
 
+  if( __res GREATER 0 )
+    ecbuild_error( "ecbuild_source_flags: failed generating source flags for target ${TARGET} from ${ECBUILD_SOURCE_FLAGS}" )
+  endif()
   set( ${OUT} ${OUTFILE} PARENT_SCOPE )
 
 endfunction()
diff --git a/cmake/ecbuild_system.cmake b/cmake/ecbuild_system.cmake
index a4361f7..f02113e 100644
--- a/cmake/ecbuild_system.cmake
+++ b/cmake/ecbuild_system.cmake
@@ -187,6 +187,7 @@ if( PROJECT_NAME STREQUAL CMAKE_PROJECT_NAME )
     include( ecbuild_add_cxx_flags )
     include( ecbuild_add_cxx11_flags )
     include( ecbuild_get_cxx11_flags )
+    include( ecbuild_check_fortran )
     include( ecbuild_add_fortran_flags )
     include( ecbuild_add_test )
     include( ecbuild_add_resources )
@@ -211,6 +212,7 @@ if( PROJECT_NAME STREQUAL CMAKE_PROJECT_NAME )
     include( ecbuild_git )
     include( ecbuild_enable_fortran )
     include( ecbuild_source_flags )
+    include( ecbuild_target_flags )
     include( ecbuild_bundle )
     include( ecbuild_pkgconfig )
     include( ecbuild_cache )
diff --git a/cmake/ecbuild_target_flags.cmake b/cmake/ecbuild_target_flags.cmake
new file mode 100644
index 0000000..4c589af
--- /dev/null
+++ b/cmake/ecbuild_target_flags.cmake
@@ -0,0 +1,91 @@
+# (C) Copyright 1996-2016 ECMWF.
+#
+# This software is licensed under the terms of the Apache Licence Version 2.0
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
+# granted to it by virtue of its status as an intergovernmental organisation
+# nor does it submit to any jurisdiction.
+
+##############################################################################
+#.rst:
+#
+# ecbuild_target_flags
+# ====================
+#
+# Override compiler flags for a given target. ::
+#
+#   ecbuild_target_flags( <target> <c_flags> <cxx_flags> <fortran_flags> )
+#
+# Required arguments:
+#
+# :target:        Target name
+# :c_flags:       Target specific C flags (can be empty)
+# :cxx_flags:     Target specific CXX flags (can be empty)
+# :fortran_flags: Target specific Fortran flags (can be empty)
+#
+# There are 3 cases, only the first applicable case takes effect:
+#
+# 1.  Use custom rules from user specified ``ECBUILD_COMPILE_FLAGS`` file and
+#     append target specific flags.
+#
+# 2.  Use JSON rules from user specified ``ECBUILD_SOURCE_FLAGS`` file and
+#     append target specific flags.
+#
+# 3.  Only the target specific flags are applied to all matching source files.
+#
+##############################################################################
+
+function( ecbuild_target_flags target c_flags cxx_flags fortran_flags )
+
+  get_property( languages GLOBAL PROPERTY ENABLED_LANGUAGES )
+
+  foreach( lang ${languages} )
+
+    string( TOLOWER ${lang} l )
+
+    if( ${target}_${l}_srcs )
+
+      # 1) Override compile flags from user specified CMake file
+      if( ECBUILD_COMPILE_FLAGS )
+
+        # Project specific flags for current language and optionally build type
+        set( pflags "${${PNAME}_${lang}_FLAGS} ${${PNAME}_${lang}_FLAGS_${CMAKE_BUILD_TYPE_CAPS}}" )
+
+        foreach( src ${${target}_${l}_srcs} )
+          get_property( oflags SOURCE ${src} PROPERTY OVERRIDE_COMPILE_FLAGS )
+          get_property( oflags_btype SOURCE ${src} PROPERTY OVERRIDE_COMPILE_FLAGS_${CMAKE_BUILD_TYPE_CAPS} )
+          # Override compile flags for source file?
+          if( oflags OR oflags_btype )
+            set_source_files_properties( ${src} PROPERTIES COMPILE_FLAGS "${oflags} ${oflags_btype}" )
+            ecbuild_debug( "ecbuild_target_flags(${target}): overriding flags for ${src} with '${oflags} ${oflags_btype}'" )
+          # Otherwise append source file specific flags to project specific and target specific flags
+          else()
+            get_property( flags SOURCE ${src} PROPERTY COMPILE_FLAGS )
+            get_property( flags_btype SOURCE ${src} PROPERTY COMPILE_FLAGS_${CMAKE_BUILD_TYPE_CAPS} )
+            set_source_files_properties( ${src} PROPERTIES COMPILE_FLAGS "${pflags} ${${l}_flags} ${flags} ${flags_btype}" )
+            ecbuild_debug( "ecbuild_target_flags(${target}): setting flags for ${src} to '${pflags} ${${l}_flags} ${flags} ${flags_btype}'" )
+          endif()
+        endforeach()
+
+      # 2) Override compile flags from user specified JSON file
+      elseif( ECBUILD_SOURCE_FLAGS )
+        ecbuild_source_flags( ${target}_${lang}_SOURCE_FLAGS
+                              ${target}_${l}
+                              "${${l}_flags}"
+                              "${${target}_${l}_srcs}" )
+
+        ecbuild_debug("ecbuild_target_flags(${target}): setting source file ${lang} flags from ${${target}_${lang}_SOURCE_FLAGS}")
+        include( ${${target}_${lang}_SOURCE_FLAGS} )
+
+      # 3) Use target specific compile flags
+      elseif( ${l}_flags )
+
+        set_source_files_properties( ${${target}_${l}_srcs} PROPERTIES COMPILE_FLAGS "${${l}_flags}" )
+        ecbuild_debug("ecbuild_target_flags(${target}): setting flags for '${${target}_${l}_srcs}' to '${${l}_flags}'")
+
+      endif()
+    endif()
+
+  endforeach()
+
+endfunction()
diff --git a/cmake/ecbuild_use_package.cmake b/cmake/ecbuild_use_package.cmake
index 6bd2bed..c88bca8 100644
--- a/cmake/ecbuild_use_package.cmake
+++ b/cmake/ecbuild_use_package.cmake
@@ -177,6 +177,7 @@ macro( ecbuild_use_package )
       # add as a subproject
 
       set( ${pkgUPPER}_subproj_dir_ ${${pkgUPPER}_subproj_dir_} CACHE PATH "Path to ${_p_PROJECT} source directory" )
+      mark_as_advanced( ${pkgUPPER}_subproj_dir_ )
 
       set( ECBUILD_PROJECTS ${ECBUILD_PROJECTS} ${_p_PROJECT} CACHE INTERNAL "" )
 
diff --git a/cmake/fortran_features/CheckFortranFeatures.cmake b/cmake/fortran_features/CheckFortranFeatures.cmake
new file mode 100644
index 0000000..992964f
--- /dev/null
+++ b/cmake/fortran_features/CheckFortranFeatures.cmake
@@ -0,0 +1,167 @@
+###############################################################################
+# checks
+set(Fortran_FEATURE_CHECK_DIR ${CMAKE_CURRENT_LIST_DIR} CACHE INTERNAL "fortran file directory")
+
+MACRO(fortran_check_single_feature FEATURE_NAME FEATURE_NUMBER RESULT_VAR)
+  IF (NOT DEFINED ${RESULT_VAR})
+    SET(_bindir "${CMAKE_BINARY_DIR}/fortran_feature_tests/fortran_${FEATURE_NAME}")
+
+    IF (${FEATURE_NUMBER})
+      SET(_SRCFILE_BASE ${Fortran_FEATURE_CHECK_DIR}/${FEATURE_NAME}-N${FEATURE_NUMBER})
+      SET(_LOG_NAME "\"${FEATURE_NAME}\" (N${FEATURE_NUMBER})")
+    ELSE (${FEATURE_NUMBER})
+      SET(_SRCFILE_BASE ${Fortran_FEATURE_CHECK_DIR}/${FEATURE_NAME})
+      SET(_LOG_NAME "\"${FEATURE_NAME}\"")
+    ENDIF (${FEATURE_NUMBER})
+    ecbuild_info("Checking Fortran support for ${_LOG_NAME}")
+
+    SET(_SRCFILE "${_SRCFILE_BASE}.F90")
+    SET(_SRCFILE_FAIL "${_SRCFILE_BASE}_fail.F90")
+    SET(_SRCFILE_FAIL_COMPILE "${_SRCFILE_BASE}_fail_compile.F90")
+
+    IF (CROSS_COMPILING)
+      try_compile(${RESULT_VAR} "${_bindir}" "${_SRCFILE}")
+      IF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
+        try_compile(${RESULT_VAR} "${_bindir}_fail" "${_SRCFILE_FAIL}")
+      ENDIF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
+    ELSE (CROSS_COMPILING)
+      try_run(_RUN_RESULT_VAR _COMPILE_RESULT_VAR
+          "${_bindir}" "${_SRCFILE}")
+      IF (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR)
+        SET(${RESULT_VAR} TRUE)
+      ELSE (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR)
+        SET(${RESULT_VAR} FALSE)
+      ENDIF (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR)
+      IF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
+        try_run(_RUN_RESULT_VAR _COMPILE_RESULT_VAR
+            "${_bindir}_fail" "${_SRCFILE_FAIL}")
+        IF (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR)
+          SET(${RESULT_VAR} TRUE)
+        ELSE (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR)
+          SET(${RESULT_VAR} FALSE)
+        ENDIF (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR)
+      ENDIF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
+    ENDIF (CROSS_COMPILING)
+    IF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL_COMPILE})
+      try_compile(_TMP_RESULT "${_bindir}_fail_compile" "${_SRCFILE_FAIL_COMPILE}")
+      IF (_TMP_RESULT)
+        SET(${RESULT_VAR} FALSE)
+      ELSE (_TMP_RESULT)
+        SET(${RESULT_VAR} TRUE)
+      ENDIF (_TMP_RESULT)
+    ENDIF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL_COMPILE})
+
+    IF (${RESULT_VAR})
+      ecbuild_info("Checking Fortran support for ${_LOG_NAME} -- works")
+    ELSE (${RESULT_VAR})
+      ecbuild_info("Checking Fortran support for ${_LOG_NAME} -- not supported")
+    ENDIF (${RESULT_VAR})
+    SET(${RESULT_VAR} ${${RESULT_VAR}} CACHE INTERNAL "Fortran support for ${_LOG_NAME}")
+  ENDIF (NOT DEFINED ${RESULT_VAR})
+ENDMACRO(fortran_check_single_feature)
+
+# Find list of all features
+function(fortran_find_all_features outvar)
+  FILE(GLOB ALL_Fortran_FEATURE_FILES "${Fortran_FEATURE_CHECK_DIR}/*.F90")
+  set(OUTPUT_VARIABLES)
+  foreach(filename ${ALL_Fortran_FEATURE_FILES})
+    get_filename_component(filename ${filename} NAME_WE)
+    string(REGEX REPLACE "_fail_compile" "" filename "${filename}")
+    string(REGEX REPLACE "_fail" "" filename "${filename}")
+    string(REGEX REPLACE "-N[0-9]*" "" filename "${filename}")
+    set(OUTPUT_VARIABLES ${OUTPUT_VARIABLES} ${filename})
+  endforeach()
+  list(REMOVE_DUPLICATES OUTPUT_VARIABLES)
+  set(${outvar} ${OUTPUT_VARIABLES} PARENT_SCOPE)
+endfunction()
+
+# Parses input and separates into arguments before REQUIRED and after REQUIRED.
+# Arguments before REQUIRED are OPTIONALS.
+# Arguments after REQUIRED are REQUIRED.
+# If no arguments, then sets output OPTIONALS to ALLFEATURES.
+function(parse_input_features ALLFEATURES OPTIONALS REQUIRED ERRORS)
+
+  if("${ARGN}" STREQUAL "")
+    set(${OPTIONALS} ${ALLFEATURES} PARENT_SCOPE)
+    set(${REQUIRED} "" PARENT_SCOPE)
+  else()
+    set(REQUIRED_FEATURES)
+    set(OPTIONAL_FEATURES)
+    set(UNKNOWN_FEATURES)
+    set(result_type OPTIONAL_FEATURES)
+    foreach(feature ${ARGN})
+      if(${feature} STREQUAL "REQUIRED")
+        set(result_type REQUIRED_FEATURES)
+      else()
+        list(FIND ALLFEATURES ${feature} feature_was_found)
+
+        if(feature_was_found EQUAL -1)
+          list(APPEND UNKNOWN_FEATURES ${feature})
+        else()
+          list(APPEND ${result_type} ${feature})
+        endif()
+
+      endif(${feature} STREQUAL "REQUIRED")
+    endforeach()
+
+    set(${OPTIONALS} ${OPTIONAL_FEATURES} PARENT_SCOPE)
+    set(${REQUIRED} ${REQUIRED_FEATURES} PARENT_SCOPE)
+    set(${ERRORS} ${UNKNOWN_FEATURES} PARENT_SCOPE)
+  endif("${ARGN}" STREQUAL "")
+endfunction(parse_input_features)
+
+# Figures out name and number of feature
+# then calls macro that does the work
+macro(_figure_out_fortran_feature current_feature)
+  # Find set of files that match current_feature, excepting _fail and _fail_compile.
+  file(GLOB ALL_FEATURE_FILES "${Fortran_FEATURE_CHECK_DIR}/${current_feature}*.F90")
+  foreach(filename ${ALL_FEATURE_FILES})
+    if(filename MATCHES "_fail")
+      list(REMOVE_ITEM ALL_FEATURE_FILES ${filename})
+    endif()
+  endforeach()
+
+  list(LENGTH ALL_FEATURE_FILES NFILES)
+  if(NOT ${NFILES} EQUAL 1)
+    ecbuild_critical("[Fortran] Expected to find only one feature. Found ${NFILES} -- ${ALL_FEATURE_FILES}.")
+  endif(NOT ${NFILES} EQUAL 1)
+
+  # Now we know which file corresponds to option.
+  get_filename_component(basename ${ALL_FEATURE_FILES} NAME_WE)
+  # If has feature number, extract it
+  set(number "")
+  if(basename MATCHES "-N[0-9]*$")
+    string(REGEX REPLACE "${current_feature}-N" "" number "${basename}")
+  endif()
+  # Then call macro
+  string(TOUPPER ${current_feature} UPPER_OPTIONAL)
+  set(VARNAME HAS_Fortran_${UPPER_OPTIONAL})
+  fortran_check_single_feature(${current_feature} "${number}" ${VARNAME})
+endmacro(_figure_out_fortran_feature)
+
+function(fortran_feature_check)
+
+  # find all features
+  fortran_find_all_features(ALL_Fortran_FEATURES)
+
+  # Parses input to this function.
+  parse_input_features("${ALL_Fortran_FEATURES}" OPTIONALS REQUIRED ERRORS ${ARGN})
+  if(NOT ${ERRORS} STREQUAL "")
+    ecbuild_info("[Fortran] The following features are unknown: ${ERRORS}.")
+  endif()
+
+  # Check optional features
+  foreach(current_feature ${OPTIONALS})
+    _figure_out_fortran_feature(${current_feature})
+  endforeach(current_feature ${ARGN})
+
+  # Check required features
+  foreach(current_feature ${REQUIRED})
+    _figure_out_fortran_feature(${current_feature})
+    set(VARNAME HAS_Fortran_${UPPER_OPTIONAL})
+    if(NOT ${VARNAME})
+      ecbuild_critical("[Fortran] Required feature ${current_feature} is not available.")
+    endif(NOT ${VARNAME})
+  endforeach(current_feature ${REQUIRED})
+
+endfunction(fortran_feature_check)
diff --git a/cmake/fortran_features/c_size_t.F90 b/cmake/fortran_features/c_size_t.F90
new file mode 100644
index 0000000..3c47136
--- /dev/null
+++ b/cmake/fortran_features/c_size_t.F90
@@ -0,0 +1,8 @@
+program test_c_sizeof
+use, intrinsic :: iso_c_binding, only : c_size_t, c_int, c_long
+
+write(0,*) "c_int    = ",c_int
+write(0,*) "c_long   = ",c_long
+write(0,*) "c_size_t = ",c_size_t
+
+end program
\ No newline at end of file
diff --git a/cmake/fortran_features/c_sizeof.F90 b/cmake/fortran_features/c_sizeof.F90
new file mode 100644
index 0000000..fc1be41
--- /dev/null
+++ b/cmake/fortran_features/c_sizeof.F90
@@ -0,0 +1,3 @@
+program test_c_sizeof
+use, intrinsic :: iso_c_binding, only : c_sizeof
+end program
\ No newline at end of file
diff --git a/cmake/fortran_features/derivedtype_interface.F90 b/cmake/fortran_features/derivedtype_interface.F90
new file mode 100644
index 0000000..d59a1c3
--- /dev/null
+++ b/cmake/fortran_features/derivedtype_interface.F90
@@ -0,0 +1,54 @@
+module constructor
+
+implicit none
+
+TYPE :: AnimalType
+  private
+  integer :: m_age
+contains
+  procedure :: age
+  procedure :: speak
+ENDTYPE
+
+! Declare constructor as interface with same name as type
+interface AnimalType
+  module procedure AnimalType__ctor
+end interface
+
+contains
+
+function AnimalType__ctor(age) result(self)
+  type(AnimalType) :: self
+  integer :: age
+  write(0,'(A)') "Constructor Animal"
+  self%m_age = age
+end function
+
+function age(self)
+  class(AnimalType), intent(inout) :: self
+  integer :: age
+  age = self%m_age
+end function
+
+subroutine speak(self)
+  class(AnimalType), intent(in) :: self
+  write(0,'(A)') "Animal::speak not overridden"
+end subroutine
+
+end module
+
+! ------------------------------------------------------------------------
+
+program test_constructor
+use constructor
+implicit none
+
+  type(AnimalType) :: animal
+
+  animal = AnimalType(8)
+
+  write(0,'(A,I0)') "age = ",animal%age()
+
+  call animal%speak()
+
+end program
diff --git a/cmake/fortran_features/derivedtype_io.F90 b/cmake/fortran_features/derivedtype_io.F90
new file mode 100644
index 0000000..47a98b0
--- /dev/null
+++ b/cmake/fortran_features/derivedtype_io.F90
@@ -0,0 +1,42 @@
+module write_module
+
+implicit none
+
+TYPE :: AnimalType
+  integer :: m_age
+  integer :: m_paws
+contains
+  procedure :: writetype
+  generic :: write(formatted) => writetype
+ENDTYPE
+
+contains
+
+subroutine writetype(animal, unit, iotype, v_list, iostat, iomsg)
+  ! Argument names here from the std, but you can name them differently.
+  class(AnimalType), intent(in) :: animal ! Object to write.
+  integer, intent(in) :: unit             ! Internal unit to write to.
+  character(*), intent(in) :: iotype      ! LISTDIRECTED or DTxxx
+  integer, intent(in) :: v_list(:)        ! parameters from fmt spec.
+  integer, intent(out) :: iostat          ! non zero on error, etc.
+  character(*), intent(inout) :: iomsg    ! define if iostat non zero.
+
+  write (unit, "(A)", IOSTAT=iostat, IOMSG=iomsg) &
+      "I am a dog"
+end subroutine writetype
+
+end module
+
+! ------------------------------------------------------------------------
+
+program test_write
+use write_module
+implicit none
+
+  type(AnimalType) :: animal
+
+  animal = AnimalType(8,4)
+
+  write(0,'(A,DT)') 'Custom writing: ',animal
+
+end program
diff --git a/cmake/fortran_features/finalization.F90 b/cmake/fortran_features/finalization.F90
new file mode 100644
index 0000000..5bacd5f
--- /dev/null
+++ b/cmake/fortran_features/finalization.F90
@@ -0,0 +1,141 @@
+module final_module
+
+implicit none
+
+integer :: final_counted = 0
+integer :: destroy_counted = 0
+
+TYPE :: AnimalType
+  character(len=20), private :: m_kind = "unidentified"
+  logical :: constructed = .false.
+contains
+  procedure :: speak
+  final :: AnimalType__dtor
+ENDTYPE
+
+interface AnimalType
+  module procedure AnimalType__ctor
+end interface
+
+interface assignment(=)
+  module procedure AnimalType__assignment
+end interface
+
+contains
+
+subroutine speak(self)
+  class(AnimalType), intent(in) :: self
+  write(0,'(2A)') "I am a ",self%m_kind
+end subroutine
+
+subroutine AnimalType__dtor(self)
+  type(AnimalType), intent(inout) :: self
+
+  write(0,'(2A)') "Final animal ",self%m_kind
+  final_counted = final_counted + 1
+
+  ! Destruction guard needed for portability
+  if( self%constructed ) then
+    write(0,'(2A)') "    Destroy animal ",self%m_kind
+    destroy_counted = destroy_counted + 1
+  endif
+end subroutine
+
+function AnimalType__ctor(animaltype_) result(self)
+  type(AnimalType) :: self
+  character(len=*) :: animaltype_
+  self%m_kind = animaltype_
+  write(0,'(3A,I0)') "Constructing animal ",self%m_kind, " -- address = ",loc(self)
+  self%constructed = .true.
+end function
+
+subroutine AnimalType__assignment(animal_out,animal_in)
+  type(AnimalType), intent(out) :: animal_out
+  class(AnimalType), intent(in) :: animal_in
+  write(0,'(3A,I0,A,I0)') '   Copying ',animal_in%m_kind, " -- from address ", loc(animal_in), " to address ", loc(animal_out)
+  animal_out%m_kind = animal_in%m_kind
+  animal_out%constructed = animal_in%constructed
+end subroutine
+
+end module
+
+! ------------------------------------------------------------------------
+
+subroutine scope_test
+use final_module
+implicit none
+
+  type(AnimalType) :: dog
+  type(AnimalType) :: cat
+
+  dog = AnimalType("dog")  ! Cray       : final called on temporary AnimalType("dog"); missing final call on dog before assignment
+                           ! Intel      : final called on dog before assignment; and on temporary AnimalType("dog")
+                           ! PGI 14.4   : final NOT called at all, possibly compiler bug
+                           ! GNU 4.9    : final called on dog before assignment; missing call on temporary AnimalType("dog")
+  call dog%speak()
+
+  ! final called on dog when out of scope
+end subroutine
+
+! -------------------------------------------------------
+
+subroutine assignment_test
+use final_module
+implicit none
+
+  type(AnimalType) :: dog
+  type(AnimalType) :: animal
+
+  dog = AnimalType("dog")    ! final called on dog before assignment
+  call dog%speak()
+  write(0,'(A)') "-- animal = dog"
+  animal = dog               ! final called on animal before assignment
+  call animal%speak()
+
+  ! final called on dog when out of scope
+  ! final called on animal when out of scope
+end subroutine
+
+! -------------------------------------------------------
+
+program test_final
+use final_module
+implicit none
+  logical :: test_failed = .false.
+
+  final_counted = 0
+  destroy_counted = 0
+
+  write(0,'(A)') " "
+  write(0,'(A)') ">>>>>> begin scope_test"
+  call scope_test
+  write(0,'(A)') "<<<<<< end scope_test"
+  write(0,'(A)') " "
+
+  write(0,'(A,I0)') "final_counted = ", final_counted
+  write(0,'(A,I0)') "destroy_counted = ", destroy_counted
+
+  if( destroy_counted < 1 ) then
+    test_failed = .true.
+    write(0,'(A)') "ASSERTION FAILED: destroy_counted < 1"
+  endif
+
+  final_counted = 0
+  destroy_counted = 0
+
+  write(0,'(A)') " "
+  write(0,'(A)') ">>>>>> begin assignment_test"
+  call assignment_test
+  write(0,'(A)') "<<<<<< end assignment_test"
+  write(0,'(A)') " "
+
+  write(0,'(A,I0)') "final_counted = ", final_counted
+  write(0,'(A,I0)') "destroy_counted = ", destroy_counted
+
+  if( destroy_counted < 2 ) then
+    test_failed = .true.
+    write(0,*) "ASSERTION FAILED: destroy_counted < 2"
+  endif
+  if( test_failed ) STOP 1
+
+end program
diff --git a/cmake/fortran_features/submodules.F90 b/cmake/fortran_features/submodules.F90
new file mode 100644
index 0000000..3a2261f
--- /dev/null
+++ b/cmake/fortran_features/submodules.F90
@@ -0,0 +1,35 @@
+module sb_module
+implicit none
+integer :: a = 1
+
+interface
+  module subroutine sb
+  end subroutine
+end interface
+
+contains
+end module sb_module
+
+! -------------------------------------------------------
+
+submodule (sb_module) sb_submod1
+implicit none
+integer :: b = 2
+
+contains
+
+module subroutine sb()
+  a = b
+end subroutine
+
+end submodule sb_submod1
+
+! -------------------------------------------------------
+
+program test_submodule
+use sb_module
+implicit none
+write(0,*) a
+call sb()
+write(0,*) a
+end program
\ No newline at end of file
diff --git a/share/ecbuild/toolchains/ecmwf-XC30-Cray.cmake b/share/ecbuild/toolchains/ecmwf-XC30-Cray.cmake
index 52924b9..c6947e8 100644
--- a/share/ecbuild/toolchains/ecmwf-XC30-Cray.cmake
+++ b/share/ecbuild/toolchains/ecmwf-XC30-Cray.cmake
@@ -20,14 +20,6 @@ set( ECBUILD_FIND_MPI OFF )
 set( ECBUILD_TRUST_FLAGS ON )
 
 ####################################################################
-# MPI
-####################################################################
-
-set( MPIEXEC                 "aprun" )
-set( MPIEXEC_NUMPROC_FLAG    "-n"    )
-set( MPIEXEC_NUMTHREAD_FLAG  "-d"    )
-
-####################################################################
 # OpenMP FLAGS
 ####################################################################
 
@@ -40,17 +32,10 @@ set( OMPSTUBS_CXX_FLAGS      "-hnoomp" )
 set( OMPSTUBS_Fortran_FLAGS  "-hnoomp" )
 
 ####################################################################
-# Fortran FLAGS
-####################################################################
-
-# -emf activates .mods and uses lower case -rmoid produces a listing file
-set( ECBUILD_Fortran_FLAGS   "-emf -rmoid" )
-
-####################################################################
 # LINK FLAGS
 ####################################################################
 
-set( ECBUILD_C_LINK_FLAGS        "-Wl,-Map,loadmap -Wl,--as-needed -Ktrap=fp" )
-set( ECBUILD_CXX_LINK_FLAGS      "-Wl,-Map,loadmap -Wl,--as-needed -Ktrap=fp" )
-set( ECBUILD_Fortran_LINK_FLAGS  "-Wl,-Map,loadmap -Wl,--as-needed -Ktrap=fp" )
+set( ECBUILD_C_LINK_FLAGS        "-Wl,-Map,loadmap -Wl,--as-needed -Wl,--eh-frame-hdr -Ktrap=fp" )
+set( ECBUILD_CXX_LINK_FLAGS      "-Wl,-Map,loadmap -Wl,--as-needed -Wl,--eh-frame-hdr -Ktrap=fp" )
+set( ECBUILD_Fortran_LINK_FLAGS  "-Wl,-Map,loadmap -Wl,--as-needed -Wl,--eh-frame-hdr -Ktrap=fp" )
 set( ECBUILD_CXX_IMPLICIT_LINK_LIBRARIES "$ENV{CC_X86_64}/lib/x86-64/libcray-c++-rts.so" CACHE STRING "" )
diff --git a/share/ecbuild/toolchains/ecmwf-XC30-GNU.cmake b/share/ecbuild/toolchains/ecmwf-XC30-GNU.cmake
index 3f69f06..3ea294f 100644
--- a/share/ecbuild/toolchains/ecmwf-XC30-GNU.cmake
+++ b/share/ecbuild/toolchains/ecmwf-XC30-GNU.cmake
@@ -20,14 +20,6 @@ set( ECBUILD_FIND_MPI OFF )
 set( ECBUILD_TRUST_FLAGS ON )
 
 ####################################################################
-# MPI
-####################################################################
-
-set( MPIEXEC                 "aprun" )
-set( MPIEXEC_NUMPROC_FLAG    "-n"    )
-set( MPIEXEC_NUMTHREAD_FLAG  "-d"    )
-
-####################################################################
 # OpenMP FLAGS
 ####################################################################
 
@@ -47,6 +39,6 @@ set( ECBUILD_Fortran_FLAGS_DEBUG  "-ffree-line-length-none -O0 -g -fcheck=bounds
 # LINK FLAGS
 ####################################################################
 
-set( ECBUILD_C_LINK_FLAGS        "-Wl,-Map,load.map -Wl,--as-needed" )
-set( ECBUILD_CXX_LINK_FLAGS      "-Wl,-Map,load.map -Wl,--as-needed" )
-set( ECBUILD_Fortran_LINK_FLAGS  "-Wl,-Map,load.map -Wl,--as-needed" )
+set( ECBUILD_C_LINK_FLAGS        "-Wl,-Map,load.map -Wl,--as-needed -Wl,--eh-frame-hdr" )
+set( ECBUILD_CXX_LINK_FLAGS      "-Wl,-Map,load.map -Wl,--as-needed -Wl,--eh-frame-hdr" )
+set( ECBUILD_Fortran_LINK_FLAGS  "-Wl,-Map,load.map -Wl,--as-needed -Wl,--eh-frame-hdr" )
diff --git a/share/ecbuild/toolchains/ecmwf-XC30-Intel.cmake b/share/ecbuild/toolchains/ecmwf-XC30-Intel.cmake
index 01c6267..d5fdb32 100644
--- a/share/ecbuild/toolchains/ecmwf-XC30-Intel.cmake
+++ b/share/ecbuild/toolchains/ecmwf-XC30-Intel.cmake
@@ -21,14 +21,6 @@ set( ECBUILD_FIND_MPI OFF )
 set( ECBUILD_TRUST_FLAGS ON )
 
 ####################################################################
-# MPI
-####################################################################
-
-set( MPIEXEC                 "aprun" )
-set( MPIEXEC_NUMPROC_FLAG    "-n"    )
-set( MPIEXEC_NUMTHREAD_FLAG  "-d"    )
-
-####################################################################
 # OpenMP FLAGS
 ####################################################################
 
@@ -68,6 +60,6 @@ set( ECBUILD_Fortran_FLAGS_DEBUG  "-O0 -g -traceback -warn all -heap-arrays -fpe
 # LINK FLAGS
 ####################################################################
 
-set( ECBUILD_C_LINK_FLAGS        "-Wl,-Map,load.map -Wl,--as-needed" )
-set( ECBUILD_CXX_LINK_FLAGS      "-Wl,-Map,load.map -Wl,--as-needed" )
-set( ECBUILD_Fortran_LINK_FLAGS  "-Wl,-Map,load.map -Wl,--as-needed" )
+set( ECBUILD_C_LINK_FLAGS        "-Wl,-Map,load.map -Wl,--as-needed -Wl,--eh-frame-hdr" )
+set( ECBUILD_CXX_LINK_FLAGS      "-Wl,-Map,load.map -Wl,--as-needed -Wl,--eh-frame-hdr" )
+set( ECBUILD_Fortran_LINK_FLAGS  "-Wl,-Map,load.map -Wl,--as-needed -Wl,--eh-frame-hdr" )
diff --git a/share/ecbuild/toolchains/ecmwf-XC30-Intel.cmake b/share/ecbuild/toolchains/ichec-fionn-Intel.cmake
similarity index 84%
copy from share/ecbuild/toolchains/ecmwf-XC30-Intel.cmake
copy to share/ecbuild/toolchains/ichec-fionn-Intel.cmake
index 01c6267..184dfb5 100644
--- a/share/ecbuild/toolchains/ecmwf-XC30-Intel.cmake
+++ b/share/ecbuild/toolchains/ichec-fionn-Intel.cmake
@@ -1,10 +1,6 @@
 ####################################################################
 # ARCHITECTURE
 ####################################################################
-set( CMAKE_SIZEOF_VOID_P 8 )
-
-# Disable relative rpaths as aprun does not respect it
-set( ENABLE_RELATIVE_RPATHS OFF CACHE STRING "Disable relative rpaths" FORCE )
 
 
 ####################################################################
@@ -13,20 +9,9 @@ set( ENABLE_RELATIVE_RPATHS OFF CACHE STRING "Disable relative rpaths" FORCE )
 
 include(CMakeForceCompiler)
 
-CMAKE_FORCE_C_COMPILER       ( cc  Intel )
-CMAKE_FORCE_CXX_COMPILER     ( CC  Intel )
-CMAKE_FORCE_Fortran_COMPILER ( ftn Intel )
-
-set( ECBUILD_FIND_MPI OFF )
-set( ECBUILD_TRUST_FLAGS ON )
-
-####################################################################
-# MPI
-####################################################################
-
-set( MPIEXEC                 "aprun" )
-set( MPIEXEC_NUMPROC_FLAG    "-n"    )
-set( MPIEXEC_NUMTHREAD_FLAG  "-d"    )
+CMAKE_FORCE_C_COMPILER       ( icc  Intel )
+CMAKE_FORCE_CXX_COMPILER     ( icpc  Intel )
+CMAKE_FORCE_Fortran_COMPILER ( ifort Intel )
 
 ####################################################################
 # OpenMP FLAGS
@@ -71,3 +56,12 @@ set( ECBUILD_Fortran_FLAGS_DEBUG  "-O0 -g -traceback -warn all -heap-arrays -fpe
 set( ECBUILD_C_LINK_FLAGS        "-Wl,-Map,load.map -Wl,--as-needed" )
 set( ECBUILD_CXX_LINK_FLAGS      "-Wl,-Map,load.map -Wl,--as-needed" )
 set( ECBUILD_Fortran_LINK_FLAGS  "-Wl,-Map,load.map -Wl,--as-needed" )
+
+###################################################################
+# 
+# Serial versions of these packages (need to specify intel_mpi versions? )
+###################################################################
+
+set( FFTW_PATH    "/ichec/packages/fftw/intel/3.3.4")
+set( NETCDF_PATH  "/ichec/packages/netcdf/intel/4.4.0")
+set( HDF5_PATH    "/ichec/packages/hdf5/intel/1.8.16")
diff --git a/share/metview/etc/GeoViewDef.orig b/share/metview/etc/GeoViewDef.orig
deleted file mode 100644
index 9c86c3a..0000000
--- a/share/metview/etc/GeoViewDef.orig
+++ /dev/null
@@ -1,132 +0,0 @@
-GEOVIEW; GEOVIEW; UPLOT
-{
-   COASTLINES
-   [
-      interface       = icon,
-      class           = MCOAST/PCOAST,
-      exclusive       = true,
-      help            = help_data,
-      help_directory  = '/System/Defaults',
-      help_name       = Coastlines,
-      help_class      = MCOAST,
-      help_definition = (MCOAST)
-   ]
-   { @ }
-
-   MAP_PROJECTION
-   {
-      CYLINDRICAL ; CYLINDRICAL
-      BONNE
-      COLLIGNON
-<<<<<<< HEAD
-      EPSG4326
-      EPSG3857
-=======
-      EPSG:4326
-      EPSG:3857
->>>>>>> release/4.7.2
-      GEOS
-      GOODE
-      LAMBERT
-      LAMBERT_NORTH_ATLANTIC
-      MERCATOR
-      MOLLWEIDE
-      POLAR_NORTH
-      POLAR_STEREOGRAPHIC ; POLAR_STEREOGRAPHIC
-      ROBINSON
-   } = CYLINDRICAL
-
-   MAP_AREA_DEFINITION
-   {
-      CORNERS
-      CENTRE
-      FULL
-   } = FULL
-
-   AREA
-   [
-      help = help_input,
-      help_icon = 'help_map',
-      help_tooltip = 'Define area on a map',
-      input_type = map,
-      input_window = '/Metview/System/Input Window'
-   ]
-   {
-      *
-      /
-   } = -90./-180./90./180
-
-   MAP_HEMISPHERE
-   {
-      NORTH ; NORTH
-      SOUTH ; SOUTH
-   } = NORTH
-
-   MAP_VERTICAL_LONGITUDE
-   {
-      *
-   } = 0
-
-   MAP_CENTRE_LATITUDE
-   {
-      @
-   } = 45.0
-
-   MAP_CENTRE_LONGITUDE
-   {
-      @
-   } = 0.0
-
-   MAP_SCALE
-   {
-      @
-   } = 130.0E4
-
-   MAP_OVERLAY_CONTROL
-   {
-      ALWAYS
-      BY_DATE
-      BY_LEVEL
-      NEVER
-   }= ALWAYS_OVERLAY
-
-   SUBPAGE_CLIPPING
-   {
-      ON
-      OFF
-   } = OFF
-
-   SUBPAGE_X_POSITION
-   {
-      @
-   } = 7.5
-
-   SUBPAGE_Y_POSITION
-   {
-      @
-   } = 5
-
-   SUBPAGE_X_LENGTH
-   {
-      @
-   } = 85
-
-   SUBPAGE_Y_LENGTH
-   {
-      @
-   } = 85
-
-   SUBPAGE_METADATA_INFO
-   {
-      ON
-      OFF
-   } = OFF
-
-   SUBPAGE_METADATA_JAVASCRIPT_PATH
-   {
-      @
-   } = map.js
-
-%include PageFrameDef
-%include SubpageFrameDef
-}
diff --git a/share/metview/etc/MAXISDef b/share/metview/etc/MAXISDef
index 6b61eda..1646e44 100755
--- a/share/metview/etc/MAXISDef
+++ b/share/metview/etc/MAXISDef
@@ -68,7 +68,7 @@ MAXIS; Magics; Automatically generated
 	AXIS_GRID_COLOUR [ help = help_colour,interface = colour ]
 	{ 
 		&PARAMSHARE&COLOUR
-	} = YELLOW
+	} = BLACK
 
 	AXIS_GRID_LINE_STYLE
 	{
@@ -290,6 +290,29 @@ MAXIS; Magics; Automatically generated
 		*
 	} = 1
 
+
+	AXIS_MINOR_GRID
+	{
+		ON;  ON
+		OFF; OFF
+	} = OFF
+
+	AXIS_MINOR_GRID_COLOUR [ help = help_colour,interface = colour ]
+	{ 
+		&PARAMSHARE&COLOUR
+	} = BLACK
+
+	AXIS_MINOR_GRID_LINE_STYLE
+	{
+		&PARAMSHARE&STYLE
+	} = SOLID
+
+	AXIS_MINOR_GRID_THICKNESS
+	{
+		*
+	} = 1
+
+
 	AXIS_TIP_TITLE
 	{
 		ON;  ON
diff --git a/share/metview/etc/MAXISRules b/share/metview/etc/MAXISRules
index 685a6ba..37d2be5 100755
--- a/share/metview/etc/MAXISRules
+++ b/share/metview/etc/MAXISRules
@@ -7,6 +7,10 @@
 	%unset AXIS_GRID_LINE_STYLE
 	%unset AXIS_GRID_COLOUR
 	%unset AXIS_GRID_REFERENCE_LINE_STYLE
+	%unset AXIS_MINOR_GRID
+	%unset AXIS_MINOR_GRID_THICKNESS
+	%unset AXIS_MINOR_GRID_LINE_STYLE
+	%unset AXIS_MINOR_GRID_COLOUR
 
 %if AXIS_TICK_LABEL <> ON %or AXIS_TICK_LABEL_TYPE <> NUMBER %then
 	%unset AXIS_TICK_LABEL_FORMAT
@@ -21,6 +25,15 @@
 	%unset AXIS_MINOR_TICK_COLOUR
 	%unset AXIS_MINOR_TICK_THICKNESS
 	%unset AXIS_MINOR_TICK_COUNT
+    %unset AXIS_MINOR_GRID
+	%unset AXIS_MINOR_GRID_THICKNESS
+	%unset AXIS_MINOR_GRID_LINE_STYLE
+	%unset AXIS_MINOR_GRID_COLOUR
+
+%if AXIS_MINOR_GRID <> ON %then
+	%unset AXIS_MINOR_GRID_THICKNESS
+	%unset AXIS_MINOR_GRID_LINE_STYLE
+	%unset AXIS_MINOR_GRID_COLOUR
 
 %if AXIS_TICK_LABEL <> ON %or AXIS_TICK_LABEL_TYPE <> LABEL_LIST %then
 	%unset AXIS_TICK_LABEL_LIST
diff --git a/share/metview/etc/ecmwf.def b/share/metview/etc/ecmwf.def
index ef55684..dfffc9f 100755
--- a/share/metview/etc/ecmwf.def
+++ b/share/metview/etc/ecmwf.def
@@ -1098,6 +1098,7 @@ CRIS = (202)
 SMOS = (203)
 AMSR2_GC = (60)
 DMBO = (181/182)
+SAPHIR = (211)
 
 # FeedBack
 
diff --git a/src/Desktop/MvQColourLine.cc b/src/Desktop/MvQColourLine.cc
index f5a2654..66c2f53 100644
--- a/src/Desktop/MvQColourLine.cc
+++ b/src/Desktop/MvQColourLine.cc
@@ -167,7 +167,16 @@ void MvQColourLine::setCustomColour(QColor color,QString name, QString realName,
 	  	colCb_->setItemText(idx,name);
 		colCb_->setItemData(idx,realName);
 		if(setCurrent)
-	  		colCb_->setCurrentIndex(idx);
+		{
+			// although we set the current index, this does not always trigger
+			// slotCurrentChanged because all custom RGB values will have the
+			// same index (42), even though they might be different colours
+			// (which could be an issue if we open two different icons which both
+			// have custom colours for the same parameter).
+			// Therefore we manually trigger slotCurrentChanged here to make sure
+			colCb_->setCurrentIndex(idx);
+			slotCurrentChanged(idx);
+		}
 	}
 	
 	if(idx != -1)
diff --git a/src/Desktop/MvQGeoHelp.cc b/src/Desktop/MvQGeoHelp.cc
index 726a646..8935fee 100644
--- a/src/Desktop/MvQGeoHelp.cc
+++ b/src/Desktop/MvQGeoHelp.cc
@@ -90,6 +90,8 @@ void MvQGeoHelp::message(const Request& msg)
 		res.push_back(string(ch));
 	 }
 	 owner_.set(param_.name(),res); 
+
+	 stop();  // stop observing the helper widget since it could be reused for other params
 	 
           //owner_.changed(*this);
 }
diff --git a/src/Macro/grib.cc b/src/Macro/grib.cc
index 4f74bb9..ea59d01 100644
--- a/src/Macro/grib.cc
+++ b/src/Macro/grib.cc
@@ -50,6 +50,14 @@ enum eGribDateType
 };
 
 
+// used in SubGribFunction
+enum eGribIndexType
+{
+    GINDEX_NUMBERS,
+    GINDEX_VECTOR
+};
+
+
 double CovarFunc( field*, field*, const MvGeoBox& );
 
 static math Math =  {0,0,0,};
@@ -283,19 +291,39 @@ public:
 	SubGribFunction(const char *n) : Function(n) { };
 	virtual Value Execute(int arity,Value *arg);
 	virtual int ValidArguments(int arity,Value *arg);
+private:
+	eGribIndexType indexType_;
 };
 
 int SubGribFunction::ValidArguments(int arity,Value *arg)
 {
 	if(arity != 2 && arity != 3 && arity != 4) return false;
 
-	for(int i=1;i<arity;i++)
-		if(arg[i].GetType() != tnumber)
-			return false;
 
 	if(arg[0].GetType() != tgrib)
 		return false;
 
+
+	// indexing can either be a set of numbers or a single vector
+	if (arg[1].GetType() == tvector)  // vector
+	{
+		if (arity > 2)
+			return false;
+		else
+		{
+			indexType_ = GINDEX_VECTOR;
+			return true;
+		}
+	}
+	else  // number(s)
+	{
+		indexType_ = GINDEX_NUMBERS;
+
+		for(int i=1;i<arity;i++)
+			if(arg[i].GetType() != tnumber)
+				return false;
+	}
+
 	return true;
 }
 
@@ -303,19 +331,46 @@ extern int vcnt;
 
 Value SubGribFunction::Execute(int arity ,Value *arg)
 {
-	int from=0,to=0,step=0;
-	fieldset *v;
+	if (indexType_ == GINDEX_NUMBERS)
+	{
+		int from=0,to=0,step=0;
+		fieldset *v;
 
-	arg[0].GetValue(v);
+		arg[0].GetValue(v);
 
-	arg[1].GetValue(from);
-	if(arity>2) arg[2].GetValue(to);
-	if(arity>3) arg[3].GetValue(step);
+		arg[1].GetValue(from);
+		if(arity>2) arg[2].GetValue(to);
+		if(arity>3) arg[3].GetValue(step);
 
-	fieldset *w = sub_fieldset(v,from,to,step);
-	if(!w)
-	   return Error("fs[]: Cannot extract sub-fieldset");
-	return Value(w);
+		fieldset *w = sub_fieldset(v,from,to,step);
+		if(!w)
+		   return Error("fs[]: Cannot extract sub-fieldset");
+		return Value(w);
+	}
+
+	else  // vector indexing (i.e. the index is itself a vector of indexes)
+	{
+		// code partly taken from MARS/field.c/sub_fieldset()
+		fieldset *v;
+		CVector  *vi;
+		arg[0].GetValue(v);
+		arg[1].GetValue(vi);
+
+		fieldset *w = new_fieldset(vi->Count());
+
+		for(int i = 0; i < vi->Count(); i++)
+		{
+			int index = (*vi)[i];
+			if (index < 1 || index > v->count)
+				return Error("index %d(%d) is out of range. Fieldset size is %d", i+1, index, v->count);
+
+			field *g = v->fields[index-1];
+			w->fields[i] = g;
+			g->refcnt++;
+		}
+
+		return Value(w);
+	}
 }
 
 //=============================================================================
diff --git a/src/Macro/misc.cc b/src/Macro/misc.cc
index 05035fa..1f8e9dc 100644
--- a/src/Macro/misc.cc
+++ b/src/Macro/misc.cc
@@ -21,6 +21,11 @@
 #include "script.h"
 #include "cbufr.h"
 
+
+#define QUOTE_PP(P) #P
+#define QUOTE_PPP(P) QUOTE_PP(P)
+
+
 //=============================================================================
 
 class NilFunction : public Function {
@@ -790,8 +795,15 @@ Value MetviewVersionFunction::Execute(int arity,Value *arg)
 	}
 
 
+	// extra code to take into account the possibility of
+	// using either GRIB_API or ecCodes for GRIB handling
+	std::string grib_package=QUOTE_PPP(GRIB_HANDLING_PACKAGE);
+	for(unsigned int i = 0; i < grib_package.length(); ++i)
+		grib_package[i] = tolower(grib_package[i]);
+	grib_package += "_version";
+
 	grib_api_version = grib_get_api_version();
-	set_value(r, "grib_api_version", "%d", grib_api_version);
+	set_value(r, grib_package.c_str(), "%d", grib_api_version);
 
 	mars_version = marsversion();
 	set_value(r, "mars_version", "%d", mars_version);
diff --git a/src/Macro/mlist.cc b/src/Macro/mlist.cc
index e458c52..55c526d 100644
--- a/src/Macro/mlist.cc
+++ b/src/Macro/mlist.cc
@@ -13,6 +13,15 @@
 #include "inc_stl.h"
 
 
+
+enum eListIndexType
+{
+    LINDEX_NUMBERS,
+    LINDEX_VECTOR
+};
+
+
+
 //=============================================================================
 
 int CList::Write(FILE *f)
@@ -170,6 +179,9 @@ public:
 	ListElemFunction(const char *n) : Function(n,2,tlist,tnumber) {};
 	virtual Value Execute(int arity,Value *arg);
 	virtual int ValidArguments(int arity,Value *arg);
+
+private:
+	eListIndexType indexType_;
 };
 
 int ListElemFunction::ValidArguments(int arity,Value *arg)
@@ -177,44 +189,86 @@ int ListElemFunction::ValidArguments(int arity,Value *arg)
 	if(arity<2 || arity > 4) return false;
 	if(arg[0].GetType() != tlist) return false;
 
-	for(int i=1;i<arity;i++)
-		if(arg[i].GetType() != tnumber)
+
+	// indexing can either be a set of numbers or a single vector
+
+	if (arg[1].GetType() == tvector)  // vector
+	{
+		if (arity > 2)
 			return false;
+		else
+		{
+			indexType_ = LINDEX_VECTOR;
+			return true;
+		}
+	}
+	else  // number(s)
+	{
+		indexType_ = LINDEX_NUMBERS;
+
+		for(int i=1;i<arity;i++)
+			if(arg[i].GetType() != tnumber)
+				return false;
+	}
 
 	return true;
 }
 
 Value ListElemFunction::Execute(int arity,Value *arg)
 {
-	CList *v;
-	int  n;
-	int  m = 0;
-	int  s = 0;
+	if (indexType_ == LINDEX_NUMBERS)
+	{
+		CList *v;
+		int  n;
+		int  m = 0;
+		int  s = 0;
 
-	arg[0].GetValue(v);
-	arg[1].GetValue(n);
-	if(arity>2) arg[2].GetValue(m);
-	if(arity>3) arg[3].GetValue(s);
+		arg[0].GetValue(v);
+		arg[1].GetValue(n);
+		if(arity>2) arg[2].GetValue(m);
+		if(arity>3) arg[3].GetValue(s);
+
+		if(m <  n) m = n;
+		if(m >  v->Count()) m = v->Count();
+		if(s <= 0) s = 1;
 
-	if(m <  n) m = n;
-	if(m >  v->Count()) m = v->Count();
-	if(s <= 0) s = 1;
+		if(n <1 || n>v->Count())
+			return Error("Index out of range. Index is %d, list size is %d",
+				n,v->Count());
 
-	if(n <1 || n>v->Count())
-		return Error("Index out of range. Index is %d, list size is %d",
-			n,v->Count());
+		if(m == n ) return (*v)[n-1];
 
-	if(m == n ) return (*v)[n-1];
 
+		int c = (m-n)/s+1;
+		CList *l = new CList(c);
+		int i,j;
 
-	int c = (m-n)/s+1;
-	CList *l = new CList(c);
-	int i,j;
+		for(i = 0, j = n-1 ; i < c ; i++, j += s)
+			(*l)[i] = (*v)[j];
 
-	for(i = 0, j = n-1 ; i < c ; i++, j += s)
-		(*l)[i] = (*v)[j];
+		return Value(l);
+	}
+
+	else  // vector indexing (i.e. the index is itself a vector of indexes)
+	{
+		CList   *v;
+		CVector *vi;
+		arg[0].GetValue(v);
+		arg[1].GetValue(vi);
+
+		// the result vector
+		CList *vnew = new CList(vi->Count());
+		for (int i = 0; i < vi->Count(); i++)
+		{
+			int index = (*vi)[i];
+			if (index < 1 || index > v->Count())
+				return Error("index %d(%d) is out of range. List size is %d", i+1, index, v->Count());
 
-	return Value(l);
+			(*vnew)[i] = (*v)[index-1];  // -1 to convert from 1-index (Macro) to 0-index (C)
+		}
+
+		return Value(vnew);
+	}
 }
 
 //=============================================================================
@@ -322,7 +376,7 @@ Value ListFindFunction::Execute(int arity,Value *arg)
         if (s && !strcmp(s, "all"))
             findAll = true;
         else
-            marslog(LOG_WARN, "find(any, list, string) only accepts 'all' as its last argument. Supplied: '%s'", s);
+            marslog(LOG_WARN, "find(list, any, string) only accepts 'all' as its last argument. Supplied: '%s'", s);
     }
 
     arg[0].GetValue(v);
diff --git a/src/Macro/mvector.cc b/src/Macro/mvector.cc
index 1323bbd..22cf418 100644
--- a/src/Macro/mvector.cc
+++ b/src/Macro/mvector.cc
@@ -61,6 +61,15 @@ enum eVectorSortType
 };
 
 
+
+enum eVectorIndexType
+{
+    VINDEX_NUMBERS,
+    VINDEX_VECTOR
+};
+
+
+
 /*******************************************************************************
  *
  * Function      : CVector::CVector(int)
@@ -730,7 +739,9 @@ Value Vector2Function::Execute(int ,Value *arg)
  *                 last element to be extracted - if supplied, then a vector
  *                 is returned. A third argument is an optional step size.
  *                 A fourth argument tells us how many elements to extract
- *                 at each step.
+ *                 at each step. Alternatively, a vector can be supplied
+ *                 instead of all these numbers - e.g. a vector index with
+ *                 6 elements will return a resulting vector with 6 elements.
  *
  ******************************************************************************/
 
@@ -739,6 +750,8 @@ public:
 	VectorGetElemFunction(char *n) : Function(n,2,tvector,tnumber) {};
 	virtual Value Execute(int arity,Value *arg);
 	virtual int ValidArguments(int arity,Value *arg);
+private:
+	eVectorIndexType indexType_;
 };
 
 int VectorGetElemFunction::ValidArguments(int arity,Value *arg)
@@ -746,9 +759,26 @@ int VectorGetElemFunction::ValidArguments(int arity,Value *arg)
 	if(arity<2 || arity > 5) return false;
 	if(arg[0].GetType() != tvector) return false;
 
-	for(int i=1;i<arity;i++) // all arguments after the first one must be numbers
-		if(arg[i].GetType() != tnumber)
+
+	// indexing can either be a set of numbers or a single vector
+	if (arg[1].GetType() == tvector)  // vector
+	{
+		if (arity > 2)
 			return false;
+		else
+		{
+			indexType_ = VINDEX_VECTOR;
+			return true;
+		}
+	}
+	else  // number(s)
+	{
+		indexType_ = VINDEX_NUMBERS;
+
+		for(int i=1;i<arity;i++) // all arguments after the first one must be numbers
+			if(arg[i].GetType() != tnumber)
+				return false;
+	}
 
 	return true;
 }
@@ -756,41 +786,66 @@ int VectorGetElemFunction::ValidArguments(int arity,Value *arg)
 
 Value VectorGetElemFunction::Execute(int arity,Value *arg)
 {
-    CVector *v;
-    int  first;
-    int  last   = 0; // index of first element
-    int  step   = 0; // step
-    int  length = 1; // how many we extract at each step
+	if (indexType_ == VINDEX_NUMBERS)
+	{
+		CVector *v;
+		int  first;
+		int  last   = 0; // index of first element
+		int  step   = 0; // step
+		int  length = 1; // how many we extract at each step
 
-    arg[0].GetValue(v);
-    arg[1].GetValue(first);
-    if (arity>2) arg[2].GetValue(last);
-    if (arity>3) arg[3].GetValue(step);
-    if (arity>4) arg[4].GetValue(length);
+		arg[0].GetValue(v);
+		arg[1].GetValue(first);
+		if (arity>2) arg[2].GetValue(last);
+		if (arity>3) arg[3].GetValue(step);
+		if (arity>4) arg[4].GetValue(length);
 
-    if (last <  first) last = first;
-    if (step <= 0) step = 1;
+		if (last <  first) last = first;
+		if (step <= 0) step = 1;
 
-    if (last+length-step >  v->Count())
-       return Error("last element out of range. last is %d, vector size is %d",
-            last+length-step,v->Count());
+		if (last+length-step >  v->Count())
+		   return Error("last element out of range. last is %d, vector size is %d",
+				last+length-step,v->Count());
 
-    if (first <1 || first>v->Count())
-        return Error("first out of range. first is %d, vector size is %d",
-            first,v->Count());
+		if (first <1 || first>v->Count())
+			return Error("first out of range. first is %d, vector size is %d",
+				first,v->Count());
 
-    if ((last == first) && (length == 1))
-        return (*v)[first-1];
+		if ((last == first) && (length == 1))
+			return (*v)[first-1];
 
 
-    int c = ((last-first)/step+1) * length;
-    CVector *vnew = new CVector(c);
-    int i,j;
+		int c = ((last-first)/step+1) * length;
+		CVector *vnew = new CVector(c);
+		int i,j;
 
-    for (i = 0, j = first-1 ; i < c ; i+=length, j += step)
-        vnew->CopyValues(i, *v, j, length);
+		for (i = 0, j = first-1 ; i < c ; i+=length, j += step)
+			vnew->CopyValues(i, *v, j, length);
 
-    return Value(vnew);
+		return Value(vnew);
+	}
+
+	else  // vector indexing (i.e. the index is itself a vector of indexes)
+	{
+		CVector *v;
+		CVector *vi;
+		arg[0].GetValue(v);
+		arg[1].GetValue(vi);
+
+		// the result vector
+		CVector *vnew = new CVector(vi->Count());
+		for (int i = 0; i < vi->Count(); i++)
+		{
+			int index = (*vi)[i];
+			if (index < 1 || index > v->Count())
+				return Error("index %d(%d) is out of range. Vector size is %d", i+1, index, v->Count());
+
+			(*vnew)[i] = (*v)[index-1];  // -1 to convert from 1-index (Macro) to 0-index (C)
+		}
+
+		return Value(vnew);
+
+	}
 }
 
 
@@ -1380,6 +1435,87 @@ Value VectorSort::Execute(int arity,Value *arg)
     return Value(v2);
 }
 
+//=============================================================================
+
+class VectorFindFunction : public Function {
+public:
+	VectorFindFunction(const char *n) : Function(n,2,tany,tvector)
+	{ info="Find where a number occurs in a vector";};
+	virtual Value Execute(int arity,Value *arg);
+	virtual int ValidArguments(int arity,Value *arg);
+};
+
+
+int VectorFindFunction::ValidArguments(int arity,Value *arg)
+{
+    if(arity != 2 && arity != 3)    return false;
+	if(arg[0].GetType() != tvector) return false;                  // first arg must be a vector
+	if(arg[1].GetType() != tnumber) return false;                  // second arg must be a number
+	if((arity == 3) && arg[2].GetType() != tstring) return false;  // third (optional) arg must be a string
+	return true;
+}
+
+
+Value VectorFindFunction::Execute(int arity,Value *arg)
+{
+    CVector *v;
+    double d;
+    bool findAll = false;
+
+    if (arity == 3)
+    {
+        const char *s;
+        arg[2].GetValue(s);
+        if (s && !strcmp(s, "all"))
+            findAll = true;
+        else
+            marslog(LOG_WARN, "find(vector, number, string) only accepts 'all' as its last argument. Supplied: '%s'", s);
+    }
+
+    arg[0].GetValue(v);
+    arg[1].GetValue(d);
+
+
+    std::vector<int> results;  // only need a vector if we're looking for more than 1 result
+
+    for(int i=0;i<v->Count();i++)
+    {
+        if((*v)[i] == d)                   // does it match?
+        {
+            if (findAll)
+            {
+                results.push_back(i+1);    // we want 'all', so add to our list
+            }
+            else
+            {
+                return Value(i+1);         // we want just the first, to return it
+            }
+        }
+    }
+
+
+    if (findAll)
+    {
+        if (results.size() > 0)
+        {
+            CVector *outvec = new CVector(results.size());
+
+            for(unsigned int i=0; i < results.size(); i++)
+            {
+                (*outvec)[i] = results[i];
+            }
+            return Value(outvec);
+        }
+        else
+        {
+            return Value();  // looked for all the values, but did not find any - return nil
+        }
+    }
+    else  // looked for the first value, but did not find it - return nil
+    {
+        return Value();
+    }
+}
 
 
 //===========================================================================
@@ -1511,6 +1647,7 @@ static void install(Context *c)
 	c->AddFunction(new VectorBitmap("bitmap"));
 	c->AddFunction(new VectorNoBitmap("nobitmap"));
 	c->AddFunction(new VectorFilter("filter"));
+	c->AddFunction(new VectorFindFunction("find"));
 	c->AddFunction(new VectorSort("sort",         VSORT_VALUES));
 	c->AddFunction(new VectorSort("sort_indices", VSORT_INDICES));
 
diff --git a/src/libMarsClient/expand.c b/src/libMarsClient/expand.c
index 7fe7421..51fb541 100644
--- a/src/libMarsClient/expand.c
+++ b/src/libMarsClient/expand.c
@@ -822,7 +822,7 @@ static parameter* match_parameter(parameter *r,parameter *lang,boolean verbose)
 		boolean prio = prio1 && prio2 && atol(prio1) != atol(prio2);
 
 		if(verbose)
-			marslog(prio?LOG_WARN:LOG_EROR,
+			marslog(prio?LOG_DBUG:LOG_EROR,
 				"Ambiguous parameter: %s could be %s or %s",
 				r->name,
 				match1->name,
@@ -833,7 +833,7 @@ static parameter* match_parameter(parameter *r,parameter *lang,boolean verbose)
 			if(atol(prio1) > atol(prio2))
 				match2 = match1;
 			if(verbose)
-				marslog(LOG_WARN,"Assuming that '%s' means '%s'",r->name,match2->name);
+				marslog(LOG_DBUG,"Assuming that '%s' means '%s'",r->name,match2->name);
 		}
 		else {
 			return NULL;
@@ -1085,10 +1085,10 @@ static request *match_verb(const request* r,request *lang)
 
 		if(n > 1)
 		{
-			marslog(LOG_WARN,"Ambiguous verb: '%s' could be:",r->name);
+			marslog(LOG_DBUG,"Ambiguous verb: '%s' could be:",r->name);
 			for(i = 0; i < top; i++)
 				if(ok[i])
-					marslog(LOG_WARN,"  %s (%s)",matches[i]->name,matches[i]->kind);
+					marslog(LOG_DBUG,"  %s (%s)",matches[i]->name,matches[i]->kind);
 			tell = true;
 		}
 	}
@@ -1097,7 +1097,7 @@ static request *match_verb(const request* r,request *lang)
 		use = 0;
 
 	if(tell)
-		marslog(LOG_INFO,"Choosing %s (%s)", matches[use]->name, matches[use]->kind);
+		marslog(LOG_DBUG,"Choosing %s (%s)", matches[use]->name, matches[use]->kind);
 	return matches[use];
 }
 
diff --git a/src/libMarsClient/tools.c b/src/libMarsClient/tools.c
index 6510be5..31c7c2c 100644
--- a/src/libMarsClient/tools.c
+++ b/src/libMarsClient/tools.c
@@ -122,7 +122,12 @@ long64 proc_mem()
 
 long64 proc_mem()
 {
-	return 0;
+    struct rusage rup;
+
+    if(getrusage(RUSAGE_SELF,&rup) != -1)
+        return rup.ru_maxrss*1024;
+
+    return 0;
 }
 
 #endif
diff --git a/src/libMvQtGui/MvQAbout.cc b/src/libMvQtGui/MvQAbout.cc
index fa55d3f..27aa499 100644
--- a/src/libMvQtGui/MvQAbout.cc
+++ b/src/libMvQtGui/MvQAbout.cc
@@ -19,6 +19,10 @@
 #include "MvVersionInfo.h"
 #include "MvPath.hpp"
 
+#define QUOTE_PP(P) #P
+#define QUOTE_PPP(P) QUOTE_PP(P)
+
+
 MvQAbout::MvQAbout(QString title, QString description, Versions version,
 	           QMap<Version,QString> text) : QDialog(0)
 {
@@ -32,7 +36,7 @@ MvQAbout::MvQAbout(QString title, QString description, Versions version,
 	
 	if(version.testFlag(GribApiVersion))
 	{
-		str  << "<p><b>GRIB_API version:</b> ";
+		str  << "<p><b>" QUOTE_PPP(GRIB_HANDLING_PACKAGE) " version:</b> ";
 
 		if(text.contains(GribApiVersion))
 		{
diff --git a/test/macros/CMakeLists.txt b/test/macros/CMakeLists.txt
index a929536..9d6ac14 100644
--- a/test/macros/CMakeLists.txt
+++ b/test/macros/CMakeLists.txt
@@ -89,6 +89,12 @@ metview_macro_test(MACRO     inline_fortran.mv
 
 metview_macro_test(MACRO     station.mv)
 
+metview_macro_test(MACRO     vectors.mv)
+
+metview_macro_test(MACRO     lists.mv)
+
+metview_macro_test(MACRO     fieldsets.mv)
+
 if(ENABLE_MARS)
     metview_macro_test(MACRO      MarsAccess.mv
                        RESOURCES  ../data/10U_GG.grb )
diff --git a/test/macros/fieldsets.mv b/test/macros/fieldsets.mv
new file mode 100644
index 0000000..645d0da
--- /dev/null
+++ b/test/macros/fieldsets.mv
@@ -0,0 +1,51 @@
+# Metview Macro
+
+# **************************** LICENSE START ***********************************
+#
+# Copyright 2016 ECMWF. This software is distributed under the terms
+# of the Apache License version 2.0. In applying this license, ECMWF does not
+# waive the privileges and immunities granted to it by virtue of its status as
+# an Intergovernmental Organization or submit itself to any jurisdiction.
+#
+# ***************************** LICENSE END ************************************
+
+# perform some basic operations on the 'fieldset' Macro data type
+
+a = read('hindcast.grib')
+steps = [0,6,24,36,48,72]
+
+assert(steps_equal(a, steps),                'all fields')
+assert(step_equal(a[1], 0),                  'first field')
+assert(step_equal(a[count(a)], 72),          'last field')
+assert(steps_equal(a[1,3],   [0,6,24]),      '2 indexes (1)')
+assert(steps_equal(a[3,6],   [24,36,48,72]), '2 indexes (2)')
+assert(steps_equal(a[2,6,2], [6,36,72]),     '3 indexes')
+
+i = |2, 3, 6, 2|
+assert(steps_equal(a[i], [6,24,72,6]),       'vector index (1)')
+i = |5|
+assert(step_equal(a[i], 48),                 'vector index (2)')
+
+# ---------------------------------------------------
+
+function step_equal(fs:fieldset, refstep:number)
+    s = grib_get_long(fs, 'step')
+    return (s = refstep)
+end steps_equal
+
+function steps_equal(fs:fieldset, refsteps:list)
+    s = grib_get_long(fs, 'step')
+    return equal(s, refsteps)
+end steps_equal
+
+
+function equal(l1: list, l2:list)
+    return (not 0 in (l1 = l2))
+end equal
+
+function assert(test:number, msg:string)
+    if (not(test)) then
+        fail(msg)
+    end if
+end assert
+
diff --git a/test/macros/lists.mv b/test/macros/lists.mv
new file mode 100644
index 0000000..2e5779f
--- /dev/null
+++ b/test/macros/lists.mv
@@ -0,0 +1,36 @@
+# Metview Macro
+
+# **************************** LICENSE START ***********************************
+#
+# Copyright 2016 ECMWF. This software is distributed under the terms
+# of the Apache License version 2.0. In applying this license, ECMWF does not
+# waive the privileges and immunities granted to it by virtue of its status as
+# an Intergovernmental Organization or submit itself to any jurisdiction.
+#
+# ***************************** LICENSE END ************************************
+
+# perform some basic operations on the 'list' Macro data type
+
+a = [10, 20, 30, 'a', 'b', 'c']
+
+assert(a[1] = 10,         'first element')
+assert(a[count(a)] = 'c', 'last element')
+assert(equal(a[1,2], [10,20]), '2 indexes')
+assert(equal(a[1,5,2], [10, 30, 'b']), '2 indexes')
+
+i = |2,1,5|  #  use a vector as an index
+assert(equal(a[i], [20, 10, 'b']), 'vector index')
+
+
+# ---------------------------------------------------
+
+function equal(l1: list, l2:list)
+    return (not 0 in (l1 = l2))
+end equal
+
+function assert(test:number, msg:string)
+    if (not(test)) then
+        fail(msg)
+    end if
+end assert
+
diff --git a/test/macros/vectors.mv b/test/macros/vectors.mv
new file mode 100644
index 0000000..1419d6a
--- /dev/null
+++ b/test/macros/vectors.mv
@@ -0,0 +1,78 @@
+# Metview Macro
+
+# **************************** LICENSE START ***********************************
+#
+# Copyright 2016 ECMWF. This software is distributed under the terms
+# of the Apache License version 2.0. In applying this license, ECMWF does not
+# waive the privileges and immunities granted to it by virtue of its status as
+# an Intergovernmental Organization or submit itself to any jurisdiction.
+#
+# ***************************** LICENSE END ************************************
+
+# perform some basic operations on the 'vector' Macro data type
+
+v = | 1, 2, 3, 4, 5, 6, 7, 8, 9,10,
+     11,12,13,14,15,16,17,18,19,20,
+     21,22,23,24,25,26,27,28,29,30,
+     31,32,33,34,35,36,37,38,39,40|
+
+
+assert(v[1]        = 1,  'first element')
+assert(v[count(v)] = 40, 'last element')
+
+#v2 = v[2,2]
+#assert(type(v2)  = 'vector', 'second element as vector - type')
+#assert(count(v2) = 1,        'second element as vector - count')
+#assert(v2[1]     = 2,        'second element as vector - value')
+
+v3 = v[4,7]
+assert(count(v3) = 4, 'elements 4,7 - count')
+v3bool = (v3 = |4,5,6,7|)
+assert(sum(v3bool) = 4, 'elements 4,7 - values')
+
+v4 = v[4,7,2]
+assert(count(v4) = 2, 'elements 4,7,2 - count')
+v4bool = (v4 = |4,6|)
+assert(sum(v4bool) = 2, 'elements 4,7,2 - values')
+
+v5 = v[4,40,10,3]
+assert(count(v5) = 12, 'elements 4,40,10,3 - count')
+v5bool = (v5 = |4,5,6,14,15,16,24,25,26,34,35,36|)
+assert(sum(v5bool) = 12, 'elements 4,40,10,3 - values')
+
+vv = |4,40,10,3|
+vi = |2, 3, 1|
+v6 = vv[vi]
+v6bool = (v6 = |40, 10, 4|)
+assert(sum(v6bool) = 3, 'elements 4,40,10,3 - values with vector indexing')
+
+assert(minvalue(v) = 1,  'minvalue')
+assert(maxvalue(v) = 40, 'maxvalue')
+assert(sum(v)      = 820, 'sum')
+assert(sum(v+10)   = 820+(10*count(v)), 'sum v+10')
+
+
+# find
+vf = |2, 3, 4, 5, 6, 3, 4, 3|
+f = find(vf, 0) # look for something not in the vector
+assert(f = nil, 'find not found should return nil')
+f = find(vf, 0, 'all') # look for something not in the vector
+assert(f = nil, 'find not found should return nil (multiple)')
+f = find(vf, 3) # find single occurrence
+assert(f = 2, 'find 3')
+f = find(vf, 2, 'all') # find all occurrences when there is only one
+assert(type(f)='vector' and f[1] = 1, 'find 2 all')
+f = find(vf, 3, 'all') # find all occurrences when there are multiple matches
+assert(type(f)='vector' and maxvalue(abs(f-|2,6,8|))=0, 'find 3 all')
+
+vf = |2, 3, 4, vector_missing_value, 6, 3, vector_missing_value, 3|
+f = find(vf, vector_missing_value, 'all') # find all missing values
+assert(type(f)='vector' and maxvalue(abs(f-|4,7|))=0, 'find vector_missing_value all')
+
+
+function assert(test:number, msg:string)
+    if (not(test)) then
+        fail(msg)
+    end if
+end assert
+

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/metview.git



More information about the debian-science-commits mailing list