# This file is part of the Owl Positioning System (OwlPS) project.
# It is subject to the copyright notice and license terms in the
# COPYRIGHT.t2t file found in the top-level directory of this
# distribution and at
#   https://code.lm7.fr/mcy/owlps/src/master/COPYRIGHT.t2t
# No part of the OwlPS Project, including this file, may be copied,
# modified, propagated, or distributed except according to the terms
# contained in the COPYRIGHT.t2t file; the COPYRIGHT.t2t file must be
# distributed along with this file, either separately or by replacing
# this notice by the COPYRIGHT.t2t file's contents.

cmake_minimum_required(VERSION 2.8)

project(OwlPS)


### Build paths ###

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")

# Path for the generated header files
set(GENERATED_INCLUDE "${PROJECT_BINARY_DIR}/include")
include_directories("${GENERATED_INCLUDE}")


### Dependencies ###
# Note: we test here the dependencies relevant for more than one module;
# other tests are done in each module's directory.

# Add cmake/Modules to the molude path so that CMake can find the
# additional FindXXX modules we (unfortunately have to) ship
set(CMAKE_MODULE_PATH
  ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules")

# Check if we've got POSIX threads
set(CMAKE_THREAD_PREFER_PTHREAD on)
find_package(Threads)
if (CMAKE_THREAD_LIBS_INIT AND CMAKE_USE_PTHREADS_INIT)
  set(HAVE_PTHREADS true)
endif()

# Check if we've got the Confuse library
find_package(Confuse)

# Check if Doxygen is available
find_package(Doxygen)


### OwlPS' version ###

# First, try to get it from the environment variable OWLPS_VERSION
if (NOT "$ENV{OWLPS_VERSION}" STREQUAL "")
  add_definitions(-DOWLPS_VERSION="$ENV{OWLPS_VERSION}")

# Environment variable OWLPS_VERSION not set: try to get the version
# number from git describe
else()
  execute_process(
    COMMAND git describe
    WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
    RESULT_VARIABLE RET
    OUTPUT_VARIABLE OWLPS_VERSION
    ERROR_QUIET
    OUTPUT_STRIP_TRAILING_WHITESPACE)
  if (${RET} EQUAL 0)
    add_definitions(-DOWLPS_VERSION="${OWLPS_VERSION}")
  else()
    add_definitions(-DOWLPS_VERSION="unknown version")
  endif()
endif()


### Options ###

# Configurations
set(CMAKE_CONFIGURATION_TYPES
  Debug Release RelWithDebInfo MinSizeRel
  CACHE STRING "Set the configurations" FORCE)
# Default configuration
if (NOT CMAKE_BUILD_TYPE)
  set(CMAKE_BUILD_TYPE RelWithDebInfo
    CACHE STRING "Set the default configuration" FORCE)
endif()


### Flags ###

# Specific compiler flags
# These variables are to be used (manually) when compiling a shared
# library or an executable (or static library).
set(SHARED_FLAGS "-fPIC")
set(EXE_FLAGS "-fPIE")

# Common compiler flags
set(C_CXX_COMMON_FLAGS "-Wall -Wextra")
set(C_FLAGS "${C_CXX_COMMON_FLAGS} -Wstrict-prototypes")
set(CXX_FLAGS "${C_CXX_COMMON_FLAGS}")

if (NOT CMAKE_C_FLAGS)
  set(CMAKE_C_FLAGS ${C_FLAGS}
    CACHE STRING "Set default C flags" FORCE)
endif()

if (NOT CMAKE_CXX_FLAGS)
  set(CMAKE_CXX_FLAGS ${CXX_FLAGS}
    CACHE STRING "Set default C++ flags" FORCE)
endif()

# Linker flags
# Question: why the hell does CMAKE_SHARED_LINKER_FLAGS contain " "
#           by default?!
if ("${CMAKE_SHARED_LINKER_FLAGS}" STREQUAL " ")
  set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--no-undefined"
    CACHE STRING "Set default shared linker flags" FORCE)
