ROOT Version: 6.14.00
Platform: MacOS High Sierra
Compiler: Eclipse Photon
Hello!
I’m attempting to compile and run within Eclipse Photon the classic ROOT GUI example detailed here: https://root.cern.ch/root/htmldoc/guides/users-guide/WritingGUI.html#a-simple-example
Specifically, I’ve been following the instructions under section 27.4.1 in the above link to put together the standalone version of the program. My code consists of what’s been used in example 2b (pasted below).
When running the program within Eclipse, the GUI pops up on screen and the Exit button works; however I have the fairly common problem of receiving the error:
Error in <TQObject::CheckConnectArgs>: slot DoDraw() does not exist
From my research online, my understanding is that this error is due to some dictionary generation for the class MyMainFrame
, which is what ex2bLinkDef.h
and following compiler lines are meant to take care of:
rootcling -f ex2bDict.cxx -c example2b.h ex2bLinkDef.h g++ -o example2b example2b.cxx ex2bDict.cxx `root-config --cflags --glibs
My issue is that I can’t seem to find a way to tell Eclipse to do the pre-build steps to perform the necessary dictionary generation. I appreciate that using Eclipse to build pre-compiled ROOT code is somewhat unconventional, hence I’ve been unable to solve the issue with the support that’s already online.
The same issue also occurs when using the version example 2a as described in the above link.
I should add that ROOT otherwise works exactly as expected within Eclipse, after adding the appropriate Compiler and Linker settings in my Eclipse project to let Eclipse know where ROOT stores its libraries etc.
I’m still somewhat new to C/C++ and ROOT, so my apologies if I’ve misused some terminology.
Appreciate any help that can be given!
My code:
example 2b.h
#include <TGFrame.h>
#include <TRootEmbeddedCanvas.h>
#ifndef GUI_H_
#define GUI_H_
class MyMainFrame : public TGMainFrame {
private:
TRootEmbeddedCanvas *fEcanvas;
public:
MyMainFrame(const TGWindow *p,UInt_t w,UInt_t h);
virtual ~MyMainFrame();
void DoDraw();
};
void example();
#endif /* GUI_H_ */
example 2b.cpp
#include <TApplication.h>
#include <TGClient.h>
#include <TCanvas.h>
#include <TF1.h>
#include <TRandom.h>
#include <TGButton.h>
#include <TRootEmbeddedCanvas.h>
#include "example2b.h"
MyMainFrame::MyMainFrame(const TGWindow *p,UInt_t w,UInt_t h) : TGMainFrame(p,w,h) {
// Creates widgets of the example
fEcanvas = new TRootEmbeddedCanvas ("Ecanvas",this,200,200);
AddFrame(fEcanvas, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 10,10,10,1));
TGHorizontalFrame *hframe=new TGHorizontalFrame(this, 200,40);
TGTextButton *draw = new TGTextButton(hframe,"&Draw");
draw->Connect("Clicked()","MyMainFrame",this,"DoDraw()");
hframe->AddFrame(draw, new TGLayoutHints(kLHintsCenterX, 5,5,3,4));
TGTextButton *exit = new TGTextButton(hframe,"&Exit ", "gApplication->Terminate()");
hframe->AddFrame(exit, new TGLayoutHints(kLHintsCenterX, 5,5,3,4));
AddFrame(hframe,new TGLayoutHints(kLHintsCenterX,2,2,2,2));
// Sets window name and shows the main frame
SetWindowName("Simple Example");
MapSubwindows();
Resize(GetDefaultSize());
MapWindow();
}
MyMainFrame::~MyMainFrame() {
// Clean up used widgets: frames, buttons, layout hints
// fMain->Cleanup();
// delete fMain;
}
void MyMainFrame::DoDraw() {
// Draws function graphics in randomly chosen interval
TF1 *f1 = new TF1("f1","sin(x)/x",0,gRandom->Rndm()*10);
f1->SetLineWidth(3);
f1->Draw();
TCanvas *fCanvas = fEcanvas->GetCanvas();
fCanvas->cd();
fCanvas->Update();
}
void example() {
// Popup the GUI...
new MyMainFrame(gClient->GetRoot(),200,200);
}
int main(int argc, char **argv) {
TApplication theApp("App",&argc,argv);
example();
theApp.Run();
return 0;
}
ex2bLinkDef.h
#pragma link C++ class MyMainFrame;
I have also put together some instructions (intended for new users) to set up ROOT for use in Eclipse, which may also be useful for reproducing the problem:
-
Verify that you have a correct installation of ROOT on your computer.
-
In a terminal window, type in the commands
root-config --cflags
and alsoroot-config --glibs
. We will be using the output of these commands to get Eclipse to know where ROOT’s libraries are. -
Create a new C/C++ project in Eclipse and open the project preferences. Go to C/C++ Build -> Settings.
-
Under the C++ linker settings, in the libraries window, add in the -l flags listed in the terminal output of the
--glibs
command. Add them one-by-one and in order, without the -l prefix. e.g. Gui, Core, Imt, etc. (Careful with casing!) -
In the library search path, add in the path shown in the terminal output of the
--glibs
command, without the -L prefix. e.g./Applications/root_v6.14.00/lib
-
Under the miscellaneous options for the linker, add into the linker flags the flags output from the
--cflags
command. e.g.-pthread -stdlib=libc++ -std=c++11 -m64
-
Under the C++ compiler settings, in the Includes settings, add the subsequent path output from the
--cflags
command into the Includes path. e.g./Applications/root_v6.14.00/include
-
Under optimisation for the compiler settings, add in the linker flags mentioned in step 6 into the optimisation flags box. Also change the optimisation level to “Optimise most”.
-
If you have library search path errors, you may also need to set the environment variables in C/C++ Build settings -> Environment.
-
Add in the variable:
LD_LIBRARY_PATH
with the value of the library path for ROOT, e.g./Applications/root_v6.14.00/lib
-
Add in the variable:
ROOTSYS
with the value of the location of the ROOT folder, e.g./Applications/root_v6.14.00
-
ROOT should now work within Eclipse, allowing you to write pre-compiled code with all of Eclipse’s features.