CMakeLists.txt 14.2 KB
Newer Older
1
cmake_minimum_required(VERSION 3.0)
2 3 4

project(biboumi)

louiz’'s avatar
louiz’ committed
5
set(${PROJECT_NAME}_VERSION_MAJOR 8)
6
set(${PROJECT_NAME}_VERSION_MINOR 0)
louiz’'s avatar
louiz’ committed
7
set(${PROJECT_NAME}_VERSION_SUFFIX "~dev")
8

9 10 11 12 13 14 15 16 17 18
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
    if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
        message(FATAL_ERROR "GCC version must be at least 5.0.")
    endif()
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
    if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.4)
        message(FATAL_ERROR "Clang version must be at least 3.4.")
    endif()
endif()

19 20 21 22 23
if(NOT CMAKE_BUILD_TYPE)
  set(CMAKE_BUILD_TYPE "Debug" CACHE STRING
      "Build type (Release/Debug/RelWithDebInfo/MinSizeRel)" FORCE)
endif()

louiz’'s avatar
louiz’ committed
24 25 26
#
## Find optional instrumentation libraries that will be used in debug only
#
27
find_library(LIBASAN NAMES asan libasan.so.4 libasan.so.3 libasan.so.2 libasan.so.1)
28 29
find_library(LIBUBSAN NAMES ubsan libubsan.so.0)

louiz’'s avatar
louiz’ committed
30 31 32
#
## Set various debug flags (instrumentation libs, coverage, …)
#
louiz’'s avatar
louiz’ committed
33
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y -pedantic -Wall -Wextra -Wconversion -fvisibility=hidden -fvisibility-inlines-hidden")
34 35 36
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
  set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage --coverage")
endif()
37 38 39 40 41 42 43
if(LIBASAN)
  set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=address")
endif()
if(LIBUBSAN)
  set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=undefined")
endif()

44
#
louiz’'s avatar
louiz’ committed
45
## Set the software version, archive name, RPM name etc
46
#
louiz’'s avatar
louiz’ committed
47
set(ARCHIVE_NAME ${CMAKE_PROJECT_NAME}-${${PROJECT_NAME}_VERSION_MAJOR}.${${PROJECT_NAME}_VERSION_MINOR})
48 49
set(RPM_VERSION ${${PROJECT_NAME}_VERSION_MAJOR}.${${PROJECT_NAME}_VERSION_MINOR})

louiz’'s avatar
louiz’ committed
50
if(${PROJECT_NAME}_VERSION_SUFFIX MATCHES ".+")
51
  set(ARCHIVE_NAME ${ARCHIVE_NAME}${${PROJECT_NAME}_VERSION_SUFFIX})
52
  set(RPM_VERSION ${RPM_VERSION}${${PROJECT_NAME}_VERSION_SUFFIX})
louiz’'s avatar
louiz’ committed
53 54 55
endif()

if(${PROJECT_NAME}_VERSION_SUFFIX MATCHES "^~dev$")
56 57 58
  # If we are on a dev version, append the hash of the current git HEAD to
  # the version
  include(FindGit)
louiz’'s avatar
louiz’ committed
59
  if(GIT_FOUND AND EXISTS "${CMAKE_SOURCE_DIR}/.git")
60 61 62 63 64
    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})")
65
      set(ARCHIVE_NAME ${ARCHIVE_NAME}${GIT_REVISION})
66
      set(RPM_VERSION ${RPM_VERSION}${GIT_REVISION})
67 68 69 70
    endif()
  endif()
endif()

71
set(SOFTWARE_VERSION
72 73
  ${${PROJECT_NAME}_VERSION_MAJOR}.${${PROJECT_NAME}_VERSION_MINOR}${${PROJECT_NAME}_VERSION_SUFFIX})

74
#
louiz’'s avatar
louiz’ committed
75
## The rule that generates the documentation
76
#
77 78
execute_process(COMMAND "date" "+%Y-%m-%d" OUTPUT_VARIABLE DOC_DATE
                OUTPUT_STRIP_TRAILING_WHITESPACE)
