diff options
Diffstat (limited to 'CMakeLists.txt')
-rw-r--r-- | CMakeLists.txt | 485 |
1 files changed, 265 insertions, 220 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c1babc5..b021411c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,233 +1,259 @@ -cmake_minimum_required(VERSION 3.10) +cmake_minimum_required(VERSION 3.16) if (POLICY CMP0092) cmake_policy(SET CMP0092 NEW) endif() -set(API_VERSION "0.6") -project(Quotient VERSION "${API_VERSION}.11" LANGUAGES CXX) +set(API_VERSION "0.7") +project(Quotient VERSION "${API_VERSION}.0" LANGUAGES CXX) + +message(STATUS) +message(STATUS "Configuring ${PROJECT_NAME} ${PROJECT_VERSION} ==>") + +include(FeatureSummary) +include(CTest) -option(${PROJECT_NAME}_INSTALL_TESTS "install quotest (former qmc-example) application" ON) # https://github.com/quotient-im/libQuotient/issues/369 option(${PROJECT_NAME}_ENABLE_E2EE "end-to-end encryption (E2EE) support" OFF) +add_feature_info(EnableE2EE ${PROJECT_NAME}_ENABLE_E2EE + "end-to-end encryption (WORK IN PROGRESS)") + +# Set a default build type if none was specified +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + message(STATUS "Setting build type to 'Debug' as none was specified") + set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build" FORCE) + # Set the possible values of build type for cmake-gui + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" + "MinSizeRel" "RelWithDebInfo") +endif() +if (CMAKE_BUILD_TYPE) + message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") +endif(CMAKE_BUILD_TYPE) +message(STATUS "Using compiler: ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}" ) include(CheckCXXCompilerFlag) +if (MSVC) + add_compile_options(/EHsc /W4 + /wd4100 /wd4127 /wd4242 /wd4244 /wd4245 /wd4267 /wd4365 /wd4456 /wd4459 + /wd4464 /wd4505 /wd4514 /wd4571 /wd4619 /wd4623 /wd4625 /wd4626 /wd4706 + /wd4710 /wd4774 /wd4820 /wd4946 /wd5026 /wd5027) +else() + foreach (FLAG all pedantic extra error=return-type) # Switch these on + CHECK_CXX_COMPILER_FLAG("-W${FLAG}" W${FLAG}_SUPPORTED) + if (W${FLAG}_SUPPORTED AND + NOT CMAKE_CXX_FLAGS MATCHES "W(no-)?${FLAG}($| )") + add_compile_options(-W${FLAG}) + endif () + endforeach () + foreach (FLAG unused-parameter gnu-zero-variadic-macro-arguments + subobject-linkage) # Switch these off + CHECK_CXX_COMPILER_FLAG("-Wno-${FLAG}" Wno-${FLAG}_SUPPORTED) + if (Wno-${FLAG}_SUPPORTED AND + NOT CMAKE_CXX_FLAGS MATCHES "W(no-)?${FLAG}($| )") + add_compile_options(-Wno-${FLAG}) + endif() + endforeach () +endif() + if (WIN32) if (NOT CMAKE_INSTALL_LIBDIR) set(CMAKE_INSTALL_LIBDIR ".") - endif () + set(CMakeFilesLocation "cmake") + else() + set(CMakeFilesLocation "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") + endif() if (NOT CMAKE_INSTALL_BINDIR) set(CMAKE_INSTALL_BINDIR ".") - endif () + endif() if (NOT CMAKE_INSTALL_INCLUDEDIR) set(CMAKE_INSTALL_INCLUDEDIR "include") - endif () + endif() else() include(GNUInstallDirs) set(INCLUDEDIR_INIT ${PROJECT_NAME}) + set(CMakeFilesLocation "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") endif(WIN32) set(${PROJECT_NAME}_INSTALL_INCLUDEDIR "${CMAKE_INSTALL_INCLUDEDIR}/${INCLUDEDIR_INIT}" CACHE PATH "directory to install ${PROJECT_NAME} include files to") +message(STATUS "Install Prefix: ${CMAKE_INSTALL_PREFIX}") +message(STATUS " Header files will be installed to ${CMAKE_INSTALL_PREFIX}/${${PROJECT_NAME}_INSTALL_INCLUDEDIR}") # Instruct CMake to run moc automatically when needed. set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) -# Set a default build type if none was specified -if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) - message(STATUS "Setting build type to 'Debug' as none was specified") - set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build" FORCE) - # Set the possible values of build type for cmake-gui - set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" - "MinSizeRel" "RelWithDebInfo") -endif() +option(BUILD_WITH_QT6 "Build Quotient with Qt 6 (EXPERIMENTAL)" OFF) -if (MSVC) - add_compile_options(/EHsc /W4 - /wd4100 /wd4127 /wd4242 /wd4244 /wd4245 /wd4267 /wd4365 /wd4456 /wd4459 - /wd4464 /wd4505 /wd4514 /wd4571 /wd4619 /wd4623 /wd4625 /wd4626 /wd4706 - /wd4710 /wd4774 /wd4820 /wd4946 /wd5026 /wd5027) +if (BUILD_WITH_QT6) + set(QtMinVersion "6.0") else() - foreach (FLAG all "" pedantic extra error=return-type no-unused-parameter - no-gnu-zero-variadic-macro-arguments) - CHECK_CXX_COMPILER_FLAG("-W${FLAG}" WARN_${FLAG}_SUPPORTED) - if ( WARN_${FLAG}_SUPPORTED AND NOT CMAKE_CXX_FLAGS MATCHES "(^| )-W?${FLAG}($| )") - add_compile_options(-W${FLAG}) - endif () - endforeach () + set(QtMinVersion "5.15") + set(QtExtraModules "Multimedia") # See #483 endif() +string(REGEX REPLACE "^(.).*" "Qt\\1" Qt ${QtMinVersion}) # makes "Qt5" or "Qt6" +find_package(${Qt} ${QtMinVersion} REQUIRED Core Network Gui Test ${QtExtraModules}) +get_filename_component(Qt_Prefix "${${Qt}_DIR}/../../../.." ABSOLUTE) +message(STATUS "Using Qt ${${Qt}_VERSION} at ${Qt_Prefix}") -find_package(Qt5 5.9 REQUIRED Network Gui Multimedia Test) -get_filename_component(Qt5_Prefix "${Qt5_DIR}/../../../.." ABSOLUTE) +find_package(${Qt}Keychain REQUIRED) if (${PROJECT_NAME}_ENABLE_E2EE) - if ((NOT DEFINED USE_INTREE_LIBQOLM OR USE_INTREE_LIBQOLM) - AND EXISTS ${PROJECT_SOURCE_DIR}/3rdparty/libQtOlm/lib/utils.h) - add_subdirectory(3rdparty/libQtOlm) - include_directories(3rdparty/libQtOlm) - if (NOT DEFINED USE_INTREE_LIBQOLM) - set (USE_INTREE_LIBQOLM 1) - endif () - endif () - if (NOT USE_INTREE_LIBQOLM) - set(SAVED_CMAKE_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_INCLUDEDIR}) - set(CMAKE_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_INCLUDEDIR}) - find_package(QtOlm 3.0.1 REQUIRED) - if (NOT QtOlm_FOUND) - message( WARNING "libQtOlm not found; configuration will most likely fail.") - message( WARNING "Make sure you have installed libQtOlm development files") - message( WARNING "as a package or checked out the library sources in lib/.") - message( WARNING "See also BUILDING.md") - endif () - endif () -else () - message( STATUS "End-to-end encryption (E2EE) support is turned off.") -endif () + find_package(${Qt} ${QtMinVersion} REQUIRED Sql) + find_package(Olm 3.2.5 REQUIRED) + set_package_properties(Olm PROPERTIES + DESCRIPTION "Implementation of the Olm and Megolm cryptographic ratchets" + URL "https://gitlab.matrix.org/matrix-org/olm" + TYPE REQUIRED + ) + if (Olm_FOUND) + message(STATUS "Using libOlm ${Olm_VERSION} at ${Olm_DIR}") + endif() -if (GTAD_PATH AND MATRIX_DOC_PATH) - get_filename_component(ABS_GTAD_PATH "${GTAD_PATH}" REALPATH) - if (EXISTS ${ABS_GTAD_PATH}) - get_filename_component(ABS_API_DEF_PATH "${MATRIX_DOC_PATH}/data/api" REALPATH) - message (STATUS "Testing ${ABS_API_DEF_PATH}") - if (NOT IS_DIRECTORY ${ABS_API_DEF_PATH}) - get_filename_component(ABS_API_DEF_PATH "${MATRIX_DOC_PATH}/api" REALPATH) - message (STATUS "Testing ${ABS_API_DEF_PATH}") - endif () - if (IS_DIRECTORY ${ABS_API_DEF_PATH}) - set(GENERATE_API 1) - if (NOT CLANG_FORMAT) - set(CLANG_FORMAT clang-format) - endif() - get_filename_component(ABS_CLANG_FORMAT "${CLANG_FORMAT}" PROGRAM) - else () - message( WARNING "${MATRIX_DOC_PATH} doesn't seem to point to a valid matrix-doc repo; disabling API stubs generation") - endif () - else (EXISTS ${ABS_GTAD_PATH}) - message( WARNING "${GTAD_PATH} doesn't exist; disabling API stubs generation") - endif () -endif () + find_package(OpenSSL 1.1.0 REQUIRED) + set_package_properties(OpenSSL PROPERTIES + DESCRIPTION "Open source SSL and TLS implementation and cryptographic library" + URL "https://www.openssl.org/" + TYPE REQUIRED + ) + if (OpenSSL_FOUND) + message(STATUS "Using OpenSSL ${OpenSSL_VERSION} at ${OpenSSL_DIR}") + endif() +endif() -message( STATUS ) -message( STATUS "=============================================================================" ) -message( STATUS " ${PROJECT_NAME} Build Information" ) -message( STATUS "=============================================================================" ) -message( STATUS "Version: ${PROJECT_VERSION}, API version: ${API_VERSION}") -if (CMAKE_BUILD_TYPE) - message( STATUS "Build type: ${CMAKE_BUILD_TYPE}") -endif(CMAKE_BUILD_TYPE) -message( STATUS "Using compiler: ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}" ) -message( STATUS "Install Prefix: ${CMAKE_INSTALL_PREFIX}" ) -message( STATUS " Header files will be installed to ${CMAKE_INSTALL_PREFIX}/${${PROJECT_NAME}_INSTALL_INCLUDEDIR}" ) -message( STATUS "Using Qt ${Qt5_VERSION} at ${Qt5_Prefix}" ) -if (GENERATE_API) - message( STATUS "Generating API stubs enabled (use --target update-api)" ) - message( STATUS " Using GTAD at ${ABS_GTAD_PATH}" ) - message( STATUS " Using API files at ${ABS_API_DEF_PATH}" ) - if (EXISTS ${ABS_CLANG_FORMAT}) - message( STATUS "clang-format is at ${ABS_CLANG_FORMAT}") - else () - message( STATUS "${CLANG_FORMAT} is NOT FOUND; API files won't be reformatted") - endif () -endif () -find_package(Git) -if (${PROJECT_NAME}_ENABLE_E2EE) - if (USE_INTREE_LIBQOLM) - message( STATUS "Using in-tree libQtOlm") - if (GIT_FOUND) - execute_process(COMMAND - "${GIT_EXECUTABLE}" rev-parse -q HEAD - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/3rdparty/libQtOlm - OUTPUT_VARIABLE QTOLM_GIT_SHA1 - OUTPUT_STRIP_TRAILING_WHITESPACE) - message( STATUS " Library git SHA1: ${QTOLM_GIT_SHA1}") - endif (GIT_FOUND) - else () - message( STATUS "Using libQtOlm ${QtOlm_VERSION} at ${QtOlm_DIR}") - endif () -endif () -message( STATUS "=============================================================================" ) -message( STATUS ) # Set up source files -set(lib_SRCS - # This .h is special in that it declares a Q_NAMESPACE but has no .cpp - # where staticMetaObject for that namespace would be defined; passing it - # to add_library (see below) puts it on the automoc radar, producing - # a compilation unit with the needed definition. +list(APPEND lib_SRCS lib/quotient_common.h - lib/networkaccessmanager.cpp - lib/connectiondata.cpp - lib/connection.cpp - lib/ssosession.cpp - lib/logging.cpp - lib/room.cpp - lib/user.cpp - lib/avatar.cpp - lib/uri.cpp - lib/uriresolver.cpp - lib/syncdata.cpp - lib/settings.cpp - lib/networksettings.cpp - lib/converters.cpp - lib/util.cpp - lib/encryptionmanager.cpp - lib/eventitem.cpp - lib/events/event.cpp - lib/events/roomevent.cpp - lib/events/stateevent.cpp - lib/events/eventcontent.cpp - lib/events/roomcreateevent.cpp - lib/events/roomtombstoneevent.cpp - lib/events/roommessageevent.cpp - lib/events/roommemberevent.cpp - lib/events/roompowerlevelsevent.cpp - lib/events/typingevent.cpp - lib/events/receiptevent.cpp - lib/events/reactionevent.cpp - lib/events/callanswerevent.cpp - lib/events/callcandidatesevent.cpp - lib/events/callhangupevent.cpp - lib/events/callinviteevent.cpp - lib/events/directchatevent.cpp - lib/events/encryptionevent.cpp - lib/events/encryptedevent.cpp - lib/events/roomkeyevent.cpp - lib/jobs/requestdata.cpp - lib/jobs/basejob.cpp - lib/jobs/syncjob.cpp - lib/jobs/mediathumbnailjob.cpp - lib/jobs/downloadfilejob.cpp + lib/quotient_export.h + lib/function_traits.h lib/function_traits.cpp + lib/omittable.h + lib/expected.h + lib/networkaccessmanager.h lib/networkaccessmanager.cpp + lib/connectiondata.h lib/connectiondata.cpp + lib/connection.h lib/connection.cpp + lib/ssosession.h lib/ssosession.cpp + lib/logging.h lib/logging.cpp + lib/room.h lib/room.cpp + lib/roomstateview.h lib/roomstateview.cpp + lib/user.h lib/user.cpp + lib/avatar.h lib/avatar.cpp + lib/uri.h lib/uri.cpp + lib/uriresolver.h lib/uriresolver.cpp + lib/eventstats.h lib/eventstats.cpp + lib/syncdata.h lib/syncdata.cpp + lib/settings.h lib/settings.cpp + lib/networksettings.h lib/networksettings.cpp + lib/converters.h lib/converters.cpp + lib/util.h lib/util.cpp + lib/eventitem.h lib/eventitem.cpp + lib/accountregistry.h lib/accountregistry.cpp + lib/mxcreply.h lib/mxcreply.cpp + lib/e2ee/e2ee.h # because it's used by generated API + lib/events/event.h lib/events/event.cpp + lib/events/eventloader.h + lib/events/roomevent.h lib/events/roomevent.cpp + lib/events/stateevent.h lib/events/stateevent.cpp + lib/events/single_key_value.h + lib/events/simplestateevents.h + lib/events/eventcontent.h lib/events/eventcontent.cpp + lib/events/eventrelation.h lib/events/eventrelation.cpp + lib/events/roomcreateevent.h lib/events/roomcreateevent.cpp + lib/events/roomtombstoneevent.h lib/events/roomtombstoneevent.cpp + lib/events/roommessageevent.h lib/events/roommessageevent.cpp + lib/events/roommemberevent.h lib/events/roommemberevent.cpp + lib/events/roomcanonicalaliasevent.h + lib/events/roomavatarevent.h + lib/events/roompowerlevelsevent.h lib/events/roompowerlevelsevent.cpp + lib/events/typingevent.h + lib/events/accountdataevents.h + lib/events/receiptevent.h lib/events/receiptevent.cpp + lib/events/reactionevent.h + lib/events/callevents.h lib/events/callevents.cpp + lib/events/directchatevent.h lib/events/directchatevent.cpp + lib/events/encryptionevent.h lib/events/encryptionevent.cpp + lib/events/encryptedevent.h lib/events/encryptedevent.cpp + lib/events/roomkeyevent.h + lib/events/stickerevent.h + lib/events/filesourceinfo.h lib/events/filesourceinfo.cpp + lib/jobs/requestdata.h lib/jobs/requestdata.cpp + lib/jobs/basejob.h lib/jobs/basejob.cpp + lib/jobs/syncjob.h lib/jobs/syncjob.cpp + lib/jobs/mediathumbnailjob.h lib/jobs/mediathumbnailjob.cpp + lib/jobs/downloadfilejob.h lib/jobs/downloadfilejob.cpp + res.qrc ) +if (${PROJECT_NAME}_ENABLE_E2EE) + list(APPEND lib_SRCS + lib/database.h lib/database.cpp + lib/keyverificationsession.h lib/keyverificationsession.cpp + lib/e2ee/qolmaccount.h lib/e2ee/qolmaccount.cpp + lib/e2ee/qolmsession.h lib/e2ee/qolmsession.cpp + lib/e2ee/qolminboundsession.h lib/e2ee/qolminboundsession.cpp + lib/e2ee/qolmoutboundsession.h lib/e2ee/qolmoutboundsession.cpp + lib/e2ee/qolmutils.h lib/e2ee/qolmutils.cpp + lib/e2ee/qolmutility.h lib/e2ee/qolmutility.cpp + lib/e2ee/qolmsession.h lib/e2ee/qolmsession.cpp + lib/e2ee/qolmmessage.h lib/e2ee/qolmmessage.cpp + lib/events/keyverificationevent.h + ) +endif() + +# Configure API files generation set(CSAPI_DIR csapi) set(FULL_CSAPI_DIR lib/${CSAPI_DIR}) set(ASAPI_DEF_DIR application-service/definitions) set(ISAPI_DEF_DIR identity/definitions) -if (GENERATE_API) - if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.12.0") - # We use globbing with CONFIGURE_DEPENDS to produce two file lists: - # one of all API files for clang-format and another of just .cpp - # files to supply for library source files. Since we expect these - # file lists to only change due to GTAD invocation, we only use - # CONFIGURE_DEPENDS when pre-requisites to update API are met. - # Read comments next to each file(GLOB_RECURSE) for caveats. - set(add_CONFIGURE_DEPENDS "CONFIGURE_DEPENDS") +set(API_GENERATION_ENABLED 0) +if (NOT MATRIX_SPEC_PATH AND MATRIX_DOC_PATH) + set(MATRIX_SPEC_PATH ${MATRIX_DOC_PATH}) +endif() +if (GTAD_PATH AND MATRIX_SPEC_PATH) + # REALPATH resolves ~ (home directory) while PROGRAM doesn't + get_filename_component(ABS_GTAD_PATH "${GTAD_PATH}" REALPATH) + get_filename_component(ABS_GTAD_PATH "${ABS_GTAD_PATH}" PROGRAM PROGRAM_ARGS GTAD_ARGS) + if (EXISTS ${ABS_GTAD_PATH}) + get_filename_component(ABS_API_DEF_PATH "${MATRIX_SPEC_PATH}/data/api" REALPATH) + if (NOT IS_DIRECTORY ${ABS_API_DEF_PATH}) + # Check the old place of API files + get_filename_component(ABS_API_DEF_PATH "${MATRIX_SPEC_PATH}/api" REALPATH) + endif () + if (IS_DIRECTORY ${ABS_API_DEF_PATH}) + set(API_GENERATION_ENABLED 1) + else () + message( WARNING "${MATRIX_SPEC_PATH} doesn't seem to point to a valid matrix-doc repo; disabling API stubs generation") + endif () + else (EXISTS ${ABS_GTAD_PATH}) + message( WARNING "${GTAD_PATH} is not executable; disabling API stubs generation") + endif () +endif () +if (API_GENERATION_ENABLED) + message( STATUS "Using GTAD at ${ABS_GTAD_PATH}" ) + message( STATUS "Found API files at ${ABS_API_DEF_PATH}" ) + if (NOT CLANG_FORMAT) + set(CLANG_FORMAT clang-format) endif() + get_filename_component(ABS_CLANG_FORMAT "${CLANG_FORMAT}" PROGRAM PROGRAM_ARGS CLANG_FORMAT_ARGS) + if (NOT ABS_CLANG_FORMAT) + message( WARNING "${CLANG_FORMAT} is NOT FOUND; API files won't be formatted") + endif () + set(FULL_CSAPI_SRC_DIR ${ABS_API_DEF_PATH}/client-server) file(GLOB_RECURSE API_DEFS RELATIVE ${PROJECT_SOURCE_DIR} ${FULL_CSAPI_SRC_DIR}/*.yaml ${ABS_API_DEF_PATH}/${ASAPI_DEF_DIR}/*.yaml ${ABS_API_DEF_PATH}/${ISAPI_DEF_DIR}/*.yaml ) - add_custom_target(generate-unformatted-api + add_custom_target(update-api ${ABS_GTAD_PATH} --config ../gtad/gtad.yaml --out ${CSAPI_DIR} ${FULL_CSAPI_SRC_DIR} old_sync.yaml- room_initial_sync.yaml- # deprecated - search.yaml- # current GTAD is limited in handling move-only data key_backup.yaml- # immature and buggy in terms of API definition sync.yaml- # we have a better handcrafted implementation + ${GTAD_ARGS} WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/lib SOURCES gtad/gtad.yaml gtad/data.h.mustache @@ -236,46 +262,41 @@ if (GENERATE_API) ${API_DEFS} VERBATIM ) - add_custom_target(update-api DEPENDS generate-unformatted-api) - if (EXISTS ${ABS_CLANG_FORMAT}) - set(CLANG_FORMAT_ARGS -i -sort-includes ${CLANG_FORMAT_ARGS}) - # FIXME: the list of files should be produced after GTAD has run. - # For now it's produced at CMake invocation. If file() hasn't found - # any files at that moment, clang-format will be called with an empty - # list of files and choke. Taking outfiles.txt from GTAD could be - # an option but this, too, must be done during the build stage, and - # there's no crossplatform way to use the contents of a file as - # input for a build target command. - file(GLOB_RECURSE api_ALL_SRCS ${add_CONFIGURE_DEPENDS} - ${FULL_CSAPI_DIR}/*.* - lib/${ASAPI_DEF_DIR}/*.* - lib/${ISAPI_DEF_DIR}/*.*) - if (api_ALL_SRCS) - add_custom_target(format-api - ${ABS_CLANG_FORMAT} ${CLANG_FORMAT_ARGS} ${api_ALL_SRCS} - DEPENDS generate-unformatted-api - VERBATIM) - add_dependencies(update-api format-api) - endif() - endif() endif() +add_feature_info(EnableApiCodeGeneration "${API_GENERATION_ENABLED}" + "build target update-api") -# Make no mistake: CMake cannot run gtad first and then populate the list of -# resulting api_SRCS files. In other words, placing the below statement after -# the block above will not lead to CMake magically reconfiguring the build -# after building the update-api target. CONFIGURE_DEPENDS somewhat helps, -# at least forcing the build system to reevaluate the glob before building -# the next target. Otherwise, you have to watch out if gtad has created -# new files and if it has, re-run cmake. -file(GLOB_RECURSE api_SRCS ${add_CONFIGURE_DEPENDS} ${FULL_CSAPI_DIR}/*.cpp) +# Produce the list of all Matrix API files for building the library. When this +# list changes (normally after calling GTAD), CONFIGURE_DEPENDS will force +# the build system to call CMake again. Checking for the glob change slows down +# each build (even if the target does not involve API generation). It would be +# ideal if GTAD could compare the initial (saved somewhere) and the generated +# file list itself and write down to some .cmake file if those are different, +# which would trigger the reconfiguration specifically before the next build. +# For now CONFIGURE_DEPENDS is the best approximation of that. +file(GLOB_RECURSE api_ALL_SRCS CONFIGURE_DEPENDS + ${FULL_CSAPI_DIR}/*.* lib/${ASAPI_DEF_DIR}/*.* lib/${ISAPI_DEF_DIR}/*.*) -set(tests_SRCS tests/quotest.cpp) +add_library(${PROJECT_NAME} ${lib_SRCS} ${api_ALL_SRCS}) +# Set BUILDING_SHARED_QUOTIENT if building as a shared library +target_compile_definitions(${PROJECT_NAME} PRIVATE + $<$<STREQUAL:$<TARGET_PROPERTY:${PROJECT_NAME},TYPE>,SHARED_LIBRARY>:BUILDING_SHARED_QUOTIENT>) +# Set QUOTIENT_STATIC in a static library setting +target_compile_definitions(${PROJECT_NAME} PUBLIC + $<$<STREQUAL:$<TARGET_PROPERTY:${PROJECT_NAME},TYPE>,STATIC_LIBRARY>:QUOTIENT_STATIC>) +target_compile_definitions(${PROJECT_NAME} PRIVATE QT_NO_JAVA_STYLE_ITERATORS QT_NO_URL_CAST_FROM_STRING QT_NO_CAST_TO_ASCII) -add_library(${PROJECT_NAME} ${lib_SRCS} ${api_SRCS}) +target_compile_definitions(${PROJECT_NAME} PUBLIC ${PROJECT_NAME}_VERSION_MAJOR=${PROJECT_VERSION_MAJOR} + ${PROJECT_NAME}_VERSION_MINOR=${PROJECT_VERSION_MINOR} ${PROJECT_NAME}_VERSION_PATCH=${PROJECT_VERSION_PATCH} + ${PROJECT_NAME}_VERSION_STRING=\"${PROJECT_VERSION}\") if (${PROJECT_NAME}_ENABLE_E2EE) target_compile_definitions(${PROJECT_NAME} PUBLIC ${PROJECT_NAME}_E2EE_ENABLED) endif() set_target_properties(${PROJECT_NAME} PROPERTIES + CXX_STANDARD 20 + CXX_EXTENSIONS OFF + VISIBILITY_INLINES_HIDDEN ON + CXX_VISIBILITY_PRESET hidden VERSION "${PROJECT_VERSION}" SOVERSION ${API_VERSION} INTERFACE_${PROJECT_NAME}_MAJOR_VERSION ${API_VERSION} @@ -283,29 +304,52 @@ set_target_properties(${PROJECT_NAME} PROPERTIES set_property(TARGET ${PROJECT_NAME} APPEND PROPERTY COMPATIBLE_INTERFACE_STRING ${PROJECT_NAME}_MAJOR_VERSION) -target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_17) +target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_20) +if (MSVC) + target_compile_options(${PROJECT_NAME} PUBLIC /Zc:preprocessor) +endif() + +# Don't use PCH w/GCC (https://bugzilla.redhat.com/show_bug.cgi?id=1721553#c34) +if (NOT CMAKE_CXX_COMPILER_ID STREQUAL GNU) + target_precompile_headers(${PROJECT_NAME} PRIVATE lib/converters.h) +endif () target_include_directories(${PROJECT_NAME} PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/lib> $<INSTALL_INTERFACE:${${PROJECT_NAME}_INSTALL_INCLUDEDIR}> ) if (${PROJECT_NAME}_ENABLE_E2EE) - target_link_libraries(${PROJECT_NAME} QtOlm) - set(FIND_DEPS "find_dependency(QtOlm)") # For QuotientConfig.cmake.in + target_link_libraries(${PROJECT_NAME} Olm::Olm + OpenSSL::Crypto + OpenSSL::SSL + ${Qt}::Sql) + set(FIND_DEPS "find_dependency(Olm) + find_dependency(OpenSSL) + find_dependency(${Qt}Sql)") # For QuotientConfig.cmake.in endif() -target_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Network Qt5::Gui Qt5::Multimedia) -set(TEST_BINARY quotest) -add_executable(${TEST_BINARY} ${tests_SRCS}) -target_link_libraries(${TEST_BINARY} Qt5::Core Qt5::Test ${PROJECT_NAME}) +target_include_directories(${PROJECT_NAME} PRIVATE ${QTKEYCHAIN_INCLUDE_DIRS}) +target_link_libraries(${PROJECT_NAME} ${Qt}::Core ${Qt}::Network ${Qt}::Gui ${QTKEYCHAIN_LIBRARIES}) + +if (Qt STREQUAL Qt5) # See #483 + target_link_libraries(${PROJECT_NAME} ${Qt}::Multimedia) +endif() configure_file(${PROJECT_NAME}.pc.in ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc @ONLY NEWLINE_STYLE UNIX) -# Installation +# Configure testing + +if (BUILD_TESTING) + enable_testing() + add_subdirectory(quotest) + add_subdirectory(autotests) +endif() + +# Configure installation install(TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME}Targets + LIBRARY RUNTIME ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} INCLUDES DESTINATION ${${PROJECT_NAME}_INSTALL_INCLUDEDIR} ) install(DIRECTORY lib/ DESTINATION ${${PROJECT_NAME}_INSTALL_INCLUDEDIR} @@ -327,26 +371,27 @@ configure_file(cmake/${PROJECT_NAME}Config.cmake.in @ONLY ) -set(ConfigFilesLocation "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") install(EXPORT ${PROJECT_NAME}Targets - FILE ${PROJECT_NAME}Targets.cmake DESTINATION ${ConfigFilesLocation}) + FILE ${PROJECT_NAME}Targets.cmake DESTINATION ${CMakeFilesLocation}) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}/${PROJECT_NAME}Config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}/${PROJECT_NAME}ConfigVersion.cmake" - DESTINATION ${ConfigFilesLocation} + DESTINATION ${CMakeFilesLocation} ) -install(EXPORT_ANDROID_MK ${PROJECT_NAME}Targets DESTINATION share/ndk-modules) +install(EXPORT_ANDROID_MK ${PROJECT_NAME}Targets DESTINATION ${CMAKE_INSTALL_DATADIR}/ndk-modules) if (WIN32) install(FILES mime/packages/freedesktop.org.xml DESTINATION mime/packages) endif (WIN32) -if (${PROJECT_NAME}_INSTALL_TESTS) - install(TARGETS ${TEST_BINARY} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) -endif () - if (UNIX AND NOT APPLE) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) endif() + +message(STATUS) +feature_summary(WHAT ENABLED_FEATURES DISABLED_FEATURES + FATAL_ON_MISSING_REQUIRED_PACKAGES) + +message(STATUS "<== End of libQuotient configuration") |