diff options
Diffstat (limited to 'CMakeLists.txt')
-rw-r--r-- | CMakeLists.txt | 309 |
1 files changed, 309 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..d6d5ce8 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,309 @@ +cmake_minimum_required(VERSION 3.0) + +project(biboumi) + +set(${PROJECT_NAME}_VERSION_MAJOR 3) +set(${PROJECT_NAME}_VERSION_MINOR 0) +set(${PROJECT_NAME}_VERSION_SUFFIX "") + +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}) + 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" "-s" + 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 + ) +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_target(dist + COMMAND git archive --prefix=${ARCHIVE_NAME}/ --format=tar HEAD + > ${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_dependencies(dist catch) + +add_custom_target(rpm + COMMAND mkdir -p rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS} + COMMAND rpmbuild --define "_topdir `pwd`/rpmbuild/" --define "_sourcedir `pwd`" -ba biboumi.spec + ) +add_dependencies(rpm dist) + +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) |