This coverage is probably more useful than the other one, because it’s not really reasonable to try to cover everything with simple units test (e.g. on network code etc). However, we should strive to have 100% coverage with our e2e tests.
316 lines
9.7 KiB
CMake
316 lines
9.7 KiB
CMake
cmake_minimum_required(VERSION 3.0)
|
|
|
|
project(biboumi)
|
|
|
|
set(${PROJECT_NAME}_VERSION_MAJOR 4)
|
|
set(${PROJECT_NAME}_VERSION_MINOR 0)
|
|
set(${PROJECT_NAME}_VERSION_SUFFIX "~dev")
|
|
|
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y -pedantic -Wall -Wextra")
|
|
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
|
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage --coverage")
|
|
endif()
|
|
|
|
# Define a __FILENAME__ macro to get the filename of each file, instead of
|
|
# the full path as in __FILE__
|
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__FILENAME__='\"$(subst ${CMAKE_SOURCE_DIR}/,,$(abspath $<))\"'")
|
|
|
|
#
|
|
## Look for external libraries
|
|
#
|
|
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/")
|
|
|
|
#
|
|
## Get the software version
|
|
#
|
|
set(ARCHIVE_NAME ${CMAKE_PROJECT_NAME}-${${PROJECT_NAME}_VERSION_MAJOR}.${${PROJECT_NAME}_VERSION_MINOR})
|
|
set(RPM_VERSION ${${PROJECT_NAME}_VERSION_MAJOR}.${${PROJECT_NAME}_VERSION_MINOR})
|
|
|
|
if(${PROJECT_NAME}_VERSION_SUFFIX MATCHES ".+")
|
|
set(ARCHIVE_NAME ${ARCHIVE_NAME}${${PROJECT_NAME}_VERSION_SUFFIX})
|
|
set(RPM_VERSION ${RPM_VERSION}${${PROJECT_NAME}_VERSION_SUFFIX})
|
|
endif()
|
|
|
|
if(${PROJECT_NAME}_VERSION_SUFFIX MATCHES "^~dev$")
|
|
# If we are on a dev version, append the hash of the current git HEAD to
|
|
# the version
|
|
include(FindGit)
|
|
if(GIT_FOUND AND EXISTS "${CMAKE_SOURCE_DIR}/.git")
|
|
execute_process(COMMAND git --git-dir=${CMAKE_SOURCE_DIR}/.git rev-parse --short HEAD
|
|
OUTPUT_VARIABLE GIT_REVISION
|
|
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
if(GIT_REVISION)
|
|
set(${PROJECT_NAME}_VERSION_SUFFIX "${${PROJECT_NAME}_VERSION_SUFFIX} (${GIT_REVISION})")
|
|
set(ARCHIVE_NAME ${ARCHIVE_NAME}${GIT_REVISION})
|
|
set(RPM_VERSION ${RPM_VERSION}${GIT_REVISION})
|
|
endif()
|
|
endif()
|
|
endif()
|
|
|
|
set(SOFTWARE_VERSION
|
|
${${PROJECT_NAME}_VERSION_MAJOR}.${${PROJECT_NAME}_VERSION_MINOR}${${PROJECT_NAME}_VERSION_SUFFIX})
|
|
|
|
include(CheckFunctionExists)
|
|
check_function_exists(ppoll HAVE_PPOLL_FUNCTION)
|
|
|
|
# To be able to include the config.h and other files generated by cmake
|
|
include_directories("${CMAKE_CURRENT_BINARY_DIR}/src/")
|
|
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/src/")
|
|
include_directories("${CMAKE_CURRENT_BINARY_DIR}/")
|
|
|
|
#
|
|
## Documentation
|
|
#
|
|
execute_process(COMMAND "date" "+%Y-%m-%d" OUTPUT_VARIABLE DOC_DATE
|
|
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
set(MAN_PAGE ${CMAKE_CURRENT_BINARY_DIR}/doc/${PROJECT_NAME}.1)
|
|
set(DOC_PAGE ${CMAKE_CURRENT_SOURCE_DIR}/doc/${PROJECT_NAME}.1.rst)
|
|
if (NOT PANDOC_EXECUTABLE)
|
|
find_program(PANDOC_EXECUTABLE NAMES pandoc
|
|
DOC "The pandoc software, to build the man page from the rst documentation")
|
|
if(PANDOC_EXECUTABLE)
|
|
message(STATUS "Found Pandoc: ${PANDOC_EXECUTABLE}")
|
|
set(WITH_DOC true)
|
|
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc/)
|
|
add_custom_command(OUTPUT ${MAN_PAGE}
|
|
COMMAND ${PANDOC_EXECUTABLE} -M date="${DOC_DATE}" -s -t man ${DOC_PAGE} -o ${MAN_PAGE}
|
|
DEPENDS ${DOC_PAGE})
|
|
add_custom_target(doc ALL DEPENDS ${MAN_PAGE})
|
|
else()
|
|
message(STATUS "Pandoc not found, documentation cannot be built")
|
|
endif()
|
|
endif()
|
|
mark_as_advanced(PANDOC_EXECUTABLE)
|
|
|
|
# Look for litesql and enable the database if found
|
|
if(WITH_LITESQL)
|
|
find_package(LITESQL REQUIRED)
|
|
elseif(NOT WITHOUT_LITESQL)
|
|
find_package(LITESQL)
|
|
endif()
|
|
|
|
if(LITESQL_FOUND)
|
|
LITESQL_GENERATE_CPP("database/database.xml"
|
|
"biboudb"
|
|
LITESQL_GENERATED_SOURCES)
|
|
|
|
add_library(database STATIC src/database/database.cpp
|
|
${LITESQL_GENERATED_SOURCES})
|
|
target_link_libraries(database ${LITESQL_LIBRARIES} utils)
|
|
if(BOTAN_FOUND)
|
|
target_link_libraries(database ${BOTAN_LIBRARIES})
|
|
endif()
|
|
set(USE_DATABASE TRUE)
|
|
endif()
|
|
|
|
add_subdirectory("louloulibs")
|
|
include_directories("louloulibs")
|
|
|
|
include_directories(${EXPAT_INCLUDE_DIRS})
|
|
include_directories(${ICONV_INCLUDE_DIRS})
|
|
include_directories(${LIBUUID_INCLUDE_DIRS})
|
|
|
|
# If they are found in louloulibs CMakeLists.txt, we inherite these values
|
|
if(SYSTEMD_FOUND)
|
|
include_directories(${SYSTEMD_INCLUDE_DIRS})
|
|
endif()
|
|
if(BOTAN_FOUND)
|
|
include_directories(SYSTEM ${BOTAN_INCLUDE_DIRS})
|
|
endif()
|
|
if(CARES_FOUND)
|
|
include_directories(${CARES_INCLUDE_DIRS})
|
|
endif()
|
|
|
|
#
|
|
## utils
|
|
#
|
|
file(GLOB source_src_utils
|
|
src/utils/*.[hc]pp)
|
|
# Todo, switch to target_sources(utils) when we go cmake >=3.1 only
|
|
add_library(src_utils STATIC ${source_src_utils})
|
|
target_link_libraries(src_utils logger config)
|
|
if(USE_DATABASE)
|
|
target_link_libraries(src_utils database)
|
|
endif()
|
|
|
|
#
|
|
## irclib
|
|
#
|
|
file(GLOB source_irc
|
|
src/irc/*.[hc]pp)
|
|
add_library(irc STATIC ${source_irc})
|
|
target_link_libraries(irc network utils logger)
|
|
|
|
#
|
|
## xmpp
|
|
#
|
|
file(GLOB source_xmpp
|
|
src/xmpp/*.[hc]pp)
|
|
add_library(xmpp STATIC ${source_xmpp})
|
|
target_link_libraries(xmpp xmpplib bridge network utils src_utils logger)
|
|
|
|
if(USE_DATABASE)
|
|
target_link_libraries(xmpp database)
|
|
target_link_libraries(irc database)
|
|
endif()
|
|
|
|
#
|
|
## bridge
|
|
#
|
|
file(GLOB source_bridge
|
|
src/bridge/*.[hc]pp)
|
|
add_library(bridge STATIC ${source_bridge})
|
|
target_link_libraries(bridge xmpp irc utils logger)
|
|
|
|
#
|
|
## Main executable
|
|
#
|
|
add_executable(${PROJECT_NAME} src/main.cpp)
|
|
target_link_libraries(${PROJECT_NAME}
|
|
xmpp
|
|
irc
|
|
bridge
|
|
utils
|
|
src_utils
|
|
config)
|
|
if(SYSTEMD_FOUND)
|
|
target_link_libraries(xmpp ${SYSTEMD_LIBRARIES})
|
|
endif()
|
|
|
|
#
|
|
## Tests
|
|
#
|
|
file(GLOB source_tests
|
|
tests/*.cpp)
|
|
add_executable(test_suite EXCLUDE_FROM_ALL
|
|
${source_tests})
|
|
target_link_libraries(test_suite
|
|
xmpplib
|
|
xmpp
|
|
irc
|
|
bridge
|
|
utils
|
|
config
|
|
logger
|
|
network)
|
|
if(USE_DATABASE)
|
|
target_link_libraries(test_suite
|
|
database)
|
|
endif()
|
|
|
|
include(ExternalProject)
|
|
ExternalProject_Add(catch
|
|
GIT_REPOSITORY "https://lab.louiz.org/louiz/Catch.git"
|
|
PREFIX "external"
|
|
UPDATE_COMMAND ""
|
|
CONFIGURE_COMMAND ""
|
|
BUILD_COMMAND ""
|
|
INSTALL_COMMAND ""
|
|
)
|
|
set_target_properties(catch PROPERTIES EXCLUDE_FROM_ALL TRUE)
|
|
ExternalProject_Get_Property(catch SOURCE_DIR)
|
|
if(NOT EXISTS ${CMAKE_SOURCE_DIR}/tests/catch.hpp)
|
|
target_include_directories(test_suite
|
|
PUBLIC "${SOURCE_DIR}/include/"
|
|
)
|
|
add_dependencies(test_suite catch)
|
|
endif()
|
|
add_custom_target(check COMMAND "test_suite"
|
|
DEPENDS test_suite biboumi)
|
|
add_custom_target(e2e COMMAND "python3" "${CMAKE_CURRENT_SOURCE_DIR}/tests/end_to_end/"
|
|
DEPENDS biboumi)
|
|
add_custom_target(e2e_valgrind COMMAND "E2E_BIBOUMI_SUPP_DIR=${CMAKE_CURRENT_SOURCE_DIR}/tests/end_to_end/" "E2E_BIBOUMI_VALGRIND=1" "python3" "${CMAKE_CURRENT_SOURCE_DIR}/tests/end_to_end/"
|
|
DEPENDS biboumi)
|
|
|
|
|
|
#
|
|
## Code coverage
|
|
#
|
|
if(CMAKE_BUILD_TYPE MATCHES Debug)
|
|
include(CodeCoverage)
|
|
SETUP_TARGET_FOR_COVERAGE(coverage
|
|
test_suite
|
|
coverage
|
|
)
|
|
SETUP_TARGET_FOR_COVERAGE(coverage_e2e
|
|
make
|
|
coverage_e2e
|
|
e2e)
|
|
endif()
|
|
|
|
#
|
|
## Install target
|
|
#
|
|
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin)
|
|
install(FILES ${MAN_PAGE} DESTINATION share/man/man1 OPTIONAL COMPONENT documentation)
|
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/biboumi.service DESTINATION lib/systemd/system COMPONENT init)
|
|
install(FILES conf/biboumi.cfg DESTINATION /etc/biboumi COMPONENT configuration)
|
|
|
|
#
|
|
## Dist target
|
|
## Generate a release tarball from the git sources
|
|
#
|
|
add_custom_command(OUTPUT ${ARCHIVE_NAME}.tar.xz
|
|
COMMAND git archive --prefix=${ARCHIVE_NAME}/ --format=tar HEAD^{tree}
|
|
> ${CMAKE_CURRENT_BINARY_DIR}/${ARCHIVE_NAME}.tar
|
|
# Append this specific file that is not part of the git repo
|
|
COMMAND tar -rf ${CMAKE_CURRENT_BINARY_DIR}/${ARCHIVE_NAME}.tar -P ${SOURCE_DIR}/single_include/catch.hpp --xform 's|/.*/|${ARCHIVE_NAME}/tests/|g'
|
|
# Remove a potential existing archive
|
|
COMMAND rm -f ${CMAKE_CURRENT_BINARY_DIR}/${ARCHIVE_NAME}.tar.xz
|
|
# Compress the archive
|
|
COMMAND xz ${CMAKE_CURRENT_BINARY_DIR}/${ARCHIVE_NAME}.tar
|
|
COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --cyan "${ARCHIVE_NAME}.tar.xz created."
|
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
|
)
|
|
add_custom_target(dist
|
|
DEPENDS ${ARCHIVE_NAME}.tar.xz
|
|
DEPENDS catch)
|
|
|
|
add_custom_target(rpm
|
|
DEPENDS dist
|
|
COMMAND mkdir -p rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
|
|
COMMAND rpmbuild --define "_topdir `pwd`/rpmbuild/" --define "_sourcedir `pwd`" -ba biboumi.spec
|
|
)
|
|
|
|
if(BOTAN_FOUND)
|
|
set(STR_WITH_BOTAN "Botan: yes")
|
|
else()
|
|
set(STR_WITH_BOTAN "Botan: no")
|
|
endif()
|
|
if(CARES_FOUND)
|
|
set(STR_WITH_CARES "c-ares: yes")
|
|
else()
|
|
set(STR_WITH_CARES "c-ares: no")
|
|
endif()
|
|
add_custom_target(PrintBuildParameters ALL
|
|
${CMAKE_COMMAND} -E cmake_echo_color --cyan "Compiling ${PROJECT_NAME} with ${STR_WITH_BOTAN}, ${STR_WITH_CARES}")
|
|
|
|
configure_file(biboumi.h.cmake src/biboumi.h)
|
|
|
|
set(SYSTEMD_SERVICE_TYPE_DOCSTRING "The value used as the Type= in the systemd unit file.")
|
|
set(WATCHDOG_SEC_DOCSTRING "The value used as WatchdogSec= in the systemd unit file.")
|
|
if(SYSTEMD_FOUND)
|
|
set(SYSTEMD_SERVICE_TYPE "notify" CACHE STRING ${SYSTEMD_SERVICE_TYPE_DOCSTRING})
|
|
set(WATCHDOG_SEC "20" CACHE STRING ${WATCHDOG_SEC_DOCSTRING})
|
|
else()
|
|
set(SYSTEMD_SERVICE_TYPE "simple" CACHE STRING ${SYSTEMD_SERVICE_TYPE_DOCSTRING})
|
|
set(WATCHDOG_SEC "" CACHE STRING ${WATCHDOG_SEC_DOCSTRING})
|
|
endif()
|
|
set(SERVICE_USER_DOCSTRING "The value used as the User= in the systemd unit file.")
|
|
if(NOT DEFINED SERVICE_USER)
|
|
set(SERVICE_USER "nobody" CACHE STRING ${SERVICE_USER_DOCSTRING})
|
|
endif()
|
|
set(SERVICE_GROUP_DOCSTRING "The value used as the Group= in the systemd unit file.")
|
|
if(NOT DEFINED SERVICE_GROUP)
|
|
set(SERVICE_GROUP "nobody" CACHE STRING ${SERVICE_GROUP_DOCSTRING})
|
|
endif()
|
|
configure_file(unit/biboumi.service.cmake biboumi.service)
|
|
|
|
# The date MUST be in english format
|
|
set(ENV{LANG} "en_US.utf-8")
|
|
execute_process(COMMAND "date" "+%a %b %d %Y" OUTPUT_VARIABLE RPM_DATE
|
|
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
unset(ENV{LANG})
|
|
|
|
configure_file(packaging/biboumi.spec.cmake biboumi.spec)
|