79
set(MAN_PAGE ${CMAKE_CURRENT_BINARY_DIR}/doc/${PROJECT_NAME}.1)
80
set(DOC_PAGE ${CMAKE_CURRENT_SOURCE_DIR}/doc/${PROJECT_NAME}.1.rst)
81 82 83 84 85 86 87 88 89 90 91 92 93 94
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()
95
endif()
96
mark_as_advanced(PANDOC_EXECUTABLE)
97

louiz’'s avatar
louiz’ committed
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
#
## Set this search path for cmake, to find our custom search modules
#
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/")
find_package(ICONV REQUIRED)
find_package(LIBUUID REQUIRED)
find_package(EXPAT REQUIRED)

#
## Find all the libraries (optional or not)
#
if(WITH_LIBIDN)
  find_package(LIBIDN REQUIRED)
elseif(NOT WITHOUT_LIBIDN)
  find_package(LIBIDN)
113 114
endif()

louiz’'s avatar
louiz’ committed
115 116 117 118 119
if(WITH_SYSTEMD)
  find_package(SYSTEMD REQUIRED)
elseif(NOT WITHOUT_SYSTEMD)
  find_package(SYSTEMD)
endif()
120

louiz’'s avatar
louiz’ committed
121 122 123 124
if(WITH_BOTAN)
  find_package(BOTAN REQUIRED)
elseif(NOT WITHOUT_BOTAN)
  find_package(BOTAN)
125 126
endif()

louiz’'s avatar
louiz’ committed
127 128 129
if(NOT BOTAN_FOUND)
  find_package(GCRYPT REQUIRED)
endif()
130

louiz’'s avatar
louiz’ committed
131 132 133 134 135 136
if(WITH_UDNS)
  find_package(UDNS REQUIRED)
elseif(NOT WITHOUT_UDNS)
  find_package(UDNS)
endif()

louiz’'s avatar
louiz’ committed
137 138 139 140
if(WITH_SQLITE3)
  find_package(SQLITE3 REQUIRED)
elseif(NOT WITHOUT_SQLITE3)
  find_package(SQLITE3)
louiz’'s avatar
louiz’ committed
141 142
endif()

louiz’'s avatar
louiz’ committed
143 144 145 146 147 148
if(WITH_POSTGRESQL)
  find_package(PQ REQUIRED)
elseif(NOT WITHOUT_POSTGRESQL)
  find_package(PQ)
endif()

louiz’'s avatar
louiz’ committed
149 150 151 152 153 154
#
## Set all the include directories, depending on what libraries are used
#
include_directories(${EXPAT_INCLUDE_DIRS})
include_directories(${ICONV_INCLUDE_DIRS})
include_directories(${LIBUUID_INCLUDE_DIRS})
155 156 157 158 159 160
if(SYSTEMD_FOUND)
  include_directories(${SYSTEMD_INCLUDE_DIRS})
endif()
if(BOTAN_FOUND)
  include_directories(SYSTEM ${BOTAN_INCLUDE_DIRS})
endif()
louiz’'s avatar
louiz’ committed
161 162
if(UDNS_FOUND)
  include_directories(${UDNS_INCLUDE_DIRS})
163
endif()
164

louiz’'s avatar
louiz’ committed
165 166 167 168
# 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}/")
169

170
#
louiz’'s avatar
louiz’ committed
171
## Define all the modules
172
#
louiz’'s avatar
louiz’ committed
173 174 175 176 177

