cmake_minimum_required(VERSION 2.8.9)

# -------------------------------------------------------------------------------------
# -------------------------------- Common settings ------------------------------------
# -------------------------------------------------------------------------------------

set(CMAKE_POSITION_INDEPENDENT_CODE ON)

# Define project name and home directory.
project(myramath_project)
set(MYRAMATH_HOME ${CMAKE_CURRENT_SOURCE_DIR})
get_filename_component(MYRAMATH_HOME ${MYRAMATH_HOME} PATH) # step up ..
get_filename_component(MYRAMATH_HOME ${MYRAMATH_HOME} PATH) # step up ../..
include_directories(${MYRAMATH_HOME})

if (WIN32)
# .. enable parallel builds
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
# .. suppress: 'variable' class 'classname' needs to have dll-interface to be used by clients of class 'classname'
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4251")
# .. suppress: 'sprintf': this function or variable may be unsafe. Consider using sprintf_s instead.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4996")
endif()

# -------------------------------------------------------------------------------------
# ------------------------- Combobox for enabling C++11 -------------------------------
# -------------------------------------------------------------------------------------

set(MYRAMATH_ENABLE_CPP11 "Enable code that depends upon C++11?")
set(${MYRAMATH_ENABLE_CPP11} "Enable" CACHE STRING "")
set(MYRAMATH_ENABLE_CPP11_ENUMS "Enable;Disable" CACHE STRING "")
set_property(CACHE ${MYRAMATH_ENABLE_CPP11} PROPERTY STRINGS ${MYRAMATH_ENABLE_CPP11_ENUMS})
mark_as_advanced(MYRAMATH_ENABLE_CPP11_ENUMS)
if (${MYRAMATH_ENABLE_CPP11} STREQUAL "Enable")
  message (STATUS "Enabling C++11 features (move constructors, initializer lists, etc)")
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMYRAMATH_ENABLE_CPP11")
elseif(${MYRAMATH_ENABLE_CPP11} STREQUAL "Disable")
  message (STATUS "Disabling C++11 features (move constructors, initializer lists, etc)")
endif()


# -------------------------------------------------------------------------------------
# ---------------------- Combobox for shared vs static library ------------------------
# -------------------------------------------------------------------------------------

# Enumerate MYRAMATH_LIBRARY_TYPE's
set(MYRAMATH_LIBRARY_SHARED "Build a shared library (targets are .dll's or .so's)")
set(MYRAMATH_LIBRARY_STATIC "Build a static library (targets are .lib's or .a's)")
# Setup combobox.
set(MYRAMATH_LIBRARY_TYPE "Choose type of library to build.")
set(${MYRAMATH_LIBRARY_TYPE} ${MYRAMATH_LIBRARY_SHARED} CACHE STRING "")
set(MYRAMATH_LIBRARY_ENUMS "${MYRAMATH_LIBRARY_SHARED};${MYRAMATH_LIBRARY_STATIC}" CACHE STRING "")
set_property(CACHE ${MYRAMATH_LIBRARY_TYPE} PROPERTY STRINGS ${MYRAMATH_LIBRARY_ENUMS})
mark_as_advanced(MYRAMATH_LIBRARY_ENUMS)
# Interpret result.
if (${MYRAMATH_LIBRARY_TYPE} STREQUAL ${MYRAMATH_LIBRARY_SHARED})
  message (STATUS "Library type: ${MYRAMATH_LIBRARY_SHARED}")
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMYRAMATH_LIBRARY_SHARED")
elseif (${MYRAMATH_LIBRARY_TYPE} STREQUAL ${MYRAMATH_LIBRARY_STATIC})
  message (STATUS "Library type: ${MYRAMATH_LIBRARY_STATIC}")
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMYRAMATH_LIBRARY_STATIC")
endif()

# -------------------------------------------------------------------------------------
# --------------------------- Combobox for BLAS mangling ------------------------------
# -------------------------------------------------------------------------------------

