diff --git a/CMakeLists.txt b/CMakeLists.txt index 39b1b03ad..aa100fdf8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,7 @@ message(STATUS "Configuring ${PROJECT_NAME} ${PROJECT_VERSION} ==>") include(FeatureSummary) include(CTest) +include(cmake/QuotientGenerateHeaders.cmake) # https://github.com/quotient-im/libQuotient/issues/369 option(${PROJECT_NAME}_ENABLE_E2EE "end-to-end encryption (E2EE) support" OFF) @@ -291,8 +292,9 @@ if (BUILD_TESTING) add_subdirectory(autotests) endif() -# Configure installation +add_subdirectory(lib) +# Configure installation install(TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME}Targets ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} diff --git a/cmake/QuotientGenerateHeaders.cmake b/cmake/QuotientGenerateHeaders.cmake new file mode 100644 index 000000000..40bcb049a --- /dev/null +++ b/cmake/QuotientGenerateHeaders.cmake @@ -0,0 +1,222 @@ +# SPDX-FileCopyrightText: 2013 Aleix Pol Gonzalez +# SPDX-FileCopyrightText: 2014 Alex Merry +# SPDX-FileCopyrightText: 2015 Patrick Spendrin +# +# SPDX-License-Identifier: BSD-3-Clause + +#[=======================================================================[.rst: +QUOTIENTGenerateHeaders +------------------ + +Generate C/C++ CamelCase forwarding headers. + +:: + + quotient_generate_headers( + HEADER_NAMES [ [...]] + [ORIGINAL ] + [HEADER_EXTENSION ] + [OUTPUT_DIR ] + [PREFIX ] + [REQUIRED_HEADERS ] + [COMMON_HEADER ] + [RELATIVE ]) + +For each CamelCase header name passed to HEADER_NAMES, a file of that name +will be generated that will include a version with ``.h`` or, if set, +``.`` appended. +For example, the generated header ``ClassA`` will include ``classa.h`` (or +``ClassA.h``, see ORIGINAL). +If a CamelCaseName consists of multiple comma-separated files, e.g. +``ClassA,ClassB,ClassC``, then multiple camelcase header files will be +generated which are redirects to the first header file. +The file locations of these generated headers will be stored in +. + +ORIGINAL specifies how the name of the original header is written: lowercased +or also camelcased. The default is LOWERCASE. Since 1.8.0. + +HEADER_EXTENSION specifies what file name extension is used for the header +files. The default is "h". Since 5.48.0. + +PREFIX places the generated headers in subdirectories. This should be a +CamelCase name like ``KParts``, which will cause the CamelCase forwarding +headers to be placed in the ``KParts`` directory (e.g. ``KParts/Part``). It +will also, for the convenience of code in the source distribution, generate +forwarding headers based on the original names (e.g. ``kparts/part.h``). This +allows includes like ``"#include "`` to be used before +installation, as long as the include_directories are set appropriately. + +OUTPUT_DIR specifies where the files will be generated; this should be within +the build directory. By default, ``${CMAKE_CURRENT_BINARY_DIR}`` will be used. +This option can be used to avoid file conflicts. + +REQUIRED_HEADERS specifies an output variable name where all the required +headers will be appended so that they can be installed together with the +generated ones. This is mostly intended as a convenience so that adding a new +header to a project only requires specifying the CamelCase variant in the +CMakeLists.txt file; the original variant will then be added to this +variable. + +COMMON_HEADER generates an additional convenience header which includes all +other header files. + +The RELATIVE argument indicates where the original headers can be found +relative to CMAKE_CURRENT_SOURCE_DIR. It does not affect the generated +CamelCase forwarding files, but quotient_generate_headers() uses it when checking +that the original header exists, and to generate originally named forwarding +headers when PREFIX is set. + +To allow other parts of the source distribution (eg: tests) to use the +generated headers before installation, it may be desirable to set the +INCLUDE_DIRECTORIES property for the library target to output_dir. For +example, if OUTPUT_DIR is CMAKE_CURRENT_BINARY_DIR (the default), you could do + +.. code-block:: cmake + + target_include_directories(MyLib PUBLIC "$") + +Example usage (without PREFIX): + +.. code-block:: cmake + + quotient_generate_headers( + MyLib_FORWARDING_HEADERS + HEADERS + MLFoo + MLBar + # etc + REQUIRED_HEADERS MyLib_HEADERS + COMMON_HEADER MLGeneral + ) + install(FILES ${MyLib_FORWARDING_HEADERS} ${MyLib_HEADERS} + DESTINATION ${CMAKE_INSTALL_PREFIX}/include + COMPONENT Devel) + +Example usage (with PREFIX): + +.. code-block:: cmake + + quotient_generate_headers( + MyLib_FORWARDING_HEADERS + HEADERS + Foo + # several classes are contained in bar.h, so generate + # additional files + Bar,BarList + # etc + PREFIX MyLib + REQUIRED_HEADERS MyLib_HEADERS + ) + install(FILES ${MyLib_FORWARDING_HEADERS} + DESTINATION ${CMAKE_INSTALL_PREFIX}/include/MyLib + COMPONENT Devel) + install(FILES ${MyLib_HEADERS} + DESTINATION ${CMAKE_INSTALL_PREFIX}/include/mylib + COMPONENT Devel) + +Since pre-1.0.0. +#]=======================================================================] + +include(CMakeParseArguments) + +function(QUOTIENT_GENERATE_HEADERS camelcase_forwarding_headers_var) + set(options) + set(oneValueArgs ORIGINAL HEADER_EXTENSION OUTPUT_DIR PREFIX REQUIRED_HEADERS COMMON_HEADER RELATIVE) + set(multiValueArgs HEADER_NAMES) + cmake_parse_arguments(EGH "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if (EGH_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Unexpected arguments to QUOTIENT_GENERATE_HEADERS: ${EGH_UNPARSED_ARGUMENTS}") + endif() + + if(NOT EGH_HEADER_NAMES) + message(FATAL_ERROR "Missing header_names argument to QUOTIENT_GENERATE_HEADERS") + endif() + + if(NOT EGH_ORIGINAL) + # default + set(EGH_ORIGINAL "LOWERCASE") + endif() + if(NOT EGH_ORIGINAL STREQUAL "LOWERCASE" AND NOT EGH_ORIGINAL STREQUAL "CAMELCASE") + message(FATAL_ERROR "Unexpected value for original argument to QUOTIENT_GENERATE_HEADERS: ${EGH_ORIGINAL}") + endif() + + if(NOT EGH_HEADER_EXTENSION) + set(EGH_HEADER_EXTENSION "h") + endif() + + if(NOT EGH_OUTPUT_DIR) + set(EGH_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}") + endif() + + # Make sure EGH_RELATIVE is /-terminated when it's not empty + if (EGH_RELATIVE AND NOT "${EGH_RELATIVE}" MATCHES "^.*/$") + set(EGH_RELATIVE "${EGH_RELATIVE}/") + endif() + + if (EGH_PREFIX) + if (NOT "${EGH_PREFIX}" MATCHES "^.*/$") + set(EGH_PREFIX "${EGH_PREFIX}/") + endif() + if (EGH_ORIGINAL STREQUAL "CAMELCASE") + set(originalprefix "${EGH_PREFIX}") + else() + string(TOLOWER "${EGH_PREFIX}" originalprefix) + endif() + endif() + + foreach(_classnameentry ${EGH_HEADER_NAMES}) + string(REPLACE "," ";" _classnames ${_classnameentry}) + list(GET _classnames 0 _baseclass) + + if (EGH_ORIGINAL STREQUAL "CAMELCASE") + set(originalbasename "${_baseclass}") + else() + string(TOLOWER "${_baseclass}" originalbasename) + endif() + + set(_actualheader "${CMAKE_CURRENT_SOURCE_DIR}/${EGH_RELATIVE}${originalbasename}.${EGH_HEADER_EXTENSION}") + if (NOT EXISTS ${_actualheader}) + message(FATAL_ERROR "Could not find \"${_actualheader}\"") + endif() + + foreach(_CLASSNAME ${_classnames}) + set(FANCY_HEADER_FILE "${EGH_OUTPUT_DIR}/${EGH_PREFIX}${_CLASSNAME}") + if (NOT EXISTS ${FANCY_HEADER_FILE}) + file(WRITE ${FANCY_HEADER_FILE} "#include \"${originalprefix}${originalbasename}.${EGH_HEADER_EXTENSION}\"\n") + endif() + list(APPEND ${camelcase_forwarding_headers_var} "${FANCY_HEADER_FILE}") + if (EGH_PREFIX) + # Local forwarding header, for namespaced headers, e.g. kparts/part.h + if(EGH_ORIGINAL STREQUAL "CAMELCASE") + set(originalclassname "${_CLASSNAME}") + else() + string(TOLOWER "${_CLASSNAME}" originalclassname) + endif() + set(REGULAR_HEADER_NAME ${EGH_OUTPUT_DIR}/${originalprefix}${originalclassname}.${EGH_HEADER_EXTENSION}) + if (NOT EXISTS ${REGULAR_HEADER_NAME}) + file(WRITE ${REGULAR_HEADER_NAME} "#include \"${_actualheader}\"\n") + endif() + endif() + endforeach() + + list(APPEND _REQUIRED_HEADERS "${_actualheader}") + endforeach() + + if(EGH_COMMON_HEADER) + #combine required headers into 1 big convenience header + set(COMMON_HEADER ${EGH_OUTPUT_DIR}/${EGH_PREFIX}${EGH_COMMON_HEADER}) + file(WRITE ${COMMON_HEADER} "// convenience header\n") + foreach(_header ${_REQUIRED_HEADERS}) + get_filename_component(_base ${_header} NAME) + file(APPEND ${COMMON_HEADER} "#include \"${_base}\"\n") + endforeach() + list(APPEND ${camelcase_forwarding_headers_var} "${COMMON_HEADER}") + endif() + + set(${camelcase_forwarding_headers_var} ${${camelcase_forwarding_headers_var}} PARENT_SCOPE) + if (NOT EGH_REQUIRED_HEADERS STREQUAL "") + set(${EGH_REQUIRED_HEADERS} ${${EGH_REQUIRED_HEADERS}} ${_REQUIRED_HEADERS} PARENT_SCOPE) + endif () +endfunction() diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt new file mode 100644 index 000000000..af62764ff --- /dev/null +++ b/lib/CMakeLists.txt @@ -0,0 +1,117 @@ +set(Quotient_HEADERS + avatar.h + connection.h + connectiondata.h + converters.h + eventitem.h + e2ee.h + logging.h + encryptionmanager.h + networkaccessmanager.h + networksettings.h + qt_connection_util.h + quotient_common.h + settings.h + joinstate.h + ssosession.h + syncdata.h + user.h + uri.h + uriresolver.h + util.h + + # jobs + jobs/basejob.h + jobs/syncjob.h + jobs/requestdata.h + jobs/downloadfilejob.h + jobs/mediathumbnailjob.h + + # events + events/event.h + events/accountdataevents.h + events/callanswerevent.h + events/callcandidatesevent.h + events/callhangupevent.h + events/callinviteevent.h + events/directchatevent.h + events/encryptedevent.h + events/eventcontent.h + events/eventloader.h + events/reactionevent.h + events/receiptevent.h + events/redactionevent.h + events/roomevent.h + events/roomkeyevent.h + events/roomavatarevent.h + events/roomcreateevent.h + events/roomcanonicalaliasevent.h + events/roompowerlevelsevent.h + events/roommessageevent.h + events/roomtombstoneevent.h + events/simplestateevents.h + events/stateevent.h + events/stickerevent.h + events/typingevent.h +) + +quotient_generate_headers( + QUOTIENT_FORWARDING_HEADERS + HEADER_NAMES + Room,FileTransferInfo,MemberSorter + Converters + Connection,LoginFlows + ConnectionData + EncryptionManager + EventItem,EventItemBase,EventStatus,TimelineItem + JoinState + Avatar + Logging + SyncData,RoomSummary,SyncRoomData + SsoSession + Settings + Uri + User + UriResolver,UriResolverBase,UriDispatcher, + Util + Jobs/BaseJob + Jobs/SyncJob + Jobs/RequestData + Jobs/MediaThumbnailJob + Jobs/DownloadFileJob + Events/Event + Events/AccountDataEvents + Events/CallAnswerEvent + Events/CallCandidatesEvent + Events/CallHangupEvent + Events/CallInviteEvent + Events/DirectChatEvent + Events/EncryptedEvent + Events/EventContent + Events/EventLoader + Events/ReactionEvent + Events/ReceiptEvent + Events/RedactionEvent + Events/RoomEvent + Events/RoomKeyEvent + Events/RoomAvatarEvent + Events/RoomCreateEvent + Events/RoomCanonicalAliasEvent + Events/RoomPowerLevelsEvent + Events/RoomMessageEvent + Events/RoomTombstoneEvent + Events/SimpleStateEvents + Events/StateEvent + Events/StickerEvent + Events/TypingEvent + PREFIX Quotient + REQUIRED_HEADERS Quotient_HEADERS +) +install(FILES ${QUOTIENT_FORWARDING_HEADERS} + DESTINATION ${CMAKE_INSTALL_PREFIX}/include/Quotient + COMPONENT Devel) + +install(FILES ${Quotient_HEADERS} + DESTINATION ${CMAKE_INSTALL_PREFIX}/include/quotient + COMPONENT Devel) +