Skip to content
Snippets Groups Projects
CMakeLists.txt 12.8 KiB
Newer Older
cmake_minimum_required(VERSION 3.11)
Christof Kaufmann's avatar
Christof Kaufmann committed

project(imagefusion)
if(NOT CMAKE_BUILD_TYPE)
  set(CMAKE_BUILD_TYPE Release)
endif()
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
    message("debug mode")
endif()
## use some modules to find out OS
Christof Kaufmann's avatar
Christof Kaufmann committed
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
include(TargetArch)
include(MiscUtils)
## fix RPATH
# use, i.e. don't skip the full RPATH for the build tree
set(CMAKE_SKIP_BUILD_RPATH  FALSE)
# when building, don't use the install RPATH already (but later on when installing) (Note, imfupython builds with install RPATH)
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
# the RPATH to be used when installing, but only if it's not a system directory
list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir)
if("${isSystemDir}" STREQUAL "-1")
   set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
endif("${isSystemDir}" STREQUAL "-1")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")

## set source and header files
include_directories(include)
include_directories(test)
Christof Kaufmann's avatar
Christof Kaufmann committed
set(SOURCES_LIB
    src/optionparser.cpp
    src/spstfm.cpp
    src/spstfm_impl.cpp
## set general compiler settings
set(CMAKE_CXX_STANDARD 17)

include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-march=native" COMPILER_SUPPORTS_MARCH_NATIVE)
if(COMPILER_SUPPORTS_MARCH_NATIVE)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native")
endif()

set(CMAKE_POSITION_INDEPENDENT_CODE ON) # required for spdlog, since it is compiled as static lib, but linked into imagefusion, which is a dynamic lib.
# set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) # Link Time Optimization (-flto -fno-fat-lto-objects) # does not work
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g")
add_compile_options(-pthread)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
  # using Clang
  add_compile_options(-Wall -Wextra -Wno-missing-braces)
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
  # using GCC
  add_compile_options(-LC_ALL=en_US.UTF-8)
  add_compile_options(-Wall -Wextra -Wno-missing-braces)
endif()


## find external libs
find_package(OpenCV REQUIRED core imgproc)
include_directories(${OpenCV_INCLUDE_DIRS})
set(LIBS ${LIBS} ${OpenCV_LIBS})
#message("Found OpenCV: ${OpenCV_INCLUDE_DIRS}, ${OpenCV_LIBS}")
find_package(GDAL REQUIRED) # custom cmake module in cmake/Modules
include_directories(${GDAL_INCLUDE_DIR})
set(LIBS ${LIBS} ${GDAL_LIBRARY})
#message("Found GDAL: ${GDAL_INCLUDE_DIR}, ${GDAL_LIBRARY}")
find_package(Boost OPTIONAL_COMPONENTS unit_test_framework)
set(TARGETS ${TARGETS} "Boost::boost")       # include headers
find_package(Armadillo REQUIRED)
include_directories(${ARMADILLO_INCLUDE_DIRS})
set(LIBS ${LIBS} ${ARMADILLO_LIBRARIES})
#message("Found Armadillo: ${ARMADILLO_INCLUDE_DIRS}, ${ARMADILLO_LIBRARIES}")
if(OPENMP_CXX_FOUND OR OPENMP_FOUND)
    add_definitions(-DWITH_OMP)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
    #message("Found OpenMP: ${OpenMP_CXX_FLAGS}")
    set(SOURCES_TEST
        ${SOURCES_TEST}
        test/parallelizer_test.cpp
    )
endif()

find_package(spdlog)
if(spdlog_FOUND)
  message("spdlog found. Using system installed shared lib, instead of building static lib.")
else()
  option(IMAGEFUSION_INSTALL_DEP_SPDLOG "Install dependency SPDLOG" ON)
  if(IMAGEFUSION_INSTALL_DEP_SPDLOG)
    set(SPDLOG_INSTALL ON)
  endif()
  add_subdirectory(3rdparty/spdlog) # checks also for compiler options, so set them before!
set(CPACK_PACKAGE_VERSION_MAJOR "0")
set(CPACK_PACKAGE_VERSION_MINOR "0")
set(CPACK_PACKAGE_VERSION_PATCH "1")
set(CPACK_PACKAGE_CONTACT "Christof Kaufmann christofkaufmann.dev@gmail.com")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "This library is an open framework to provide multiple data fusion algorithms for remote sensing time series generation.")
set(CPACK_COMPONENT_DOC_DISPLAY_NAME "API Documentation")
set(CPACK_COMPONENT_LIB_DISPLAY_NAME "Imagefusion Library")
set(CPACK_COMPONENT_DEV_DISPLAY_NAME "C++ Headers")
set(CPACK_COMPONENT_UTILS_DISPLAY_NAME "Utilities")
set(CPACK_COMPONENT_DOC_DESCRIPTION "API documentation with examples how to program with the Imagefusion framework.")
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.txt")
Christof Kaufmann's avatar
Christof Kaufmann committed
is_symbol_defined(symdef __linux__)
if(symdef)
    ## package
    # common stuff
