Skip to content
Snippets Groups Projects
CMakeLists.txt 6.96 KiB
Newer Older
cmake_minimum_required(VERSION 3.15)
set(CXX_STANDARD 14)
Cyril Moineau's avatar
Cyril Moineau committed

file(STRINGS "${CMAKE_SOURCE_DIR}/version.txt" version)
project(aidge_core
        VERSION ${version}
        DESCRIPTION "Core algorithms for operators and graph of the AIDGE framework" 
        LANGUAGES CXX)
message(STATUS "Project name: ${CMAKE_PROJECT_NAME}")
message(STATUS "Project version: ${version}")
add_definitions(-DPROJECT_VERSION="${version}")

message(STATUS "Project name: ${CMAKE_PROJECT_NAME}")
message(STATUS "Project version: ${version}")

# Note : project name is {project} and python module name is also {project}
set(module_name _${CMAKE_PROJECT_NAME}) # target name
Cyril Moineau's avatar
Cyril Moineau committed

##############################################
# Define options
option(PYBIND "python binding" OFF)
option(WERROR "Warning as error" OFF)
option(TEST "Enable tests" ON)
Olivier BICHLER's avatar
Olivier BICHLER committed
option(COVERAGE "Enable coverage" OFF)
Maxence Naud's avatar
Maxence Naud committed
option(ENABLE_ASAN "Enable ASan (AddressSanitizer) for runtime analysis of memory use (over/underflow, memory leak, ...)" OFF)
Olivier BICHLER's avatar
Olivier BICHLER committed

##############################################
# Import utils CMakeLists
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")

if(CMAKE_COMPILER_IS_GNUCXX AND COVERAGE)
    Include(CodeCoverage)
endif()
Cyril Moineau's avatar
Cyril Moineau committed

##############################################
# Find system dependencies
Cyril Moineau's avatar
Cyril Moineau committed

