Commit ce580686 authored by Stephan Thober's avatar Stephan Thober
Browse files

adding cmake files, licence, and readme. Removing Makefile

parent 26b02450
# This cmake file is not meant to be edited for a special setup.
# For special setups use cache line files or command line options, as described a few
# lines ahead concerning module independend builds
cmake_minimum_required(VERSION 3.5)
project(edk Fortran)
# The variable "CMAKE_BUILD_MODULE_SYSTEM_INDEPENDEND" can be set before executing cmake via a cache command:
# $cmake -DCMAKE_BUILD_MODULE_SYSTEM_INDEPENDEND:STRING=ON ..
# or cache file:
# $cmake -C ../CMakeCacheFiles/eve ..
# or after executing CMake editing the CMakeCache.txt, preferably with a corresponding cmake editor i.e ccmake
set(CMAKE_BUILD_MODULE_SYSTEM_INDEPENDEND OFF CACHE STRING "build the module independend of the module system, so the build in the build tree works even after a module purge")
message(STATUS "build independend of module system ${CMAKE_BUILD_MODULE_SYSTEM_INDEPENDEND}")
# set specific place where to search for the netCDF directory
set(CMAKE_NETCDF_DIR " " CACHE STRING "set set specific place where to search for the netCDF directory")
message(STATUS "search in additional directory ${CMAKE_NETCDF_DIR} for netCDF")
# The variable "CMAKE_WITH_MPI" can be set before executing cmake via a cache command:
# $cmake -DCMAKE_WITH_MPI:STRING=ON ..
# or in a cache file:
# $cmake -C ../CMakeCacheFiles/example
# or after executing CMake editing the CMakeCache.txt, preferably with a corresponding cmake editor i.e. ccmake
set(CMAKE_WITH_MPI OFF CACHE STRING "build the module with MPI, so it can be executed using mpirun")
# same with OpenMP
set(CMAKE_WITH_OpenMP OFF CACHE STRING "build the module with OpenMP parallelization")
# same with lapack
set(CMAKE_WITH_LAPACK OFF CACHE STRING "build the module with lapack library")
# additional cmake-modules created for the purpose of finding netCDF or other libraries ly in the source_directory in
# a folder named cmake-modules. This command tells cmake to search there for Find<module>.cmake files
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules)
set (NETCDF_F90 "YES")
# the FindNetCDFF.cmake file can be found after we added the cmake-modules folder to the CMAKE_MODULE_PATH
# the build fails, if it is not present
find_package(NetCDFF REQUIRED)
# from that module we gain the following variables:
# NETCDF_INCLUDES : the include directory
# NETCDF_LINK_LIBRARIES : the absolute path to and with the libraries
# NETCDF_CFLAGS_OTHER : additional compilation flags
# NETCDF_LDFLAGS_OTHER : additional linking flags
# if cmake provides a findLIBRARY module, this gets invoked via find_package(LIBRARY)
if (CMAKE_WITH_MPI)
# find if there is an MPI setup on the system and if so, set corresponding variables
find_package(MPI)
if (NOT ${MPI_Fortran_FOUND})
message(FATAL_ERROR "MPI required but not found")
else()
message(STATUS "found MPI_Fortran_COMPILER ${MPI_Fortran_COMPILER}")
endif()
endif()
if (CMAKE_WITH_OpenMP)
# find if there is an OpenMP setup on the system and if so, set corresponding variables
find_package(OpenMP)
if (NOT ${OpenMP_Fortran_FOUND})
message(FATAL_ERROR "OpenMP required but not found")
endif()
endif()
if (CMAKE_WITH_LAPACK)
# find if there is an LAPACK library on the system and if so, set corresponding variables
find_package(LAPACK)
if (NOT ${LAPACK_FOUND})
message(FATAL_ERROR "lapack required but not found")
endif()
endif()
include_directories(${NETCDF_INCLUDES} ${MPI_Fortran_INCLUDE_PATH} ${OpenMP_Fortran_LIBRARY})
# ifort and gfortran need the flag -cpp to interpret definitions like -DMRM2MHM
# the nag compiler is not able to interpret the flag -cpp but can interpret these definitions anyway
# so we check whether the compiler is able to use the flag -cpp
# for that we need the module CheckFortranCompilerFlag
include(CheckFortranCompilerFlag)
CHECK_Fortran_COMPILER_FLAG("-cpp" CPP_FLAG)
# if the flag exists, we add it to the compilation flags
if (CPP_FLAG)
set(ADDITIONAL_GCC_FLAGS "-cpp")
endif()
# this function adds definitions but also creates a corresponding CMAKE variable with CACHE STRING
# i.e.:
# The variable "${defCMakeName}" can be set before executing cmake via a cache command cmake -D...
# or in a cache file:
# $cmake -C ../CMakeCacheFiles/example
# or after executing CMake editing the CMakeCache.txt, preferably with a corresponding cmake editor i.e. ccmake
# cmake ..
function(cpp_definitions defName defCMakeName value cacheString)
set(${defCMakeName} "${value}" CACHE STRING "${cacheString}")
if (${defCMakeName})
add_definitions("${defName}")
endif()
endfunction()
# Add definitions. These should later be set via the cache line file and only
# have a default value here. These part only concerns user build definitions like MRM2MHM
#add_definitions(-DMRM2MHM=.true.)
cpp_definitions("-DABSOFT" "CMAKE_ABSOFT" "OFF" "Documentation to be added. If you you are developer, you might edit this string in CMakeLists.txt")
# Compile.
#
# This is not recommended but wished by some members of our working group. With this command
# all files in src with the ending f90 or h are written into sources, and therefore linked
# together to the executable, if relevant or not
file(GLOB_RECURSE sources src/*.f90 src/*.h)
# this command is able to create dependencies, compile and add the sources in the right order
add_executable(edk ${sources})
# the libraries are added to the executable by the linker, using the full path and using the
# rpath option, except the libraries are located in ${CMAKE_Fortran_IMPLICIT_LINK_DIRECTORIES}.
target_link_libraries(edk ${NETCDF_LINK_LIBRARIES} ${MPI_Fortran_LIBRARIES} ${OpenMP_Fortran_LIBRARIES} ${LAPACK_LIBRARIES})
set_property(TARGET edk PROPERTY COMPILE_FLAGS "${CMAKE_Fortran_FLAGS} ${ADDITIONAL_GCC_FLAGS} ${NETCDF_CFLAGS_OTHER} ${MPI_Fortran_COMPILE_FLAGS} ${OpenMP_Fortran_FLAGS}")
set_property(TARGET edk PROPERTY LINK_FLAGS "${NETCDF_LDFLAGS_OTHER} ${MPI_Fortran_LINK_FLAGS} ${OpenMP_Fortran_FLAGS} ${LAPACK_LINKER_FLAGS}")
# set compiling flags for debug and realese version
if(CMAKE_Fortran_COMPILER_ID MATCHES "GNU")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -ffree-form -ffixed-line-length-132")
set(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -pedantic-errors -Wall -W -O -g -Wno-maybe-uninitialized")
set(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE} -O3")
cpp_definitions("-DGFORTRAN" "CMAKE_GFORTRAN" "ON" "Code exchange for gfortran compiler dependent issues")
endif()
if(CMAKE_Fortran_COMPILER_ID MATCHES "Intel")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -nofixed -assume byterecl -fp-model source -m64 -assume realloc-lhs ") # precise -> source: suppress warning, computation identical
set(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -warn all -g -debug -traceback -fp-stack-check -O0 -debug -check all")
set(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE} -O3 -qoverride-limits")
endif()
message(STATUS "the following debug flags will be used: ${CMAKE_Fortran_FLAGS_DEBUG}")
# Usually that works fine, except, one is on a module system and tries to execute the executable
# in the end without having the modules loaded. A workaround is provided using the variable
# CMAKE_BUILD_MODULE_SYSTEM_INDEPENDEND
# if this variable is set to ON (do not set the variable inside of this cmake file), then the
# paths are added to the INSTALL_RPATH, and via the second command also to the build.
# It is a bit of a mess and workaround though.
if (CMAKE_BUILD_MODULE_SYSTEM_INDEPENDEND)
set_target_properties(edk PROPERTIES INSTALL_RPATH "${CMAKE_Fortran_IMPLICIT_LINK_DIRECTORIES}")
set_target_properties(edk PROPERTIES BUILD_WITH_INSTALL_RPATH ON)
endif()
#set_target_properties(edk PROPERTIES SKIP_BUILD_RPATH OFF)
#set_target_properties(edk PROPERTIES INSTALL_RPATH_USE_LINKPATH ON)
# possibility to create symlinks to the build or to the source directory, so a copy of mhm does not have to be done. On the other
# hand, only for the test basins the executable would not be copied or linked to a predictable location. So it may be a good
# idea to not copy it with the cmake setup
#add_custom_target(link_namelists ALL "${CMAKE_COMMAND}" -E create_symlink "${CMAKE_CURRENT_SOURCE_DIR}/mhm.nml" "${CMAKE_CURRENT_BINARY_DIR}/mhm.nml")
Dependencies:
=============
For Windows, some Linux distributions and soon also MacOS
specific installation instructions for the following list
can be found below.
- a fortran compiler
- make (a tool to compile a program)
- cmake (version >= 3.5) (a tool to create a system dependent makefile)
- fitting netcdf-fortran libraries (libraries for the usage of the data format netcdf on which edk depends)
- (optional, but makes things much easier) git
Git is a version-control system. If you want to contribute to a project, it is highly recommended to
use Git. You can use Git to download (clone) the project to your local pc and have a look at the history or
synchronize it without copying the whole repository again. You can also download the project folder without
Git, but this would not allow you to pull updates from and push changes to our repository.
System dependend installation instructions:
===========================================
### Windows:
[Cygwin](https://cygwin.com/) is an environment with a terminal that allows to compile and
run programs of Unix-like systems. You can find further instructions to install cygwin on the webpage, as well as
instructions on how to install further dependencies after the installation.
After the installation of cygwin and its dependencies edk will be installed
using cygwin. All commands and the execution of edk only run in that environment.
Install cygwin by executing the cygwin setup and choose the following dependencies:
- [ ] gcc-fortran (the fortran compiler)
- [ ] make
- [ ] cmake (version >= 3.5)
- [ ] libnetcdf-fortran-devel
- [ ] Git *(optional, Git is also available outside of cygwin, [see the Git website](https://git-scm.com/downloads))*
While installing cygwin you will have to choose a mirror. A mirror is a server
on the internet where the files for the installation come from. Choose any server
located near your city and when in doubt, choose the first one in the list.
In the next step you can find all available packages provided by cygwin, set
the view to "full". In the search panel you can filter the packages
by the dependencies listed above (e.g. make). When you choose a
version, the newest one is usually a good choice if not marked as experimental.
*Note for UFZ members:* Install cygwin locally, do not choose a location on the
network for the installation.
Some cygwin versions create a new home directory for you. You may check e.g. here:
C:\cygwin64\home\$username
### Ubuntu, Mint and other apt-get based systems with matching repositories:
sudo apt-get install git # (optional)
sudo apt-get install gfortran netcdf-bin libnetcdf-dev libnetcdff-dev cmake
### Archlinux:
sudo pacman -S git # (optional)
sudo pacman -S gcc-libs netcdf-fortran cmake
### Module systems:
If you are on a module system, load the modules gcc or intel depending on your
favorite compiler. Then, load the modules netcdf-fortran and cmake.
These modules will have system specific names, environments, etc.
You may use `module spider` to find the right packages and the
right dependencies, potentially use corresponding wiki pages.
#### On eve (the cluster at the UFZ):
From the source directory use a script provided in `moduleLoadScripts`,
for example for the GNU 7.3 compiler:
source moduleLoadScripts/eve.gfortran73
### MacOS:
*(to be added)*
Specific setups:
================
The following hints can replace the step `cmake ..` in the installation instruction.
You can skip this part and continue with "Installation", if you do not have a module system
setup (like on clusters) or if you have not installed all packages with a package manager,
such as cygwin or apt-get.
### Module systems:
The executable can be build in a way that it runs independend of loaded modules in the end. The
module system, though, adds system paths in the backround the user should not care about too much, so
the setup is a workaround. (This would be the case with any other building tool aswell.)
It should be stable, anyway.
In case you want to have a module-independend build, instead of just executing `cmake ..`, either run
cmake -DCMAKE_BUILD_MODULE_SYSTEM_INDEPENDEND:STRING=ON ..
or
cmake -C ../CMakeCacheFiles/eve ..
or change the variable `CMAKE_BUILD_MODULE_SYSTEM_INDEPENDEND` with `ccmake` to `ON` after running `cmake ..`.
### None standard locations for the netcdf-library (e.g. standard setup Macs in CHS):
Find the location of the `nf-config` file, for example by using:
find / -iname "*nf-config*" 2>/dev/null
This searches the root directory `/` for a file with a name containing the string "nf-config", not
taking into account upper and lower case. It writes error messages like "permission denied" into
the void.
Then, instead of running `cmake ..` if not using the standard compiler,
set the fortran compiler variable to the wished compiler, e.g.
export FC=gfortran
then either run
cmake -DCMAKE_NETCDF_DIR:STRING=/path/to/nf-config/of/used/compiler
or copy the file `specificSetup` to some other place:
cp ../CMakeCacheFiles/specificSetup .
However, in case you want to keep it, you should choose a place
outside the build repository. Edit the file as follows:
add the path to your `nf-config` file, and after editing, run:
cmake -C specificSetup ..
or change the variable `CMAKE_NETCDF_DIR` to the path to the `nf-config` file with `ccmake` after running `cmake ..`.
Installation
============
1. Change to a directory where you want to store the source code.
2. Clone the corresponding edk repository into a folder, either using Git (if installed):
git clone -b cmake git@git.ufz.de:chs/progs/EDK.git edk/
3. Create and change to a build directory where you want to store the build, e.g. inside the Git source directory
cd edk
mkdir build
Change into the build directory:
cd build
4. Generate a system dependent makefile
Execute `cmake` with the path to the Git source directory as parameter.
cmake ..
If everything worked well a Makefile was created with the corresponding paths.
*Note: have a look at "Specific setups" above in case you are using module systems,
or when the netcdf libraries are not located where the package manager usually installs libraries,
or when they are not saved in environment variables (i.e., classical MacOS setups at CHS).*
5. Make the build:
Execute make:
make
If this also worked fine, an executable was created, which has to be moved or copied to the Git source directory.
6. Execute the file:
cd ..
cp build/edk .
On Windows the executable is called `edk.exe` instead of `edk`. In that case
instead of `cp build/edk .` execute
cp build/edk.exe .
Now you might execute edk:
./edk
*Note concerning the development of the cmake setup: one could automatically
link the executable with the `cmake` code inside the Git source directory
which is not done for two reasons:*
- *The executable depends on your local system, so it should never be commited and pushed to other users.
Nothing should be build inside the source directory which we did not do by hand.*
- *The directory where edk is executed usually is not the source directory but the directory where you want to run
your tests. In case of the test setup it is the same, usually it is not.*
Building Realease or Debug versions:
====================================
If you want to set up specific versions of the build, you can
create different folders for that. Assume a release and a debug
version. Then a good idea would be to create one folder named
`debug` and one folder named `release`
mkdir release
mkdir debug
inside the `release` folder one would execute
cmake -DCMAKE_BUILD_TYPE=Release ..
and inside the `debug` folder
cmake -DCMAKE_BUILD_TYPE=Debug ..
Executing
make
in the corresponding folder would then always result in a release build or respectively in a debug build.
Trouble shooting:
=================
On brew/homebrew setup MacOS systems there is no working `nf-config` by now. Execute:
nf-config --all
and if it says something like "is not implemented yet" the issue is not solved yet. But it is on my tracklist.
In any other case feel free to write an email to <mailto:maren.kaluza@ufz.de>.
**cmake** is far from being my main task, so it will probably take a while until I can track a problem.
I would be happy having bug reports, anyhow.
This diff is collapsed.
This diff is collapsed.
# The External Drift Kriging -- EDK program
This repository contains the external drift kriging (EDK) Fortran program developed at the Dept. Computational Hydrosystems at the Helmholtz Centre for Environmental Research - UFZ.
The EDK comes with a [LICENSE][1] agreement, this includes also the GNU Lesser General Public License.
**Please note**: The GitLab repository grants read access to the code.
If you like to contribute to the code, please contact stephan.thober@ufz.de.
## Installation
Installation instructions can be found in [INSTALL][2] for Windows, MacOS, and GNU/Linux distributions.
[1]: LICENSE
[2]: INSTALL.md
# - Find NetCDF
# Find the native NetCDF includes and library
#
# NETCDF_INCLUDES - where to find netcdf.h, etc
# NETCDF_LIBRARIES - Link these libraries when using NetCDF
# NETCDF_FOUND - True if NetCDF found including required interfaces (see below)
#
# Your package can require certain interfaces to be FOUND by setting these
#
# NETCDF_CXX - require the C++ interface and link the C++ library
# NETCDF_F77 - require the F77 interface and link the fortran library
# NETCDF_F90 - require the F90 interface and link the fortran library
#
# The following are not for general use and are included in
# NETCDF_LIBRARIES if the corresponding option above is set.
#
# NETCDF_LIBRARIES_C - Just the C interface
# NETCDF_LIBRARIES_CXX - C++ interface, if available
# NETCDF_LIBRARIES_F77 - Fortran 77 interface, if available
# NETCDF_LIBRARIES_F90 - Fortran 90 interface, if available
#
# Normal usage would be:
# set (NETCDF_F90 "YES")
# find_package (NetCDF REQUIRED)
# target_link_libraries (uses_f90_interface ${NETCDF_LIBRARIES})
# target_link_libraries (only_uses_c_interface ${NETCDF_LIBRARIES_C})
if (NETCDF_INCLUDES AND NETCDF_LIBRARIES)
# Already in cache, be silent
set (NETCDF_FIND_QUIETLY TRUE)
endif (NETCDF_INCLUDES AND NETCDF_LIBRARIES)
find_path (NETCDF_INCLUDES netcdf.h
HINTS NETCDF_DIR ENV NETCDF_DIR)
find_library (NETCDF_LIBRARIES_C NAMES netcdf)
mark_as_advanced(NETCDF_LIBRARIES_C)
set (NetCDF_has_interfaces "YES") # will be set to NO if we're missing any interfaces
set (NetCDF_libs "${NETCDF_LIBRARIES_C}")
get_filename_component (NetCDF_lib_dirs "${NETCDF_LIBRARIES_C}" PATH)
macro (NetCDF_check_interface lang header libs)
if (NETCDF_${lang})
find_path (NETCDF_INCLUDES_${lang} NAMES ${header}
HINTS "${NETCDF_INCLUDES}" NO_DEFAULT_PATH)
find_library (NETCDF_LIBRARIES_${lang} NAMES ${libs}
HINTS "${NetCDF_lib_dirs}" NO_DEFAULT_PATH)
mark_as_advanced (NETCDF_INCLUDES_${lang} NETCDF_LIBRARIES_${lang})
if (NETCDF_INCLUDES_${lang} AND NETCDF_LIBRARIES_${lang})
list (INSERT NetCDF_libs 0 ${NETCDF_LIBRARIES_${lang}}) # prepend so that -lnetcdf is last
else (NETCDF_INCLUDES_${lang} AND NETCDF_LIBRARIES_${lang})
set (NetCDF_has_interfaces "NO")
message (STATUS "Failed to find NetCDF interface for ${lang}")
endif (NETCDF_INCLUDES_${lang} AND NETCDF_LIBRARIES_${lang})
endif (NETCDF_${lang})
endmacro (NetCDF_check_interface)
NetCDF_check_interface (CXX netcdfcpp.h netcdf_c++)
NetCDF_check_interface (F77 netcdf.inc netcdff)
NetCDF_check_interface (F90 netcdf.mod netcdff)
set (NETCDF_LIBRARIES "${NetCDF_libs}" CACHE STRING "All NetCDF libraries required for interface level")
# handle the QUIETLY and REQUIRED arguments and set NETCDF_FOUND to TRUE if
# all listed variables are TRUE
include (FindPackageHandleStandardArgs)
find_package_handle_standard_args (NetCDF DEFAULT_MSG NETCDF_LIBRARIES NETCDF_INCLUDES NetCDF_has_interfaces)
mark_as_advanced (NETCDF_LIBRARIES NETCDF_INCLUDES)
# from this module we gain the following variables:
# NETCDF_INCLUDES : the include directory
# NETCDF_LINK_LIBRARIES : the absolute path to and with the libraries
# NETCDF_CFLAGS_OTHER : additional compilation flags
# NETCDF_LDFLAGS_OTHER : additional linking flags
# The cmake config approach of finding libraries
# This is the cleanest way. If the package itself provides a CMake config and
# defines the way of building the package, it is a good way to use the hints.
# On some systems that config file does not exist or cannot be found (strange setup module
# systems for instance). In that case we fall back to another method. PkgConfig would be a
# feasible approach, see below. But we then go the nf-config way.
#****************************************************************
#find_package(netCDF CONFIG)
#message(STATUS "found cmake config ${netCDF_CONFIG}")
#include(${netCDF_CONFIG} OPTIONAL RESULT_VARIABLE FOUND_NETCDFF_MODULE)
#if (FOUND_NETCDFF_MODULE)
# find_library(NETCDF_LINK_LIBRARIES NAMES ${netCDF_LIBRARIES} HINTS ${netCDF_LIB_DIR})
# message(STATUS "found netcdf libraries: ${NETCDF_LINK_LIBRARIES} in ${netCDF_LIB_DIR}")
# #set(NETCDF_CFLAGS_OTHER "-I/usr/include" CACHE STRING "Additional compiler flags for NetCDF")
# set(NETCDF_CFLAGS_OTHER "${netCDF_C_COMPILER_FLAGS}" CACHE STRING "Additional compiler flags for NetCDF")
# message(STATUS "netcdff netcdf link flags ${NETCDF_CFLAGS_OTHER}")
# set(NETCDF_LDFLAGS_OTHER "${netCDF_LDFLAGS}" CACHE STRING "Additional link flags for NetCDF")
# message(STATUS "found netcdf other flags ${NETCDF_LDFLAGS_OTHER}")
# set(NETCDF_INCLUDES "${netCDF_LIB_DIR}" CACHE STRING "Include directories for NetCDF")
#endif()
# The PkgConfig approach of finding libraries
# PkgConfig does not exist on many systems, so we do not use this approach
# Anyway, one can see quite well here how the variables may be called and what we need
#*************************************************************************************
#find_package(PkgConfig REQUIRED)
#pkg_check_modules(_NETCDF REQUIRED netcdf-fortran)
##find_path(NETCDF_INCLUDE_DIR HINTS ${_NETCDF_INCLUDE_DIRS})
#find_library(NETCDF_LIBRARIES NAMES ${_NETCDF_LIBRARIES} HINTS ${_NETCDF_LIBRARY_DIRS})
#set(NETCDF_CFLAGS_OTHER "${_NETCDF_CFLAGS_OTHER}" CACHE STRING "Additional compiler flags for NetCDF")
#set(NETCDF_LDFLAGS_OTHER "${_NETCDF_LDFLAGS_OTHER}" CACHE STRING "Additional link flags for NetCDF")
#set(NETCDF_INCLUDE_DIR "${_NETCDF_INCLUDE_DIRS}" CACHE STRING "Include directories for NetCDF")
##message(STATUS "NETCDF VARIABLES: libraries: ${NETCDF_LIBRARIES}, flags: ${NETCDF_FLAGS}, dirs: ${NETCDF_INCLUDE_DIR}")
#find_package_handle_standard_args(NETCDF REQUIRED_VARS NETCDF_LIBRARIES)
# The nf-config approach
# nf-config is a readable file and a program existent on any system, although, on MacOS setups with brew everything
# is commented except an "echo "nf-config is not implemented yet""...
# executing "nf-config" writes out a description of every parameter of the file and "nf-config --all" prints how the
# parameters are set
# with these parameters we are able to set the library, include directory and flag variables accordingly.
#********************************************************************************************************
# Finds the program nf-config in different locations, including the $PATH, but also, if set, in NETCDF_DIR
# that variable can be set via the cmake cache file, either after cmake was executed in the CMakeCache.txt
# with a specific editor (or by hand), or while executing cmake via cache line variables or a cache line file.
# If nf-config is found, it is written into the NETCDFF_CONFIG variable and can be executed afterwards using
# ${NETCDFF_CONFIG}.
if (NOT FOUND_NETCDFF_MODULE)
find_program(NETCDFF_CONFIG nf-config
HINTS ${CMAKE_NETCDF_DIR})
message(STATUS "found ${NETCDFF_CONFIG}")
execute_process(COMMAND ${NETCDFF_CONFIG} --includedir OUTPUT_VARIABLE NETCDF_INCLUDES OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS "netcdff includes ${NETCDF_INCLUDES}")
execute_process(COMMAND ${NETCDFF_CONFIG} --fflags OUTPUT_VARIABLE NETCDF_CFLAGS_OTHER OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS "netcdff netcdf link flags ${NETCDF_CFLAGS_OTHER}")
execute_process(COMMAND ${NETCDFF_CONFIG} --flibs OUTPUT_VARIABLE NETCDF_LDFLAGS OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS "netcdff netcdf library link flags ${NETCDF_LDFLAGS}")
if (CMAKE_BUILD_MODULE_SYSTEM_INDEPENDEND)
find_program(NETCDF_CONFIG nc-config
HINTS ${CMAKE_NETCDF_DIR})
execute_process(COMMAND ${NETCDF_CONFIG} --libs OUTPUT_VARIABLE NETCDF_LIBS OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS "netcdf library link flags ${NETCDF_LIBS}")
endif()
# In a clean cmake setup the libraries are included via the target_link_libraries and not
# via flags. Cmake creates system dependend flags and rpaths using the libraries itself.
# nf-config on the other hand gives us a list of flags, linking with -l and -L.
# we cut the flag string into seperated flags and create libraries and other flags from it
string(REPLACE " " ";" NETCDF_LDFLAGS_LIST "${NETCDF_LDFLAGS} ${NETCDF_LIBS}")
foreach(flag ${NETCDF_LDFLAGS_LIST})
# message(STATUS "${flag}")
if (flag MATCHES "^-L(.*)")
list(APPEND _search_paths ${CMAKE_MATCH_1})
continue()
endif()
if (flag MATCHES "^-l(.*)")
set(_pkg_search "${CMAKE_MATCH_1}")
else()
list(APPEND _link_flags "${flag}")
continue()
endif()
if(_search_paths)
# Firstly search in -L paths
find_library(pkgcfg_lib_NETCDF_${_pkg_search}
NAMES ${_pkg_search}
HINTS ${_search_paths} NO_DEFAULT_PATH)
endif()
find_library(pkgcfg_lib_NETCDF_${_pkg_search}
NAMES ${_pkg_search}
HINTS ENV LD_LIBRARY_PATH)
message(STATUS "found ${pkgcfg_lib_NETCDF_${_pkg_search}}")
list(APPEND _libs "${pkgcfg_lib_NETCDF_${_pkg_search}}")
endforeach()
set(NETCDF_LINK_LIBRARIES "${_libs}")
message(STATUS "found netcdf libraries ${NETCDF_LINK_LIBRARIES}")
set(NETCDF_LDFLAGS_OTHER "${_link_flags}")
message(STATUS "found netcdf other flags ${NETCDF_LDFLAGS_OTHER}")
endif()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment