############################################################################
# Copyright (c) Johan Mabille, Sylvain Corlay, Wolf Vollprecht and         #
# Martin Renou                                                             #
# Copyright (c) QuantStack                                                 #
# Copyright (c) Serge Guelton                                              #
#                                                                          #
# Distributed under the terms of the BSD 3-Clause License.                 #
#                                                                          #
# The full license is in the file LICENSE, distributed with this software. #
############################################################################

cmake_minimum_required(VERSION 3.1)
project(xsimd)
option(XSIMD_REFACTORING ON)

set(XSIMD_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)

# Versioning
# ==========

file(STRINGS "${XSIMD_INCLUDE_DIR}/xsimd/config/xsimd_config.hpp" xsimd_version_defines
     REGEX "#define XSIMD_VERSION_(MAJOR|MINOR|PATCH)")
foreach(ver ${xsimd_version_defines})
    if(ver MATCHES "#define XSIMD_VERSION_(MAJOR|MINOR|PATCH) +([^ ]+)$")
        set(XSIMD_VERSION_${CMAKE_MATCH_1} "${CMAKE_MATCH_2}" CACHE INTERNAL "")
    endif()
endforeach()
set(${PROJECT_NAME}_VERSION
    ${XSIMD_VERSION_MAJOR}.${XSIMD_VERSION_MINOR}.${XSIMD_VERSION_PATCH})
message(STATUS "xsimd v${${PROJECT_NAME}_VERSION}")

# Build
# =====

