Skip to content
Snippets Groups Projects
CMakeLists.txt 24.42 KiB
#######################################################################
#                                                                     #
#  Copyright 2019 Max Planck Institute                                #
#                 for Dynamics and Self-Organization                  #
#                                                                     #
#  This file is part of TurTLE.                                       #
#                                                                     #
#  TurTLE is free software: you can redistribute it and/or modify     #
#  it under the terms of the GNU General Public License as published  #
#  by the Free Software Foundation, either version 3 of the License,  #
#  or (at your option) any later version.                             #
#                                                                     #
#  TurTLE is distributed in the hope that it will be useful,          #
#  but WITHOUT ANY WARRANTY; without even the implied warranty of     #
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      #
#  GNU General Public License for more details.                       #
#                                                                     #
#  You should have received a copy of the GNU General Public License  #
#  along with TurTLE.  If not, see <http://www.gnu.org/licenses/>     #
#                                                                     #
# Contact: Cristian.Lalescu@ds.mpg.de                                 #
#                                                                     #
#######################################################################



cmake_minimum_required(VERSION 3.6)
cmake_policy(VERSION 3.12)

if (DEFINED ENV{MPICXX})
    message(STATUS "Using CMAKE_CXX_COMPILER=MPICXX")
    set(CMAKE_CXX_COMPILER $ENV{MPICXX})
else()
    message(STATUS "MPICXX environment variable undefined, trying to find MPI")
    set(MPI_STATIC ON)
    find_package(MPI REQUIRED)
endif()

if (DEFINED ENV{MPICC})
    set(CMAKE_C_COMPILER $ENV{MPICC})
    message(STATUS "Using CMAKE_C_COMPILER=MPICC")
endif()

if (DEFINED ENV{CMAKE_INSTALL_PREFIX})
    set(CMAKE_INSTALL_PREFIX $ENV{CMAKE_INSTALL_PREFIX})
endif()

project(TurTLE)

execute_process(COMMAND python3 ${PROJECT_SOURCE_DIR}/get_version.py OUTPUT_VARIABLE TURTLE_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE)

project(TurTLE
        VERSION ${TURTLE_VERSION}
        LANGUAGES CXX)


set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/morse ${CMAKE_MODULE_PATH})
set(TURTLE_LIBS "")

option(NDEBUG "Define NDEBUG macro" ON)
if(NDEBUG)
    add_definitions(-DNDEBUG)
endif()

# taken from https://vicrucann.github.io/tutorials/quick-cmake-doxygen/
# indicate the documentation build as an option and set it to ON by default
option(BUILD_DOC "Build documentation" OFF)

# check if Doxygen is installed
find_package(Doxygen)
if (DOXYGEN_FOUND)
    # set input and output files
    set(DOXYGEN_IN ${CMAKE_CURRENT_SOURCE_DIR}/documentation/cpp/cpp_config)
    set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)

    # request to configure the file
    configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY)
    message("Doxygen build started")

    # note the option ALL which allows to build the docs together with the application
    add_custom_target( doc_doxygen
        COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
        WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
        COMMENT "Generating API documentation with Doxygen"
        VERBATIM )
else (DOXYGEN_FOUND)
    message("Doxygen needs to be installed to generate the doxygen documentation")
endif (DOXYGEN_FOUND)

