################################################################################
# cmake options:
#   -DCMAKE_BUILD_TYPE=Debug|RelWithDebInfo|Release|Production
#   -DCMAKE_INSTALL_PREFIX=/path/to/install
#
#   -DCMAKE_C_COMPILER=gcc
#   -CMAKE_Fortran_COMPILER=gfortran
#
#   -DCMAKE_PREFIX_PATH=/path/to/jasper:/path/to/any/package/out/of/place
#   -DBUILD_SHARED_LIBS=OFF

cmake_minimum_required( VERSION 2.8.4 FATAL_ERROR )

project( libemos )

enable_language( Fortran )

set( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../ecbuild/cmake")

include( ecbuild_system )

ecbuild_requires_macro_version( 1.6 )

ecbuild_add_option( FEATURE INSTALL_TABLES   DESCRIPTION "enable the installations of BUFR/GRIBex tables and LSM"                       DEFAULT ON )
ecbuild_add_option( FEATURE INSTALL_TOOLS    DESCRIPTION "enable the installations of BUFR/GRIBex tools"                                DEFAULT ON )
ecbuild_add_option( FEATURE FORTRAN90        DESCRIPTION "enable tools which need Fortran 90 (only required for FC=pgf77)"              DEFAULT ON )
ecbuild_add_option( FEATURE SINGLE_PRECISION DESCRIPTION "enable single precision version of library (in addition to double precision)" DEFAULT ON )
ecbuild_add_option( FEATURE GRIBEX_ABORT     DESCRIPTION "abort execution on GRIBEX calls"                                              DEFAULT OFF )


################################################################################
# compiler/linker flags

if( ${CMAKE_SYSTEM_NAME} MATCHES "Linux" )
  set( emos_special_system_def linux FOPEN64 )
elseif( ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" )
  set( emos_special_system_def darwin )
endif()

get_filename_component(Fortran_COMPILER_NAME ${CMAKE_Fortran_COMPILER} NAME)

message(">>> CMAKE_Fortran_COMPILER full path: " ${CMAKE_Fortran_COMPILER})
message(">>> CMAKE_Fortran_COMPILER name:      " ${Fortran_COMPILER_NAME})
message(">>> CMAKE_Fortran_COMPILER ID:        " ${CMAKE_Fortran_COMPILER_ID})

# double precision flags: only for d.p. Fortran-based targets (compiling & linking)
if(CMAKE_Fortran_COMPILER_ID MATCHES "GNU")
  set(emos_double_precision_flags "-fdefault-real-8 -fdefault-double-8")
elseif(CMAKE_Fortran_COMPILER_ID MATCHES "Intel")
  set(emos_double_precision_flags "-r8 -i4")
elseif( CMAKE_Fortran_COMPILER_ID MATCHES "PGI")
  set(emos_double_precision_flags "-r8 -i4")
elseif(CMAKE_Fortran_COMPILER_ID MATCHES "Cray")
  set(emos_double_precision_flags "-s integer32 -s real64")
else()
  set(emos_double_precision_flags "")
endif()

# build type flags
if(CMAKE_Fortran_COMPILER_ID MATCHES "GNU")
  set(CMAKE_Fortran_FLAGS         "-ffixed-line-length-none -fcray-pointer -fno-second-underscore -Wuninitialized -DSHAREDMEMORY")
  set(CMAKE_Fortran_FLAGS_RELEASE "-O2 -mtune=native")
  set(CMAKE_Fortran_FLAGS_RELWITHDEBINFO "-g -O2 -mtune=native")
  set(CMAKE_Fortran_FLAGS_DEBUG   "-g")
  set(emos_special_compiler_def   "gfortran")
elseif(CMAKE_Fortran_COMPILER_ID MATCHES "Intel")
  set(CMAKE_Fortran_FLAGS         "-DSHAREDMEMORY")
  set(CMAKE_Fortran_FLAGS_RELEASE "-f77rtl -O3")
  set(CMAKE_Fortran_FLAGS_RELWITHDEBINFO "-f77rtl -O2 -g")
  set(CMAKE_Fortran_FLAGS_DEBUG   "-f77rtl -O0 -g")
elseif(CMAKE_Fortran_COMPILER_ID MATCHES "PGI")
  set(CMAKE_Fortran_FLAGS         "-fast -Kieee -Mvect=prefetch -noswitcherror")
  set(CMAKE_Fortran_FLAGS_RELEASE "-O2")
  set(CMAKE_Fortran_FLAGS_RELWITHDEBINFO "-g -O2")
  set(CMAKE_Fortran_FLAGS_DEBUG   "-g")
elseif(CMAKE_Fortran_COMPILER_ID MATCHES "Cray")
  set(CMAKE_Fortran_FLAGS         "-ev -Wl,--as-needed -h PIC -emf -hflex_mp=conservative -hfp1 -hadd_paren -DSHAREDMEMORY")
  set(CMAKE_Fortran_FLAGS_RELEASE "")
  set(CMAKE_Fortran_FLAGS_RELWITHDEBINFO "-G2")
  set(CMAKE_Fortran_FLAGS_DEBUG   "-G0 -hfp0")
  set(CMAKE_C_FLAGS               "-Wl,--as-needed -h PIC -DSHAREDMEMORY")
  set(CMAKE_SKIP_RPATH TRUE)
else()
  message("No optimized Fortran compiler flags are known, we just try -O2...")
  set(CMAKE_Fortran_FLAGS_RELEASE "-O2")
  set(CMAKE_Fortran_FLAGS_RELWITHDEBINFO "-O2 -g")
  set(CMAKE_Fortran_FLAGS_DEBUG   "-O0 -g")
endif()


################################################################################
# projects

ecbuild_use_package( PROJECT grib_api VERSION 1.9.16 REQUIRED )

ecbuild_declare_project()

################################################################################
# contents

# project export variables

set( LIBEMOS_INCLUDE_DIRS   ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} )
set( LIBEMOS_LIBRARIES      emos )
set( LIBEMOS_TPLS           grib_api )

set_directory_properties(PROPERTIES COMPILE_DEFINITIONS "${ECKIT_DEFINITIONS};${GRIB_API_DEFINITIONS}" )

include_directories( ${LIBEMOS_INCLUDE_DIRS}  )
include_directories( ${GRIB_API_INCLUDE_DIRS} )

if( BUFR_TABLES_PATH )

  message( STATUS "BUFR_TABLES_PATH : ${BUFR_TABLES_PATH}" )

  if( IS_ABSOLUTE ${BUFR_TABLES_PATH} )
    add_definitions( -DBUFR_TABLES_PATH="${BUFR_TABLES_PATH}/" )
  else()
    add_definitions( -DBUFR_TABLES_PATH="${CMAKE_INSTALL_PREFIX}/${BUFR_TABLES_PATH}/" )
  endif()

else()
    add_definitions( -DBUFR_TABLES_PATH="${CMAKE_INSTALL_PREFIX}/${INSTALL_DATA_DIR}/tables/bufrtables/" )
endif()

# get_directory_property( LIBEMOS_DEFINITIONS COMPILE_DEFINITIONS ) # don't export libemos definitions

# config header

ecbuild_generate_config_headers( DESTINATION ${INSTALL_INCLUDE_DIR}/libemos )

configure_file( libemos_config.h.in  libemos_config.h  @ONLY )
configure_file( libemos_version.h.in libemos_version.h @ONLY )
configure_file( libemos_version.c.in libemos_version.c @ONLY )

install(FILES
  ${CMAKE_CURRENT_BINARY_DIR}/libemos_config.h
  ${CMAKE_CURRENT_BINARY_DIR}/libemos_version.h
  DESTINATION
  ${INSTALL_INCLUDE_DIR}/libemos )


################################################################################
# sources

add_subdirectory( common )
add_subdirectory( gribex )
add_subdirectory( interpolation )
add_subdirectory( bufrdc_wmo )
add_subdirectory( pbio )
add_subdirectory( grib_api_merging )
add_subdirectory( tests )
if( ENABLE_INSTALL_TOOLS )
  add_subdirectory( tools )
endif()

#DEFINITIONS  FORTRAN_NO_UNDERSCORE

if( ${Fortran_COMPILER_NAME} MATCHES "ifort" OR CMAKE_Fortran_COMPILER_ID MATCHES "Intel" )
  set_source_files_properties( ${gribex_srcs} PROPERTIES COMPILE_FLAGS "-O0" )
endif()


list( APPEND libemos_srcs
  ${emos_common_src_files}
  ${interpolation_srcs}
  ${gribex_srcs}
  ${bufrdc_wmo_srcs}
  ${pbio_srcs}
  ${grib_api_merging_srcs} )


################################################################################
# tables: BUFR and LSM interpolation

# should we install the old tables?
# probably only for new architectures
if( ENABLE_INSTALL_TABLES )
  install(
    DIRECTORY
      bufrtables
      gribtables
      gribtemplates
      land_sea_mask
    DESTINATION ${INSTALL_DATA_DIR}/tables
    FILE_PERMISSIONS OWNER_READ GROUP_READ WORLD_READ )
endif()

### interpolation tables are always installed
if( NOT INTERPOL_TABLES_PATH )
  set(INTERPOL_TABLES_PATH "${INSTALL_DATA_DIR}/tables" )
endif()

# tables path to passed as PATH into compilation -D must be absolute
if( IS_ABSOLUTE ${INTERPOL_TABLES_PATH} )
  set(emos_interpol_tables_def INTERPOL_TABLES_PATH="${INTERPOL_TABLES_PATH}" )
else()
  set(emos_interpol_tables_def INTERPOL_TABLES_PATH="${CMAKE_INSTALL_PREFIX}/${INTERPOL_TABLES_PATH}" )
endif()

message( STATUS "INTERPOL_TABLES_PATH: ${INTERPOL_TABLES_PATH}" )

# copy the tables/interpol to the build directory
file( COPY tables/interpol DESTINATION ${CMAKE_BINARY_DIR}/${INSTALL_DATA_DIR}/tables )

# always install tables/interpol
install( DIRECTORY tables/interpol DESTINATION ${INTERPOL_TABLES_PATH} FILE_PERMISSIONS OWNER_READ GROUP_READ WORLD_READ )

################################################################################
# final definitions

list( APPEND LIBEMOS_DEFINITIONS
  ${emos_interpol_tables_def}
  ${emos_special_compiler_def}
  ${emos_special_system_def}
  REAL_8
  REAL_BIGGER_THAN_INTEGER
  POINTER_64
  _LARGEFILE64_SOURCE
  _FILE_OFFSET_BITS=64
  LITTLE_ENDIAN
  INTEGER_IS_INT
  ${GRIB_API_DEFINITIONS} )

################################################################################
# targets: libraries (single & douple p.) and version-check executable

set( LIBEMOS_BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR} )

if( HAVE_SINGLE_PRECISION )
  add_subdirectory( libemos-sp )
endif()
add_subdirectory( libemos-dp )

ecbuild_add_executable(
  TARGET      libemos_version
  DEFINITIONS ${LIBEMOS_DEFINITIONS}
  LIBS        emos
  SOURCES     version.c )

ecbuild_add_resources( TARGET libemos_rcs SOURCES_DONT_PACK compile.sh )

################################################################################
# finalize

ecbuild_pkgconfig(
  NAME        emosR64
  URL         "https://software.ecmwf.int/wiki/display/EMOS/"
  DESCRIPTION "Interpolation library, including BUFR & CREX encoding/decoding routines"
  LANGUAGES   C FORTRAN
  LIBRARIES   emosR64 )
if( HAVE_SINGLE_PRECISION )
ecbuild_pkgconfig(
  NAME        emos
  URL         "https://software.ecmwf.int/wiki/display/EMOS/"
  DESCRIPTION "Interpolation library, including BUFR & CREX encoding/decoding routines (single precision)"
  LANGUAGES   C FORTRAN
  LIBRARIES   emos )
endif()

ecbuild_install_project( NAME libemos )
ecbuild_print_summary()

