cmake_minimum_required(VERSION 3.13)
project(vlfeat LANGUAGES C)
message(STATUS "System processor ARCH is ${CMAKE_SYSTEM_PROCESSOR}")

macro(READ_VERSION)
   execute_process(COMMAND grep Changes -A 2 README.md
      WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
      OUTPUT_VARIABLE PRE_VERSION)
   string(REGEX MATCH "[0-9\.]+" VLFEAT_VERSION "${PRE_VERSION}")

   # Find version components
   string(REGEX REPLACE "^([0-9]+).*" "\\1"
      VLFEAT_VERSION_MAJOR "${VLFEAT_VERSION}")
   string(REGEX REPLACE "^[0-9]+\\.([0-9]+).*" "\\1"
      VLFEAT_VERSION_MINOR "${VLFEAT_VERSION}")
   string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+)" "\\1"
      VLFEAT_VERSION_PATCH ${VLFEAT_VERSION})
   string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.[0-9]+(.*)" "\\1"
      VLFEAT_VERSION_CANDIDATE ${VLFEAT_VERSION})
   set(VLFEAT_SOVERSION "${VLFEAT_VERSION_MAJOR}.${VLFEAT_VERSION_MINOR}")
endmacro(READ_VERSION)

if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|arm|ppc64")
   set(DEFAULT_AVX OFF)
   set(DEFAULT_SSE OFF)
else()
   set(DEFAULT_AVX ON)
   set(DEFAULT_SSE ON)
endif()
message(STATUS "Defaulting AVX instruction set to ${DEFAULT_AVX}")

option(BUILD_SHARED_LIBS "Build shared library" ON)
option(USE_SSE_INSTRUCTIONS "Compile your program with SSE2/3/4 instructions" ${DEFAULT_SSE})
option(USE_AVX_INSTRUCTIONS "Compile your program with AVX instructions" ${DEFAULT_AVX})
option(USE_THREADS "Compile your program with threads" ON)
option(USE_OPENMP "Compile your program with OpenMP support" ON)

if (NOT CMAKE_BUILD_TYPE)
   set(CMAKE_BUILD_TYPE Release)
endif()

# ==============================================================================
# GNUInstallDirs CMake module
# - Define GNU standard installation directories
# - Provides install directory variables as defined by the GNU Coding Standards.
# ==============================================================================
include(GNUInstallDirs)

READ_VERSION()

# configuring
# use PIC code for link into shared lib
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG)
   add_definitions(-fPIC)
   # compat to glibc 2.3.4
   add_definitions(-DDISABLE_COMPAT -D_GNU_SOURCE -fno-stack-protector)
   add_link_options(-Wl,--as-needed)
endif()

find_package(OpenMP)
if(USE_OPENMP AND USE_THREADS AND OPENMP_FOUND)
   add_definitions(-fopenmp)
   link_libraries(${OpenMP_C_LIBRARIES})
   add_definitions(-DOPENMP_NO_DEFAULT_NONE)
   message(STATUS "Enabling OpenMP support")
else(USE_OPENMP AND USE_THREADS AND OPENMP_FOUND)
   add_definitions(-DVL_DISABLE_OPENMP)
   message(STATUS "Disabling OpenMP support")
endif(USE_OPENMP AND USE_THREADS AND OPENMP_FOUND)

if(USE_AVX_INSTRUCTIONS)
   add_definitions(-mavx)
   message(STATUS "Enabling AVX instructions")
else(USE_AVX_INSTRUCTIONS)
   add_definitions(-DVL_DISABLE_AVX)
   message(STATUS "Disabling AVX instructions")
endif(USE_AVX_INSTRUCTIONS)

if(USE_SSE_INSTRUCTIONS)
   add_definitions(-msse2 -msse3 -msse4)
   message(STATUS "Enabling SSE2 instructions")
else(USE_SSE_INSTRUCTIONS)
   add_definitions(-DVL_DISABLE_SSE2)
   message(STATUS "Disabling SSE2 instructions")
endif(USE_SSE_INSTRUCTIONS)

find_package(Threads)
if(USE_THREADS AND THREADS_HAVE_PTHREAD_ARG)
   add_definitions(-pthreads)
   message(STATUS "Enabling threads")
else(USE_THREADS AND THREADS_HAVE_PTHREAD_ARG)
   add_definitions(-DVL_DISABLE_THREADS)
   message(STATUS "Disabling threads")
endif(USE_THREADS AND THREADS_HAVE_PTHREAD_ARG)

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/vl)
link_libraries(m)

# Sources

file(GLOB FEATS vl/*.c)
file(GLOB MANS1 src/*.1)
file(GLOB MANS7 src/*.7)

set_source_files_properties(${FEATS} PROPERTIES LANGUAGE C)

add_library(vlfeat ${FEATS})
#target_link_libraries(vlfeat gomp m)

set_target_properties(vlfeat PROPERTIES
   VERSION ${VLFEAT_VERSION}
   SOVERSION ${VLFEAT_SOVERSION}
   DEFINE_SYMBOL VLFEAT_EXPORTS
)

add_executable(sift src/sift.c)
add_dependencies(sift vlfeat)
target_link_libraries(sift vlfeat)
target_include_directories(sift
   PUBLIC
      ${CMAKE_CURRENT_SOURCE_DIR})

add_executable(mser src/mser.c)
add_dependencies(mser vlfeat)
target_link_libraries(mser vlfeat)
target_include_directories(mser
   PUBLIC
      ${CMAKE_CURRENT_SOURCE_DIR})

add_executable(aib src/aib.c)
add_dependencies(aib vlfeat)
target_link_libraries(aib vlfeat)
target_include_directories(aib
   PUBLIC
      ${CMAKE_CURRENT_SOURCE_DIR})

# Installation scripts
install (
    TARGETS sift mser aib vlfeat
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBEXECDIR})


install(TARGETS vlfeat
   DESTINATION ${CMAKE_INSTALL_LIBDIR}
   EXPORT aliceVision-targets
)

install(
   DIRECTORY ./vl
   DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
   COMPONENT headers
   FILES_MATCHING PATTERN "*.h" PATTERN "*.th"
)

install(FILES ${MANS1} DESTINATION ${CMAKE_INSTALL_MANDIR}/man7)
install(FILES ${MANS7} DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