# check if sphinx is available
find_package(Sphinx)
if (SPHINX_FOUND)
    if(NOT DEFINED SPHINX_THEME)
        set(SPHINX_THEME default)
    endif()

    if(NOT DEFINED SPHINX_THEME_DIR)
        set(SPHINX_THEME_DIR)
    endif()

    # configured documentation tools and intermediate build results
    set(BINARY_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/sphinx_build")

    # Sphinx cache with pickled ReST documents
    set(SPHINX_CACHE_DIR "${CMAKE_CURRENT_BINARY_DIR}/sphinx_doctrees")

    # HTML output directory
    set(SPHINX_HTML_DIR "${CMAKE_CURRENT_BINARY_DIR}/sphinx_html")
    # LaTeX output directory
    set(SPHINX_LATEX_DIR "${CMAKE_CURRENT_BINARY_DIR}/sphinx_latex")

    configure_file(
        "${PROJECT_SOURCE_DIR}/documentation/conf.py.in"
        "${BINARY_BUILD_DIR}/conf.py"
        @ONLY)

    add_custom_target(doc_html
        ${SPHINX_EXECUTABLE}
            -q -b html
            -c "${BINARY_BUILD_DIR}"
            -d "${SPHINX_CACHE_DIR}"
            "${PROJECT_SOURCE_DIR}/documentation"
            "${SPHINX_HTML_DIR}"
            COMMENT "Building HTML documentation with Sphinx")

    add_custom_target(doc_latex
        ${SPHINX_EXECUTABLE}
            -q -b latex
            -c "${BINARY_BUILD_DIR}"
            -d "${SPHINX_CACHE_DIR}"
            "${PROJECT_SOURCE_DIR}/documentation"
            "${SPHINX_LATEX_DIR}"
            COMMENT "Building LaTeX documentation with Sphinx")
else (SPHINX_FOUND)
    message("Sphinx needs to be installed to generate the full documentation")
endif (SPHINX_FOUND)

option(TIMING_OUTPUT "Toggle timing output. WARNING: memory usage is proportional to `niter_todo`" OFF)
if(TIMING_OUTPUT)
    add_definitions(-DUSE_TIMINGOUTPUT)
endif()

#####################################################################################
## MPI

set(CMAKE_CXX_COMPILE_FLAGS "${CMAKE_CXX_COMPILE_FLAGS} ${MPI_CXX_COMPILE_OPTIONS}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${MPI_CXX_LINK_FLAGS}")
include_directories(${MPI_CXX_INCLUDE_DIRS})
add_definitions(${MPI_CXX_COMPILE_DEFINITIONS})
list(APPEND TURTLE_LIBS "${MPI_CXX_LIBRARIES}")

#####################################################################################
## CXX Standard

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# set(CMAKE_CXX_EXTENSIONS OFF)

#####################################################################################
## OpenMP

find_package(OpenMP REQUIRED)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
list(APPEND TURTLE_LIBS "${OpenMP_CXX_LIB_NAMES}")

#####################################################################################
## Extra flags

set(CMAKE_CXX_COMPILE_FLAGS "${CMAKE_CXX_COMPILE_FLAGS} $ENV{TURTLE_COMPILATION_FLAGS} -Wall -g -fopenmp")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_COMPILE_FLAGS}")

#####################################################################################
## HDF5

set(HDF5_STATIC ON)
if(NOT DEFINED ENV{HDF5_ROOT})
    message(WARNING "The environment variable HDF5_ROOT is undefined, this might cause trouble in finding the HDF5")
endif()

set(HDF5_PREFER_PARALLEL TRUE)
set(HDF5_NO_FIND_PACKAGE_CONFIG_FILE TRUE)
find_package(HDF5 REQUIRED)

message(STATUS "HDF5_C_INCLUDE_DIRS ${HDF5_C_INCLUDE_DIRS}")

include_directories(${HDF5_C_INCLUDE_DIRS})
add_definitions(${HDF5_C_DEFINITIONS})
list(APPEND TURTLE_LIBS "${HDF5_C_LIBRARIES}")

option(TURTLE_HDF5_USE_SZIP "Set to on to also link against SZIP" OFF)

if(TURTLE_HDF5_USE_SZIP)
    option(TURTLE_HDF5_SZIP_LIB_PATH "Additional lib path for SZIP" "")
    if(TURTLE_HDF5_SZIP_LIB_PATH)
        link_directories(${TURTLE_HDF5_SZIP_LIB_PATH})
    endif()
    list(APPEND TURTLE_LIBS "z")
endif()


#####################################################################################
## GSL
find_package(GSL)

if (GSL_FOUND)
    include_directories(${GSL_INCLUDE_DIRS})
    list(APPEND TURTLE_LIBS "${GSL_LIBRARIES}")
endif()

#####################################################################################
## FFTW

set(FFTW_STATIC ON)
if(NOT DEFINED ENV{FFTW_DIR})
    message(WARNING "The environment variable FFTW_DIR is undefined, this might cause trouble in finding the FFTW")
endif()

find_package(FFTW REQUIRED)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FFTW_CFLAGS_OTHER}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FFTW_LDFLAGS_OTHER}")
list(APPEND TURTLE_LIBS "${FFTW_LIBRARIES}")
include_directories(${FFTW_INCLUDE_DIRS})
link_directories(${FFTW_LIBRARY_DIRS})

find_package(FFTW REQUIRED SIMPLE)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FFTW_CFLAGS_OTHER}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FFTW_LDFLAGS_OTHER}")
list(APPEND TURTLE_LIBS "${FFTW_LIBRARIES}")
include_directories(${FFTW_INCLUDE_DIRS})
link_directories(${FFTW_LIBRARY_DIRS})

# hack for FFTW OMP libs
find_library(
    FFTWF_OMP fftw3f_omp
    HINTS ${FFTW_LIBRARY_DIRS} $ENV{FFTW_LIBDIR} $ENV{FFTW_OPENMP_LIBDIR})