endif()

# Linker flags when linking an executable
# Note: -fpie prevents from building static executables, therefore it
#       has been deactivated, but it would be nice to find a work-around
#       to allow building dynamic (and semistatic) targets with -pie and
#       static ones without.
#if ("${CMAKE_EXE_LINKER_FLAGS}" STREQUAL " ")
#  set(CMAKE_EXE_LINKER_FLAGS "-pie -fPIE"
#    CACHE STRING "Set default shared linker flags" FORCE)
#endif()


### Libraries targets ###

add_subdirectory(libowlps)
include_directories(libowlps)

add_subdirectory(libowlps-client)
include_directories(libowlps-client)

add_subdirectory(libowlps-resultreader)
include_directories(libowlps-resultreader)


### Programs targets ###

## Aggregator ##

if (HAVE_PTHREADS AND CONFUSE_FOUND)
  add_subdirectory(owlps-aggregator)

else() # Warn the user about missing dependencies
  if (NOT HAVE_PTHREADS)
    message(WARNING
      "OwlPS Aggregator dependency missing: POSIX threads")
  endif()
  if (NOT CONFUSE_FOUND)
    message(WARNING
      "OwlPS Aggregator dependency missing: libConfuse")
  endif()
endif()

## Client ##

add_subdirectory(owlps-client)

## Listener ##

add_subdirectory(owlps-listener)

## Positioner ##

# OwlPS Positioner can be built only with a minimal version of GCC, or
# Clang++. CMAKE_CXX_COMPILER_VERSION is not guaranteed to be set, so we
# will test the version number only if possible.
set(POSITIONER_MIN_GCC_VERSION 4.7)
set(POSITIONER_MIN_CLANG_VERSION 3.2)

if (CMAKE_CXX_COMPILER_ID STREQUAL GNU) # Are we using GCC?
  # Test the compiler version if we can
  if (${CMAKE_CXX_COMPILER_VERSION} AND
      ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS ${POSITIONER_MIN_GCC_VERSION})
    # GCC's version is too low
    message(WARNING
      "OwlPS Positioner requires GCC (g++) >= ${POSITIONER_MIN_GCC_VERSION}")
  else()
    # GCC's version is OK or we couldn'd get it
    add_subdirectory(owlps-positioner)
  endif()

elseif (CMAKE_CXX_COMPILER_ID STREQUAL Clang) # Are we using Clang?
  if (${CMAKE_CXX_COMPILER_VERSION} AND
      ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS ${POSITIONER_MIN_CLANG_VERSION})
    # Clang's version is too low
    message(WARNING
      "OwlPS Positioner requires GCC >= ${POSITIONER_MIN_GCC_VERSION}")
  else()
    # Clang's version is OK or we couldn'd get it
    add_subdirectory(owlps-positioner)
  endif()

else() # we're not using GCC
  message(WARNING
    "OwlPS Positioner requires GCC (>= ${POSITIONER_MIN_GCC_VERSION}) or Clang (>= ${POSITIONER_MIN_CLANG_VERSION})")
endif()

## UDP-to-HTTP ##

if (HAVE_PTHREADS)
  add_subdirectory(owlps-udp-to-http)

else() # Warn the user about missing dependencies
  message(WARNING
    "OwlPS UDP-to-HTTP dependency missing: POSIX threads")
endif()

## Scripts ##

add_subdirectory(scripts)


### Documentation ###

add_subdirectory(doc)


### Meta-targets ###

# The OWLPS_SEMISTATIC_TARGET is defined in subdirectories
add_custom_target(semistatic DEPENDS ${OWLPS_SEMISTATIC_TARGETS})

# The OWLPS_STATIC_TARGET is defined in subdirectories
add_custom_target(static DEPENDS ${OWLPS_STATIC_TARGETS})



### Tests ###

add_custom_target(tests
  COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test_positioner
  DEPENDS test_positioner)
