diff --git a/.travis.yml b/.travis.yml index ee641ec..ea5b4a6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,4 @@ +dist: trusty language: cpp cache: apt env: diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..6c3a268 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,18 @@ +cmake_minimum_required(VERSION 3.12.0 FATAL_ERROR) + +project(qamqp LANGUAGES CXX VERSION 0.5.0) + +get_filename_component(QAMQP_PATH "${CMAKE_CURRENT_SOURCE_DIR}" ABSOLUTE) +include(${QAMQP_PATH}/cmake/CMakeSettings.cmake) + +add_subdirectory(src) +add_subdirectory(tests/auto) + +if (${WITH_TUTORIALS}) + message(STATUS "Adding tutorials...") + add_subdirectory(tutorials) +else() + message(STATUS "Not adding tutorials (use -DWITH_TUTORIALS=ON for that)...") +endif() + +include(CPack) diff --git a/README.md b/README.md index 426a315..1283d93 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,70 @@ QAMQP ============= A Qt4/Qt5 implementation of AMQP 0.9.1, focusing primarily on RabbitMQ support. + +Building with CMake +------------ +- ensure you have the following packages on the `PATH` + - **CMake** >= 3.12 + - **Qt** >= 5.9 + - **lcov** + +- checkout sources +```sh +$ cd ~/src +$ git clone git@github.com:ssproessig/qamqp.git +``` + +- we are going to build in a separate out-of-tree build directory + - building `Debug` build with default compiler + ```sh + $ mkdir -p ~/build/qamqp-debug && cd ~/build/qamqp-debug + $ cmake ~/src/qamqp + $ cmake --build . + ``` + + - building `Release` build with **clang** compiler and **ninja** generator + ```sh + $ mkdir -p ~/build/qamqp-clang-release && cd ~/build/qamqp-clang-release + $ + $ EXPORT CXX=clang++-10 + $ + $ cmake -G Ninja ~/src/qamqp + $ cmake --build . + ``` + +- running tests with coverage from inside the build directory +```sh +$ # ... after building, in the build directory +$ ctest -V # -V for verbose output of QTest +$ sh generate_coverage.sh +$ ... +$ firefox coverage/index.html +``` + +- building a release with **Visual Studio 2019 Win64** (make sure to have **[OpenCppCoverage](https://github.com/OpenCppCoverage/OpenCppCoverage)** on the `PATH`) +```bat +F:\2019\qamqp>cmake G:\_projects\qamqp +... + +F:\2019\qamqp>cmake --build . --parallel 8 --config RelWithDebInfo +... + +F:\2019\qamqp>Opencppcoverage --export_type html:coverage --modules "qamqp*.exe" --sources G:\_projects\qamqp\src --optimized_build --cover_children -- ctest -C RelWithDebInfo +... +... open coverage/index.html in your browser .... +... + +F:\2019\qamqp>cpack -G ZIP +... +CPack: - package: F:/2019/qamqp/qamqp-0.5.0-ee2bfd8-win64.zip generated. +``` + + Usage ------------ +Use `-DWITH_TUTORIALS=ON` to enable the tutorials in CMake. + * [hello world](https://github.com/mbroadst/qamqp/tree/master/tutorials/helloworld) * [pubsub](https://github.com/mbroadst/qamqp/tree/master/tutorials/pubsub) * [routing](https://github.com/mbroadst/qamqp/tree/master/tutorials/routing) @@ -14,6 +76,7 @@ Usage * [topics](https://github.com/mbroadst/qamqp/tree/master/tutorials/topics) * [work queues](https://github.com/mbroadst/qamqp/tree/master/tutorials/workqueues) + Documentation ------------ Coming soon! diff --git a/cmake/00_CMake_Policies.cmake b/cmake/00_CMake_Policies.cmake new file mode 100644 index 0000000..00597e6 --- /dev/null +++ b/cmake/00_CMake_Policies.cmake @@ -0,0 +1,5 @@ +# from CMake 3.1 on: we want the NEW interpretation in of variables +cmake_policy(SET CMP0054 NEW) + +# if the generator supports it, generate build_commands.json +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) diff --git a/cmake/01_git_Integration.cmake b/cmake/01_git_Integration.cmake new file mode 100644 index 0000000..5069312 --- /dev/null +++ b/cmake/01_git_Integration.cmake @@ -0,0 +1,65 @@ +# idea shamelessly taken from: http://xit0.org/2013/04/cmake-use-git-branch-and-commit-details-in-project/ +# with some additions, e.g. for finding git, checking if source directory is git directory, renaming variables to VCS + +# initialize commit variables +set(GIT_BRANCH_DEFAULT "unknown") +set(GIT_COMMIT_ID_DEFAULT "0000000") +set(VCS_BRANCH ${GIT_BRANCH_DEFAULT}) +set(VCS_COMMIT_ID ${GIT_COMMIT_ID_DEFAULT}) + +# we need the local systems git +find_package(Git REQUIRED) + +# if we have git ... +if (GIT_FOUND) + # is the source directory under git version control at all? + execute_process( + COMMAND ${GIT_EXECUTABLE} status + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + RESULT_VARIABLE VCS_IS_GIT + OUTPUT_QUIET + ERROR_QUIET + ) + + # only if we are under git version control... + if(VCS_IS_GIT EQUAL 0) + # Get the current working branch + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE VCS_BRANCH + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + # Get the latest abbreviated commit hash of the working branch + execute_process( + COMMAND ${GIT_EXECUTABLE} log -1 --format=%h + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE VCS_COMMIT_ID + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + else() + if (VCS_BRANCH STREQUAL GIT_BRANCH_DEFAULT OR VCS_COMMIT_ID STREQUAL GIT_COMMIT_ID_DEFAULT) + message(WARNING "! Not building sources from git repository. You need to provide VCS_BRANCH and VCS_COMMIT_ID manually.") + endif() + endif() + + # output the version information we are on + message(STATUS "Processing sources from '${CMAKE_SOURCE_DIR}' provided by git") + message(STATUS " on branch: ${VCS_BRANCH}") + message(STATUS " revision: ${VCS_COMMIT_ID}") +# no git -> no versioning +else() + message(WARNING "! No git executable found. Unable to determine VCS_BRANCH and VCS_COMMIT_ID. Provide them manually.") +endif() + + +# a helper function to add VCS information to the FILE_NAME passed +function(_add_vcs_info_to_file FILE_NAME) + set_property( + SOURCE ${FILE_NAME} + APPEND + PROPERTY COMPILE_DEFINITIONS + GIT_BRANCH="${VCS_BRANCH}" GIT_VERSION="${VCS_COMMIT_ID}" + ) +endfunction() diff --git a/cmake/05_CPack_Support.cmake b/cmake/05_CPack_Support.cmake new file mode 100644 index 0000000..ab8ab6e --- /dev/null +++ b/cmake/05_CPack_Support.cmake @@ -0,0 +1,28 @@ +# if no PACKAGE version is set via CLI parameters, set it to development +if (NOT CPACK_PACKAGE_VERSION) + message(STATUS "! no CPACK_PACKAGE_VERSION parameter seen. Defaulting to development version ${PROJECT_VERSION}") + set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) +endif() + +# extract version information to separate numbers +string(REPLACE "." ";" VERSION_LIST ${CPACK_PACKAGE_VERSION}) +list(GET VERSION_LIST 0 CPACK_PACKAGE_VERSION_MAJOR) +list(GET VERSION_LIST 1 CPACK_PACKAGE_VERSION_MINOR) +list(GET VERSION_LIST 2 CPACK_PACKAGE_VERSION_PATCH) + +# append the git hash to it +set(CPACK_PACKAGE_VERSION_SIMPLE ${CPACK_PACKAGE_VERSION}) +set(CPACK_PACKAGE_VERSION ${CPACK_PACKAGE_VERSION}-${VCS_COMMIT_ID}) +message(STATUS " this is version ${CPACK_PACKAGE_VERSION}.") + +# general package options +set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY 0) +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Qt5 library implementation of AMQP 0.9.1, focusing on RabbitMQ") +set(CPACK_PACKAGE_NAME "qamqp") +set(CPACK_PACKAGE_VENDOR "Matt Broadstone and contributors") +set(CPACK_PACKAGE_CONTACT mbroadst@gmail.com) + +# when packaging unter Debian (cpack -G DEB) we can auto-detect .deb dependencies +set (CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) + +# NOTE: 'include(CPack)' MUST happen after all CPACK_ variables are set in the including sub directories (e.g. for menu links) diff --git a/cmake/06_CTest_Support.cmake b/cmake/06_CTest_Support.cmake new file mode 100644 index 0000000..30bfa86 --- /dev/null +++ b/cmake/06_CTest_Support.cmake @@ -0,0 +1,27 @@ +enable_testing() + + +function(add_qtest) + + cmake_parse_arguments( + ADD_QTEST_PREFIX + "" + "NAME" + "SOURCES;LIBS" + ${ARGN} + ) + + + add_executable(${ADD_QTEST_PREFIX_NAME} ${ADD_QTEST_PREFIX_SOURCES}) + + target_include_directories(${ADD_QTEST_PREFIX_NAME} + PRIVATE + ${QAMQP_PATH}/src + ${QAMQP_PATH}/tests/common + ) + target_link_libraries(${ADD_QTEST_PREFIX_NAME} ${ADD_QTEST_PREFIX_LIBS} Qt5::Test) + _enable_compiler_coverage_flags_for(${ADD_QTEST_PREFIX_NAME}) + + add_test(NAME ${ADD_QTEST_PREFIX_NAME} COMMAND ${ADD_QTEST_PREFIX_NAME}) + +endfunction() diff --git a/cmake/10_DefaultBuildType.cmake b/cmake/10_DefaultBuildType.cmake new file mode 100644 index 0000000..fe0ad11 --- /dev/null +++ b/cmake/10_DefaultBuildType.cmake @@ -0,0 +1,13 @@ +if ("${CMAKE_BUILD_TYPE}" STREQUAL "") + message(STATUS "Defaulting to 'Debug' build. Use -DCMAKE_BUILD_TYPE=Release for releases.") + set(CMAKE_BUILD_TYPE "Debug") +endif() + +message(STATUS "This is a '${CMAKE_BUILD_TYPE}' build with the '${CMAKE_GENERATOR}' generator.") +message(STATUS "The 'install' target will use the prefix '${CMAKE_INSTALL_PREFIX}'") + +if ("${CMAKE_TOOLCHAIN_FILE}" STREQUAL "") + message(STATUS "Not using cross-compile toolchain. Building locally ...") +else() + message(STATUS "Cross-compiling using toolchain file '${CMAKE_TOOLCHAIN_FILE}' ...") +endif() diff --git a/cmake/20_FindDependencies.cmake b/cmake/20_FindDependencies.cmake new file mode 100644 index 0000000..11b07b1 --- /dev/null +++ b/cmake/20_FindDependencies.cmake @@ -0,0 +1 @@ +include(${CMAKE_CURRENT_LIST_DIR}/21_FindQt.cmake) diff --git a/cmake/21_FindQt.cmake b/cmake/21_FindQt.cmake new file mode 100644 index 0000000..91bfcd1 --- /dev/null +++ b/cmake/21_FindQt.cmake @@ -0,0 +1,21 @@ +find_package(Qt5 5.9 REQUIRED COMPONENTS Core Network Test) + +# now prepare the qt version for usage in our CMakeLists +get_target_property (QT_QMAKE_EXECUTABLE Qt5::qmake IMPORTED_LOCATION) + +# execute qmake to get version +execute_process(COMMAND ${QT_QMAKE_EXECUTABLE} -version OUTPUT_VARIABLE QT_VERSION_RAW) +string(REGEX MATCH "[0-9]\.[0-9]+\.[0-9]+" QT_VERSION ${QT_VERSION_RAW}) + +# status output +message(STATUS "...using '${QT_QMAKE_EXECUTABLE}'. Qt version: ${QT_VERSION}") + +# extract version number parts +string(REPLACE "." ";" QT_VERSION_LIST ${QT_VERSION}) +list(GET QT_VERSION_LIST 0 QT_VERSION_MAJOR) +list(GET QT_VERSION_LIST 1 QT_VERSION_MINOR) +list(GET QT_VERSION_LIST 2 QT_VERSION_PATCH) + +# per default: we enable auto-mocing and include those generated Qt files automatically +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) diff --git a/cmake/50_CompilerSwitches.cmake b/cmake/50_CompilerSwitches.cmake new file mode 100644 index 0000000..1d2fff1 --- /dev/null +++ b/cmake/50_CompilerSwitches.cmake @@ -0,0 +1,23 @@ +# settings to apply to all compilers +set(CMAKE_POSITION_INDEPENDENT_CODE ON) + +# we aim for C++14 +set(CMAKE_CXX_STANDARD 14) + + +# declare some "empty default implementation" macros that can be specialized per compiler +macro(_enable_compiler_coverage_flags_for __target) +endmacro() + + +# compiler specific settings +if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + include(${CMAKE_CURRENT_LIST_DIR}/51_CompilerSwitches_GCC.cmake) +elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") + include(${CMAKE_CURRENT_LIST_DIR}/52_CompilerSwitches_Clang.cmake) +elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + include(${CMAKE_CURRENT_LIST_DIR}/53_CompilerSwitches_MSVC.cmake) +endif() + +# finally we support building "releases with symbol" +include(${CMAKE_CURRENT_LIST_DIR}/59_StripDebugSymbolsInRelease.cmake) diff --git a/cmake/51_CompilerSwitches_GCC.cmake b/cmake/51_CompilerSwitches_GCC.cmake new file mode 100644 index 0000000..60f3100 --- /dev/null +++ b/cmake/51_CompilerSwitches_GCC.cmake @@ -0,0 +1,28 @@ +# 1) determine compiler version +execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE COMPILER_VERSION) +string(REGEX MATCHALL "[0-9]+" COMPILER_VERSION_COMPONENTS ${COMPILER_VERSION}) +list(APPEND COMPILER_VERSION_COMPONENTS 0) +list(GET COMPILER_VERSION_COMPONENTS 0 COMPILER_MAJOR) +list(GET COMPILER_VERSION_COMPONENTS 1 COMPILER_MINOR) + +message(STATUS "Using ${CMAKE_CXX_COMPILER} in version ${COMPILER_MAJOR}.${COMPILER_MINOR}") + +# 2) control build flags according to build type +if (${CMAKE_BUILD_TYPE} STREQUAL "Debug") + # debugging symbols and no optimization please + add_definitions(-g3 -O0) +else(${CMAKE_BUILD_TYPE} STREQUAL "Release") + # optimize the build please + add_definitions(-O3) +endif() + +# 3) finally ensure we see many warnings +add_definitions(-Wall -Wextra) + +# 4) helper for coverage instrumentation +macro(_enable_compiler_coverage_flags_for __target) + if(${CMAKE_BUILD_TYPE} STREQUAL "Debug") + set_property(TARGET ${__target} APPEND_STRING PROPERTY COMPILE_FLAGS " -fprofile-arcs -ftest-coverage ") + target_link_libraries(${__target} gcov) + endif() +endmacro() diff --git a/cmake/52_CompilerSwitches_Clang.cmake b/cmake/52_CompilerSwitches_Clang.cmake new file mode 100644 index 0000000..73161d5 --- /dev/null +++ b/cmake/52_CompilerSwitches_Clang.cmake @@ -0,0 +1,41 @@ +# control build flags according to build type +if (${CMAKE_BUILD_TYPE} STREQUAL "Debug") + # debugging symbols and no optimization please + add_definitions(-g3 -O0) + + # some extended clang analyzers - MUST be enabled manually via CMake parameter + if(${CLANG_ANALYSIS}) + set(CLANG_ANALYZERS address) + + message(STATUS "enabling clang analysis code generation: ${CLANG_ANALYZERS}") + + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=${CLANG_ANALYZERS}") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=${CLANG_ANALYZERS}") + set(CMAKE_LINKER "${CXX_COMPILER}") + endif() + +else(${CMAKE_BUILD_TYPE} STREQUAL "Release") + # optimize the build please + add_definitions(-g -O3) +endif() + +# set warning options +if (DEFINED $ENV{ENV_CLANG_CXXFLAGS}) + add_definitions($ENV{ENV_CLANG_CXXFLAGS}) +else() + add_definitions(-Weverything + -Wno-weak-vtables -Wno-padded -Wno-packed + -Wno-c++98-compat-pedantic -Wno-c++98-compat + -Wno-exit-time-destructors -Wno-missing-prototypes + -Wno-documentation-unknown-command + -Wno-used-but-marked-unused + -Wno-gnu-zero-variadic-macro-arguments + -Wno-disabled-macro-expansion + -Wno-global-constructors + ) + + # clang 3.9 introduced a new warning that needs to be checked - apple clang does not yet support it + if (NOT CMAKE_CXX_COMPILER_ID MATCHES "AppleClang" AND ${CMAKE_CXX_COMPILER_VERSION} VERSION_GREATER "3.8") + add_definitions(-Wno-undefined-func-template) + endif() +endif() diff --git a/cmake/53_CompilerSwitches_MSVC.cmake b/cmake/53_CompilerSwitches_MSVC.cmake new file mode 100644 index 0000000..bfef41d --- /dev/null +++ b/cmake/53_CompilerSwitches_MSVC.cmake @@ -0,0 +1,5 @@ +# disable manifest generation +# read here: http://stackoverflow.com/a/8359871 +set(CMAKE_EXE_LINKER_FLAGS /MANIFEST:NO) +set(CMAKE_MODULE_LINKER_FLAGS /MANIFEST:NO) +set(CMAKE_SHARED_LINKER_FLAGS /MANIFEST:NO) diff --git a/cmake/59_StripDebugSymbolsInRelease.cmake b/cmake/59_StripDebugSymbolsInRelease.cmake new file mode 100644 index 0000000..8a03e2b --- /dev/null +++ b/cmake/59_StripDebugSymbolsInRelease.cmake @@ -0,0 +1,52 @@ +if(${CMAKE_BUILD_TYPE} STREQUAL "Release") + set(WILL_CREATE_RELEASE_WITH_SYMBOLS OFF) + + # define an option for that + option(RELEASE_WITH_SYMBOLS "When building a release, generate debug symbols as well BUT strip them from the binary" OFF) + + # did the user request it from the cmake options? + if(${RELEASE_WITH_SYMBOLS}) + # do we have a supported build environment? + if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR + "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR + "${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") + + # find the required binaries + find_program(STRIP_BINARY "${COMPILER_PREFIX}strip") + find_program(OBJCOPY_BINARY "${COMPILER_PREFIX}objcopy") + + if ("${STRIP_BINARY}" STREQUAL "STRIP_BINARY-NOTFOUND") + message(STATUS "ReleaseWSymbols: Did not find a 'strip' util for that toolchain!") + else() + if ("${OBJCOPY_BINARY}" STREQUAL "OBJCOPY_BINARY-NOTFOUND") + message(STATUS "ReleaseWSymbols: Did not find a 'objcopy' util for that toolchain!") + else() + # if we reach here, we can enable "release with symbols" + set(WILL_CREATE_RELEASE_WITH_SYMBOLS ON) + endif() + endif() + else() + message(STATUS "ReleaseWSymbols: Don't know how to strip symbols for compiler '${CMAKE_CXX_COMPILER_ID}'!") + endif() + endif() + + # finally some debug output + if(${WILL_CREATE_RELEASE_WITH_SYMBOLS}) + message(STATUS "ReleaseWSymbols: Will create a 'Release' with debug symbols being stripped to separate files.") + + # create binaries with debugging information, although we are building a Release + add_definitions(-g3) + + # define a helper to strip the binary + macro(_strip_debug_symbols __target) + # first create a copy of the target file + add_custom_command(TARGET ${__target} POST_BUILD COMMAND ${OBJCOPY_BINARY} --only-keep-debug $ $.debug) + + # now strip its debug information from original + add_custom_command(TARGET ${__target} POST_BUILD COMMAND ${STRIP_BINARY} -g $) + + # finally install debug + install(FILES $.debug DESTINATION debug) + endmacro() + endif() +endif() diff --git a/cmake/CMakeSettings.cmake b/cmake/CMakeSettings.cmake new file mode 100644 index 0000000..3269f0c --- /dev/null +++ b/cmake/CMakeSettings.cmake @@ -0,0 +1,16 @@ +# update our CMake policies +include(${CMAKE_CURRENT_LIST_DIR}/00_CMake_Policies.cmake NO_POLICY_SCOPE) + +# adding some helpers for CMake et.al. +include(${CMAKE_CURRENT_LIST_DIR}/01_git_Integration.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/05_CPack_Support.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/06_CTest_Support.cmake) + +# define the default build type +include(${CMAKE_CURRENT_LIST_DIR}/10_DefaultBuildType.cmake) + +# find all needed libraries +include(${CMAKE_CURRENT_LIST_DIR}/20_FindDependencies.cmake) + +# set global compiler switches, depending on compiler being used +include(${CMAKE_CURRENT_LIST_DIR}/50_CompilerSwitches.cmake) diff --git a/qamqp.pri b/qamqp.pri index 0e7a383..37f72d5 100644 --- a/qamqp.pri +++ b/qamqp.pri @@ -1,5 +1,9 @@ QAMQP_VERSION = 0.5.0 +contains(QT_MAJOR_VERSION, 4) { + DEFINES += Q_NULLPTR=0 +} + isEmpty(QAMQP_LIBRARY_TYPE) { QAMQP_LIBRARY_TYPE = shared } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..5acb6c4 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,35 @@ +set(LIB_NAME qamqp-lib) + +file(GLOB HDR *.h) +file(GLOB SRC *.cpp) + +source_group("${LIB_NAME} Sources" ${HDR} ${SRC}) + +_add_vcs_info_to_file(qamqpclient.cpp) + +set(LNK Qt5::Core Qt5::Network) + +add_library(${LIB_NAME}-static ${API} ${SRC}) +target_link_libraries(${LIB_NAME}-static ${LNK}) + +add_library(${LIB_NAME} SHARED ${API} ${SRC}) +target_link_libraries(${LIB_NAME} ${LNK}) + +add_library(${LIB_NAME}-coverage OBJECT ${API} ${SRC}) +target_link_libraries(${LIB_NAME}-coverage ${LNK}) +_enable_compiler_coverage_flags_for(${LIB_NAME}-coverage) + +if ("${CMAKE_BUILD_TYPE}" STREQUAL "Release") + install(TARGETS ${LIB_NAME}-static EXPORT ${PROJECT_EXPORT}) + install(TARGETS ${LIB_NAME} EXPORT ${PROJECT_EXPORT}) + install(FILES + qamqpauthenticator.h + qamqpchannel.h + qamqpclient.h + qamqpexchange.h + qamqpglobal.h + qamqpmessage.h + qamqpqueue.h + qamqptable.h + DESTINATION include) +endif() diff --git a/src/qamqpclient.cpp b/src/qamqpclient.cpp index 41a0a17..86f7be9 100644 --- a/src/qamqpclient.cpp +++ b/src/qamqpclient.cpp @@ -435,18 +435,21 @@ void QAmqpClientPrivate::tune(const QAmqpMethodFrame &frame) QByteArray data = frame.arguments(); QDataStream stream(&data, QIODevice::ReadOnly); - qint16 channel_max = 0, - heartbeat_delay = 0; - qint32 frame_max = 0; - - stream >> channel_max; - stream >> frame_max; - stream >> heartbeat_delay; - - if (!frameMax) - frameMax = frame_max; - channelMax = !channelMax ? channel_max : qMax(channel_max, channelMax); - heartbeatDelay = !heartbeatDelay ? heartbeat_delay: heartbeatDelay; + qint16 peerChannelMax = 0; + qint16 peerHeartbeatDelay = 0; + qint32 peerFrameMax = 0; + + stream >> peerChannelMax; + stream >> peerFrameMax; + stream >> peerHeartbeatDelay; + + // resolve tune parameters to use on the connection: + // a) if we did not configure parameters manually, use the received peer parameters + // b) if we configured them, use the smaller value, as otherwise the peer providing this value may not work + frameMax = !frameMax ? peerFrameMax : qMin(frameMax, peerFrameMax); + channelMax = !channelMax ? peerChannelMax : qMin(channelMax, peerChannelMax); + // c) heartbeat delay is not relevant framing layer, so use whatever value is configured + heartbeatDelay = !heartbeatDelay ? peerHeartbeatDelay : heartbeatDelay; qAmqpDebug("-> connection#tune( channel_max=%d, frame_max=%d, heartbeat=%d )", channelMax, frameMax, heartbeatDelay); diff --git a/tests/auto/CMakeLists.txt b/tests/auto/CMakeLists.txt new file mode 100644 index 0000000..cf7aa8b --- /dev/null +++ b/tests/auto/CMakeLists.txt @@ -0,0 +1,17 @@ +set(LNK Qt5::Core Qt5::Network) + +add_qtest(NAME qamqpchannel SOURCES qamqpchannel/tst_qamqpchannel.cpp $ LIBS ${LNK}) +add_qtest(NAME qamqpclient SOURCES qamqpclient/certs.qrc qamqpclient/tst_qamqpclient.cpp $ LIBS ${LNK}) +add_qtest(NAME qamqpexchange SOURCES qamqpexchange/tst_qamqpexchange.cpp $ LIBS ${LNK}) +add_qtest(NAME qamqpqueue SOURCES qamqpqueue/tst_qamqpqueue.cpp $ LIBS ${LNK}) + +if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + set(COVERAGE_SH ${PROJECT_BINARY_DIR}/generate_coverage.sh) + file(WRITE ${COVERAGE_SH} "!/bin/sh\n") + file(APPEND ${COVERAGE_SH} "\n") + file(APPEND ${COVERAGE_SH} "lcov --capture --directory src --output-file coverage-gcov.info \n") + file(APPEND ${COVERAGE_SH} "lcov --output-file coverage-gcov.info --remove coverage-gcov.info '${PROJECT_BINARY_DIR}/*' '*Qt*' '*include*'\n") + file(APPEND ${COVERAGE_SH} "\n") + file(APPEND ${COVERAGE_SH} "genhtml coverage-gcov.info --prefix src/ --output-directory coverage\n") +endif() + diff --git a/tests/auto/qamqpclient/tst_qamqpclient.cpp b/tests/auto/qamqpclient/tst_qamqpclient.cpp index 67ccf6f..d592a67 100644 --- a/tests/auto/qamqpclient/tst_qamqpclient.cpp +++ b/tests/auto/qamqpclient/tst_qamqpclient.cpp @@ -179,9 +179,9 @@ void tst_QAMQPClient::tune() client.connectToHost(); QVERIFY(waitForSignal(&client, SIGNAL(connected()))); - QCOMPARE((int)client.channelMax(), 15); - QCOMPARE((int)client.heartbeatDelay(), 600); - QCOMPARE((int)client.frameMax(), 5000); + QCOMPARE(client.channelMax(), qint16(15)); + QCOMPARE(client.heartbeatDelay(), qint16(600)); + QCOMPARE(client.frameMax(), qint32(5000)); client.disconnectFromHost(); QVERIFY(waitForSignal(&client, SIGNAL(disconnected()))); diff --git a/tutorials/CMakeLists.txt b/tutorials/CMakeLists.txt new file mode 100644 index 0000000..99a5898 --- /dev/null +++ b/tutorials/CMakeLists.txt @@ -0,0 +1,40 @@ +function(add_tutorial) + + cmake_parse_arguments( + ADD_TUTORIAL_PREFIX + "" + "NAME" + "SOURCES" + ${ARGN} + ) + + + add_executable(${ADD_TUTORIAL_PREFIX_NAME} ${ADD_TUTORIAL_PREFIX_SOURCES}) + + target_include_directories(${ADD_TUTORIAL_PREFIX_NAME} + PRIVATE + ${QAMQP_PATH}/src + ${QAMQP_PATH}/tests/common + ) + target_link_libraries(${ADD_TUTORIAL_PREFIX_NAME} qamqp-lib-static Qt5::Core Qt5::Network) + +endfunction() + + +add_tutorial(NAME tutorial_helloworld_receive SOURCES helloworld/receive/main.cpp) +add_tutorial(NAME tutorial_helloworld_send SOURCES helloworld/send/main.cpp) + +add_tutorial(NAME tutorial_pubsub_emit_log SOURCES pubsub/emit_log/main.cpp) +add_tutorial(NAME tutorial_pubsub_receive_logs SOURCES pubsub/receive_logs/main.cpp) + +add_tutorial(NAME tutorial_routing_emit_log_direct SOURCES routing/emit_log_direct/main.cpp) +add_tutorial(NAME tutorial_routing_receive_logs_direct SOURCES routing/receive_logs_direct/main.cpp) + +add_tutorial(NAME tutorial_rpc_rpc_client SOURCES rpc/rpc_client/main.cpp rpc/rpc_client/fibonaccirpcclient.cpp rpc/rpc_client/fibonaccirpcclient.h) +add_tutorial(NAME tutorial_rpc_rpc_server SOURCES rpc/rpc_server/main.cpp rpc/rpc_server/server.cpp rpc/rpc_server/server.h) + +add_tutorial(NAME tutorial_topics_emit_log_topic SOURCES topics/emit_log_topic/main.cpp) +add_tutorial(NAME tutorial_topics_receive_logs_topic SOURCES topics/receive_logs_topic/main.cpp) + +add_tutorial(NAME tutorial_workqueues_new_task SOURCES workqueues/new_task/main.cpp) +add_tutorial(NAME tutorial_workqueues_worker SOURCES workqueues/worker/main.cpp)