MINUIT2 and Makefiles

Hello,

I’m trying to make a Makefile to compile some .cc code some of which uses Minuit2.

I was able to run the code in ROOT by .L class.cc and then running the main code from a .C macro. However, as the framework gets larger I want a more professional way of doing this. I made this make file:

CFLAGS=-c -g -Wall `root-config --cflags`
LDFLAGS=`root-config --glibs`
SOURCES=TauAna.cc class1.cc class2.cc
OBJECTS=$(SOURCES:.cc=.o)
EXECUTABLE=TauAna

all: $(SOURCES) $(EXECUTABLE)

$(EXECUTABLE): $(OBJECTS)
	$(CC) $(LDFLAGS) $(OBJECTS) -o $@

.cc.o:
	$(CC) $(CFLAGS) $< -o $@

clean:
	rm ./*~ ./*.o ./TauAna

And I am seeing these types of errors:

g++ -c -g -Wall `root-config --cflags` TauAna.cc -o TauAna.o
g++ `root-config --glibs` TauAna.o -o TauAna
Undefined symbols for architecture x86_64:
  "ROOT::Minuit2::MnStrategy::MnStrategy(unsigned int)", referenced from:
      RunMinuit(TString, TString) in TauAna.o
  "ROOT::Minuit2::MnApplication::SetLimits(unsigned int, double, double)", referenced from:
      RunMinuit(TString, TString) in TauAna.o
  "ROOT::Minuit2::MnApplication::MnApplication(ROOT::Minuit2::FCNBase const&, ROOT::Minuit2::MnUserParameterState const&, ROOT::Minuit2::MnStrategy const&, unsigned int)", referenced from:
      ROOT::Minuit2::MnMigrad::MnMigrad(ROOT::Minuit2::FCNBase const&, ROOT::Minuit2::MnUserParameterState const&, ROOT::Minuit2::MnStrategy const&) in TauAna.o
  "ROOT::Minuit2::MnApplication::operator()(unsigned int, double)", referenced from:
      RunMinuit(TString, TString) in TauAna.o
      vtable for ROOT::Minuit2::MnMigrad in TauAna.o
  "ROOT::Minuit2::MinimumBuilder::MinimumBuilder()", referenced from:
      ROOT::Minuit2::VariableMetricBuilder::VariableMetricBuilder(ROOT::Minuit2::VariableMetricBuilder::ErrorUpdatorType) in TauAna.o
  "ROOT::Minuit2::MnUserParameters::MnUserParameters(std::__1::vector<double, std::__1::allocator<double> > const&, std::__1::vector<double, std::__1::allocator<double> > const&)", referenced from:
      RunMinuit(TString, TString) in TauAna.o
  "ROOT::Minuit2::MnUserParameterState::MnUserParameterState(ROOT::Minuit2::MinimumState const&, double, ROOT::Minuit2::MnUserTransformation const&)", referenced from:
      ROOT::Minuit2::BasicFunctionMinimum::UserParameters() const in TauAna.o
  "ROOT::Minuit2::MnUserParameterState::MnUserParameterState(ROOT::Minuit2::MnUserParameters const&)", referenced from:
      RunMinuit(TString, TString) in TauAna.o
  "ROOT::Minuit2::MnMinos::MnMinos(ROOT::Minuit2::FCNBase const&, ROOT::Minuit2::FunctionMinimum const&, unsigned int)", referenced from:
      RunMinuit(TString, TString) in TauAna.o
  "ROOT::Minuit2::MnPrint::SetLevel(int)", referenced from:
      RunMinuit(TString, TString) in TauAna.o
  "ROOT::Minuit2::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, ROOT::Minuit2::FunctionMinimum const&)", referenced from:
      RunMinuit(TString, TString) in TauAna.o
  "ROOT::Minuit2::ModularFunctionMinimizer::Minimize(ROOT::Minuit2::FCNGradientBase const&, ROOT::Minuit2::MnUserParameters const&, ROOT::Minuit2::MnStrategy const&, unsigned int, double) const", referenced from:
      vtable for ROOT::Minuit2::VariableMetricMinimizer in TauAna.o
  "ROOT::Minuit2::ModularFunctionMinimizer::Minimize(ROOT::Minuit2::FCNGradientBase const&, ROOT::Minuit2::MnUserParameters const&, ROOT::Minuit2::MnUserCovariance const&, ROOT::Minuit2::MnStrategy const&, unsigned int, double) const", referenced from:
      vtable for ROOT::Minuit2::VariableMetricMinimizer in TauAna.o
  "ROOT::Minuit2::ModularFunctionMinimizer::Minimize(ROOT::Minuit2::FCNGradientBase const&, ROOT::Minuit2::MnUserParameterState const&, ROOT::Minuit2::MnStrategy const&, unsigned int, double) const", referenced from:
      vtable for ROOT::Minuit2::VariableMetricMinimizer in TauAna.o
  "ROOT::Minuit2::ModularFunctionMinimizer::Minimize(ROOT::Minuit2::FCNGradientBase const&, std::__1::vector<double, std::__1::allocator<double> > const&, std::__1::vector<double, std::__1::allocator<double> > const&, unsigned int, unsigned int, double) const", referenced from:
      vtable for ROOT::Minuit2::VariableMetricMinimizer in TauAna.o
  "ROOT::Minuit2::ModularFunctionMinimizer::Minimize(ROOT::Minuit2::FCNGradientBase const&, std::__1::vector<double, std::__1::allocator<double> > const&, unsigned int, std::__1::vector<double, std::__1::allocator<double> > const&, unsigned int, unsigned int, double) const", referenced from:
      vtable for ROOT::Minuit2::VariableMetricMinimizer in TauAna.o
  "ROOT::Minuit2::ModularFunctionMinimizer::Minimize(ROOT::Minuit2::MnFcn const&, ROOT::Minuit2::GradientCalculator const&, ROOT::Minuit2::MinimumSeed const&, ROOT::Minuit2::MnStrategy const&, unsigned int, double) const", referenced from:
      vtable for ROOT::Minuit2::VariableMetricMinimizer in TauAna.o
  "ROOT::Minuit2::ModularFunctionMinimizer::Minimize(ROOT::Minuit2::FCNBase const&, ROOT::Minuit2::MnUserParameters const&, ROOT::Minuit2::MnStrategy const&, unsigned int, double) const", referenced from:
      vtable for ROOT::Minuit2::VariableMetricMinimizer in TauAna.o
  "ROOT::Minuit2::ModularFunctionMinimizer::Minimize(ROOT::Minuit2::FCNBase const&, ROOT::Minuit2::MnUserParameters const&, ROOT::Minuit2::MnUserCovariance const&, ROOT::Minuit2::MnStrategy const&, unsigned int, double) const", referenced from:
      vtable for ROOT::Minuit2::VariableMetricMinimizer in TauAna.o
  "ROOT::Minuit2::ModularFunctionMinimizer::Minimize(ROOT::Minuit2::FCNBase const&, ROOT::Minuit2::MnUserParameterState const&, ROOT::Minuit2::MnStrategy const&, unsigned int, double) const", referenced from:
      vtable for ROOT::Minuit2::VariableMetricMinimizer in TauAna.o
  "ROOT::Minuit2::ModularFunctionMinimizer::Minimize(ROOT::Minuit2::FCNBase const&, std::__1::vector<double, std::__1::allocator<double> > const&, std::__1::vector<double, std::__1::allocator<double> > const&, unsigned int, unsigned int, double) const", referenced from:
      vtable for ROOT::Minuit2::VariableMetricMinimizer in TauAna.o
  "ROOT::Minuit2::ModularFunctionMinimizer::Minimize(ROOT::Minuit2::FCNBase const&, std::__1::vector<double, std::__1::allocator<double> > const&, unsigned int, std::__1::vector<double, std::__1::allocator<double> > const&, unsigned int, unsigned int, double) const", referenced from:
      vtable for ROOT::Minuit2::VariableMetricMinimizer in TauAna.o
  "ROOT::Minuit2::MnMinos::operator()(unsigned int, unsigned int, double) const", referenced from:
      RunMinuit(TString, TString) in TauAna.o

Does anyone know what I have missed?

Thanks.

$(CC) $(CFLAGS) -o $@ $(OBJECTS) $(LDFLAGS)

Hi,

In which part should this be changed?

Thanks

:thinking: Looks like a linker command line to me. :scream:

It didnt work, which is why I was asking.

It seems I forgot about:

LDFLAGS=`root-config --glibs` -lMinuit2

This seems to have fixed the Minuit2 errors. I still have some errors related to my own classes:

Undefined symbols for architecture x86_64:
  "Likelihood::Class()", referenced from:
      Likelihood::IsA() const in Likelihood.o
      Likelihood::ShowMembers(TMemberInspector&) const in Likelihood.o
  "Likelihood::Streamer(TBuffer&)", referenced from:
      vtable for Likelihood in Likelihood.o
  "ROOT::GenerateInitInstance(Likelihood const*)", referenced from:
      ___cxx_global_var_init.1 in Likelihood.o
  "ROOT::GenerateInitInstance(Poisson const*)", referenced from:
      ___cxx_global_var_init.1 in Poisson.o
  "vtable for Poisson", referenced from:
      Poisson::Poisson(unsigned int, double, double, double, double, double, double, double, double) in Likelihood.o
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [TauAna] Error 1

Likelihood and Poisson are two of my classes. I assume there’s an additional step

You need to generate dictionaries for your classes:

ROOT macros and shared libraries → Embedding the rootcling call into a GNU Makefile

A simple “LinkDef.h” file could look like this:

#if defined(__CINT__) || defined(__CLING__)
#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;
#pragma link C++ nestedclasses;

#pragma link C++ class Poisson+;
#pragma link C++ class Likelihood+;
#endif

I tried the LinkDef and this as my Makefile:

ROOTSYS=Users/user/ROOT-minuit/root_build
CC=g++
CFLAGS=-c -g -Wall `root-config --cflags`
LDFLAGS=`root-config --glibs` -lMinuit2
SOURCES=TauAna.cc Likelihood.cc Poisson.cc
OBJECTS=$(SOURCES:.cc=.o)
EXECUTABLE=TauAna

MyDict.cxx: $(HEADERS) LinkDef.h
	rootcling -f $@ -c $(CXXFLAGS) -p $^

libMyLib.so: MyDict.cxx $(SOURCES)
	g++ -shared -o$@ `root-config --ldflags` $(CXXFLAGS) -I$(ROOTSYS)/include $^

all: $(SOURCES) $(EXECUTABLE)

$(EXECUTABLE): $(OBJECTS)
	$(CC) $(LDFLAGS) $(OBJECTS) -o $@


.cc.o:
	$(CC) $(CFLAGS) $< -o $@

clean:
	rm ./*~ ./*.o ./TauAna

The only print out I see is this

rootcling -f MyDict.cxx -c  -p LinkDef.h
Warning: Unused class rule: Likelihood
Warning: Unused class rule: Poisson

No executable is produced

I guess you need to provide something like:

HEADERS=Poisson.h Likelihood.h

Hi,

Yes, I just realized my mistake. I edited it to this:

ROOTSYS=Users/user/ROOT-minuit/root_build
CC=g++
CFLAGS=-c -g -Wall `root-config --cflags`
LDFLAGS=`root-config --glibs` -lMinuit2
SOURCES=TauAna.cc Likelihood.cc Poisson.cc
HEADERS=TauAna.hh Likelihood.hh Poisson.hh
OBJECTS=$(SOURCES:.cc=.o)
EXECUTABLE=TauAna

MyDict.cxx: $(HEADERS) LinkDef.h
	rootcling -f $@ -c $(CXXFLAGS) -p $^

libMyLib.so: MyDict.cxx $(SOURCES)
	g++ -shared -o$@ `root-config --ldflags` $(CXXFLAGS) -I$(ROOTSYS)/include $^

all: $(SOURCES) $(EXECUTABLE)

$(EXECUTABLE): $(OBJECTS)
	$(CC) $(LDFLAGS) $(OBJECTS) -o $@


.cc.o:
	$(CC) $(CFLAGS) $< -o $@

clean:
	rm ./*~ ./*.o ./TauAna

If I try just calling

make

then the only print out I get is this:

rootcling -f MyDict.cxx -c  -p TauAna.hh Likelihood.hh Poisson.hh LinkDef.h

Try with the following “Makefile”:

CC=`root-config --cxx`
CFLAGS=`root-config --cflags` -g -Wall
LDFLAGS=`root-config --glibs` -lMinuit2
SOURCES=TauAna.cc Poisson.cc Likelihood.cc MyDict.cc
OBJECTS=$(SOURCES:.cc=.o)
HEADERS=Poisson.hh Likelihood.hh
EXECUTABLE=TauAna

all: $(EXECUTABLE)

$(EXECUTABLE): $(OBJECTS)
	$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)

MyDict.cc: $(HEADERS) LinkDef.h
	rootcling -f $@ -c $(CXXFLAGS) -p $^

.cc.o:
	$(CC) $(CFLAGS) -o $@ -c $<

clean:
	rm -f ./*~ ./*.o ./MyDict.* ./$(EXECUTABLE)
1 Like

Thanks this worked!