CMake + Signals/Slots


Hello everybody

I’m trying compile a standalone application to show x,y cursor coordinates using signal/slot. I have seen several examples but no complete. This example runs on interactive ROOT but don’t work in standalone flawor.

Error in <TQObject::CheckConnectArgs>: slot printEvent(int,int,int,TObject*) does not exist

I don’t know what is the lack.

signalslot.zip (2.3 KB) (Sorry. I am newbie and I can’t uplink files)

CMakeLists.txt

cmake_minimum_required(VERSION 3.10)

set(TARGET_NAME signalslot)
set(TARGET_VERSION 0.0.0)

if(ROOT_DIR)
    message("ROOT_DIR OK ${ROOT_DIR}")
else()
    message(FATAL_ERROR "ROOT_DIR undefined")
endif(ROOT_DIR)

find_package(ROOT 6.36 CONFIG REQUIRED)

project(${TARGET_NAME}
        VERSION ${TARGET_VERSION}
		LANGUAGES CXX)

set(CMAKE_CXX_STANDARD ${ROOT_CXX_STANDARD})
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_VERBOSE_MAKEFILE ON)


add_executable (${TARGET_NAME}
    printEvent.h
    main.cpp
)

target_include_directories (${TARGET_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

target_link_libraries (${TARGET_NAME} PUBLIC
    ROOT::Core
    ROOT::Gpad
    ROOT::Graf
    ROOT::Hist
    ROOT::Imt
    ROOT::MathCore
    ROOT::Thread
    ROOT::Tree
 )

root_generate_dictionary(printEventLib printEvent.h MODULE ${TARGET_NAME}  LINKDEF printEventLinkDef.h)

main.cpp

#include <TROOT.h>
#include <TH1.h>
#include <TCanvas.h>
#include <TApplication.h>
#include <TRootCanvas.h>


#include "printEvent.h"

//___________________________________________________________________
int main(int argc, char *argv[])
{
// Temporary work around the lack of automatic refresh of the list
// when a script is reloaded.
// From exec3() tutorial
//    gROOT->GetListOfGlobalFunctions()->Delete();

    TApplication app("App", &argc, argv);

    TH1F *h = new TH1F("h","h",100,-3,3);
    h->FillRandom("gaus",1000);
    TCanvas *c1=new TCanvas("c1");
    h->Draw();
    c1->Update();

    c1->Connect("ProcessedEvent(Int_t,Int_t,Int_t,TObject*)",
                nullptr,
                nullptr,
                "printEvent(Int_t,Int_t,Int_t,TObject*)");


    TRootCanvas *rc = (TRootCanvas *)c1->GetCanvasImp();
    rc->Connect("CloseWindow()", "TApplication", gApplication, "Terminate()");


    app.Run();

    return 0;

}

printEvent.h

#ifndef PRINTEVENT_H
#define PRINTEVENT_H
void printEvent(Int_t event, Int_t px, Int_t py, TObject *selected);
#endif // PRINTEVENT_H

printeEvent.cpp

#include <TROOT.h>
#include <TCanvas.h>

void printEvent(Int_t event, Int_t px, Int_t py, TObject *selected)
{
    TCanvas *c = (TCanvas *) gTQSender;
    printf("Canvas %s: event=%d, x=%d, y=%d, selected=%s\n", c->GetName(),
           event, px, py, selected->IsA()->GetName());
}

printEventLinkDef.h

#ifndef PRINTEVENTLINKDEF_H
#define PRINTEVENTLINKDEF_H

#ifdef __CLING__
#pragma link C++ function printEvent(Int_t event, Int_t px, Int_t py, TObject *selected);
#endif

#endif // PRINTEVENTLINKDEF_H

This is a terminal session that first run the program on ROOT interactive console perfectly and after compile and execute standalone application unsuccessfully.

yo@myPC:~/cern$ . root/bin/thisroot.sh

yo@myPC:~/cern$cmake --version
cmake version 3.28.3

CMake suite maintained and supported by Kitware (kitware.com/cmake).

yo@myPC:~/cern$ g++ --version
g++ (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0
Copyright (C) 2023 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

yo@myPC:~/cern$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 24.04.3 LTS
Release:        24.04
Codename:       noble


yo@myPC:~/cern$ cd signalslot/
yo@myPC:~/cern/signalslot$ root
   ------------------------------------------------------------------
  | Welcome to ROOT 6.36.000                       https://root.cern |
  | (c) 1995-2025, The ROOT Team; conception: R. Brun, F. Rademakers |
  | Built for linuxx8664gcc on May 25 2025, 16:47:38                 |
  | From tags/v6-36-00@v6-36-00                                      |
  | With c++ (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0                   |
  | Try '.help'/'.?', '.demo', '.license', '.credits', '.quit'/'.q'  |
   ------------------------------------------------------------------

root [0] .L printEvent.cpp
root [1] .L main.cpp
root [2] main(0,nullptr)
Error in <TApplication::TApplication>: only one instance of TApplication allowed
Canvas c1: event=52, x=662, y=350, selected=TCanvas
Canvas c1: event=51, x=662, y=350, selected=TCanvas
Canvas c1: event=53, x=620, y=343, selected=TCanvas
Canvas c1: event=52, x=620, y=343, selected=TFrame
Canvas c1: event=51, x=620, y=343, selected=TFrame
Canvas c1: event=51, x=583, y=337, selected=TFrame
Canvas c1: event=51, x=557, y=333, selected=TFrame
Canvas c1: event=51, x=549, y=332, selected=TFrame
Canvas c1: event=51, x=546, y=332, selected=TFrame
Canvas c1: event=51, x=547, y=332, selected=TFrame
Canvas c1: event=51, x=549, y=332, selected=TFrame
Canvas c1: event=51, x=555, y=332, selected=TFrame
Canvas c1: event=51, x=559, y=332, selected=TFrame
Canvas c1: event=51, x=570, y=332, selected=TFrame

yo@myPC:~/cern/signalslot$ mkdir build
yo@myPC:~/cern/signalslot$ cd build

yo@myPC:~/cern/signalslot/build$ cmake .. -DROOT_DIR=/home/yo/cern/root/cmake -DVDT_INCLUDE_DIR=/usr/include -DVDT_LIBRARY=/usr/lib/x86_64-linux-gnu/libvdt.so

ROOT_DIR OK /home/yo/cern/root/cmake
CMake Warning (dev) at /home/yo/cern/root/cmake/ROOTConfig-targets.cmake:57 (add_library):
  ADD_LIBRARY called with SHARED option but the target platform does not
  support dynamic linking.  Building a STATIC library instead.  This may lead
  to problems.
Call Stack (most recent call first):
  /home/yo/cern/root/cmake/ROOTConfig.cmake:113 (include)
  CMakeLists.txt:12 (find_package)
This warning is for project developers.  Use -Wno-dev to suppress it.

CMake Warning (dev) at /home/yo/cern/root/cmake/ROOTConfig-targets.cmake:65 (add_library):
  ADD_LIBRARY called with SHARED option but the target platform does not
  support dynamic linking.  Building a STATIC library instead.  This may lead
  to problems.
Call Stack (most recent call first):
  /home/yo/cern/root/cmake/ROOTConfig.cmake:113 (include)
  CMakeLists.txt:12 (find_package)
This warning is for project developers.  Use -Wno-dev to suppress it.


... A Lot of Warnings more ...


-- Found Vdt: /usr/include (found version "0.4")
-- The CXX compiler identification is GNU 13.3.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/lib/ccache/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (0.2s)
-- Generating done (0.0s)
-- Build files have been written to: /home/yo/cern/signalslot/build

yo@myPC:~/cern/signalslot/build$ make
/usr/bin/cmake -S/home/yo/cern/signalslot -B/home/yo/cern/signalslot/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /home/yo/cern/signalslot/build/CMakeFiles /home/yo/cern/signalslot/build//CMakeFiles/progress.marks
make  -f CMakeFiles/Makefile2 all
make[1]: Entering directory '/home/yo/cern/signalslot/build'
make  -f CMakeFiles/printEventLib.dir/build.make CMakeFiles/printEventLib.dir/depend
make[2]: Entering directory '/home/yo/cern/signalslot/build'
[ 25%] Generating printEventLib.cxx, signalslot_rdict.pcm, signalslot.rootmap
/usr/bin/cmake -E env LD_LIBRARY_PATH=/home/yo/cern/root/lib:/home/yo/cern/root/lib /home/yo/cern/root/bin/rootcling -v2 -f printEventLib.cxx -s /home/yo/cern/signalslot/build/signalslot -rml signalslot -rmf /home/yo/cern/signalslot/build/signalslot.rootmap -DROOT_SUPPORT_CLAD -compilerI/usr/include/c++/13 -compilerI/usr/include/x86_64-linux-gnu/c++/13 -compilerI/usr/include/c++/13/backward -compilerI/usr/lib/gcc/x86_64-linux-gnu/13/include -compilerI/usr/local/include -compilerI/usr/include/x86_64-linux-gnu -compilerI/usr/include -I/home/yo/cern/signalslot -I/home/yo/cern/signalslot -I/home/yo/cern/root/include printEvent.h /home/yo/cern/signalslot/printEventLinkDef.h
cd /home/yo/cern/signalslot/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/yo/cern/signalslot /home/yo/cern/signalslot /home/yo/cern/signalslot/build /home/yo/cern/signalslot/build /home/yo/cern/signalslot/build/CMakeFiles/printEventLib.dir/DependInfo.cmake "--color="
make[2]: Leaving directory '/home/yo/cern/signalslot/build'
make  -f CMakeFiles/printEventLib.dir/build.make CMakeFiles/printEventLib.dir/build
make[2]: Entering directory '/home/yo/cern/signalslot/build'
[ 50%] Building CXX object CMakeFiles/printEventLib.dir/printEventLib.cxx.o
/usr/lib/ccache/c++ -DROOT_SUPPORT_CLAD -I/home/yo/cern/signalslot -I/home/yo/cern/root/include -std=gnu++17 -fPIC -MD -MT CMakeFiles/printEventLib.dir/printEventLib.cxx.o -MF CMakeFiles/printEventLib.dir/printEventLib.cxx.o.d -o CMakeFiles/printEventLib.dir/printEventLib.cxx.o -c /home/yo/cern/signalslot/build/printEventLib.cxx
make[2]: Leaving directory '/home/yo/cern/signalslot/build'
[ 50%] Built target printEventLib
make  -f CMakeFiles/signalslot.dir/build.make CMakeFiles/signalslot.dir/depend
make[2]: Entering directory '/home/yo/cern/signalslot/build'
cd /home/yo/cern/signalslot/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/yo/cern/signalslot /home/yo/cern/signalslot /home/yo/cern/signalslot/build /home/yo/cern/signalslot/build /home/yo/cern/signalslot/build/CMakeFiles/signalslot.dir/DependInfo.cmake "--color="
make[2]: Leaving directory '/home/yo/cern/signalslot/build'
make  -f CMakeFiles/signalslot.dir/build.make CMakeFiles/signalslot.dir/build
make[2]: Entering directory '/home/yo/cern/signalslot/build'
[ 75%] Building CXX object CMakeFiles/signalslot.dir/main.cpp.o
/usr/lib/ccache/c++ -DROOT_SUPPORT_CLAD -I/home/yo/cern/signalslot -isystem /home/yo/cern/root/include -std=gnu++17 -MD -MT CMakeFiles/signalslot.dir/main.cpp.o -MF CMakeFiles/signalslot.dir/main.cpp.o.d -o CMakeFiles/signalslot.dir/main.cpp.o -c /home/yo/cern/signalslot/main.cpp
[100%] Linking CXX executable signalslot
/usr/bin/cmake -E cmake_link_script CMakeFiles/signalslot.dir/link.txt --verbose=1
/usr/lib/ccache/c++ CMakeFiles/signalslot.dir/main.cpp.o CMakeFiles/printEventLib.dir/printEventLib.cxx.o -o signalslot  /home/yo/cern/root/lib/libCore.so /home/yo/cern/root/lib/libGpad.so /home/yo/cern/root/lib/libGraf.so /home/yo/cern/root/lib/libHist.so /home/yo/cern/root/lib/libImt.so /home/yo/cern/root/lib/libMathCore.so /home/yo/cern/root/lib/libThread.so /home/yo/cern/root/lib/libTree.so /home/yo/cern/root/lib/libMatrix.so /home/yo/cern/root/lib/libMathCore.so /home/yo/cern/root/lib/libImt.so /home/yo/cern/root/lib/libMultiProc.so /home/yo/cern/root/lib/libNet.so /home/yo/cern/root/lib/libRIO.so /home/yo/cern/root/lib/libThread.so /home/yo/cern/root/lib/libCore.so
make[2]: Leaving directory '/home/yo/cern/signalslot/build'
[100%] Built target signalslot
make[1]: Leaving directory '/home/yo/cern/signalslot/build'
/usr/bin/cmake -E cmake_progress_start /home/yo/cern/signalslot/build/CMakeFiles 0

yo@myPC:~/cern/signalslot/build$ ls
CMakeCache.txt  CMakeFiles  cmake_install.cmake  Makefile  module.modulemap  printEventLib.cxx  signalslot  signalslot_rdict.pcm  signalslot.rootmap

yo@myPC:~/cern/signalslot/build$ ./signalslot
Error in <TQObject::CheckConnectArgs>: slot printEvent(int,int,int,TObject*) does not exist


Thanks in advance


Maybe this example helps with CMake and signal+slots helps: TRentrantRWlock thread lock, program freezes - #12 by ferhue

You could try to spot the differences.
(The suppressWarnings workarounds are not necessary)