set(TURTLE_LIBS ${FFTWF_OMP} ${TURTLE_LIBS})
find_library(
    FFTW_OMP fftw3_omp
    HINTS ${FFTW_LIBRARY_DIRS} $ENV{FFTW_LIBDIR} $ENV{FFTW_OPENMP_LIBDIR})
set(TURTLE_LIBS ${FFTW_OMP} ${TURTLE_LIBS})

# hack for FFTW MPI libs
find_library(
    FFTWF_MPI fftw3f_mpi
    HINTS ${FFTW_LIBRARY_DIRS} $ENV{FFTW_LIBDIR} $ENV{FFTW_MPI_LIBDIR})
set(TURTLE_LIBS ${FFTWF_MPI} ${TURTLE_LIBS})
find_library(
    FFTW_MPI fftw3_mpi
    HINTS ${FFTW_LIBRARY_DIRS} $ENV{FFTW_LIBDIR} $ENV{FFTW_MPI_LIBDIR})
set(TURTLE_LIBS ${FFTW_MPI} ${TURTLE_LIBS})


#####################################################################################
## Get the links and include from deps

get_property(ALL_INCLUDE_DIRS DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES)
get_property(ALL_LINK_DIRS DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY LINK_DIRECTORIES)

#####################################################################################
## Build the lib

include_directories(${PROJECT_SOURCE_DIR}/cpp)

#file(GLOB_RECURSE cpp_for_lib ${PROJECT_SOURCE_DIR}/*.cpp)
set(cpp_for_lib
    ${PROJECT_SOURCE_DIR}/cpp/full_code/code_base.cpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/direct_numerical_simulation.cpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/NSVE.cpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/static_field.cpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/kraichnan_field.cpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/joint_acc_vel_stats.cpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/test.cpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/filter_test.cpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/field_test.cpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/write_filtered_test.cpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/Gauss_field_test.cpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/symmetrize_test.cpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/field_output_test.cpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/test_tracer_set.cpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/get_rfields.cpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/write_rpressure.cpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/bandpass_stats.cpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/field_single_to_double.cpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/resize.cpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/NSVE_field_stats.cpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/native_binary_to_hdf5.cpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/postprocess.cpp
    ${PROJECT_SOURCE_DIR}/cpp/field.cpp
    ${PROJECT_SOURCE_DIR}/cpp/kspace.cpp
    ${PROJECT_SOURCE_DIR}/cpp/field_layout.cpp
    ${PROJECT_SOURCE_DIR}/cpp/hdf5_tools.cpp
    ${PROJECT_SOURCE_DIR}/cpp/fftw_tools.cpp
    ${PROJECT_SOURCE_DIR}/cpp/vorticity_equation.cpp
    ${PROJECT_SOURCE_DIR}/cpp/field_binary_IO.cpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n1.cpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n2.cpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n3.cpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n4.cpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n5.cpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n6.cpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n7.cpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n8.cpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n9.cpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n10.cpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/Lagrange_polys.cpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/field_tinterpolator.cpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/particle_set.cpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/rhs/tracer_rhs.cpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/rhs/tracer_with_collision_counter_rhs.cpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/particle_solver.cpp
    ${PROJECT_SOURCE_DIR}/cpp/scope_timer.cpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/test_interpolation.cpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/NSVEparticles.cpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/NSVEcomplex_particles.cpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/NSVE_Stokes_particles.cpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/NSVEp_extra_sampling.cpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/inner/particles_inner_computer.cpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/ornstein_uhlenbeck_process.cpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/ou_vorticity_equation.cpp)

