#                                               -*- cmake -*-
#
#  CMakeLists.txt
#
#  (C) Copyright 2005-2011 EDF-EADS-Phimeca
#
#  This library is free software; you can redistribute it and/or
#  modify it under the terms of the GNU Lesser General Public
#  License as published by the Free Software Foundation; either
#  version 2.1 of the License.
#
#  This library is distributed in the hope that it will be useful
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#  Lesser General Public License for more details.
#
#  You should have received a copy of the GNU Lesser General Public
#  License along with this library; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
#
#  @author: $LastChangedBy: dutka $
#  @date:   $LastChangedDate: 2010-02-04 16:44:49 +0100 (Thu, 04 Feb 2010) $
#  Id:      $Id: Makefile.am 1473 2010-02-04 15:44:49Z dutka $
#

cmake_minimum_required ( VERSION 2.8 )

project ( OpenTURNS CXX C Fortran )

option ( USE_BISON "Looks for Bison if true and then build parser" ON )
option ( USE_FLEX  "Looks for Flex if true and then build lexer" ON )

# Defines our own module path
set ( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/CMakeModules" ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY} )

# Find system prerequisites
include ( CMakeDetermineCXXCompiler )
include ( CMakeDetermineCCompiler )
include ( CMakeDetermineFortranCompiler )
include ( CMakeTestFortranCompiler )
include ( CheckIncludeFile )
include ( CMakeFortranCompiler )

if ( USE_BISON )
  find_package ( BISON REQUIRED )
endif ( USE_BISON )
if ( USE_FLEX )
  find_package ( FLEX REQUIRED )
endif ( USE_FLEX )

find_package ( BLAS )
find_package ( LAPACK )
find_package ( Doxygen )
find_package ( LibXml2 )
find_package ( Threads )
find_package ( Libdl )
find_package ( Regex )
find_package ( R COMPONENTS base rotRPackage REQUIRED )

find_program ( BC_EXECUTABLE
               NAMES bc
	       DOC "Path to the system bc command"
	     )
mark_as_advanced ( BC_EXECUTABLE )
find_program ( RM_EXECUTABLE
               NAMES rm rem del delete
	       DOC "Path to the system remove command"
	     )
mark_as_advanced ( RM_EXECUTABLE )
check_include_file ( arpa/inet.h   HAVE_ARPA_INET_H   )
check_include_file ( assert.h      HAVE_ASSERT_H      )
check_include_file ( dirent.h      HAVE_DIRENT_H      )
check_include_file ( errno.h       HAVE_ERRNO_H       )
check_include_file ( inttypes.h    HAVE_INTTYPES_H    )
check_include_file ( math.h        HAVE_MATH_H        )
check_include_file ( netdb.h       HAVE_NETDB_H       )
check_include_file ( netinet/in.h  HAVE_NETINET_IN_H  )
check_include_file ( netinet/tcp.h HAVE_NETINET_TCP_H )
check_include_file ( pthread.h     HAVE_PTHREAD_H     )
check_include_file ( regex.h       HAVE_REGEX_H       )
check_include_file ( semaphore.h   HAVE_SEMAPHORE_H   )
check_include_file ( signal.h      HAVE_SIGNAL_H      )
check_include_file ( stdbool.h     HAVE_STDBOOL_H     )
check_include_file ( stdint.h      HAVE_STDINT_H      )
check_include_file ( stdlib.h      HAVE_STDLIB_H      )
check_include_file ( string.h      HAVE_STRING_H      )
check_include_file ( strings.h     HAVE_STRINGS_H     )
check_include_file ( sys/socket.h  HAVE_SYS_SOCKET_H  )
check_include_file ( sys/stat.h    HAVE_SYS_STAT_H    )
check_include_file ( sys/time.h    HAVE_SYS_TIME_H    )
check_include_file ( sys/types.h   HAVE_SYS_TYPES_H   )
check_include_file ( sys/un.h      HAVE_SYS_UN_H      )
check_include_file ( unistd.h      HAVE_UNISTD_H      )


# Some useful macros to ease CMakeLists.txt file writing
set ( SOURCEFILES "" CACHE INTERNAL "List of source files to compile" )
macro ( ot_add_source_file FILENAME )
  set ( sf ${SOURCEFILES} ${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME} )
  set ( SOURCEFILES ${sf} CACHE INTERNAL "List of source files to compile" )
endmacro ( ot_add_source_file )

set ( BUILT_SOURCEFILES "" CACHE INTERNAL "List of source files to compile" )
macro ( ot_add_built_source_file FILENAME )
  set ( sf ${BUILT_SOURCEFILES} ${FILENAME} )
  set ( BUILT_SOURCEFILES ${sf} CACHE INTERNAL "List of built source files to compile" )
endmacro ( ot_add_built_source_file )

set ( HEADERFILES "" CACHE INTERNAL "List of header files to install" )
macro ( ot_install_header_file FILENAME )
  set ( hf ${HEADERFILES} ${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME} )
  set ( HEADERFILES ${hf} CACHE INTERNAL "List of header files to install" )
endmacro ( ot_install_header_file )

set ( SWIGFILES "" CACHE INTERNAL "List of SWIG files to install" )
macro ( ot_install_swig_file FILENAME )
  set ( hf ${SWIGFILES} ${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME} )
  set ( SWIGFILES ${hf} CACHE INTERNAL "List of SWIG files to install" )
endmacro ( ot_install_swig_file )

set ( INTERNAL_INCLUDE_DIRS "" CACHE INTERNAL "List of directories with header files needed for build" )
macro ( ot_add_current_dir_to_include_dirs )
  set ( inc_dirs ${INTERNAL_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR} )
  set ( INTERNAL_INCLUDE_DIRS ${inc_dirs} CACHE INTERNAL "List of directories with header files needed for build" )
endmacro ( ot_add_current_dir_to_include_dirs )
macro ( ot_add_build_dir_to_include_dirs DIR )
  set ( inc_dirs ${INTERNAL_INCLUDE_DIRS} ${DIR} )
  set ( INTERNAL_INCLUDE_DIRS ${inc_dirs} CACHE INTERNAL "List of directories with header files needed for build" )
endmacro ( ot_add_build_dir_to_include_dirs )


# Add definitions according to the prerequisites found
add_definitions ( -DHAVE_CONFIG_H )
if ( LIBXML2_FOUND )
  set ( HAVE_LIBXML2 TRUE )
  add_definitions ( ${LIBXML2_DEFINITIONS} )
  #include_directories ( ${LIBXML2_INCLUDE_DIR} )
  ot_add_build_dir_to_include_dirs ( ${LIBXML2_INCLUDE_DIR} )
  set ( OPENTURNS_DEFINITIONS ${OPENTURNS_DEFINITIONS} ${LIBXML2_DEFINITIONS} )
  set ( OPENTURNS_INCLUDE     ${OPENTURNS_INCLUDE}     ${LIBXML2_INCLUDE_DIR} )
endif ( LIBXML2_FOUND )


if ( Threads_FOUND )
  add_definitions ( -pthread )
endif ( Threads_FOUND )

if ( LIBDL_FOUND )
  set ( HAVE_LIBDL TRUE )
  include_directories ( ${LIBDL_INCLUDE_DIR} )
endif ( LIBDL_FOUND )

if ( REGEX_FOUND )
  set ( HAVE_REGEX TRUE )
  include_directories ( ${REGEX_INCLUDE_DIR} )
endif ( REGEX_FOUND )

set ( CPACK_PACKAGE_NAME          openturns      )
set ( CPACK_PACKAGE_VERSION_MAJOR 0              )
set ( CPACK_PACKAGE_VERSION_MINOR 15             )
set ( CPACK_PACKAGE_VERSION_PATCH   )
set ( CPACK_SOURCE_GENERATOR      "TGZ;TBZ2"     )
set ( CPACK_BINARY_STGZ           "OFF")
set ( CPACK_BINARY_TBZ2           "ON")
set ( CPACK_BINARY_TGZ            "ON")
set ( CPACK_BINARY_TZ             "OFF")
#set ( CPACK_INSTALL_CMAKE_PROJECTS "lib;OpenTURNSLib;ALL;/" "python;OpenTURNSPython;ALL;/" )

# Set global definitions
# TODO: remove PACKAGE_<XX> from source code. Needed for compatibility with autotools
set ( PACKAGE_NAME           ${CPACK_PACKAGE_NAME} )
set ( PACKAGE_VERSION        ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR} )
if ( CPACK_PACKAGE_VERSION_PATCH )
  set ( PACKAGE_VERSION       ${PACKAGE_VERSION}.${CPACK_PACKAGE_VERSION_PATCH} )