# Enumerate MANGLE_BLAS schemes
set(MYRAMATH_MANGLE_BLAS0 "Lowercase with leading 'myra_', yields 'myra_dgemm', use this for MyraKL")
set(MYRAMATH_MANGLE_BLAS1 "Uppercase without underscores, yields 'DGEMM'")
set(MYRAMATH_MANGLE_BLAS2 "Uppercase with trailing underscore, yields 'DGEMM_'")
set(MYRAMATH_MANGLE_BLAS3 "Lowercase without underscores, yields 'dgemm'")
set(MYRAMATH_MANGLE_BLAS4 "Lowercase with trailing underscore, yields 'dgemm_', use this for Intel MKL")
# Setup combobox.
set(MYRAMATH_MANGLE_BLAS "Choose mangling scheme for BLAS symbols.")
set(${MYRAMATH_MANGLE_BLAS} ${MYRAMATH_MANGLE_BLAS0} CACHE STRING "")
set(MYRAMATH_MANGLE_BLAS_ENUMS "${MYRAMATH_MANGLE_BLAS0};${MYRAMATH_MANGLE_BLAS4};${MYRAMATH_MANGLE_BLAS2};${MYRAMATH_MANGLE_BLAS3};${MYRAMATH_MANGLE_BLAS1}" CACHE STRING "")
set_property(CACHE ${MYRAMATH_MANGLE_BLAS} PROPERTY STRINGS ${MYRAMATH_MANGLE_BLAS_ENUMS})
mark_as_advanced(MYRAMATH_MANGLE_BLAS_ENUMS)
# Interpret result.
if (${MYRAMATH_MANGLE_BLAS} STREQUAL ${MYRAMATH_MANGLE_BLAS0})
  message (STATUS "BLAS Mangling scheme: ${MYRAMATH_MANGLE_BLAS0}")
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMYRAMATH_MANGLE_BLAS0")
elseif (${MYRAMATH_MANGLE_BLAS} STREQUAL ${MYRAMATH_MANGLE_BLAS1})
  message (STATUS "BLAS Mangling scheme: ${MYRAMATH_MANGLE_BLAS1}")
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMYRAMATH_MANGLE_BLAS1")
elseif (${MYRAMATH_MANGLE_BLAS} STREQUAL ${MYRAMATH_MANGLE_BLAS2})
  message (STATUS "BLAS Mangling scheme: ${MYRAMATH_MANGLE_BLAS2}")
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMYRAMATH_MANGLE_BLAS2")
elseif (${MYRAMATH_MANGLE_BLAS} STREQUAL ${MYRAMATH_MANGLE_BLAS3})
  message (STATUS "BLAS Mangling scheme: ${MYRAMATH_MANGLE_BLAS3}")
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMYRAMATH_MANGLE_BLAS3")
elseif (${MYRAMATH_MANGLE_BLAS} STREQUAL ${MYRAMATH_MANGLE_BLAS4})
  message (STATUS "BLAS Mangling scheme: ${MYRAMATH_MANGLE_BLAS4}")
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMYRAMATH_MANGLE_BLAS4")    
endif()

# -------------------------------------------------------------------------------------
# -------------------------- Combobox for LAPACK mangling -----------------------------
# -------------------------------------------------------------------------------------

