# $Id: a3ad2e3a9ae71b3bc393ca9a3f1ab2277f171d35 $

cmake_minimum_required (VERSION 2.6)
project (GeographicLib)

# Version information
set (GeographicLib_VERSION_MAJOR 1)
set (GeographicLib_VERSION_MINOR 21)
set (GeographicLib_VERSION
     "${GeographicLib_VERSION_MAJOR}.${GeographicLib_VERSION_MINOR}")
# The library version tracks the numbering given by libtool in the
# autoconf set up.
set (LIBVERSION 9)
set (LIBVERSIONFULL 9.3.0)

# Set CMAKE_INSTALL_PREFIX from first element of CMAKE_PREFIX_PATH
if (WIN32)
  if (DEFINED CMAKE_PREFIX_PATH
    AND CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
    list (GET CMAKE_PREFIX_PATH 0 CMAKE_INSTALL_PREFIX)
    set (CMAKE_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}
      CACHE PATH "Installation directory for GeographicLib" FORCE)
  endif ()
  message (STATUS "CMAKE_INSTALL_PREFIX set to ${CMAKE_INSTALL_PREFIX}")
endif ()

# User-settable cache variables

# (1) Build as a shared library?  On Windows systems, this is typically
# more trouble than it's worth.
if (WIN32)
  option (GEOGRAPHIC_SHARED_LIB "Build GeographicLib as a shared library" OFF)
else ()
  option (GEOGRAPHIC_SHARED_LIB "Build GeographicLib as a shared library" ON)
endif ()

# (2) Compiler the Matlab interfaces?  Skip Matlab compilation if OFF
option (MATLAB_COMPILER
  "Compiler for matlab/octave interface: mex or mkoctfile or OFF" OFF)

# (3) Where to look for data files.  Various classes look in the geoids,
# gravity, magnetic, subdirectories of ${GEOGRAPHICLIB_DATA}.
if (WIN32)
  # The binary installers for the data files for Windows are created
  # with Inno Setup which uses {commonappdata}.  On most Windows
  # systems this is
  # "C:/Documents and Settings/All Users/Application Data", while on
  # newer systems (Windows 7), it is C:/ProgramData.  However the
  # longer name "works" on all Windows systems.
  set (GEOGRAPHICLIB_DATA
    "C:/Documents and Settings/All Users/Application Data/GeographicLib"
    CACHE PATH "Location for data for GeographicLib")
else ()
  set (GEOGRAPHICLIB_DATA
    "${CMAKE_INSTALL_PREFIX}/share/GeographicLib"
    CACHE PATH "Location for data for GeographicLib")
endif ()

# (4) Compiler the Matlab interfaces?  Skip Matlab compilation if OFF
if (WIN32)
  option (GEOGRAPHICLIB_EXAMPLES
    "Build example programs in examples directory" OFF)
elseif ()
  option (GEOGRAPHICLIB_EXAMPLES
    "Build example programs in examples directory" ON)
endif ()

# The debug version of the library is called Geographic_d.
set (CMAKE_DEBUG_POSTFIX _d)

# Determine system properties
include (CheckTypeSize)
check_type_size ("long double" LONG_DOUBLE BUILTIN_TYPES_ONLY)
include (TestBigEndian)
test_big_endian (WORDS_BIGENDIAN)

# Create a Config.h to expose system information to the compiler
configure_file (
    "${PROJECT_SOURCE_DIR}/include/GeographicLib/Config.h.in"
    "${PROJECT_BINARY_DIR}/include/GeographicLib/Config.h" )

# The documentation depends on doxygen.  In addition, the man pages are
# written as pod files and converted to nroff format, C++ code, and
# html.  Because this require tools that may not be available on an
# end-user's system, the creation of the final documentation is
# therefore only done in "MAINTAINER" mode.  The maintainer runs "make
# distrib-all" which installs the transformed documentation files into
# the source tree.
if (NOT WIN32)
  set (DOXYGEN_SKIP_DOT ON)
  find_package (Doxygen)
  find_program (HAVE_POD2MAN pod2man)
  find_program (HAVE_POD2HTML pod2html)
  find_program (HAVE_DOXYGEN doxygen)
