#------------------------------- # PROJECT INFORMATION #------------------------------- cmake_minimum_required(VERSION 3.14) project(sdbus-c++ VERSION 2.1.0 LANGUAGES CXX C) include(GNUInstallDirs) # Installation directories for `install` command and pkgconfig file # ------------------------------- # CONFIGURATION OPTIONS # ------------------------------- option(SDBUSCPP_BUILD_LIBSYSTEMD "Fetch & build libsystemd static library and make it part of libsdbus-c++, instead of searching for it in the system" OFF) if(NOT SDBUSCPP_BUILD_LIBSYSTEMD) set(SDBUSCPP_SDBUS_LIB "default" CACHE STRING "sd-bus implementation library to search for and use (default, systemd, elogind, or basu)") set_property(CACHE SDBUSCPP_SDBUS_LIB PROPERTY STRINGS default systemd elogind basu) else() set(SDBUSCPP_LIBSYSTEMD_VERSION "252" CACHE STRING "libsystemd version (>=239) to build and incorporate into libsdbus-c++") set(SDBUSCPP_LIBSYSTEMD_EXTRA_CONFIG_OPTS "" CACHE STRING "Additional configuration options to be passed as-is to libsystemd build system") endif() option(SDBUSCPP_INSTALL "Enable installation of sdbus-c++ (downstream projects embedding sdbus-c++ may want to turn this OFF)" ON) option(SDBUSCPP_BUILD_TESTS "Build tests" OFF) if (SDBUSCPP_BUILD_TESTS) option(SDBUSCPP_BUILD_PERF_TESTS "Build also sdbus-c++ performance tests" OFF) option(SDBUSCPP_BUILD_STRESS_TESTS "Build also sdbus-c++ stress tests" OFF) set(SDBUSCPP_TESTS_INSTALL_PATH "tests/${PROJECT_NAME}" CACHE STRING "Specifies where the test binaries will be installed") set(SDBUSCPP_GOOGLETEST_VERSION 1.14.0 CACHE STRING "Version of gmock library to use") set(SDBUSCPP_GOOGLETEST_GIT_REPO "https://github.com/google/googletest.git" CACHE STRING "A git repo to clone and build googletest from if gmock is not found in the system") endif() option(SDBUSCPP_BUILD_CODEGEN "Build generator tool for C++ native bindings" OFF) option(SDBUSCPP_BUILD_EXAMPLES "Build example programs" OFF) option(SDBUSCPP_BUILD_DOCS "Build documentation for sdbus-c++" ON) if(SDBUSCPP_BUILD_DOCS) option(SDBUSCPP_BUILD_DOXYGEN_DOCS "Build doxygen documentation for sdbus-c++ API" OFF) endif() #option(SDBUSCPP_CLANG_TIDY "Co-compile with clang-tidy static analyzer" OFF) #option(SDBUSCPP_COVERAGE "Build sdbus-c++ with code coverage instrumentation" OFF) # We promote the BUILD_SHARED_LIBS flag to a (global) option only if we are the main project if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR) option(BUILD_SHARED_LIBS "Build shared libraries (.so) instead of static ones (.a)" ON) endif() message(STATUS "") message(STATUS " *******************************************") message(STATUS " * SDBUS-C++ CONFIGURATION *") message(STATUS " *******************************************") message(STATUS "") message(STATUS " SDBUSCPP_BUILD_LIBSYSTEMD: ${SDBUSCPP_BUILD_LIBSYSTEMD}") if(SDBUSCPP_BUILD_LIBSYSTEMD) message(STATUS " SDBUSCPP_LIBSYSTEMD_VERSION: ${SDBUSCPP_LIBSYSTEMD_VERSION}") message(STATUS " SDBUSCPP_LIBSYSTEMD_EXTRA_CONFIG_OPTS: ${SDBUSCPP_LIBSYSTEMD_EXTRA_CONFIG_OPTS}") endif() message(STATUS " SDBUSCPP_INSTALL: ${SDBUSCPP_INSTALL}") message(STATUS " SDBUSCPP_BUILD_TESTS: ${SDBUSCPP_BUILD_TESTS}") if(SDBUSCPP_BUILD_TESTS) message(STATUS " SDBUSCPP_BUILD_PERF_TESTS: ${SDBUSCPP_BUILD_PERF_TESTS}") message(STATUS " SDBUSCPP_BUILD_STRESS_TESTS: ${SDBUSCPP_BUILD_STRESS_TESTS}") message(STATUS " SDBUSCPP_TESTS_INSTALL_PATH: ${SDBUSCPP_TESTS_INSTALL_PATH}") message(STATUS " SDBUSCPP_GOOGLETEST_VERSION: ${SDBUSCPP_GOOGLETEST_VERSION}") message(STATUS " SDBUSCPP_GOOGLETEST_GIT_REPO: ${SDBUSCPP_GOOGLETEST_GIT_REPO}") endif() message(STATUS " SDBUSCPP_BUILD_CODEGEN: ${SDBUSCPP_BUILD_CODEGEN}") message(STATUS " SDBUSCPP_BUILD_EXAMPLES: ${SDBUSCPP_BUILD_EXAMPLES}") message(STATUS " SDBUSCPP_BUILD_DOCS: ${SDBUSCPP_BUILD_DOCS}") if(SDBUSCPP_BUILD_DOCS) message(STATUS " SDBUSCPP_BUILD_DOXYGEN_DOCS: ${SDBUSCPP_BUILD_DOXYGEN_DOCS}") endif() message(STATUS " BUILD_SHARED_LIBS: ${BUILD_SHARED_LIBS}") message(STATUS "") #------------------------------- # PERFORMING CHECKS & PREPARING THE DEPENDENCIES #------------------------------- if(SDBUSCPP_BUILD_LIBSYSTEMD) # Build static libsystemd library as an external project include(cmake/LibsystemdExternalProject.cmake) set(SDBUS_IMPL "systemd") set(SDBUS_LIB "libsystemd") else() # Search for sd-bus implementations in the system as per user's configuration set(SDBUS_LIBS ${SDBUSCPP_SDBUS_LIB}) if(SDBUSCPP_SDBUS_LIB STREQUAL "default") set(SDBUS_LIBS systemd elogind basu) # This is the default search order endif() set(MINIMUM_SDBUS_VERSION 238) find_package(PkgConfig REQUIRED) foreach(LIB ${SDBUS_LIBS}) if(LIB STREQUAL "systemd") pkg_check_modules(Systemd IMPORTED_TARGET GLOBAL libsystemd>=${MINIMUM_SDBUS_VERSION}) if(TARGET PkgConfig::Systemd) set(SDBUS_IMPL "systemd") set(SDBUS_LIB "libsystemd") break() endif() elseif(LIB STREQUAL "elogind") pkg_check_modules(Systemd IMPORTED_TARGET GLOBAL libelogind>=${MINIMUM_SDBUS_VERSION}) if(TARGET PkgConfig::Systemd) set(SDBUS_IMPL "elogind") set(SDBUS_LIB "libelogind") string(REPLACE "." ";" VERSION_LIST ${Systemd_VERSION}) list(GET VERSION_LIST 0 Systemd_VERSION) break() endif() elseif(LIB STREQUAL "basu") pkg_check_modules(Systemd IMPORTED_TARGET GLOBAL basu) if(TARGET PkgConfig::Systemd) set(SDBUS_IMPL "basu") set(SDBUS_LIB "basu") set(Systemd_VERSION "240") # https://git.sr.ht/~emersion/basu/commit/d4d185d29a26 break() endif() else() message(FATAL_ERROR "Unrecognized sd-bus implementation library ${LIB}") endif() endforeach() if(NOT TARGET PkgConfig::Systemd) message(FATAL_ERROR "None of ${SDBUS_LIBS} libraries implementing sd-bus was found (Are their dev packages installed?)") endif() add_library(Systemd::Libsystemd ALIAS PkgConfig::Systemd) string(REGEX MATCHALL "([0-9]+)" SYSTEMD_VERSION_LIST "${Systemd_VERSION}") list(GET SYSTEMD_VERSION_LIST 0 SDBUSCPP_LIBSYSTEMD_VERSION) message(STATUS "Building with libsystemd v${SDBUSCPP_LIBSYSTEMD_VERSION}") endif() find_package(Threads REQUIRED) #------------------------------- # SOURCE FILES CONFIGURATION #------------------------------- set(SDBUSCPP_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src) set(SDBUSCPP_INCLUDE_SUBDIR sdbus-c++) set(SDBUSCPP_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include/${SDBUSCPP_INCLUDE_SUBDIR}) set(SDBUSCPP_CPP_SRCS ${SDBUSCPP_SOURCE_DIR}/Connection.cpp ${SDBUSCPP_SOURCE_DIR}/Error.cpp ${SDBUSCPP_SOURCE_DIR}/Message.cpp ${SDBUSCPP_SOURCE_DIR}/Object.cpp ${SDBUSCPP_SOURCE_DIR}/Proxy.cpp ${SDBUSCPP_SOURCE_DIR}/Types.cpp ${SDBUSCPP_SOURCE_DIR}/Flags.cpp ${SDBUSCPP_SOURCE_DIR}/VTableUtils.c ${SDBUSCPP_SOURCE_DIR}/SdBus.cpp) set(SDBUSCPP_HDR_SRCS ${SDBUSCPP_SOURCE_DIR}/Connection.h ${SDBUSCPP_SOURCE_DIR}/IConnection.h ${SDBUSCPP_SOURCE_DIR}/MessageUtils.h ${SDBUSCPP_SOURCE_DIR}/Utils.h ${SDBUSCPP_SOURCE_DIR}/Object.h ${SDBUSCPP_SOURCE_DIR}/Proxy.h ${SDBUSCPP_SOURCE_DIR}/ScopeGuard.h ${SDBUSCPP_SOURCE_DIR}/VTableUtils.h ${SDBUSCPP_SOURCE_DIR}/SdBus.h ${SDBUSCPP_SOURCE_DIR}/ISdBus.h) set(SDBUSCPP_PUBLIC_HDRS ${SDBUSCPP_INCLUDE_DIR}/ConvenienceApiClasses.h ${SDBUSCPP_INCLUDE_DIR}/ConvenienceApiClasses.inl ${SDBUSCPP_INCLUDE_DIR}/VTableItems.h ${SDBUSCPP_INCLUDE_DIR}/VTableItems.inl ${SDBUSCPP_INCLUDE_DIR}/Error.h ${SDBUSCPP_INCLUDE_DIR}/IConnection.h ${SDBUSCPP_INCLUDE_DIR}/AdaptorInterfaces.h ${SDBUSCPP_INCLUDE_DIR}/ProxyInterfaces.h ${SDBUSCPP_INCLUDE_DIR}/StandardInterfaces.h ${SDBUSCPP_INCLUDE_DIR}/IObject.h ${SDBUSCPP_INCLUDE_DIR}/IProxy.h ${SDBUSCPP_INCLUDE_DIR}/Message.h ${SDBUSCPP_INCLUDE_DIR}/MethodResult.h ${SDBUSCPP_INCLUDE_DIR}/Types.h ${SDBUSCPP_INCLUDE_DIR}/TypeTraits.h ${SDBUSCPP_INCLUDE_DIR}/Flags.h ${SDBUSCPP_INCLUDE_DIR}/sdbus-c++.h) set(SDBUSCPP_SRCS ${SDBUSCPP_CPP_SRCS} ${SDBUSCPP_HDR_SRCS} ${SDBUSCPP_PUBLIC_HDRS}) #------------------------------- # GENERAL COMPILER CONFIGURATION #------------------------------- set(CMAKE_CXX_STANDARD 20) #---------------------------------- # LIBRARY BUILD INFORMATION #---------------------------------- set(SDBUSCPP_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}") set(SDBUSCPP_VERSION "${PROJECT_VERSION}") # Having an object target allows unit tests to reuse already built sources without re-building add_library(sdbus-c++-objlib OBJECT ${SDBUSCPP_SRCS}) target_compile_definitions(sdbus-c++-objlib PRIVATE BUILD_LIB=1 LIBSYSTEMD_VERSION=${SDBUSCPP_LIBSYSTEMD_VERSION} SDBUS_${SDBUS_IMPL} SDBUS_HEADER=<${SDBUS_IMPL}/sd-bus.h>) target_include_directories(sdbus-c++-objlib PUBLIC $ $) if(BUILD_SHARED_LIBS) set_target_properties(sdbus-c++-objlib PROPERTIES POSITION_INDEPENDENT_CODE ON) endif() if(SDBUSCPP_BUILD_LIBSYSTEMD) add_dependencies(sdbus-c++-objlib LibsystemdBuildProject) endif() target_link_libraries(sdbus-c++-objlib PUBLIC Systemd::Libsystemd Threads::Threads) add_library(sdbus-c++) target_include_directories(sdbus-c++ PUBLIC $ $) set_target_properties(sdbus-c++ PROPERTIES PUBLIC_HEADER "${SDBUSCPP_PUBLIC_HDRS}" VERSION "${SDBUSCPP_VERSION}" SOVERSION "${SDBUSCPP_VERSION_MAJOR}" OUTPUT_NAME "sdbus-c++") target_link_libraries(sdbus-c++ PRIVATE sdbus-c++-objlib) #---------------------------------- # TESTS #---------------------------------- if(SDBUSCPP_BUILD_TESTS) message(STATUS "Building with tests") enable_testing() add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/tests") endif() #---------------------------------- # UTILS #---------------------------------- if(SDBUSCPP_BUILD_CODEGEN) message(STATUS "Building with code generator tool") add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/tools") endif() #---------------------------------- # EXAMPLES #---------------------------------- if(SDBUSCPP_BUILD_EXAMPLES) message(STATUS "Building with examples") add_subdirectory(examples) endif() #---------------------------------- # DOCUMENTATION #---------------------------------- if(SDBUSCPP_BUILD_DOCS) message(STATUS "Building with documentation") add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/docs") endif() #---------------------------------- # CMAKE CONFIG & PACKAGE CONFIG #---------------------------------- include(CMakePackageConfigHelpers) configure_package_config_file(cmake/sdbus-c++-config.cmake.in cmake/sdbus-c++-config.cmake INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/sdbus-c++) write_basic_package_version_file(cmake/sdbus-c++-config-version.cmake COMPATIBILITY SameMajorVersion) if(BUILD_SHARED_LIBS AND (SDBUSCPP_BUILD_LIBSYSTEMD OR Systemd_LINK_LIBRARIES MATCHES "/libsystemd\.a(;|$)")) set(PKGCONFIG_REQS ".private") else() set(PKGCONFIG_REQS "") endif() set(PKGCONFIG_DEPS ${SDBUS_LIB}) configure_file(pkgconfig/sdbus-c++.pc.in pkgconfig/sdbus-c++.pc @ONLY) #---------------------------------- # INSTALLATION #---------------------------------- if(SDBUSCPP_INSTALL) set(EXPORT_SET sdbus-c++) if(NOT BUILD_SHARED_LIBS) list(APPEND EXPORT_SET "sdbus-c++-objlib") endif() install(TARGETS ${EXPORT_SET} EXPORT sdbus-c++-targets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT sdbus-c++-runtime LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT sdbus-c++-runtime NAMELINK_COMPONENT sdbus-c++-dev ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT sdbus-c++-dev PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${SDBUSCPP_INCLUDE_SUBDIR} COMPONENT sdbus-c++-dev) install(EXPORT sdbus-c++-targets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/sdbus-c++ NAMESPACE SDBusCpp:: COMPONENT sdbus-c++-dev) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/cmake/sdbus-c++-config.cmake ${CMAKE_CURRENT_BINARY_DIR}/cmake/sdbus-c++-config-version.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/sdbus-c++ COMPONENT sdbus-c++-dev) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/pkgconfig/sdbus-c++.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig COMPONENT sdbus-c++-dev) if(SDBUSCPP_BUILD_DOCS) install(FILES README README.md NEWS COPYING ChangeLog AUTHORS DESTINATION ${CMAKE_INSTALL_DOCDIR} COMPONENT sdbus-c++-doc) endif() endif() #---------------------------------- # CPACK #---------------------------------- set(CPACK_PACKAGE_VENDOR "Kistler") set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "High-level C++ D-Bus library") set(CPACK_PACKAGE_CONTACT "info@kistler.com") set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md") set(CPACK_COMPONENTS_ALL runtime dev doc) set(CPACK_COMPONENT_DEV_DEPENDS "runtime") # specific for DEB generator set(CPACK_DEB_COMPONENT_INSTALL ON) set(CPACK_DEBIAN_RUNTIME_DEBUGINFO_PACKAGE ON) set(CPACK_DEBIAN_RUNTIME_PACKAGE_NAME ${PROJECT_NAME}) set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT) set(CPACK_DEBIAN_PACKAGE_SECTION "libs") set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) set(CPACK_DEBIAN_ENABLE_COMPONENT_DEPENDS ON) set(CPACK_DEBIAN_DEV_PACKAGE_DEPENDS "libsystemd-dev (>=${MINIMUM_SDBUS_VERSION})") include(CPack)