# Enumerate MANGLE_LAPACK schemes
set(MYRAMATH_MANGLE_LAPACK0 "Lowercase with leading 'myra_', yields 'myra_dgetrf', use this for MyraKL")
set(MYRAMATH_MANGLE_LAPACK1 "Uppercase without underscores, yields 'DGETRF'")
set(MYRAMATH_MANGLE_LAPACK2 "Uppercase with trailing underscore, yields 'DGETRF_'")
set(MYRAMATH_MANGLE_LAPACK3 "Lowercase without underscores, yields 'dgetrf_'")
set(MYRAMATH_MANGLE_LAPACK4 "Lowercase with trailing underscore, yields 'dgetrf_', use this for Intel MKL")
# Setup combobox.
set(MYRAMATH_MANGLE_LAPACK "Choose mangling scheme for LAPACK symbols.")
set(${MYRAMATH_MANGLE_LAPACK} ${MYRAMATH_MANGLE_LAPACK0} CACHE STRING "")
set(MYRAMATH_MANGLE_LAPACK_ENUMS "${MYRAMATH_MANGLE_LAPACK0};${MYRAMATH_MANGLE_LAPACK4};${MYRAMATH_MANGLE_LAPACK2};${MYRAMATH_MANGLE_LAPACK3};${MYRAMATH_MANGLE_LAPACK1}" CACHE STRING "")
set_property(CACHE ${MYRAMATH_MANGLE_LAPACK} PROPERTY STRINGS ${MYRAMATH_MANGLE_LAPACK_ENUMS})
mark_as_advanced(MYRAMATH_MANGLE_LAPACK_ENUMS)
# Interpret result.
if (${MYRAMATH_MANGLE_LAPACK} STREQUAL ${MYRAMATH_MANGLE_LAPACK0})
  message (STATUS "LAPACK Mangling scheme: ${MYRAMATH_MANGLE_LAPACK0}")
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMYRAMATH_MANGLE_LAPACK0")
elseif (${MYRAMATH_MANGLE_LAPACK} STREQUAL ${MYRAMATH_MANGLE_LAPACK1})
  message (STATUS "LAPACK Mangling scheme: ${MYRAMATH_MANGLE_LAPACK1}")
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMYRAMATH_MANGLE_LAPACK1")
elseif (${MYRAMATH_MANGLE_LAPACK} STREQUAL ${MYRAMATH_MANGLE_LAPACK2})
  message (STATUS "LAPACK Mangling scheme: ${MYRAMATH_MANGLE_LAPACK2}")
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMYRAMATH_MANGLE_LAPACK2")
elseif (${MYRAMATH_MANGLE_LAPACK} STREQUAL ${MYRAMATH_MANGLE_LAPACK3})
  message (STATUS "LAPACK Mangling scheme: ${MYRAMATH_MANGLE_LAPACK3}")
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMYRAMATH_MANGLE_LAPACK3")
elseif (${MYRAMATH_MANGLE_LAPACK} STREQUAL ${MYRAMATH_MANGLE_LAPACK4})
  message (STATUS "LAPACK Mangling scheme: ${MYRAMATH_MANGLE_LAPACK4}")
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMYRAMATH_MANGLE_LAPACK4")    
endif()

# -------------------------------------------------------------------------------------
# ------------------------ Combobox for enabling OpenMP -------------------------------
# -------------------------------------------------------------------------------------

set(MYRAMATH_ENABLE_OPENMP "Enable code that depends upon OpenMP?")
set(${MYRAMATH_ENABLE_OPENMP} "Enable" CACHE STRING "")
set(MYRAMATH_ENABLE_OPENMP_ENUMS "Enable;Disable" CACHE STRING "")
set_property(CACHE ${MYRAMATH_ENABLE_OPENMP} PROPERTY STRINGS ${MYRAMATH_ENABLE_OPENMP_ENUMS})
mark_as_advanced(MYRAMATH_ENABLE_OPENMP_ENUMS)
if (${MYRAMATH_ENABLE_OPENMP} STREQUAL "Enable")
  find_package(OpenMP)
  if (OPENMP_FOUND)
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMYRAMATH_ENABLE_OMP")
    message(STATUS "Enabling OpenMP")
  endif()
elseif(${MYRAMATH_ENABLE_OPENMP} STREQUAL "Disable")
  message (STATUS "Disabling OpenMP")
endif()

# -------------------------------------------------------------------------------------
# -------------------------------- Building library -----------------------------------
# -------------------------------------------------------------------------------------

