diff --git a/.travis.yml b/.travis.yml index e317b0c2e..bd382bd84 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,14 +4,11 @@ language: cpp env: matrix: - - OS_TYPE=debian9 CMAKE_BUILD_TYPE=DEBUG SONAR_SCANNER=OFF COVERALLS=OFF - - OS_TYPE=debian9 CMAKE_BUILD_TYPE=RELEASE SONAR_SCANNER=OFF COVERALLS=OFF - - OS_TYPE=debian8 CMAKE_BUILD_TYPE=Debug SONAR_SCANNER=ON COVERALLS=ON - - OS_TYPE=debian8 CMAKE_BUILD_TYPE=RELEASE SONAR_SCANNER=OFF COVERALLS=OFF - - OS_TYPE=debian7 CMAKE_BUILD_TYPE=RELEASE SONAR_SCANNER=OFF COVERALLS=OFF -# - OS_TYPE=debian7 CMAKE_BUILD_TYPE=DEBUG -# - OS_TYPE=win32 -# etc + - OS_TYPE=debian10 CMAKE_BUILD_TYPE=Release SONAR_SCANNER=OFF COVERALLS=OFF STOCK_CPPZMQ=ON + - OS_TYPE=debian10 CMAKE_BUILD_TYPE=Debug SONAR_SCANNER=OFF COVERALLS=OFF STOCK_CPPZMQ=ON + - OS_TYPE=debian9 CMAKE_BUILD_TYPE=Debug SONAR_SCANNER=OFF COVERALLS=OFF STOCK_CPPZMQ=ON + - OS_TYPE=debian8 CMAKE_BUILD_TYPE=Debug SONAR_SCANNER=ON COVERALLS=ON STOCK_CPPZMQ=OFF + - OS_TYPE=debian7 CMAKE_BUILD_TYPE=Debug SONAR_SCANNER=OFF COVERALLS=OFF STOCK_CPPZMQ=ON notifications: email: false @@ -35,7 +32,7 @@ before_install: - docker pull tangocs/mysql:9.2.2 - docker pull tangocs/tango-cs:latest - git clone https://github.com/JoakimSoderberg/coveralls-cmake.git - - git clone -b v4.2.2 https://${CI_USER_TOKEN}@github.com/zeromq/cppzmq.git cppzmq + - (test ${STOCK_CPPZMQ} = "OFF" && git clone -b v4.2.2 https://${CI_USER_TOKEN}@github.com/zeromq/cppzmq.git cppzmq) || mkdir cppzmq - git clone -b tango-9-lts https://${CI_USER_TOKEN}@github.com/tango-controls/tango-idl.git idl - wget https://sonarcloud.io/static/cpp/build-wrapper-linux-x86.zip && unzip build-wrapper-linux-x86.zip @@ -47,12 +44,12 @@ before_script: - docker build --build-arg APP_UID=$(id -u) --build-arg APP_GID=$(id -g) -t cpp_tango .travis/${OS_TYPE} - docker run --name cpp_tango -e TANGO_HOST=${TANGO_HOST} -e BINTRAY_USER_NAME=tango-ci -e BINTRAY_API_KEY=${CI_BINTRAY_API_KEY} -e COVERALLS_REPO_TOKEN=${COVERALLS_REPO_TOKEN} --link tango_cs:tango_cs -v `pwd`:/home/tango/src -v `pwd`/idl:/home/tango/idl -v `pwd`/cppzmq:/home/tango/cppzmq -v `pwd`/coveralls-cmake:/home/tango/coveralls-cmake -v `pwd`/build-wrapper-linux-x86:/home/tango/build-wrapper-linux-x86 -dit cpp_tango - .travis/install_tango_idl.sh - - .travis/install_cppzmq.sh + - (test ${STOCK_CPPZMQ} = "OFF" && .travis/install_cppzmq.sh) || true #work around gcov ignored by sonar - sudo mkdir /home/tango && sudo mkdir /home/tango/src && sudo mount --bind `pwd` /home/tango/src script: - - .travis/${OS_TYPE}/run.sh + - .travis/run.sh - .travis/test.sh COVERALLS=OFF after_success: diff --git a/.travis/debian10/Dockerfile b/.travis/debian10/Dockerfile new file mode 100644 index 000000000..38a782d63 --- /dev/null +++ b/.travis/debian10/Dockerfile @@ -0,0 +1,27 @@ +FROM debian:buster + +ARG APP_UID=2000 + +ARG APP_GID=2000 + +MAINTAINER TANGO Controls team + +RUN apt-get update && apt-get install -y apt-utils + +RUN apt-get install -y build-essential cmake + +RUN apt-get install -y curl lsb-release + +RUN apt-get install -y omniidl libomniorb4-dev libcos4-dev libomnithread4-dev libzmq3-dev + +RUN apt-get install -y python2 + +RUN groupadd -g "$APP_GID" tango + +RUN useradd -u "$APP_UID" -g "$APP_GID" -ms /bin/bash tango + +ENV PKG_CONFIG_PATH=/home/tango/lib/pkgconfig + +USER tango + +WORKDIR /home/tango diff --git a/.travis/debian7/run.sh b/.travis/debian7/run.sh deleted file mode 100755 index b2c4754f2..000000000 --- a/.travis/debian7/run.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -docker exec cpp_tango mkdir -p /home/tango/src/build - -echo "Build cppTango:$CMAKE_BUILD_TYPE" -docker exec cpp_tango cmake -H/home/tango/src -B/home/tango/src/build -DCMAKE_VERBOSE_MAKEFILE=true -DCPPZMQ_BASE=/home/tango -DCMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -if [ $? -ne "0" ] -then - exit -1 -fi - -docker exec cpp_tango make -C /home/tango/src/build -j 2 \ No newline at end of file diff --git a/.travis/debian8/run.sh b/.travis/debian8/run.sh deleted file mode 100755 index 62e1240ce..000000000 --- a/.travis/debian8/run.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env bash -#this script is executed from within Travis environment. TANGO_HOST is already set -echo "TANGO_HOST=$TANGO_HOST" - -docker exec cpp_tango mkdir -p /home/tango/src/build - -echo "Run cmake cppTango in $CMAKE_BUILD_TYPE mode" -echo "Using COVERALLS=$COVERALLS" - -docker exec cpp_tango cmake -H/home/tango/src -B/home/tango/src/build -DCOVERALLS=$COVERALLS -DCOVERALLS_MODULE_PATH=/home/tango/coveralls-cmake/cmake -DCMAKE_VERBOSE_MAKEFILE=true -DCMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -if [ $? -ne "0" ] -then - exit -1 -fi - -docker exec cpp_tango /home/tango/build-wrapper-linux-x86/build-wrapper-linux-x86-64 --out-dir /home/tango/src/bw-output make -C /home/tango/src/build -j 2 \ No newline at end of file diff --git a/.travis/debian9/run.sh b/.travis/debian9/run.sh deleted file mode 100755 index 552a7c906..000000000 --- a/.travis/debian9/run.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash -docker exec cpp_tango mkdir -p /home/tango/src/build - -echo "Build cppTango:$CMAKE_BUILD_TYPE" -docker exec cpp_tango cmake -H/home/tango/src -B/home/tango/src/build -DCMAKE_VERBOSE_MAKEFILE=true -DCPPZMQ_BASE=/home/tango -DCMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -if [ $? -ne "0" ] -then - exit -1 -fi - -docker exec cpp_tango make -C /home/tango/src/build -j 2 \ No newline at end of file diff --git a/.travis/run.sh b/.travis/run.sh new file mode 100755 index 000000000..842c075bc --- /dev/null +++ b/.travis/run.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +set -e + +echo "############################" +echo "CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE" +echo "OS_TYPE=$OS_TYPE" +echo "TANGO_HOST=$TANGO_HOST" +echo "COVERALLS=$COVERALLS" +echo "############################" + +docker exec cpp_tango mkdir -p /home/tango/src/build + +# set defaults +MAKEFLAGS=${MAKEFLAGS:- -j 2} +COVERALLS=${COVERALLS:-OFF} +USE_PCH=${USE_PCH:-OFF} +COVERALLS_MODULE_PATH=/home/tango/coveralls-cmake/cmake + +docker exec cpp_tango cmake \ + -H/home/tango/src \ + -B/home/tango/src/build \ + -DCMAKE_VERBOSE_MAKEFILE=ON \ + -DCPPZMQ_BASE=/home/tango \ + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} \ + -DCOVERALLS=${COVERALLS} \ + -DCOVERALLS_MODULE_PATH=${COVERALLS_MODULE_PATH} + +if [[ "$COVERALLS" == "ON" ]] +then + docker exec cpp_tango \ + /home/tango/build-wrapper-linux-x86/build-wrapper-linux-x86-64 \ + --out-dir /home/tango/src/bw-output \ + make -C /home/tango/src/build +else + docker exec cpp_tango make -C /home/tango/src/build +fi diff --git a/INSTALL.md b/INSTALL.md index 72f7e92fa..9ee2c7f48 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -44,30 +44,9 @@ Typical output: -- Installing: /storage/Projects/org.tango/git/cppTango/build/install/include/idl/tango.h ``` -## Ubuntu 16.04 compilation problem +## Installing required cppzmq version on older systems -When compiling on Ubuntu 16.04 or on Debian stretch, the following error can occur: - -``` -[ 17%] Building CXX object cppapi/client/CMakeFiles/client_objects.dir/zmqeventconsumer.cpp.o -/home/ingvord/Projects/org.tango/git/cppTango/cppapi/client/zmqeventconsumer.cpp: In member function ‘virtual void* Tango::ZmqEventConsumer::run_undetached(void*)’: -/home/ingvord/Projects/org.tango/git/cppTango/cppapi/client/zmqeventconsumer.cpp:186:18: error: cannot convert ‘zmq::socket_t’ to ‘void*’ in assignment - items[0].socket = *control_sock; - ^ -/home/ingvord/Projects/org.tango/git/cppTango/cppapi/client/zmqeventconsumer.cpp:187:18: error: cannot convert ‘zmq::socket_t’ to ‘void*’ in assignment - items[1].socket = *heartbeat_sub_sock; - ^ -/home/ingvord/Projects/org.tango/git/cppTango/cppapi/client/zmqeventconsumer.cpp:188:18: error: cannot convert ‘zmq::socket_t’ to ‘void*’ in assignment - items[2].socket = *event_sub_sock; - ^ -/home/ingvord/Projects/org.tango/git/cppTango/cppapi/client/zmqeventconsumer.cpp: In member function ‘bool Tango::ZmqEventConsumer::process_ctrl(zmq::message_t&, zmq::pollitem_t*, int&)’: -/home/ingvord/Projects/org.tango/git/cppTango/cppapi/client/zmqeventconsumer.cpp:1063:47: error: cannot convert ‘zmq::socket_t’ to ‘void*’ in assignment - poll_list[old_poll_nb].socket = *tmp_sock; -``` - -This is due to incompatibility of zmq.hpp file provided in libzmq3-dev:4.1.7 -(ubuntu 16.04), i.e. it is not possible to compile cppTango using zmq.hpp file -provided by libzmq3-dev:4.1.7 (ubuntu 16.04). +On some debian versions, 7 (wheezy) and older, there is no compatible cppzmq version available. This requires installing [cppzmq](https://github.com/zeromq/cppzmq) via: @@ -80,6 +59,16 @@ cmake -DENABLE_DRAFTS=OFF -DCPPZMQ_BUILD_TESTS=OFF .. sudo make install ``` +And then pass `-DCPPZMQ_BASE=/usr/local` to cmake or use + +``` +mkdir build +cd build +configure CXXFLAGS="-I /usr/local/include" .. +``` + +when compiling via the tango source distribution. + # Using pkg-config Once installed cppTango provides [pkg-config](https://en.wikipedia.org/wiki/Pkg-config) file `tango.pc` diff --git a/configure/CMakeLists.txt b/configure/CMakeLists.txt index d926c65db..22ed7bb5f 100644 --- a/configure/CMakeLists.txt +++ b/configure/CMakeLists.txt @@ -151,6 +151,18 @@ Please install cppzmq (https://github.com/zeromq/cppzmq) on your system and/or u /include and system include directories).") endif() +if(NOT WIN32) + try_compile(TANGO_ZMQ_HAS_DISCONNECT ${CMAKE_BINARY_DIR}/test_cppzmq_disconnect + SOURCES ${CMAKE_SOURCE_DIR}/configure/test_cppzmq_disconnect.cpp + COMPILE_DEFINITIONS "-I ${CPPZMQ_BASE}/include -I ${ZMQ_BASE}/include" + LINK_LIBRARIES "${ZMQ_PKG_LIBRARIES}") + + message(STATUS "Check if zmq::socket has a disconnect method: ${TANGO_ZMQ_HAS_DISCONNECT}") +else() + set(TANGO_ZMQ_HAS_DISCONNECT TRUE) + message(STATUS "Check if zmq::socket has a disconnect method: ${TANGO_ZMQ_HAS_DISCONNECT} (hardcoded)") +endif(NOT WIN32) + message("Verifying ${OMNIIDL_PATH}omniidl") if(WIN32) execute_process(COMMAND ${OMNIIDL_PATH}omniidl.exe -V RESULT_VARIABLE FAILED) diff --git a/configure/test_cppzmq_disconnect.cpp b/configure/test_cppzmq_disconnect.cpp new file mode 100644 index 000000000..707fcc261 --- /dev/null +++ b/configure/test_cppzmq_disconnect.cpp @@ -0,0 +1,8 @@ +#include + +int main(int, char**) +{ + zmq::context_t c; + zmq::socket_t s(c, ZMQ_REQ); + s.disconnect("some endpoint"); +} diff --git a/cpp_test_suite/cxxtest/CMakeLists.txt b/cpp_test_suite/cxxtest/CMakeLists.txt index 1d9a1b93e..a06a2c5ad 100644 --- a/cpp_test_suite/cxxtest/CMakeLists.txt +++ b/cpp_test_suite/cxxtest/CMakeLists.txt @@ -1,16 +1,22 @@ find_package (Threads REQUIRED) find_program(PYTHON_INTERPRETER NAMES python2 python) +if(NOT PYTHON_INTERPRETER) + message(SEND_ERROR "Could not find python 2.") +endif() + macro(CXX_GENERATE_TEST name) message("Generate ${name}.cpp") + set(GENERATED_FILE "${CMAKE_CURRENT_SOURCE_DIR}/${name}.cpp") execute_process(COMMAND "${PYTHON_INTERPRETER}" cxxtestgen.py --template=${CMAKE_CURRENT_SOURCE_DIR}/template/tango_template.tpl - -o ${CMAKE_CURRENT_SOURCE_DIR}/${name}.cpp + -o ${GENERATED_FILE} ../../new_tests/${name}.cpp - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin) + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin + RESULT_VARIABLE GENERATOR_OUTPUT) - if(${FAILED}) - message(SEND_ERROR " Failed to generate ${name}.cpp. rv=${FAILED}") + if(NOT EXISTS ${GENERATED_FILE}) + message(SEND_ERROR " Failed to generate ${name}.cpp due to \"${GENERATOR_OUTPUT}\".") endif() add_executable(${name} $ ${name}.cpp) diff --git a/cpp_test_suite/environment/CMakeLists.txt b/cpp_test_suite/environment/CMakeLists.txt index 4ccab1f55..f22e4b28b 100644 --- a/cpp_test_suite/environment/CMakeLists.txt +++ b/cpp_test_suite/environment/CMakeLists.txt @@ -1,5 +1,5 @@ #TODO windows -configure_file(tango_host.cmake ${PROJECT_BINARY_DIR}/tango_host @ONLY) +configure_file(tango_host.cmake tango_host @ONLY) configure_file(pre_test.sh.cmake pre_test.sh @ONLY) execute_process(COMMAND chmod +x ${CMAKE_CURRENT_BINARY_DIR}/pre_test.sh) @@ -20,4 +20,4 @@ add_custom_target(run-tests ${CMAKE_CURRENT_BINARY_DIR}/run.sh execute_process(COMMAND chmod +x ${CMAKE_CURRENT_SOURCE_DIR}/shutdown.sh) add_custom_target(stop-tango ${CMAKE_CURRENT_SOURCE_DIR}/shutdown.sh WORKING_DIRECTORY ${PROJECT_BINARY_DIR} - SOURCES shutdown.sh) \ No newline at end of file + SOURCES shutdown.sh) diff --git a/cpp_test_suite/environment/post_test.sh.cmake b/cpp_test_suite/environment/post_test.sh.cmake index 16f419921..34d4c1ce4 100644 --- a/cpp_test_suite/environment/post_test.sh.cmake +++ b/cpp_test_suite/environment/post_test.sh.cmake @@ -6,4 +6,6 @@ PID=$(<@PROJECT_BINARY_DIR@/cpp_test_ds/DevTest_@INST_NAME@.pid) kill $PID PID=$(<@PROJECT_BINARY_DIR@/cpp_test_ds/fwd_ds/FwdTest_@INST_NAME@.pid) -kill $PID \ No newline at end of file +kill $PID + +exit 0 diff --git a/cpp_test_suite/environment/pre_test.sh.cmake b/cpp_test_suite/environment/pre_test.sh.cmake index 5dae38aff..59b6a22db 100644 --- a/cpp_test_suite/environment/pre_test.sh.cmake +++ b/cpp_test_suite/environment/pre_test.sh.cmake @@ -21,4 +21,4 @@ echo "`ldd @PROJECT_BINARY_DIR@/cpp_test_ds/fwd_ds/FwdTest`" @PROJECT_BINARY_DIR@/cpp_test_ds/fwd_ds/FwdTest @INST_NAME@ -v5 1>@PROJECT_BINARY_DIR@/cpp_test_ds/fwd_ds/FwdTest_@INST_NAME@.out 2>&1 & echo $! > @PROJECT_BINARY_DIR@/cpp_test_ds/fwd_ds/FwdTest_@INST_NAME@.pid -sleep 3 \ No newline at end of file +sleep 3 diff --git a/cppapi/client/eventconsumer.h b/cppapi/client/eventconsumer.h index e8923dec8..856c16b5b 100644 --- a/cppapi/client/eventconsumer.h +++ b/cppapi/client/eventconsumer.h @@ -45,13 +45,6 @@ #include -#ifdef ZMQ_VERSION - #if ZMQ_VERSION > 30201 - #define ZMQ_HAS_DISCONNECT - #endif -#endif - - namespace Tango { diff --git a/cppapi/client/eventkeepalive.cpp b/cppapi/client/eventkeepalive.cpp index 88b468e1b..89b547efb 100644 --- a/cppapi/client/eventkeepalive.cpp +++ b/cppapi/client/eventkeepalive.cpp @@ -188,7 +188,7 @@ bool EventConsumerKeepAliveThread::reconnect_to_zmq_channel(EvChanIte &ipos,Even string adm_name = ipos->second.full_adm_name; -#ifdef ZMQ_HAS_DISCONNECT +#ifdef TANGO_ZMQ_HAS_DISCONNECT // // Forget exception which could happen during massive restart of device server process running on the same host // @@ -406,7 +406,7 @@ void EventConsumerKeepAliveThread::re_subscribe_event(EvCbIte &epos,EvChanIte &i void EventConsumerKeepAliveThread::reconnect_to_zmq_event(EvChanIte &ipos,EventConsumer *event_consumer,DeviceData &dd) { EvCbIte epos; -#ifdef ZMQ_HAS_DISCONNECT +#ifdef TANGO_ZMQ_HAS_DISCONNECT bool disconnect_called = false; #endif @@ -448,7 +448,7 @@ void EventConsumerKeepAliveThread::reconnect_to_zmq_event(EvChanIte &ipos,EventC string prefix = fqen.substr(0,pos + 1); d_name.insert(0,prefix); -#ifdef ZMQ_HAS_DISCONNECT +#ifdef TANGO_ZMQ_HAS_DISCONNECT if (disconnect_called == false) { event_consumer->disconnect_event(epos->second.fully_qualified_event_name,epos->second.endpoint); diff --git a/cppapi/client/zmqeventconsumer.cpp b/cppapi/client/zmqeventconsumer.cpp index 5dcd158e9..36d5b9a86 100644 --- a/cppapi/client/zmqeventconsumer.cpp +++ b/cppapi/client/zmqeventconsumer.cpp @@ -800,7 +800,7 @@ bool ZmqEventConsumer::process_ctrl(zmq::message_t &received_ctrl,zmq::pollitem_ // const char *event_name = &(tmp_ptr[1]); -#ifdef ZMQ_HAS_DISCONNECT +#ifdef TANGO_ZMQ_HAS_DISCONNECT const char *endpoint = &(tmp_ptr[1 + ::strlen(event_name) + 1]); const char *endpoint_event = &(tmp_ptr[1 + ::strlen(event_name) + ::strlen(endpoint) + 2]); #endif @@ -822,7 +822,7 @@ bool ZmqEventConsumer::process_ctrl(zmq::message_t &received_ctrl,zmq::pollitem_ multi_tango_host(heartbeat_sub_sock,UNSUBSCRIBE,base_name); } -#ifdef ZMQ_HAS_DISCONNECT +#ifdef TANGO_ZMQ_HAS_DISCONNECT // // Remove the endpoint in the vector of already connected heartbeat and disconnect the socket to this endpoint // @@ -1349,7 +1349,7 @@ void ZmqEventConsumer::connect_event_channel(string &channel_name,TANGO_UNUSED(D buffer[length] = ZMQ_CONNECT_HEARTBEAT; length++; -#ifdef ZMQ_HAS_DISCONNECT +#ifdef TANGO_ZMQ_HAS_DISCONNECT buffer[length] = 0; #else if (reconnect == true) @@ -1721,7 +1721,7 @@ void ZmqEventConsumer::connect_event_system(TANGO_UNUSED(string &device_name),TA buffer[length] = ZMQ_CONNECT_EVENT; length++; -#ifdef ZMQ_HAS_DISCONNECT +#ifdef TANGO_ZMQ_HAS_DISCONNECT buffer[length] = 0; #else if (filters.size() == 1 && filters[0] == "reconnect") @@ -3546,7 +3546,7 @@ ReceivedFromAdmin ZmqEventConsumer::initialize_received_from_admin(const Tango:: return result; } -#ifdef ZMQ_HAS_DISCONNECT +#ifdef TANGO_ZMQ_HAS_DISCONNECT void ZmqEventConsumer::disconnect_socket(zmq::socket_t& socket, const char* endpoint) { try diff --git a/cppapi/server/tango_const.h.in b/cppapi/server/tango_const.h.in index 9edb756f2..6f3473576 100644 --- a/cppapi/server/tango_const.h.in +++ b/cppapi/server/tango_const.h.in @@ -146,6 +146,8 @@ const int PUB_HWM = 1000; const int SUB_HWM = 1000; const int SUB_SEND_HWM = 10000; +#cmakedefine TANGO_ZMQ_HAS_DISCONNECT + // // Event when using a file as database stuff //