set(FMT_VERSION 10.2.1)
message(STATUS "Retrieving fmt ${FMT_VERSION} from git")
FetchContent_Declare(
    fmt
    GIT_REPOSITORY https://github.com/fmtlib/fmt.git
    GIT_TAG        ${FMT_VERSION} # or a later release
Olivier BICHLER's avatar
Olivier BICHLER committed

Olivier BICHLER's avatar
Olivier BICHLER committed
set(FMT_SYSTEM_HEADERS ON)
set_property(TARGET fmt PROPERTY POSITION_INDEPENDENT_CODE ON)
Olivier BICHLER's avatar
Olivier BICHLER committed

Olivier BICHLER's avatar
Olivier BICHLER committed
find_package(Threads REQUIRED)

##############################################
# Create target and set properties
Cyril Moineau's avatar
Cyril Moineau committed

file(GLOB_RECURSE src_files "src/*.cpp")
file(GLOB_RECURSE inc_files "include/*.hpp")

add_library(${module_name} ${src_files} ${inc_files})
Cyril Moineau's avatar
Cyril Moineau committed

#Set target properties
set_property(TARGET ${module_name} PROPERTY POSITION_INDEPENDENT_CODE ON)
target_include_directories(${module_name}
    PUBLIC
        $<INSTALL_INTERFACE:include>
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    PRIVATE
        ${CMAKE_CURRENT_SOURCE_DIR}/src
)
if( ${ENABLE_ASAN} )
    message("Building ${module_name} with ASAN.")
    set(SANITIZE_FLAGS -fsanitize=address -fno-omit-frame-pointer)
    target_link_libraries(${module_name}
        PUBLIC
            -fsanitize=address
    )
    target_compile_options(${module_name}
        PRIVATE
            ${SANITIZE_FLAGS}
    )
endif()

Cyril Moineau's avatar
Cyril Moineau committed
if (PYBIND)
    # Handles Python + pybind11 headers dependencies
    include(PybindModuleCreation)
    generate_python_binding(${CMAKE_PROJECT_NAME} ${module_name})

    target_link_libraries(${module_name}
        PUBLIC
            pybind11::pybind11
        PRIVATE
            Python::Module
        )
Cyril Moineau's avatar
Cyril Moineau committed
endif()
Olivier BICHLER's avatar
Olivier BICHLER committed
target_link_libraries(${module_name} PUBLIC Threads::Threads fmt::fmt)
target_compile_features(${module_name} PRIVATE cxx_std_14)

if (DOSANITIZE STREQUAL "ON")
set(SANITIZE_FLAGS -fsanitize=address,leak,undefined,float-divide-by-zero -fno-omit-frame-pointer)
#TODO sanitizer seems buggy in some situations with msvc, leading to linker errors, temporarily inactivating it
#set(SANITIZE_MSVC_FLAGS)
set(SANITIZE_MSVC_FLAGS /fsanitize=address)
target_compile_definitions(${module_name} PUBLIC _DISABLE_VECTOR_ANNOTATION)
else()
set(SANITIZE_FLAGS)
set(SANITIZE_MSVC_FLAGS)
endif()

set(STRICT_ALIASING_FLAGS -fstrict-aliasing -Wstrict-aliasing=2)

# -fvisibility=hidden required by pybind11
target_compile_options(${module_name} PUBLIC
    $<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:GNU>>:
    -fvisibility=hidden>)
Olivier BICHLER's avatar
Olivier BICHLER committed
target_compile_options(${module_name} PRIVATE
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:GNU>>:
-Wall -Wextra -Wold-style-cast -Winline -pedantic -Werror=narrowing -Wshadow $<$<BOOL:${WERROR}>:-Werror> ${SANITIZE_FLAGS}>)
target_compile_options(${module_name} PRIVATE
$<$<CXX_COMPILER_ID:GNU>:${STRICT_ALIASING_FLAGS}>)
Olivier BICHLER's avatar
Olivier BICHLER committed
target_compile_options(${module_name} PRIVATE
$<$<CXX_COMPILER_ID:MSVC>:
/W4 /wd4477 /DWIN32 /D_WINDOWS /GR /EHsc /MP /Zc:__cplusplus /Zc:preprocessor /permissive- ${SANITIZE_MSVC_FLAGS}>)
if (DOSANITIZE STREQUAL "ON")
    target_compile_options(${module_name} PRIVATE $<$<CXX_COMPILER_ID:MSVC>:/MDd>)
endif()
# TODO FIXME: I'm not sure it's a good idea to propagate this option but, at this point, it was the only way that worked to silence C4477
target_compile_options(${module_name} PUBLIC $<$<CXX_COMPILER_ID:MSVC>: /wd4477>)

target_link_options(${module_name} PUBLIC $<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:GNU>>:${SANITIZE_FLAGS}>)
#target_link_options(${module_name} PUBLIC $<$<CXX_COMPILER_ID:MSVC>:${SANITIZE_MSVC_FLAGS}>)
Olivier BICHLER's avatar
Olivier BICHLER committed
if(CMAKE_COMPILER_IS_GNUCXX AND COVERAGE)
    append_coverage_compiler_flags()
endif()

##############################################
# Installation instructions
if(NOT $ENV{AIDGE_INSTALL} STREQUAL "")
    set(CMAKE_INSTALL_PREFIX $ENV{AIDGE_INSTALL})
    message(WARNING "CMAKE_INSTALL_PREFIX set to env variable AIDGE_INSTALL by default = ${CMAKE_INSTALL_PREFIX}")
endif()

include(GNUInstallDirs)
set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/${CMAKE_PROJECT_NAME})
install(TARGETS ${module_name} EXPORT ${CMAKE_PROJECT_NAME}-targets
  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
  INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)

install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

#Export the targets to a script
install(EXPORT ${CMAKE_PROJECT_NAME}-targets
 FILE "${CMAKE_PROJECT_NAME}-targets.cmake"
#  COMPONENT ${module_name}
)

#Create a ConfigVersion.cmake file
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
    "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}-config-version.cmake"
    VERSION ${version}
    COMPATIBILITY AnyNewerVersion
)

configure_package_config_file("${CMAKE_PROJECT_NAME}-config.cmake.in"
    "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}-config.cmake"
    INSTALL_DESTINATION ${INSTALL_CONFIGDIR}
)

#Install the config, configversion and custom find modules
install(FILES
    "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}-config.cmake"
    "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}-config-version.cmake"
    DESTINATION ${INSTALL_CONFIGDIR}
)

##############################################
## Exporting from the build tree
message(STATUS "Exporting created targets to use them in another build")
export(EXPORT ${CMAKE_PROJECT_NAME}-targets
    FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}-targets.cmake")


##############################################
## Add test
    if(PYBIND)
        message(FATAL_ERROR "PYBIND and TEST are both enabled. But cannot compile with catch_2.\nChoose between pybind and Catch2 for compilation.")
    enable_testing()
    add_subdirectory(unit_tests)