set(XSIMD_HEADERS
${XSIMD_INCLUDE_DIR}/xsimd/arch/xsimd_constants.hpp
${XSIMD_INCLUDE_DIR}/xsimd/arch/xsimd_fma3_avx.hpp
${XSIMD_INCLUDE_DIR}/xsimd/arch/xsimd_fma3_avx2.hpp
${XSIMD_INCLUDE_DIR}/xsimd/arch/xsimd_fma3_sse.hpp
${XSIMD_INCLUDE_DIR}/xsimd/arch/xsimd_fma4.hpp
${XSIMD_INCLUDE_DIR}/xsimd/arch/xsimd_generic.hpp
${XSIMD_INCLUDE_DIR}/xsimd/arch/xsimd_isa.hpp
${XSIMD_INCLUDE_DIR}/xsimd/arch/xsimd_neon.hpp
${XSIMD_INCLUDE_DIR}/xsimd/arch/xsimd_neon64.hpp
${XSIMD_INCLUDE_DIR}/xsimd/arch/xsimd_scalar.hpp
${XSIMD_INCLUDE_DIR}/xsimd/arch/xsimd_sse2.hpp
${XSIMD_INCLUDE_DIR}/xsimd/arch/xsimd_sse3.hpp
${XSIMD_INCLUDE_DIR}/xsimd/arch/xsimd_sse4_1.hpp
${XSIMD_INCLUDE_DIR}/xsimd/arch/xsimd_sse4_2.hpp
${XSIMD_INCLUDE_DIR}/xsimd/arch/xsimd_ssse3.hpp
${XSIMD_INCLUDE_DIR}/xsimd/arch/xsimd_sve.hpp
${XSIMD_INCLUDE_DIR}/xsimd/config/xsimd_arch.hpp
${XSIMD_INCLUDE_DIR}/xsimd/config/xsimd_config.hpp
${XSIMD_INCLUDE_DIR}/xsimd/config/xsimd_cpuid.hpp
${XSIMD_INCLUDE_DIR}/xsimd/memory/xsimd_aligned_allocator.hpp
${XSIMD_INCLUDE_DIR}/xsimd/memory/xsimd_alignment.hpp
${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_all_registers.hpp
${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_api.hpp
${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_neon_register.hpp
${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_neon64_register.hpp
${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_avx2_register.hpp
${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_avx512f_register.hpp
${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_avx_register.hpp
${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_batch.hpp
${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_batch_constant.hpp
${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_fma3_avx_register.hpp
${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_fma3_avx2_register.hpp
${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_fma3_sse_register.hpp
${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_fma4_register.hpp
${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_generic_arch.hpp
${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_register.hpp
${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_sse2_register.hpp
${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_sse3_register.hpp
${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_sse4_1_register.hpp
${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_sse4_2_register.hpp
${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_ssse3_register.hpp
${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_sve_register.hpp
${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_traits.hpp
${XSIMD_INCLUDE_DIR}/xsimd/types/xsimd_utils.hpp
${XSIMD_INCLUDE_DIR}/xsimd/xsimd.hpp
)

add_library(xsimd INTERFACE)

target_include_directories(xsimd INTERFACE
    $<BUILD_INTERFACE:${XSIMD_INCLUDE_DIR}>
    $<INSTALL_INTERFACE:include>)

if (ENABLE_XTL_COMPLEX)
    target_compile_features(xsimd INTERFACE cxx_std_14)
else()
    target_compile_features(xsimd INTERFACE cxx_std_11)
endif()

OPTION(ENABLE_XTL_COMPLEX "enables support for xcomplex defined in xtl" OFF)
OPTION(BUILD_TESTS "xsimd test suite" OFF)

if(ENABLE_XTL_COMPLEX)
    find_package(xtl 0.7.0 REQUIRED)
    target_compile_definitions(xsimd INTERFACE XSIMD_ENABLE_XTL_COMPLEX=1)
    target_link_libraries(xsimd INTERFACE xtl)
endif()

if(BUILD_TESTS)
    enable_testing()
    add_subdirectory(test)
endif()

OPTION(BUILD_BENCHMARK "xsimd benchmarks" OFF)
if(BUILD_BENCHMARK)
    add_subdirectory(benchmark)
endif()

OPTION(BUILD_EXAMPLES "xsimd examples" OFF)
if(BUILD_EXAMPLES)
    add_subdirectory(examples)
endif()

# Installation
# ============

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
include(JoinPaths)
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)

install(TARGETS xsimd
        EXPORT ${PROJECT_NAME}-targets)

# Makes the project importable from the build directory
export(EXPORT ${PROJECT_NAME}-targets
       FILE "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Targets.cmake")

install(DIRECTORY ${XSIMD_INCLUDE_DIR}/xsimd
        DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

# GNUInstallDirs "DATADIR" wrong here; CMake search path wants "share".
set(XSIMD_CMAKECONFIG_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" CACHE STRING "install path for xsimdConfig.cmake")

configure_package_config_file(${PROJECT_NAME}Config.cmake.in
                              "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
                              INSTALL_DESTINATION ${XSIMD_CMAKECONFIG_INSTALL_DIR})

# xsimd is header-only and does not depend on the architecture.
# Remove CMAKE_SIZEOF_VOID_P from xtensorConfigVersion.cmake so that an xtensorConfig.cmake
# generated for a 64 bit target can be used for 32 bit targets and vice versa.
set(_XTENSOR_CMAKE_SIZEOF_VOID_P ${CMAKE_SIZEOF_VOID_P})
unset(CMAKE_SIZEOF_VOID_P)
write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
                                 VERSION ${${PROJECT_NAME}_VERSION}
                                 COMPATIBILITY SameMajorVersion)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
              ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
        DESTINATION ${XSIMD_CMAKECONFIG_INSTALL_DIR})
install(EXPORT ${PROJECT_NAME}-targets
        FILE ${PROJECT_NAME}Targets.cmake
        DESTINATION ${XSIMD_CMAKECONFIG_INSTALL_DIR})

join_paths(libdir_for_pc_file "\${exec_prefix}" "${CMAKE_INSTALL_LIBDIR}")
join_paths(includedir_for_pc_file "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}")
configure_file(${PROJECT_NAME}.pc.in
               "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc"
                @ONLY)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc"
        DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig/")