# List all the folders containing library code.
set(LIB_DIR "")
set(LIB_DIR "${LIB_DIR};${MYRAMATH_HOME}/myramath/utility")
set(LIB_DIR "${LIB_DIR};${MYRAMATH_HOME}/myramath/io")
set(LIB_DIR "${LIB_DIR};${MYRAMATH_HOME}/myramath/expression")
set(LIB_DIR "${LIB_DIR};${MYRAMATH_HOME}/myramath/dense")
set(LIB_DIR "${LIB_DIR};${MYRAMATH_HOME}/myramath/dense/detail")
set(LIB_DIR "${LIB_DIR};${MYRAMATH_HOME}/myramath/sparse")
set(LIB_DIR "${LIB_DIR};${MYRAMATH_HOME}/myramath/iterative")
set(LIB_DIR "${LIB_DIR};${MYRAMATH_HOME}/myramath/jobgraph")
set(LIB_DIR "${LIB_DIR};${MYRAMATH_HOME}/myramath/jobgraph/detail")
set(LIB_DIR "${LIB_DIR};${MYRAMATH_HOME}/myramath/pdense")
set(LIB_DIR "${LIB_DIR};${MYRAMATH_HOME}/myramath/pdense/detail")
set(LIB_DIR "${LIB_DIR};${MYRAMATH_HOME}/myramath/multifrontal")
set(LIB_DIR "${LIB_DIR};${MYRAMATH_HOME}/myramath/multifrontal/symbolic")
set(LIB_DIR "${LIB_DIR};${MYRAMATH_HOME}/myramath/multifrontal/symbolic/detail")
set(LIB_DIR "${LIB_DIR};${MYRAMATH_HOME}/myramath/multifrontal/detail")
set(LIB_DIR "${LIB_DIR};${MYRAMATH_HOME}/myramath/multifrontal/detail/llt")
set(LIB_DIR "${LIB_DIR};${MYRAMATH_HOME}/myramath/multifrontal/detail/lu")
set(LIB_DIR "${LIB_DIR};${MYRAMATH_HOME}/myramath/multifrontal/rcholesky")
set(LIB_DIR "${LIB_DIR};${MYRAMATH_HOME}/myramath/multifrontal/zcholesky")
set(LIB_DIR "${LIB_DIR};${MYRAMATH_HOME}/myramath/multifrontal/rldlt")
set(LIB_DIR "${LIB_DIR};${MYRAMATH_HOME}/myramath/multifrontal/zldlh")
set(LIB_DIR "${LIB_DIR};${MYRAMATH_HOME}/myramath/multifrontal/zldlt")
set(LIB_DIR "${LIB_DIR};${MYRAMATH_HOME}/myramath/multifrontal/lu")
set(LIB_DIR "${LIB_DIR};${MYRAMATH_HOME}/myramath/multifrontal/normal")
set(LIB_DIR "${LIB_DIR};${MYRAMATH_HOME}/myramath/lowrank")
set(LIB_DIR "${LIB_DIR};${MYRAMATH_HOME}/myramath/lowrank/detail")