file(GLOB source_utils
        src/utils/*.[hc]pp)
add_library(utils OBJECT ${source_utils})

178
file(GLOB source_irc
louiz’'s avatar
louiz’ committed
179 180
        src/irc/*.[hc]pp)
add_library(irc OBJECT ${source_irc})
181

182
file(GLOB source_xmpp
louiz’'s avatar
louiz’ committed
183 184
        src/xmpp/*.[hc]pp)
add_library(xmpp OBJECT ${source_xmpp})
185

louiz’'s avatar
louiz’ committed
186
file(GLOB source_identd
louiz’'s avatar
louiz’ committed
187 188
        src/identd/*.[hc]pp)
add_library(identd OBJECT ${source_identd})
louiz’'s avatar
louiz’ committed
189

190
file(GLOB source_bridge
louiz’'s avatar
louiz’ committed
191 192
        src/bridge/*.[hc]pp)
add_library(bridge OBJECT ${source_bridge})
193

louiz’'s avatar
louiz’ committed
194 195 196 197 198 199 200 201 202 203 204 205
file(GLOB source_config
        src/config/*.[hc]pp)
add_library(config OBJECT ${source_config})

file(GLOB source_logger
        src/logger/*.[hc]pp)
add_library(logger OBJECT ${source_logger})

file(GLOB source_network
        src/network/*.[hc]pp)
add_library(network OBJECT ${source_network})

206 207 208
option(DEBUG_SQL_QUERIES
       "If set to true, every SQL statement executed will be logged and timed"
       OFF)
209
if(SQLITE3_FOUND OR PQ_FOUND)
louiz’'s avatar
louiz’ committed
210 211 212
  file(GLOB source_database
          src/database/*.[hc]pp)
  add_library(database OBJECT ${source_database})
213

214 215 216 217 218 219
  if(SQLITE3_FOUND)
    include_directories(database ${SQLITE3_INCLUDE_DIRS})
  endif()
  if(PQ_FOUND)
    include_directories(database ${PQ_INCLUDE_DIRS})
  endif()
louiz’'s avatar
louiz’ committed
220 221 222 223
  set(USE_DATABASE TRUE)
else()
  add_library(database OBJECT "")
endif()
louiz’'s avatar
louiz’ committed
224

225
#
louiz’'s avatar
louiz’ committed
226
## Define the executables
227
#
louiz’'s avatar
louiz’ committed
228 229 230 231 232 233 234 235 236 237 238 239 240 241

## main
add_executable(${PROJECT_NAME} src/main.cpp
        $<TARGET_OBJECTS:utils>
        $<TARGET_OBJECTS:config>
        $<TARGET_OBJECTS:logger>
        $<TARGET_OBJECTS:network>
        $<TARGET_OBJECTS:xmpp>
        $<TARGET_OBJECTS:bridge>
        $<TARGET_OBJECTS:irc>
        $<TARGET_OBJECTS:identd>
        $<TARGET_OBJECTS:database>)

## test_suite
louiz’'s avatar
louiz’ committed
242 243
file(GLOB source_tests
  tests/*.cpp)
louiz’'s avatar
louiz’ committed
244 245 246 247 248 249 250 251 252 253
add_executable(test_suite ${source_tests}
        $<TARGET_OBJECTS:utils>
        $<TARGET_OBJECTS:config>
        $<TARGET_OBJECTS:logger>
        $<TARGET_OBJECTS:network>
        $<TARGET_OBJECTS:xmpp>
        $<TARGET_OBJECTS:bridge>
        $<TARGET_OBJECTS:irc>
        $<TARGET_OBJECTS:identd>
        $<TARGET_OBJECTS:database>)
254
set_target_properties(test_suite PROPERTIES EXCLUDE_FROM_ALL TRUE)
255

louiz’'s avatar
louiz’ committed
256 257 258
#
## Link the executables with their libraries
#
259
target_link_libraries(${PROJECT_NAME}
260
        ${ICONV_LIBRARIES}
261
        ${LIBUUID_LIBRARIES}
262
        ${EXPAT_LIBRARY})
263
target_link_libraries(test_suite
264
        ${ICONV_LIBRARIES}
265
        ${LIBUUID_LIBRARIES}
266
        ${EXPAT_LIBRARY})
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285
if(SYSTEMD_FOUND)
  target_link_libraries(${PROJECT_NAME} ${SYSTEMD_LIBRARIES})
  target_link_libraries(test_suite ${SYSTEMD_LIBRARIES})
endif()
if(BOTAN_FOUND)
  target_link_libraries(${PROJECT_NAME} ${BOTAN_LIBRARIES})
  target_link_libraries(test_suite ${BOTAN_LIBRARIES})
elseif(GCRYPT_FOUND)
  target_link_libraries(${PROJECT_NAME} ${GCRYPT_LIBRARIES})
  target_link_libraries(test_suite ${GCRYPT_LIBRARIES})
endif()
if(UDNS_FOUND)
  target_link_libraries(${PROJECT_NAME} ${UDNS_LIBRARIES})
  target_link_libraries(test_suite ${UDNS_LIBRARIES})
endif()
if(LIBIDN_FOUND)
  target_link_libraries(${PROJECT_NAME} ${LIBIDN_LIBRARIES})
  target_link_libraries(test_suite ${LIBIDN_LIBRARIES})
endif()
286
if(USE_DATABASE)
287 288 289 290 291 292 293 294
  if(SQLITE3_FOUND)
    target_link_libraries(${PROJECT_NAME} ${SQLITE3_LIBRARIES})
    target_link_libraries(test_suite ${SQLITE3_LIBRARIES})
  endif()
  if(PQ_FOUND)
    target_link_libraries(${PROJECT_NAME} ${PQ_LIBRARIES})
    target_link_libraries(test_suite ${PQ_LIBRARIES})
endif()
295
endif()
296

297 298 299 300 301 302 303 304
# Define a __FILENAME__ macro with the relative path (from the base project directory)
# of each source file
file(GLOB_RECURSE source_all src/*.[hc]pp tests/*.[hc]pp)
foreach(file ${source_all})
  file(RELATIVE_PATH shorter_file ${CMAKE_CURRENT_SOURCE_DIR} ${file})
  set_property(SOURCE ${file} APPEND PROPERTY COMPILE_DEFINITIONS __FILENAME__="${shorter_file}")
endforeach()

louiz’'s avatar
louiz’ committed
305 306 307
#
## Add a rule to download the catch unit test framework
#
louiz’'s avatar
louiz’ committed
308 309
include(ExternalProject)
ExternalProject_Add(catch
310
  GIT_REPOSITORY "https://lab.louiz.org/louiz/Catch.git"
louiz’'s avatar
louiz’ committed
311 312 313 314 315
  PREFIX "external"
  UPDATE_COMMAND ""
  CONFIGURE_COMMAND ""
  BUILD_COMMAND ""
  INSTALL_COMMAND ""
316
  )
317
set_target_properties(catch PROPERTIES EXCLUDE_FROM_ALL TRUE)
louiz’'s avatar
louiz’ committed
318
ExternalProject_Get_Property(catch SOURCE_DIR)
319 320
if(NOT EXISTS ${CMAKE_SOURCE_DIR}/tests/catch.hpp)
  target_include_directories(test_suite
321
    PUBLIC "${SOURCE_DIR}/single_include/"
322 323 324
    )
  add_dependencies(test_suite catch)
endif()
louiz’'s avatar
louiz’ committed
325 326 327 328

#
## Add some custom rules to launch the tests
#
louiz’'s avatar
louiz’ committed
329
add_custom_target(check COMMAND "test_suite"
330
  DEPENDS test_suite biboumi)
331
set_target_properties(check PROPERTIES EXCLUDE_FROM_ALL TRUE)
332 333
add_custom_target(e2e COMMAND "python3" "${CMAKE_CURRENT_SOURCE_DIR}/tests/end_to_end/"
  DEPENDS biboumi)
334
set_target_properties(e2e PROPERTIES EXCLUDE_FROM_ALL TRUE)
louiz’'s avatar
louiz’ committed
335 336
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)
louiz’'s avatar
louiz’ committed
337
if(CMAKE_BUILD_TYPE MATCHES Debug)
338
  include(CodeCoverage)
339
  SETUP_TARGET_FOR_COVERAGE(coverage_check
340 341 342 343
    ./test_suite
    coverage_test_suite)
  add_dependencies(coverage_check test_suite)

344
  SETUP_TARGET_FOR_COVERAGE(coverage_e2e
345
    python3
346
    coverage_e2e
347 348
    ${CMAKE_CURRENT_SOURCE_DIR}/tests/end_to_end/)
  add_dependencies(coverage_e2e biboumi)
349 350 351 352 353 354 355 356

  ADD_CUSTOM_TARGET(coverage
    COMMAND ${LCOV_PATH} -a coverage_e2e.info -a coverage_test_suite.info -o coverage_total.info

    COMMAND ${GENHTML_PATH} -o coverage_total coverage_total.info

    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
    )
357
endif()
358
add_custom_target(everything DEPENDS test_suite biboumi)
louiz’'s avatar
louiz’ committed
359

louiz’'s avatar
louiz’ committed
360 361 362
#
## Install target
#
363 364
install(TARGETS ${PROJECT_NAME} RUNTIME                     DESTINATION bin)
install(FILES   ${MAN_PAGE}                                 DESTINATION share/man/man1         OPTIONAL COMPONENT documentation)
365
install(FILES   ${CMAKE_CURRENT_BINARY_DIR}/biboumi.service DESTINATION lib/systemd/system     COMPONENT init)
366 367
file(GLOB policy_files conf/*policy.txt)
install(FILES   ${policy_files}                             DESTINATION /etc/biboumi           COMPONENT configuration)
louiz’'s avatar
louiz’ committed
368 369 370 371 372

#
## Dist target
## Generate a release tarball from the git sources
#
373
add_custom_command(OUTPUT ${ARCHIVE_NAME}.tar.xz
374
  COMMAND git archive --prefix=${ARCHIVE_NAME}/ --format=tar HEAD^{tree}
375 376 377 378 379 380 381
          > ${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
382
  COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --cyan "${ARCHIVE_NAME}.tar.xz created."
383 384
  WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
  )
385 386 387
add_custom_target(dist
  DEPENDS ${ARCHIVE_NAME}.tar.xz
  DEPENDS catch)
388 389

add_custom_target(rpm
390
  DEPENDS dist
391 392 393
  COMMAND mkdir -p rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
  COMMAND rpmbuild --define "_topdir `pwd`/rpmbuild/" --define "_sourcedir `pwd`" -ba biboumi.spec
  )
394

louiz’'s avatar
louiz’ committed
395 396 397
#
## Set some variables that will be used in the cmake-generated files
#
398 399
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.")
400
if(SYSTEMD_FOUND)
401 402
  set(SYSTEMD_SERVICE_TYPE "notify" CACHE STRING ${SYSTEMD_SERVICE_TYPE_DOCSTRING})
  set(WATCHDOG_SEC "20" CACHE STRING ${WATCHDOG_SEC_DOCSTRING})
403
else()
404 405
  set(SYSTEMD_SERVICE_TYPE "simple" CACHE STRING ${SYSTEMD_SERVICE_TYPE_DOCSTRING})
  set(WATCHDOG_SEC "" CACHE STRING ${WATCHDOG_SEC_DOCSTRING})
406
endif()
407
set(SERVICE_USER_DOCSTRING "The value used as the User= in the systemd unit file.")
408
if(NOT DEFINED SERVICE_USER)
409
  set(SERVICE_USER "nobody" CACHE STRING ${SERVICE_USER_DOCSTRING})
410
endif()
411
set(SERVICE_GROUP_DOCSTRING "The value used as the Group= in the systemd unit file.")
412
if(NOT DEFINED SERVICE_GROUP)
413
  set(SERVICE_GROUP "nobody" CACHE STRING ${SERVICE_GROUP_DOCSTRING})
414
endif()
415

louiz’'s avatar
louiz’ committed
416
# Force the format of the date output
417
set(ENV{LANG} "C")
418 419
execute_process(COMMAND "date" "+%a %b %d %Y" OUTPUT_VARIABLE RPM_DATE
                OUTPUT_STRIP_TRAILING_WHITESPACE)
420
unset(ENV{LANG})
421

louiz’'s avatar
louiz’ committed
422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454
set(POLLER_DOCSTRING "Choose the poller between POLL and EPOLL (Linux-only)")
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
  set(POLLER "EPOLL" CACHE STRING ${POLLER_DOCSTRING})
else()
  set(POLLER "POLL" CACHE STRING ${POLLER_DOCSTRING})
endif()
if((NOT ${POLLER} MATCHES "POLL") AND
(NOT ${POLLER} MATCHES "EPOLL"))
  message(FATAL_ERROR "POLLER must be either POLL or EPOLL")
endif()

#
## Check if we have std::get_time and put_time
#
include(CheckCXXSourceCompiles)

check_cxx_source_compiles("
  #include <iomanip>
  int main()
  { std::get_time(nullptr, \"\"); }"
        HAS_GET_TIME)

mark_as_advanced(HAS_GET_TIME)

check_cxx_source_compiles("
  #include <iomanip>
  int main()
  { std::put_time(nullptr, \"\"); }"
        HAS_PUT_TIME)

mark_as_advanced(HAS_PUT_TIME)

configure_file(unit/biboumi.service.cmake biboumi.service)
455
configure_file(packaging/biboumi.spec.cmake biboumi.spec)
456
configure_file(src/biboumi.h.cmake src/biboumi.h)