endif ()
if (NOT WIN32 AND HAVE_POD2MAN AND HAVE_POD2HTML AND DOXYGEN_FOUND)
  set (MAINTAINER ON CACHE BOOL "Allow build of additional components")
else ()
  set (MAINTAINER OFF CACHE BOOL "Allow build of additional components")
endif ()
if (MAINTAINER)
  add_custom_target (distrib-all)
  add_dependencies (distrib-all distrib-man distrib-doc)
endif ()

# Look for the tool to compile the Matlab interfaces.
if (MATLAB_COMPILER)
  if (WIN32)
    set (MATLAB_COMPILER_EXT ".bat")
  else ()
    set (MATLAB_COMPILER_EXT "")
  endif ()
  find_program (MEX "${MATLAB_COMPILER}${MATLAB_COMPILER_EXT}")
  if (MATLAB_COMPILER MATCHES "mex")
    get_filename_component (MATLABDIR "${MEX}" REALPATH)
    get_filename_component (MATLABDIR "${MATLABDIR}" PATH)
    find_program (MEXEXTPROG "mexext${MATLAB_COMPILER_EXT}"
      PATHS "${MATLABDIR}")
    execute_process (COMMAND "${MEXEXTPROG}"
      OUTPUT_VARIABLE MEXEXT OUTPUT_STRIP_TRAILING_WHITESPACE)
  else ()
    set (MEXEXT "mex")
  endif ()
  if (NOT MEX)
    message (WARNING
      "Cannot find Matlab compiler ${MATLAB_COMPILER}${MATLAB_COMPILER_EXT}")
  elseif (NOT MEXEXT)
    set (MEX OFF)
    message (WARNING "Cannot determine extension for Matlab compiled code")
  endif ()
endif ()

