How do I get my bare bones ROOT TApplication to link with CMake?

After installing ROOT with:

wget https://root.cern/download/root_v6.28.04.Linux-ubuntu22-x86_64-gcc11.3.tar.gz
tar -xzvf root_v6.28.04.Linux-ubuntu22-x86_64-gcc11.3.tar.gz
source root/bin/thisroot.sh

I have the following minimal ROOT6 TApplication-based project

CMakeLists.txt

cmake_minimum_required(VERSION 3.9)
project (TestRoot CXX)
find_package(ROOT REQUIRED COMPONENTS RIO Core Gpad)
set(SOURCES main.cpp MainFrame.hpp)
add_executable(TestRoot ${SOURCES})
target_link_libraries(TestRoot ROOT::RIO ROOT::Core ROOT::Gpad)
target_include_directories(TestRoot PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
ROOT_GENERATE_DICTIONARY(MainFrame_dict MainFrame.hpp MODULE TestRoot LINKDEF LinkDef.h)

main.cpp

#include "TF1.h"
#include "TApplication.h"
#include "TCanvas.h"
#include "TRootCanvas.h"

int main(int argc, char **argv) {
  TApplication app("app", &argc, argv);
  TCanvas* c = new TCanvas("c", "Something", 0, 0, 800, 600);
  TF1 *f1 = new TF1("f1","sin(x)", -5, 5);
  f1->SetLineColor(kBlue+1);
  f1->SetTitle("My graph;x; sin(x)");
  f1->Draw();
  c->Modified(); c->Update();
  TRootCanvas *rc = (TRootCanvas *)c->GetCanvasImp();
  rc->Connect("CloseWindow()", "TApplication", gApplication, "Terminate()");
  app.Run();
  return 0;
}

MainFrame.hpp

#include <TGFrame.h>
/*
class MainFrame : public TGMainFrame {
  public:
    using TGMainFrame::TGMainFrame;
    virtual ~MainFrame() = default;
    ClassDef(MainFrame, 1);
};
*/

LinkDef.h

#ifdef __CLING__
#pragma link C++ class MainFrame;
#endif // __CLING__

This runs and pops up a sine graph but if I try uncommenting the MainFrame class in the MainFrame.hpp file, I get a linker error which begins with:

[build] /usr/bin/ld: CMakeFiles/MainFrame_dict.dir/MainFrame_dict.cxx.o: in function `MainFrame::Streamer(TBuffer&)':
[build] /home/***/Documents/TestRoot/build/MainFrame_dict.cxx:122: undefined reference to `TGMainFrame::Streamer(TBuffer&)'
[build] /usr/bin/ld: /home/***/Documents/TestRoot/build/MainFrame_dict.cxx:126: undefined reference to `TGMainFrame::Streamer(TBuffer&)'
[build] /usr/bin/ld: CMakeFiles/MainFrame_dict.dir/MainFrame_dict.cxx.o: in function `TGWindow::HandleExpose(Event_t*)':
[build] /home/***/root/include/TGWindow.h:102: undefined reference to `TGClient::NeedRedraw(TGWindow*, bool)'
[build] /usr/bin/ld: CMakeFiles/MainFrame_dict.dir/MainFrame_dict.cxx.o: in function `TGFrame::ReparentWindow(TGWindow const*, int, int)':

What is going wrong here? Alternatively can anyone point me to an example ROOT6 CMake project that I can use as a starting point for a single page application (button + text fields + canvas) on Linux?


ROOT Version: 6.28.04
Platform: Ubuntu 22
Compiler: g++


Use ClassDef(MainFrame, 0); and add the Gui libraries (find_package(ROOT REQUIRED COMPONENTS RIO Core Gpad Gui) and target_link_libraries(TestRoot ROOT::RIO ROOT::Core ROOT::Gpad ROOT::Gui))

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.