set(hpp_for_lib
    ${PROJECT_SOURCE_DIR}/cpp/full_code/code_base.hpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/direct_numerical_simulation.hpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/NSVE.hpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/static_field.hpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/kraichnan_field.hpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/joint_acc_vel_stats.hpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/test.hpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/filter_test.hpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/Gauss_field_test.hpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/field_test.hpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/write_filtered_test.hpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/symmetrize_test.hpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/field_output_test.hpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/test_tracer_set.hpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/get_rfields.hpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/write_rpressure.hpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/bandpass_stats.hpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/field_single_to_double.hpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/resize.hpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/NSVE_field_stats.hpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/native_binary_to_hdf5.hpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/postprocess.hpp
    ${PROJECT_SOURCE_DIR}/cpp/field.hpp
    ${PROJECT_SOURCE_DIR}/cpp/kspace.hpp
    ${PROJECT_SOURCE_DIR}/cpp/field_layout.hpp
    ${PROJECT_SOURCE_DIR}/cpp/hdf5_tools.hpp
    ${PROJECT_SOURCE_DIR}/cpp/fftw_tools.hpp
    ${PROJECT_SOURCE_DIR}/cpp/vorticity_equation.hpp
    ${PROJECT_SOURCE_DIR}/cpp/field_binary_IO.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n1.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n2.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n3.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n4.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n5.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n6.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n7.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n8.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n9.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n10.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/Lagrange_polys.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/abstract_particle_set.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/particle_set.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/field_tinterpolator.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/abstract_particle_rhs.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/rhs/tracer_rhs.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/rhs/deformation_tensor_rhs.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/rhs/tracer_with_collision_counter_rhs.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/particle_solver.hpp
    ${PROJECT_SOURCE_DIR}/cpp/scope_timer.hpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/test_interpolation.hpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/NSVEparticles.hpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/NSVEcomplex_particles.hpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/NSVE_Stokes_particles.hpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/NSVEp_extra_sampling.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/inner/particles_inner_computer.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/inner/particles_inner_computer_2nd_order.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/inner/particles_inner_computer_empty.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/abstract_particles_input.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/abstract_particles_output.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/abstract_particles_system.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/abstract_particles_system_with_p2p.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/alltoall_exchanger.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/lock_free_bool_array.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/p2p/p2p_computer_empty.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/p2p/p2p_computer.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/p2p/p2p_ghost_collisions.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/p2p/p2p_distr_mpi.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/p2p/p2p_tree.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/particles_adams_bashforth.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/particles_distr_mpi.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/particles_field_computer.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/particles_generic_interp.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/particles_input_hdf5.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/particles_output_hdf5.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/particles_output_mpiio.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/particles_output_sampling_hdf5.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/particles_sampling.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/particles_system_builder.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/particles_system.hpp
    ${PROJECT_SOURCE_DIR}/cpp/particles/particles_utils.hpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/main_code.hpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/codes_with_no_output.hpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/NSVE_no_output.hpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/NSVEparticles_no_output.hpp
    ${PROJECT_SOURCE_DIR}/cpp/base.hpp
    ${PROJECT_SOURCE_DIR}/cpp/env_utils.hpp
    ${PROJECT_SOURCE_DIR}/cpp/fftw_interface.hpp
    ${PROJECT_SOURCE_DIR}/cpp/turtle_timer.hpp
    ${PROJECT_SOURCE_DIR}/cpp/omputils.hpp
    ${PROJECT_SOURCE_DIR}/cpp/shared_array.hpp
    ${PROJECT_SOURCE_DIR}/cpp/spectrum_function.hpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/ornstein_uhlenbeck_process.hpp
    ${PROJECT_SOURCE_DIR}/cpp/full_code/ou_vorticity_equation.hpp)

if(GSL_FOUND)
    LIST(APPEND cpp_for_lib ${PROJECT_SOURCE_DIR}/cpp/particles/rhs/deformation_tensor_rhs.cpp)
    LIST(APPEND hpp_for_lib ${PROJECT_SOURCE_DIR}/cpp/particles/rhs/deformation_tensor_rhs.hpp)
endif()

#file(GLOB_RECURSE hpp_for_lib ${PROJECT_SOURCE_DIR}/*.hpp)
LIST(APPEND source_files ${hpp_for_lib} ${cpp_for_lib})

add_library(TurTLE ${source_files})

target_link_libraries(TurTLE ${TURTLE_LIBS})

install(TARGETS TurTLE EXPORT TURTLE_EXPORT DESTINATION lib/ )
install(DIRECTORY ${PROJECT_SOURCE_DIR}/cpp/ DESTINATION include/TurTLE/ FILES_MATCHING PATTERN "*.h*")

#####################################################################################
## Export the configuration

configure_file(${PROJECT_SOURCE_DIR}/cmake/TurTLEConfig.cmake.in ${PROJECT_BINARY_DIR}/TurTLEConfig.cmake @ONLY)

install(FILES "${PROJECT_BINARY_DIR}/TurTLEConfig.cmake" DESTINATION lib/)
export(TARGETS TurTLE FILE "${PROJECT_BINARY_DIR}/TurTLELibraryDepends.cmake")
install(EXPORT TURTLE_EXPORT DESTINATION lib/)
if(EXISTS "${PROJECT_BINARY_DIR}/bash_setup_for_TurTLE.sh")
    install(
        FILES "${PROJECT_BINARY_DIR}/bash_setup_for_TurTLE.sh"
        PERMISSIONS OWNER_READ GROUP_READ WORLD_READ
        DESTINATION "lib/"
        )