endif ( CPACK_PACKAGE_VERSION_PATCH )
set ( PACKAGE_BUGREPORT      bugs@openturns.org )
set ( OPENTURNS_HOME_ENV_VAR OPENTURNS_HOME     )
set ( OPENTURNS_INSTALL_PATH
      ${CMAKE_INSTALL_PREFIX}
      CACHE PATH "The directory where Open TURNS is installed"
    )
set ( OPENTURNS_LIBRARY_PATH
      ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}/openturns
      CACHE PATH "The directory where the library is installed"
    )
set ( OPENTURNS_INCLUDE_PATH
      ${CMAKE_INSTALL_PREFIX}/include/openturns
      CACHE PATH "The directory where the header files are installed"
    )
set ( OPENTURNS_SYSCONFIG_PATH
      ${CMAKE_INSTALL_PREFIX}/etc
      CACHE PATH "The directory where the configuration file is installed"
    )
set ( OPENTURNS_DATA_PATH
      ${CMAKE_INSTALL_PREFIX}/share
      CACHE PATH "The directory where the common files are installed"
    )
set ( OPENTURNS_WRAPPER_PATH
      ${OPENTURNS_LIBRARY_PATH}/wrappers
      CACHE PATH "The directory where the wrapper files are installed"
    )
set ( OPENTURNS_EXAMPLE_PATH
      ${CMAKE_INSTALL_PREFIX}/share/openturns/examples
      CACHE PATH "The directory where the example files are installed"
    )