# Set a default build type for single-configuration cmake generators if
# no build type is set.
if (NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
  set (CMAKE_BUILD_TYPE Release)
endif ()

# On non-Windows machine, make the compiler more picky.
if (NOT WIN32)
  set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
endif ()

# The list of tools (to be installed into, e.g., /usr/local/bin)
set (TOOLS CartConvert ConicProj GeodesicProj GeoConvert Geod
  GeoidEval Gravity MagneticField Planimeter TransverseMercatorProj)
# The list of scripts (to be installed into, e.g., /usr/local/sbin)
set (SCRIPTS
  geographiclib-get-geoids geographiclib-get-gravity geographiclib-get-magnetic)

# Set the include directories.  Look in ${PROJECT_BINARY_DIR}/include
# first because that's where Config.h will be
include_directories ("${PROJECT_BINARY_DIR}/include")
include_directories (include)

# The list of subdirectories to process
add_subdirectory (src)
add_subdirectory (include/GeographicLib)
add_subdirectory (tools)
add_subdirectory (man)
add_subdirectory (doc)
add_subdirectory (matlab)
add_subdirectory (python/geographiclib)
if (GEOGRAPHICLIB_EXAMPLES)
  add_subdirectory (examples)
endif ()

# config file support for find_package(GeographicLib).  This only
# supports finding GeographicLib in the "install" tree (as opposed to
# the "build" tree).  The process installs geographiclib-config.cmake in
# ${INSTALL_CMAKE_DIR} and @GEOGRAPHICLIB_ROOT_DIR@ is the relative path
# to the root from there.  (Thus the whole install tree can be
# relocated.)
if (WIN32)
  set (INSTALL_CMAKE_DIR "cmake")
  set (GEOGRAPHICLIB_ROOT_DIR "..")
else ()
  set (INSTALL_CMAKE_DIR
    "share/cmake/${PROJECT_NAME}-${GeographicLib_VERSION}")
  set (GEOGRAPHICLIB_ROOT_DIR "../../..")
endif ()
configure_file (cmake/geographiclib-config.cmake.in
  "${PROJECT_BINARY_DIR}/cmake/geographiclib-config.cmake" @ONLY)
configure_file (cmake/geographiclib-config-version.cmake.in
  "${PROJECT_BINARY_DIR}/cmake/geographiclib-config-version.cmake" @ONLY)
install (FILES
  "${PROJECT_BINARY_DIR}/cmake/geographiclib-config.cmake"
  "${PROJECT_BINARY_DIR}/cmake/geographiclib-config-version.cmake"
  DESTINATION "${INSTALL_CMAKE_DIR}")

# Make information about the cmake targets (the library and the tools)
# available.
install (EXPORT depends
  FILE geographiclib-depends.cmake
  DESTINATION "${INSTALL_CMAKE_DIR}")

# Packaging support; we deal with 
# (1) a source distribution: cmake make a tar.gz file and the zip file
# is created from this.  Only the maintainer can do this, because of
# the need to generate additional documentation files.
# (2) a binary distribution: code is included for Linux, Apple, and
# Windows, but only the Windows distribution has been exercised.

# Need to ensure that system dlls get included in a binary distribution
if (NOT DEFINED CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS)
  # Visual Studio Express does include redistributable components so
  # squelch the warning.
  set (CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS ON)
endif ()
include (InstallRequiredSystemLibraries)

# The configuration of CPack is via variable that need to be set before
# the include (CPack).
set (CPACK_PACKAGE_VERSION_MAJOR ${GeographicLib_VERSION_MAJOR})
set (CPACK_PACKAGE_VERSION_MINOR ${GeographicLib_VERSION_MINOR})
set (CPACK_PACKAGE_VERSION_PATCH 0)
set (CPACK_PACKAGE_CONTACT charles@karney.com)
set (CPACK_PACKAGE_VENDOR "GeographicLib")
set (CPACK_PACKAGE_DESCRIPTION_SUMMARY
  "Geographic library, utilities, and documentation")
# The list of files to be excluded from the source distribution.
set (CPACK_SOURCE_IGNORE_FILES
  "#"
  "~\$"
  "/\\\\.git"
  "${PROJECT_SOURCE_DIR}/BUILD"
  "${PROJECT_SOURCE_DIR}/(tests|testdata|cgi-bin|.*\\\\.cache)/"
  "${PROJECT_SOURCE_DIR}/(distrib|.*-distrib|.*-installer|geodesic-papers)/"
  "${PROJECT_SOURCE_DIR}/[^/]*\\\\.(html|kmz)\$"
  "${PROJECT_SOURCE_DIR}/(autogen|biblio|js-compress)\\\\.sh\$"
  "${PROJECT_SOURCE_DIR}/(geodesic-biblio.txt|makefile-admin)\$" )
set (CPACK_SOURCE_GENERATOR TGZ)

set (CPACK_RESOURCE_FILE_LICENSE ${PROJECT_SOURCE_DIR}/LICENSE.txt)
set (CPACK_PACKAGE_INSTALL_DIRECTORY
  "${PROJECT_NAME}-${GeographicLib_VERSION}")
set (CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY}")

if (WIN32)
  # The Windows binary packager is NSIS.  Set the necessary variables
  # for this.
  set (CPACK_NSIS_CONTACT "charles@karney.com")
  set (CPACK_NSIS_URL_INFO_ABOUT "http://geographiclib.sf.net")
  set (CPACK_NSIS_HELP_LINK "mailto:charles@karney.com")
  if (CMAKE_SIZEOF_VOID_P EQUAL 8)
    # Hardcode the prefix for Visual Studio 10
    set (CPACK_NSIS_INSTALL_ROOT "C:\\\\pkg-vc10-x64")
    set (CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY}-win64")
    set (CPACK_NSIS_PACKAGE_NAME
      "${PROJECT_NAME} x64 ${GeographicLib_VERSION}")
    set (CPACK_PACKAGE_INSTALL_REGISTRY_KEY
      "${PROJECT_NAME}-x64-${GeographicLib_VERSION}")
  else ()
    # Hardcode the prefix for Visual Studio 10
    set (CPACK_NSIS_INSTALL_ROOT "C:\\\\pkg-vc10")
    set (CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY}-win32")
    set (CPACK_NSIS_PACKAGE_NAME
      "${PROJECT_NAME} ${GeographicLib_VERSION}")
    set (CPACK_PACKAGE_INSTALL_REGISTRY_KEY
      "${PROJECT_NAME}-${GeographicLib_VERSION}")
  endif ()
  set (CPACK_NSIS_DISPLAY_NAME ${CPACK_NSIS_PACKAGE_NAME})
  set (CPACK_NSIS_EXTRA_INSTALL_COMMANDS "
  CreateShortCut \\\"$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Library Documentation.lnk\\\" \\\"$INSTDIR\\\\share\\\\doc\\\\GeographicLib\\\\html\\\\index.html\\\"
  CreateShortCut \\\"$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Utility Documentation.lnk\\\" \\\"$INSTDIR\\\\share\\\\doc\\\\GeographicLib\\\\html\\\\utilities.html\\\"
")
  set (CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS "
  !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP
  Delete \\\"$SMPROGRAMS\\\\$MUI_TEMP\\\\Library Documentation.lnk\\\"
  Delete \\\"$SMPROGRAMS\\\\$MUI_TEMP\\\\Utility Documentation.lnk\\\"
")
  set (CPACK_NSIS_MODIFY_PATH ON)
elseif (APPLE)
  # Not tested
  set (CPACK_GENERATOR DMG)
  set (CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY}-darwin")
else ()
  # Not tested
  set (CPACK_GENERATOR TGZ)
endif ()

include (CPack)

# Another maintainer-specific target is building the source distribution
# via the target dist.  This calls package_source to make a tar.gz file.
# However this needs to be touched up to support the vanilla Makefiles
# provided with GeographicLib.  This entails
# (1) creating Makefile (which includes Makefile.mk);
# (2) creating a bare-bones Config.h (with just the version information);
# (3) making sure that make thinks the generated documentation files are
# up-to-date.
# Then a new tar.gz file and zip file are created.  To avoid potential
# problems with directory permissions, tar and zip are told only to
# archive the files.
if (MAINTAINER)
  add_custom_target (dist
    COMMAND ${CMAKE_MAKE_PROGRAM} package_source
    COMMAND
      cd _CPack_Packages/Linux-Source/TGZ/${CPACK_SOURCE_PACKAGE_FILE_NAME} &&
      echo include Makefile.mk > Makefile &&
      echo "\\#define" GEOGRAPHICLIB_VERSION_STRING
      \\"${GeographicLib_VERSION}\\" > include/GeographicLib/Config.h
    COMMAND
      cd _CPack_Packages/Linux-Source/TGZ/${CPACK_SOURCE_PACKAGE_FILE_NAME} &&
      touch man/*.usage man/*.1 man/*.1.html && touch doc/html/index.html
    COMMAND
      cd _CPack_Packages/Linux-Source/TGZ &&
      find ${CPACK_SOURCE_PACKAGE_FILE_NAME} -type f |
      tar cfzT ${CMAKE_BINARY_DIR}/${CPACK_SOURCE_PACKAGE_FILE_NAME}.tar.gz -
    COMMAND
      rm -f ${CPACK_SOURCE_PACKAGE_FILE_NAME}.zip &&
      cd _CPack_Packages/Linux-Source/TGZ &&
      find ${CPACK_SOURCE_PACKAGE_FILE_NAME} -type f |
      zip -q ${CMAKE_BINARY_DIR}/${CPACK_SOURCE_PACKAGE_FILE_NAME}.zip -@
  )
  add_dependencies (dist distrib-all)
endif ()

# Add a test target; the tests are in tools.
enable_testing ()
