cmake_minimum_required(VERSION 3.10)

project(
  libvori
  VERSION 0.1
  LANGUAGES CXX)

# Set a default build type if none was specified
set(DEFAULT_BUILD_TYPE "RelWithDebInfo")

if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
  message(
    STATUS
      "Setting build type to '${DEFAULT_BUILD_TYPE}' as none was specified.")
  set(CMAKE_BUILD_TYPE
      "${DEFAULT_BUILD_TYPE}"
      CACHE STRING "Choose the type of build." FORCE)
  # Set the possible values of build type for cmake-gui
  set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
                                               "MinSizeRel" "RelWithDebInfo")
endif()

add_library(
  voriobjs OBJECT
  src/bqb_alphabet.cpp
  src/bqb_bitset.cpp
  src/bqb_crc.cpp
  src/bqb_cubeframe.cpp
  src/bqb_driver.cpp
  src/bqb_engine.cpp
  src/bqb_examples.cpp
  src/bqb_extrapolator.cpp
  src/bqb_format.cpp
  src/bqb_hilbert.cpp
  src/bqb_hufftree.cpp
  src/bqb_integerengine.cpp
  src/bqb_interface.cpp
  src/bqb_largeinteger.cpp
  src/bqb_linalg.cpp
  src/bqb_math.cpp
  src/bqb_parmset.cpp
  src/bqb_tools.cpp
  src/elementdata.cpp
  src/snapshot.cpp
  src/tetrapak.cpp
  src/tools.cpp
  src/xdmatrix3.cpp
  src/xdvec3array.cpp
  src/xdvector3.cpp)

add_library(
  voroppobjs OBJECT
  src/v_base.cpp
  src/v_base_wl.cpp
  src/v_cell.cpp
  src/v_common.cpp
  src/v_compute.cpp
  src/v_container.cpp
  src/v_container_prd.cpp
  src/v_pre_container.cpp
  src/v_unitcell.cpp
  src/v_wall.cpp)

set(GCC_FLAGS -Wundef -Wall -Wextra -Wformat -Wformat-security -pedantic)
# the code originating from the Voro++ library breaks when vectorized, disable
# AVX on compilers which support -mavx
include(CheckCXXCompilerFlag)
check_cxx_compiler_flag(-mavx compiler_has_avx)
if(compiler_has_avx)
  set(VOROPP_EXTRA_FLAGS -mno-avx)
endif()

# The default RelWithDebInfo build type adds -g and -O2
target_compile_features(voriobjs PUBLIC cxx_std_11)
target_compile_options(
  voriobjs
  PRIVATE $<$<COMPILE_LANGUAGE:CXX>:$<$<CXX_COMPILER_ID:GNU>:${GCC_FLAGS}>>)

target_compile_features(voroppobjs PUBLIC cxx_std_11)
target_compile_options(
  voroppobjs
  PRIVATE $<$<COMPILE_LANGUAGE:CXX>:$<$<CXX_COMPILER_ID:GNU>:${GCC_FLAGS}>>
          $<$<COMPILE_LANGUAGE:CXX>:${VOROPP_EXTRA_FLAGS}>)

add_library(vori $<TARGET_OBJECTS:voriobjs> $<TARGET_OBJECTS:voroppobjs>
                 src/main.cpp)
target_compile_features(vori PUBLIC cxx_std_11)
target_compile_options(
  vori
  PRIVATE $<$<COMPILE_LANGUAGE:CXX>:$<$<CXX_COMPILER_ID:GNU>:${GCC_FLAGS}>>)

include(GNUInstallDirs)
install(TARGETS vori ARCHIVE DESTINATION lib)

if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
  include(CTest)
endif()

add_executable(test01 $<TARGET_OBJECTS:voriobjs> $<TARGET_OBJECTS:voroppobjs>
                      src/main.cpp)
target_compile_features(test01 PUBLIC cxx_std_11)
target_compile_options(
  test01
  PRIVATE $<$<COMPILE_LANGUAGE:CXX>:$<$<CXX_COMPILER_ID:GNU>:${GCC_FLAGS}>>)
target_compile_definitions(test01 PRIVATE TEST) # same source as the lib, but
                                                # with a -DTEST
add_test(NAME test01 COMMAND $<TARGET_NAME:test01>)