Christof Kaufmann's avatar
Christof Kaufmann committed
    set(CPACK_GENERATOR "DEB")
    set(CPACK_DEB_COMPONENT_INSTALL ON)
    set(CPACK_DEBIAN_PACKAGE_SECTION science)
    set(CPACK_PACKAGING_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX})
    set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Christof Kaufmann / Dinesh Kumar Babu")
    set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)

    # lib
    set(CPACK_DEBIAN_LIB_PACKAGE_NAME "libimagefusion")
    set(CPACK_DEBIAN_LIB_PACKAGE_RECOMMENDS "imagefusion-utils, libimagefusion-dev, libimagefusion-doc")
#    set(CPACK_DEBIAN_LIB_FILE_NAME DEB-DEFAULT) # requires CPack 3.6

    # utils
    set(CPACK_DEBIAN_UTILS_PACKAGE_NAME "imagefusion-utils")
    set(CPACK_DEBIAN_UTILS_PACKAGE_DEPENDS "libimagefusion")
#    set(CPACK_DEBIAN_UTILS_FILE_NAME DEB-DEFAULT) # requires CPack 3.6

    # dev
    set(CPACK_DEBIAN_DEV_PACKAGE_NAME "libimagefusion-dev")
    set(CPACK_DEBIAN_DEV_PACKAGE_DEPENDS "libimagefusion")
    set(CPACK_DEBIAN_DEV_PACKAGE_RECOMMENDS "libimagefusion-doc")
#    set(CPACK_DEBIAN_DEV_FILE_NAME DEB-DEFAULT) # requires CPack 3.6
    # doc
    set(CPACK_DEBIAN_DOC_PACKAGE_NAME "libimagefusion-doc")
    set(CPACK_DEBIAN_DOC_PACKAGE_RECOMMENDS "libimagefusion, libimagefusion-dev")
#    set(CPACK_DEBIAN_DOC_FILE_NAME DEB-DEFAULT) # requires CPack 3.6
Christof Kaufmann's avatar
Christof Kaufmann committed

    # To use this:
    # make package
    # sudo apt install ./imagefusion*.deb
Christof Kaufmann's avatar
Christof Kaufmann committed
endif()
is_symbol_defined(symdef _WIN32)
if(symdef)
    set(CPACK_GENERATOR WIX)
    set(CPACK_PACKAGE_NAME "Imagefusion Framework")
    set(CPACK_PACKAGE_VENDOR "Hochschule Bochum")
    set(CPACK_PACKAGE_INSTALL_DIRECTORY "imagefusion")
    set(CPACK_COMPONENT_LIB_DESCRIPTION "The Imagefusion library runtime (dll) is required for running the utilities.")
    set(CPACK_COMPONENT_HEADER_DESCRIPTION "This will install the C++ header files and the archive file. Both are required if you want to compile your own utilities and link against the library")
    set(CPACK_WIX_UPGRADE_GUID "075D56E1-D26C-47D1-AA64-984F3064AF3A")
#    set(CPACK_WIX_PRODUCT_GUID "075D56E1-D26C-47D1-AA64-984F3064AF3A")
endif()
is_symbol_defined(symdef __APPLE__)
if(symdef)
    # FIXME
endif()

include(CPack)


## build targets
# documentation targets (doc and docinternal)
find_package(Doxygen)
option(BUILD_DOCUMENTATION "Create and install the HTML based API documentation (requires Doxygen)" ${DOXYGEN_FOUND})
if(BUILD_DOCUMENTATION)
    if(NOT DOXYGEN_FOUND)
         message(FATAL_ERROR "Doxygen is needed to build the documentation. If you do not want to build the documentation, just deselect the CMake option BUILD_DOCUMENTATION.")
    endif()

    set(doxyfile ${CMAKE_CURRENT_SOURCE_DIR}/doc/doxyfile)
    set(doxyfile_internal ${CMAKE_CURRENT_SOURCE_DIR}/doc/doxyfileinternal)

    add_custom_target(doc
                      COMMAND ${DOXYGEN_EXECUTABLE} ${doxyfile}
                      WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/doc
                      COMMENT "Generating API documentation with Doxygen"
                      VERBATIM)

    add_custom_target(docinternal
                      COMMAND ${DOXYGEN_EXECUTABLE} ${doxyfile_internal}
                      WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/doc
                      COMMENT "Generating API documentation with Doxygen"
                      VERBATIM)
endif()
is_symbol_defined(symdef __linux__)
if(symdef)
    # install directory structure
    if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/doc/html/)
        install(FILES doc/doc.html
                DESTINATION share/doc/imagefusion
                COMPONENT doc)
        install(DIRECTORY doc/html
                DESTINATION share/doc/imagefusion
                COMPONENT doc)
    endif()
endif()
is_symbol_defined(symdef _WIN32)
if(symdef)
    if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/doc/html/")
        install(FILES doc/doc.html
                DESTINATION doc
                COMPONENT doc)
        install(DIRECTORY doc/html
                DESTINATION doc
                COMPONENT doc)
    endif()