# Collect the .h's and .cpp's in LIB_DIR's, it all goes into the LIB_CPP's
set(LIB_CPP "")
foreach(lib_dir ${LIB_DIR})
  file(GLOB LIB_CPP_THISDIR ${lib_dir}/*.h ${lib_dir}/*.cpp)
  set(LIB_CPP "${LIB_CPP};${LIB_CPP_THISDIR}")
endforeach(lib_dir ${LIB_DIR})

# Examine collected LIB_CPP files.
message("========================================================================")
message("Started from ${MYRAMATH_HOME}, collecting LIB_CPP's:")
message("========================================================================")
foreach(LIB_CPP ${LIB_CPP})
  message("  ${LIB_CPP}")
endforeach(LIB_CPP ${LIB_CPP})
message("")

# Build a shared library from all the LIB_CPP's
if (${MYRAMATH_LIBRARY_TYPE} STREQUAL ${MYRAMATH_LIBRARY_SHARED})
  add_library(myramath SHARED ${LIB_CPP})
elseif (${MYRAMATH_LIBRARY_TYPE} STREQUAL ${MYRAMATH_LIBRARY_STATIC})
  add_library(myramath STATIC ${LIB_CPP})
endif()

# Set path to debugging symbols (.pdb)
set_target_properties(myramath PROPERTIES COMPILE_PDB_NAME "myramath" COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" )

# When building the shared library, you should compile with -DLIBEXPORT to
# add __declspec(dllexport) to all the functions/classes that are marked
# with the MYRAMATH_EXPORT macro. Without -DLIBEXPORT, any MYRAMATH_EXPORT functions
# get __declspec(dllimport) instead. (You want this when compiling user 
# code and unit tests, so it's the desired default behavior).
set_target_properties (myramath PROPERTIES COMPILE_DEFINITIONS "LIBEXPORT")

# -------------------------------------------------------------------------------------
# -------------------------------- Build unit tests -----------------------------------
# -------------------------------------------------------------------------------------

# List all the folders containing test code.
set(TEST_DIR "")
set(TEST_DIR "${TEST_DIR};${MYRAMATH_HOME}/tests/unit")
set(TEST_DIR "${TEST_DIR};${MYRAMATH_HOME}/tests/utility")
set(TEST_DIR "${TEST_DIR};${MYRAMATH_HOME}/tests/io")
set(TEST_DIR "${TEST_DIR};${MYRAMATH_HOME}/tests/expression")
set(TEST_DIR "${TEST_DIR};${MYRAMATH_HOME}/tests/dense")
set(TEST_DIR "${TEST_DIR};${MYRAMATH_HOME}/tests/sparse")
set(TEST_DIR "${TEST_DIR};${MYRAMATH_HOME}/tests/iterative")
set(TEST_DIR "${TEST_DIR};${MYRAMATH_HOME}/tests/jobgraph")
set(TEST_DIR "${TEST_DIR};${MYRAMATH_HOME}/tests/pdense")
set(TEST_DIR "${TEST_DIR};${MYRAMATH_HOME}/tests/pdense/detail")
set(TEST_DIR "${TEST_DIR};${MYRAMATH_HOME}/tests/multifrontal/symbolic")
set(TEST_DIR "${TEST_DIR};${MYRAMATH_HOME}/tests/multifrontal/detail")
set(TEST_DIR "${TEST_DIR};${MYRAMATH_HOME}/tests/multifrontal/rcholesky")
set(TEST_DIR "${TEST_DIR};${MYRAMATH_HOME}/tests/multifrontal/zcholesky")
set(TEST_DIR "${TEST_DIR};${MYRAMATH_HOME}/tests/multifrontal/rldlt")
set(TEST_DIR "${TEST_DIR};${MYRAMATH_HOME}/tests/multifrontal/zldlh")
set(TEST_DIR "${TEST_DIR};${MYRAMATH_HOME}/tests/multifrontal/zldlt")
set(TEST_DIR "${TEST_DIR};${MYRAMATH_HOME}/tests/multifrontal/lu")
set(TEST_DIR "${TEST_DIR};${MYRAMATH_HOME}/tests/multifrontal/normal")
set(TEST_DIR "${TEST_DIR};${MYRAMATH_HOME}/tests/matlab")
set(TEST_DIR "${TEST_DIR};${MYRAMATH_HOME}/tests/lowrank")

# Collect the .cpp's in TEST_DIR's, it all goes into the TEST_CPP's
set(TEST_CPP "")
foreach(test_dir ${TEST_DIR})
  file(GLOB TEST_CPP_THISDIR ${test_dir}/*.h ${test_dir}/*.cpp)
  set(TEST_CPP "${TEST_CPP};${TEST_CPP_THISDIR}")
endforeach(test_dir ${TEST_DIR})

# Examine collected TEST_CPP files.
message("========================================================================")
message("Started from ${MYRAMATH_HOME}, collecting TEST_CPP's:")
message("========================================================================")
foreach(TEST_CPP ${TEST_CPP})
  message("  ${TEST_CPP}")
endforeach(TEST_CPP ${TEST_CPP})
message("")

# Make tester executable.
add_executable(myramath_tests ${MYRAMATH_HOME}/tests/myramath_tests.cpp ${TEST_CPP})
target_link_libraries(myramath_tests myramath)

# -------------------------------------------------------------------------------------
# --------------------------------- Build profiles ------------------------------------
# -------------------------------------------------------------------------------------

# List all the folders containing profile code.
set(PROFILE_DIR "")
set(PROFILE_DIR "${PROFILE_DIR};${MYRAMATH_HOME}/profile/dense")
set(PROFILE_DIR "${PROFILE_DIR};${MYRAMATH_HOME}/profile/pdense")
set(PROFILE_DIR "${PROFILE_DIR};${MYRAMATH_HOME}/profile/multifrontal/symbolic")
set(PROFILE_DIR "${PROFILE_DIR};${MYRAMATH_HOME}/profile/multifrontal/rcholesky")
set(PROFILE_DIR "${PROFILE_DIR};${MYRAMATH_HOME}/profile/multifrontal/zcholesky")
set(PROFILE_DIR "${PROFILE_DIR};${MYRAMATH_HOME}/profile/multifrontal/rldlt")
set(PROFILE_DIR "${PROFILE_DIR};${MYRAMATH_HOME}/profile/multifrontal/zldlh")
set(PROFILE_DIR "${PROFILE_DIR};${MYRAMATH_HOME}/profile/multifrontal/zldlt")
set(PROFILE_DIR "${PROFILE_DIR};${MYRAMATH_HOME}/profile/multifrontal/lu")

# Collect the .cpp's in PROFILE_DIR's, it all goes into the PROFILE_CPP's
set(PROFILE_CPP "")
foreach(PROFILE_DIR ${PROFILE_DIR})
  file(GLOB PROFILE_CPP_THISDIR ${PROFILE_DIR}/*.h ${PROFILE_DIR}/*.cpp)
  set(PROFILE_CPP "${PROFILE_CPP};${PROFILE_CPP_THISDIR}")
endforeach(PROFILE_DIR ${PROFILE_DIR})

# Examine collected PROFILE_CPP files.
message("========================================================================")
message("Started from ${MYRAMATH_HOME}, collecting PROFILE_CPP's:")
message("========================================================================")
foreach(PROFILE_CPP ${PROFILE_CPP})
  message("  ${PROFILE_CPP}")
endforeach(PROFILE_CPP ${PROFILE_CPP})
message("")

# Make profiler executable.
add_executable(myramath_profile ${MYRAMATH_HOME}/profile/myramath_profile.cpp ${PROFILE_CPP})
target_link_libraries(myramath_profile myramath)

# -------------------------------------------------------------------------------------
# --------------------------------- Build tutorials -----------------------------------
# -------------------------------------------------------------------------------------

# List all the folders containing tutorial code.
set(TUTORIAL_DIR "")
set(TUTORIAL_DIR "${TUTORIAL_DIR};${MYRAMATH_HOME}/tutorial/expression")
set(TUTORIAL_DIR "${TUTORIAL_DIR};${MYRAMATH_HOME}/tutorial/dense")
set(TUTORIAL_DIR "${TUTORIAL_DIR};${MYRAMATH_HOME}/tutorial/sparse")
set(TUTORIAL_DIR "${TUTORIAL_DIR};${MYRAMATH_HOME}/tutorial/multifrontal")
set(TUTORIAL_DIR "${TUTORIAL_DIR};${MYRAMATH_HOME}/tutorial/iterative")
set(TUTORIAL_DIR "${TUTORIAL_DIR};${MYRAMATH_HOME}/tutorial/pdense")
set(TUTORIAL_DIR "${TUTORIAL_DIR};${MYRAMATH_HOME}/tutorial/jobgraph")

# Collect the .cpp's in TUTORIAL_DIR's, it all goes into the TUTORIAL_CPP's
set(TUTORIAL_CPP "")
foreach(TUTORIAL_DIR ${TUTORIAL_DIR})
  file(GLOB TUTORIAL_CPP_THISDIR ${TUTORIAL_DIR}/*.h ${TUTORIAL_DIR}/*.cpp)
  set(TUTORIAL_CPP "${TUTORIAL_CPP};${TUTORIAL_CPP_THISDIR}")
endforeach(TUTORIAL_DIR ${TUTORIAL_DIR})

# Examine collected TUTORIAL_CPP files.
message("========================================================================")
message("Started from ${MYRAMATH_HOME}, collecting TUTORIAL_CPP's:")
message("========================================================================")
foreach(TUTORIAL_CPP ${TUTORIAL_CPP})
  message("  ${TUTORIAL_CPP}")
endforeach(TUTORIAL_CPP ${TUTORIAL_CPP})
message("")

# Make tutorial executable.
add_executable(myramath_tutorial ${MYRAMATH_HOME}/tutorial/myramath_tutorial.cpp ${TUTORIAL_CPP})
target_link_libraries(myramath_tutorial myramath)

# -------------------------------------------------------------------------------------
# ----------------------------------- Installation ------------------------------------
# -------------------------------------------------------------------------------------

set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}")

# Release configuration.
install(TARGETS myramath CONFIGURATIONS Release DESTINATION "${CMAKE_INSTALL_PREFIX}/release" )
install(TARGETS myramath_tests CONFIGURATIONS Release DESTINATION "${CMAKE_INSTALL_PREFIX}/release")
install(TARGETS myramath_profile CONFIGURATIONS Release DESTINATION "${CMAKE_INSTALL_PREFIX}/release")
install(TARGETS myramath_tutorial CONFIGURATIONS Release DESTINATION "${CMAKE_INSTALL_PREFIX}/release")

# Debug configuration.
install(TARGETS myramath CONFIGURATIONS Debug DESTINATION "${CMAKE_INSTALL_PREFIX}/debug" )
install(TARGETS myramath_tests CONFIGURATIONS Debug DESTINATION "${CMAKE_INSTALL_PREFIX}/debug")
install(TARGETS myramath_profile CONFIGURATIONS Debug DESTINATION "${CMAKE_INSTALL_PREFIX}/debug")
install(TARGETS myramath_tutorial CONFIGURATIONS Debug DESTINATION "${CMAKE_INSTALL_PREFIX}/debug")
install(FILES "$<TARGET_FILE_DIR:myramath>/myramath.pdb" CONFIGURATIONS Debug DESTINATION "${CMAKE_INSTALL_PREFIX}/debug" OPTIONAL)
install(FILES $<TARGET_PDB_FILE:myramath_tests> CONFIGURATIONS Debug DESTINATION "${CMAKE_INSTALL_PREFIX}/debug" OPTIONAL)
install(FILES $<TARGET_PDB_FILE:myramath_profile> CONFIGURATIONS Debug DESTINATION "${CMAKE_INSTALL_PREFIX}/debug" OPTIONAL)
install(FILES $<TARGET_PDB_FILE:myramath_tutorial> CONFIGURATIONS Debug DESTINATION "${CMAKE_INSTALL_PREFIX}/debug" OPTIONAL)

# Release configuration build with debug symbols.
install(TARGETS myramath CONFIGURATIONS RelWithDebInfo DESTINATION "${CMAKE_INSTALL_PREFIX}/release_debugsymbols" )
install(TARGETS myramath_tests CONFIGURATIONS RelWithDebInfo DESTINATION "${CMAKE_INSTALL_PREFIX}/release_debugsymbols")
install(TARGETS myramath_profile CONFIGURATIONS RelWithDebInfo DESTINATION "${CMAKE_INSTALL_PREFIX}/release_debugsymbols")
install(TARGETS myramath_tutorial CONFIGURATIONS RelWithDebInfo DESTINATION "${CMAKE_INSTALL_PREFIX}/release_debugsymbols")
install(FILES "$<TARGET_FILE_DIR:myramath>/myramath.pdb" CONFIGURATIONS RelWithDebInfo DESTINATION "${CMAKE_INSTALL_PREFIX}/release_debugsymbols" OPTIONAL)
install(FILES $<TARGET_PDB_FILE:myramath_tests> CONFIGURATIONS RelWithDebInfo DESTINATION "${CMAKE_INSTALL_PREFIX}/release_debugsymbols" OPTIONAL)
install(FILES $<TARGET_PDB_FILE:myramath_profile> CONFIGURATIONS RelWithDebInfo DESTINATION "${CMAKE_INSTALL_PREFIX}/release_debugsymbols" OPTIONAL)
install(FILES $<TARGET_PDB_FILE:myramath_tutorial> CONFIGURATIONS RelWithDebInfo DESTINATION "${CMAKE_INSTALL_PREFIX}/release_debugsymbols" OPTIONAL)