endif()


#####################################################################################
## Install the python3 wrapper
# copy command
install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory ${PROJECT_SOURCE_DIR}/TurTLE ${PROJECT_BINARY_DIR}/python/TurTLE/)")
if(EXISTS "${PROJECT_BINARY_DIR}/host_info.py")
    install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/host_info.py ${PROJECT_BINARY_DIR}/python/TurTLE/)")
else()
    if(EXISTS "${PROJECT_SOURCE_DIR}/host_info.py")
        install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/host_info.py ${PROJECT_BINARY_DIR}/python/TurTLE/)")
    else()
        install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/pc_host_info.py ${PROJECT_BINARY_DIR}/python/TurTLE/host_info.py)")
    endif()
endif()
install(CODE "execute_process(COMMAND python3 ${PROJECT_SOURCE_DIR}/setup.py install --force --prefix=${CMAKE_INSTALL_PREFIX} WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/python/)")


#####################################################################################
## Add tests
include(CTest)
set(TEST_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/test_runs/")
enable_testing()
if (BUILD_TESTING)
    file(MAKE_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
    ### basic functionality
    add_test(
        NAME test_fftw
        COMMAND turtle.test_fftw
        WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
    add_test(
        NAME test_Parseval
        COMMAND turtle.test_Parseval
        WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
    ### basic particle functionality
    add_test(
        NAME test_tracer_set
        COMMAND turtle TEST test_tracer_set  -n 32 --np 2 --ntpp 2 --simname tracer_set_testsim
        WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
    ### compare DNS output to stored results
    add_test(
        NAME test_NSVEparticles
        COMMAND turtle.test_NSVEparticles --np 2 --ntpp 2
        WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
    set_tests_properties(test_NSVEparticles PROPERTIES TIMEOUT 2000)
    ### check whether data is messed up by p2p calculations
    add_test(
        NAME test_Heun_p2p
        COMMAND turtle.test_Heun_p2p  -n 32 --np 2 --ntpp 2 --simname tracer_set_Heun_p2p --src-simname dns_nsveparticles --src-iteration 0
        WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
    ### simple runs of post-processing tools
    add_test(
        NAME test_pp_single_to_double
        COMMAND turtle PP field_single_to_double --simname dns_nsveparticles --iter0 32 --iter1 32
        WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
    add_test(
        NAME test_pp_get_rfields
        COMMAND turtle PP get_rfields --simname dns_nsveparticles --iter0 0 --iter1 64
        WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
    add_test(
        NAME test_pp_write_rpressure
        COMMAND turtle PP write_rpressure --simname dns_nsveparticles --iter0 0 --iter1 64
        WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
    add_test(
        NAME test_pp_joint_acc_vel_stats
        COMMAND turtle PP joint_acc_vel_stats --simname dns_nsveparticles --iter0 0 --iter1 64
        WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
    add_test(
        NAME test_pp_resize
        COMMAND turtle PP resize --simname dns_nsveparticles --new_nx 96 --new_ny 96 --new_nz 96 --new_simname dns_nsveparticles_resized
        WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
    ### simple runs of different DNS
    add_test(
        NAME test_NSVEp_extra_sampling
        COMMAND turtle DNS NSVEp_extra_sampling -n 32 --np 2 --ntpp 2  --src-simname dns_nsveparticles --src-iteration 32 --simname dns_nsvep_extra_sampling --nparticles 1000
        WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
    add_test(
        NAME test_NSVEcomplex_particles
        COMMAND turtle DNS NSVEcomplex_particles -n 32 --np 2 --ntpp 2 --src-simname dns_nsveparticles --src-iteration 32 --simname dns_nsvecomplex_particles --nparticles 1000
        WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
    add_test(
        NAME test_static_field
        COMMAND turtle DNS static_field --simname dns_static_field --nparticles 10000
        WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
    add_test(
        NAME test_kraichnan_field
        COMMAND turtle DNS kraichnan_field --simname dns_kraichnan_field --dtfactor 0.05 --nparticles 10000 --ntpp 2
        WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
    add_test(
        NAME test_NSVE_Stokes_particles
        COMMAND turtle DNS NSVE_Stokes_particles  -n 32 --np 2 --ntpp 2 --src-simname dns_nsveparticles --src-iteration 32 --simname dns_nsve_tokes_particles --nparticles 10000
        WORKING_DIRECTORY ${TEST_OUTPUT_DIRECTORY})
endif(BUILD_TESTING)