Christof Kaufmann's avatar
Christof Kaufmann committed
endif()
is_symbol_defined(symdef __APPLE__)
if(symdef)
endif()

if(Boost_UNIT_TEST_FRAMEWORK_FOUND AND CMAKE_PROJECT_NAME STREQUAL imagefusion)
#     message("Found Boost unit_test_framework: ${Boost_INCLUDE_DIRS}, ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}")
    enable_testing()
    add_subdirectory(test)
add_library(imagefusion SHARED ${SOURCES_LIB})
#target_include_directories(imagefusion INTERFACE $<INSTALL_INTERFACE:${OpenCV_INCLUDE_DIRS};${GDAL_INCLUDE_DIR};${Boost_INCLUDE_DIRS};${ARMADILLO_INCLUDE_DIRS};include/imagefusion>)
target_include_directories(imagefusion INTERFACE "$<INSTALL_INTERFACE:${GDAL_INCLUDE_DIR};include/imagefusion;spdlog::spdlog>")
target_link_libraries(imagefusion PUBLIC ${TARGETS} ${LIBS} spdlog)
if(spdlog_FOUND)
  install(TARGETS imagefusion
          EXPORT ImagefusionTargets
          INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
          ARCHIVE  DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT dev
          LIBRARY  DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT lib
          RUNTIME  DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT lib)
else() # building spdlog as dependency requires also to specify it in this export
  install(TARGETS imagefusion spdlog
          EXPORT ImagefusionTargets
          INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
          ARCHIVE  DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT dev
          LIBRARY  DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT lib
          RUNTIME  DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT lib)
endif()

install(DIRECTORY include/
        DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}
        FILES_MATCHING PATTERN "*.h")

# utilities (included in target all)
add_subdirectory("utils")

# uninstall target (see https://gitlab.kitware.com/cmake/community/wikis/FAQ#can-i-do-make-uninstall-with-cmake)
if(NOT TARGET uninstall)
    configure_file(
        "${CMAKE_CURRENT_SOURCE_DIR}/cmake/uninstall.cmake.in"
        "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
        IMMEDIATE @ONLY)

    add_custom_target(uninstall
        COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
endif()

# python interface target
add_subdirectory(python/pybind11)
pybind11_add_module(imfupython python/src/interface.cpp)
set_target_properties(imfupython PROPERTIES OUTPUT_NAME "_raw")
if(DEFINED IMFUPYTHON_INSTALL_RPATH)
    set_target_properties(imfupython PROPERTIES CMAKE_CXX_VISIBILITY_PRESET "hidden")
    set_target_properties(imfupython PROPERTIES BUILD_WITH_INSTALL_RPATH TRUE)
    set_target_properties(imfupython PROPERTIES INSTALL_RPATH "${IMFUPYTHON_INSTALL_RPATH}")
#add_library(gdal UNKNOWN IMPORTED) # import this library with abs path if rpath is enabled
#set_property(TARGET gdal PROPERTY IMPORTED_LOCATION "/usr/lib/libgdal.so.20")
target_link_libraries(imfupython PRIVATE imagefusion gdal)
#install(TARGETS imfupython EXPORT ImagefusionTargets # how to install?
#        RUNTIME  DESTINATION bin COMPONENT lib)


## export CMake config file (for use in external projects)
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
  "${CMAKE_CURRENT_BINARY_DIR}/imagefusion/ImagefusionConfigVersion.cmake"
  VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}"
  COMPATIBILITY AnyNewerVersion
)
export(EXPORT ImagefusionTargets
  FILE "${CMAKE_CURRENT_BINARY_DIR}/imagefusion/ImagefusionTargets.cmake"
  NAMESPACE Imagefusion::
)
configure_file(cmake/ImagefusionConfig.cmake
  "${CMAKE_CURRENT_BINARY_DIR}/imagefusion/ImagefusionConfig.cmake"
  COPYONLY
)

set(ConfigPackageLocation "${CMAKE_INSTALL_LIBDIR}/cmake/imagefusion")
install(EXPORT ImagefusionTargets
        FILE ImagefusionTargets.cmake
        NAMESPACE Imagefusion::
        DESTINATION ${ConfigPackageLocation}
        COMPONENT   dev
install(FILES cmake/ImagefusionConfig.cmake
              "${CMAKE_CURRENT_BINARY_DIR}/imagefusion/ImagefusionConfigVersion.cmake"
        DESTINATION ${ConfigPackageLocation}
        COMPONENT   dev
)


## Fix for QtCreator IDE, meaningless for CMake
# if you add a header file run "cmake .." in build again to update QTCreator
file(GLOB_RECURSE HeaderFiles "include/*.h")
file(GLOB_RECURSE TestHeaderFiles "test/*.h")
file(GLOB_RECURSE TestHeaderFiles "utils/*.h")
add_custom_target(headers SOURCES ${HeaderFiles} ${TestHeaderFiles})