set ( OPENTURNS_SAMPLE_PATH
      ${CMAKE_INSTALL_PREFIX}/share/openturns/examples
      CACHE PATH "The directory where the sample files are installed"
    )
set ( OPENTURNS_DOC_PATH
      ${CMAKE_INSTALL_PREFIX}/share/openturns/doc
      CACHE PATH "The directory where the license files are installed"
    )
set ( OPENTURNS_TEMPDIR "/tmp" CACHE PATH "The directory for temporary files. /tmp by default." )

foreach ( _var INSTALL_PATH LIBRARY_PATH INCLUDE_PATH SYSCONFIG_PATH DATA_PATH WRAPPER_PATH EXAMPLE_PATH SAMPLE_PATH DOC_PATH TEMPDIR )
  set ( ${_var} ${OPENTURNS_${_var}} )
endforeach ( _var )

# Selectively add or remove RPATH from executable
set ( OPENTURNS_SYSTEM_INSTALL OFF CACHE BOOL "True if Open TURNS is installed in a system directory. RPATH removed. False by default." )
if ( NOT OPENTURNS_SYSTEM_INSTALL )
  set ( CMAKE_INSTALL_RPATH ${OPENTURNS_LIBRARY_PATH}
                            ${CMAKE_Fortran_IMPLICIT_LINK_DIRECTORIES}
      )
  set ( CMAKE_BUILD_WITH_INSTALL_RPATH    TRUE )
  set ( CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE )
endif ( NOT OPENTURNS_SYSTEM_INSTALL )


# The tests can't be run if this function is absent
enable_testing ()
add_custom_target ( check COMMENT "Run pre-installation tests" )
add_custom_target ( installcheck COMMENT "Run post-installation tests" )

# Recurse in subdirectories
add_subdirectory ( utils )
add_subdirectory ( wrappers )

add_definitions ( -fPIC -DPIC )


set ( OPENTURNS_BUILD_LIB ON CACHE BOOL "Build the library" )
if ( OPENTURNS_BUILD_LIB )
  add_subdirectory ( lib )
  add_dependencies ( check cppcheck )
  add_dependencies ( installcheck cppinstallcheck )
endif ( OPENTURNS_BUILD_LIB )


set ( OPENTURNS_BUILD_PYTHON ON CACHE BOOL "Build the python module for the library" )
if ( OPENTURNS_BUILD_PYTHON )
  find_package ( SWIG REQUIRED )
  include ( ${SWIG_USE_FILE} )
  mark_as_advanced ( SWIG_VERSION SWIG_DIR )
  if ( SWIG_FOUND )
    message ( STATUS "Found SWIG version ${SWIG_VERSION} : ${SWIG_EXECUTABLE}" )
  endif ( SWIG_FOUND )
  find_package ( PythonInterp REQUIRED )
  find_package ( PythonLibs REQUIRED )

  if ( PYTHONINTERP_FOUND )
    string ( RANDOM tmpPyScript )
    set ( tmpPyScript "${tmpPyScript}.py" )
    file ( WRITE  ${tmpPyScript}
"# Automaticaly generated by CMake. Do NOT edit. Changes will be lost
import sys
print '%d.%d' % ( sys.version_info[0], sys.version_info[1] )
" )
    get_source_file_property ( PYSCRIPT_LOC ${tmpPyScript} LOCATION )
    execute_process ( COMMAND ${PYTHON_EXECUTABLE} ${PYSCRIPT_LOC}
                      OUTPUT_VARIABLE PYTHON_VERSION
                      #ERROR_QUIET
                      OUTPUT_STRIP_TRAILING_WHITESPACE )
    file ( REMOVE ${tmpPyScript} )

    set ( OPENTURNS_PYTHON_MODULE_PATH
          ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}/python${PYTHON_VERSION}/site-packages
          CACHE PATH "The directory where the python modules are installed"
        )
    set ( PYTHON_MODULE_PATH ${OPENTURNS_PYTHON_MODULE_PATH} )

  endif ( PYTHONINTERP_FOUND )

  add_subdirectory ( python )

  add_dependencies ( installcheck pyinstallcheck )

endif ( OPENTURNS_BUILD_PYTHON )


set ( OPENTURNS_BUILD_VALIDATION ON CACHE BOOL "Build the validation files of the library" )
if ( OPENTURNS_BUILD_VALIDATION )
  add_subdirectory ( validation )
endif ( OPENTURNS_BUILD_VALIDATION )

include ( CPack )
