Makefile doesn't work

Hi!

I’m trying to compile a C++ program written for ROOT with a Makefile I created.
I’ve installed the last version of ROOT on Ubuntu 17.04. The root files are in the Download/root-6.08.06 directory.

These are the Makefile commands:

ROOTCFLAGS:= root-config --cflags
ROOTLFLAGS:= root-config --glibs
root: root.o
**(LINK.cc) **(ROOTCFLAGS) **(ROOTLFLAGS) **(@F).o -o **(@F) root.o: root.cpp **(LINK.cc) ***(ROOTCFLAGS) -c * *.cpp -o $(@F)
clean:
rm *.o

Before executing “make root” I go to the root directory and type . bin/thisroot.sh, which should set all the necessary ambient variables to root directories.

If I try in the bash root-config --cflags and root-config --glibs I get the right paths to the /include and /lib directories.

However this is what I get:

make root
g++ -std=c++11 root-config --cflags -c root.cpp -o root.o
g++ -std=c++11 root-config --cflags root-config --glibs root.o -o root
root.o: In function graph_thread(void*)': root.cpp:(.text+0x5ab): undefined reference to TThread::Lock()’
root.cpp:(.text+0x5d4): undefined reference to TGraph::TGraph(int, double const*, double const*)' root.cpp:(.text+0x5e3): undefined reference to TGraph::SetTitle(char const*)’
root.cpp:(.text+0x604): undefined reference to TGraph::TGraph(int, double const*, double const*)' root.cpp:(.text+0x613): undefined reference to TGraph::SetTitle(char const*)’
root.cpp:(.text+0x633): undefined reference to TText::TText(double, double, char const*)' root.cpp:(.text+0x638): undefined reference to TThread::UnLock()’
root.cpp:(.text+0x648): undefined reference to TGraph::SetMaximum(double)' root.cpp:(.text+0x66c): undefined reference to TGraph::Draw(char const*)’
root.cpp:(.text+0x67b): undefined reference to TObject::Draw(char const*)' root.cpp:(.text+0x69f): undefined reference to TGraph::Draw(char const*)’
root.cpp:(.text+0x6e2): undefined reference to TObject::Draw(char const*)' root.cpp:(.text+0x720): undefined reference to TQObject::Emit(char const*)’
root.cpp:(.text+0x7a0): undefined reference to TText::~TText()' root.cpp:(.text+0x7a8): undefined reference to TGraph::~TGraph()’
root.cpp:(.text+0x7b0): undefined reference to TGraph::~TGraph()' root.cpp:(.text+0x9b3): undefined reference to TGraph::~TGraph()’
root.cpp:(.text+0x9c0): undefined reference to TGraph::~TGraph()' root.cpp:(.text+0x9cd): undefined reference to TText::~TText()’
root.o: In function TPad::Modified(bool)': root.cpp:(.text._ZN4TPad8ModifiedEb[_ZN4TPad8ModifiedEb]+0x25): undefined reference to TQObject::Emit(char const*)’
root.o: In function TCanvasImp::IsA() const': root.cpp:(.text._ZNK10TCanvasImp3IsAEv[_ZNK10TCanvasImp3IsAEv]+0x1): undefined reference to TCanvasImp::Class()’
root.o: In function TCanvasImp::ShowMembers(TMemberInspector&) const': root.cpp:(.text._ZNK10TCanvasImp11ShowMembersER16TMemberInspector[_ZNK10TCanvasImp11ShowMembersER16TMemberInspector]+0xd): undefined reference to TCanvasImp::Class()’
root.cpp:(.text._ZNK10TCanvasImp11ShowMembersER16TMemberInspector[_ZNK10TCanvasImp11ShowMembersER16TMemberInspector]+0x21): undefined reference to ROOT::Class_ShowMembers(TClass*, void const*, TMemberInspector&)' root.o: In function TApplicationImp::ShowMembers(TMemberInspector&) const’:
root.cpp:(.text._ZNK15TApplicationImp11ShowMembersER16TMemberInspector[_ZNK15TApplicationImp11ShowMembersER16TMemberInspector]+0xd): undefined reference to TApplicationImp::Class()' root.cpp:(.text._ZNK15TApplicationImp11ShowMembersER16TMemberInspector[_ZNK15TApplicationImp11ShowMembersER16TMemberInspector]+0x21): undefined reference to ROOT::Class_ShowMembers(TClass*, void const*, TMemberInspector&)’
root.o: In function TApplicationImp::IsA() const': root.cpp:(.text._ZNK15TApplicationImp3IsAEv[_ZNK15TApplicationImp3IsAEv]+0x1): undefined reference to TApplicationImp::Class()’
root.o: In function _GLOBAL__sub_I_canvas': root.cpp:(.text.startup+0x11): undefined reference to TVersionCheck::TVersionCheck(int)’
root.o: In function main': root.cpp:(.text.startup+0xd1): undefined reference to TApplication::TApplication(char const*, int*, char**, void*, int)’
root.cpp:(.text.startup+0xdb): undefined reference to TStorage::ObjectAlloc(unsigned long)' root.cpp:(.text.startup+0xfb): undefined reference to TCanvas::TCanvas(char const*, char const*, int, int)’
root.cpp:(.text.startup+0x121): undefined reference to TPad::Divide(int, int, float, float, int)' root.cpp:(.text.startup+0x147): undefined reference to TThread::TThread(char const*, void* ()(void), void*, TThread::EPriority)’
root.cpp:(.text.startup+0x151): undefined reference to TThread::Run(void*)' root.cpp:(.text.startup+0x15e): undefined reference to TApplication::Run(bool)’
root.cpp:(.text.startup+0x163): undefined reference to TThread::SetCancelAsynchronous()' root.cpp:(.text.startup+0x16b): undefined reference to TThread::Kill()’
root.cpp:(.text.startup+0x17f): undefined reference to TThread::~TThread()' root.cpp:(.text.startup+0x187): undefined reference to TApplication::~TApplication()’
root.cpp:(.text.startup+0x1e6): undefined reference to TObject::operator delete(void*)' root.cpp:(.text.startup+0x1ee): undefined reference to TApplication::~TApplication()’
root.cpp:(.text.startup+0x206): undefined reference to TThread::~TThread()' root.o: In function TApplicationImp::~TApplicationImp()‘:
root.cpp:(.text._ZN15TApplicationImpD2Ev[_ZN15TApplicationImpD5Ev]+0x10): undefined reference to TString::~TString()' root.o: In function TApplicationImp::~TApplicationImp()’:
root.cpp:(.text._ZN15TApplicationImpD0Ev[_ZN15TApplicationImpD5Ev]+0x14): undefined reference to TString::~TString()' root.o:(.data.rel.ro._ZTV15TApplicationImp[_ZTV15TApplicationImp]+0x80): undefined reference to TApplicationImp::Streamer(TBuffer&)’
root.o:(.data.rel.ro._ZTV10TCanvasImp[_ZTV10TCanvasImp]+0x100): undefined reference to `TCanvasImp::Streamer(TBuffer&)’
collect2: error: ld returned 1 exit status
Makefile:44: recipe for target ‘root’ failed
make: *** [root] Error 1

I’ve tried to fix it in the last two days but I didn’t manage to do anything. I haven’t even found a solution in the forum.

Thanks anyone who can help me!

You can just add “source dir_to_root/bin/thisroot.sh” to the bashrc.

Or does the problem only occur by compiling via a makefile? Can you call ROOT directly in the shell?

When linking, the order of the libraries and files is important.
linker -lmyLib something-the-depends-on-lib is wrong,
linker something-the-depends-on-lib -lmyLib is correct.

So put the required libraries after the part that requires the lib. In your case, move $(ROOTLFLAGS) to the end of the line.

Personally I would suggest you try CMake. ROOT even comes with a FindROOT.cmake file for you to include.

Edit: have a look at https://stackoverflow.com/questions/45135/why-does-the-order-in-which-libraries-are-linked-sometimes-cause-errors-in-gcc

I would also suggest CMake. Judging from the following output:

g++ -std=c++11 root-config --cflags -c root.cpp -o root.o
g++ -std=c++11 root-config --cflags root-config --glibs root.o -o root

it looks like your forgot the back ticks around the root-config commands:

ROOTCFLAGS:= `root-config --cflags`
ROOTLFLAGS:= `root-config --glibs`
root: root.o
	$(LINK.cc) $(ROOTCFLAGS) $(@F).o -o $(@F) $(ROOTLFLAGS)
root.o: root.cpp
	$(LINK.cc) $(ROOTCFLAGS) -c $ *.cpp -o $(@F)
clean: 
	rm *.o

First of all thanks everyone for the replies.

It tourned out I had to put the libs flags at at the end of the compilation code, as behrenhoff said. It’s strange because I’ve written the code on a Mac with a previous version of ROOT and I’ve managed to compile with the initial order of compilation, but probably I’m not remembering well.

Thank you again!

Might well be. If it works with the “wrong” order depends on the linker default settings. The correct order does not depend on linker default settings, i.e. the order shown in my post is always correct, your initial order might work or might not work.

For example, if you add the linker flag -Wl,--no-as-needed (or if that is the default setting), it will work. The default setting of your g++ is -Wl,--as-needed, basically discarding everything from the library that isn’t needed on the left side.

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