Integrate ROOT (and MINUIT2) into my project with CMake

I followed the guide : root.cern.ch/how/integrate-root … ject-cmake, but encountered some difficulties linking Minuit2.

After cmaking (cmake …) in my build folder I try to compile my code via ‘make’ and get the following error of missing symbols:

[quote]Undefined symbols for architecture x86_64:
“ROOT::Minuit2::MnUserParameters::Add(std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&, double, double)”, referenced from:
_main in main.cpp.o
"ROOT::Minuit2::operator<<(std::basic_ostream<char, std::char_traits >&, ROOT::Minuit2::FunctionMinimum const&)", referenced from:
_main in main.cpp.o
"ROOT::Minuit2::ModularFunctionMinimizer::Minimize(ROOT::Minuit2::FCNGradientBase const&, std::vector<double, std::allocator > const&, std::vector<double, std::allocator > const&, unsigned int, unsigned int, double) const", referenced from:
vtable for ROOT::Minuit2::VariableMetricMinimizer in main.cpp.o
"ROOT::Minuit2::ModularFunctionMinimizer::Minimize(ROOT::Minuit2::FCNGradientBase const&, std::vector<double, std::allocator > const&, unsigned int, std::vector<double, std::allocator > const&, unsigned int, unsigned int, double) const", referenced from:
vtable for ROOT::Minuit2::VariableMetricMinimizer in main.cpp.o
"ROOT::Minuit2::ModularFunctionMinimizer::Minimize(ROOT::Minuit2::FCNBase const&, std::vector<double, std::allocator > const&, std::vector<double, std::allocator > const&, unsigned int, unsigned int, double) const", referenced from:
vtable for ROOT::Minuit2::VariableMetricMinimizer in main.cpp.o
"ROOT::Minuit2::ModularFunctionMinimizer::Minimize(ROOT::Minuit2::FCNBase const&, std::vector<double, std::allocator > const&, unsigned int, std::vector<double, std::allocator > const&, unsigned int, unsigned int, double) const", referenced from:
vtable for ROOT::Minuit2::VariableMetricMinimizer in main.cpp.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
make[2]: *** [mixing] Error 1
make[1]: *** [CMakeFiles/mixing.dir/all] Error 2
make: *** [all] Error 2[/quote]

I have ROOT installed vie macports. So I checked the ‘libMinuit2.rootmap’ from the Minuit2 library I try to link. It shows all the missing symbols. Why are the symbols undefined if I link them in my CMakeTexts.txt via target_link_libraries:

CMakeLists.txt:

[quote]cmake_minimum_required(VERSION 3.7.0)
project(mixing CXX Fortran)

SET UP ROOT root.cern.ch/how/integrate-root … ject-cmake

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} /opt/local/libexec/root6/etc/root/cmake)
find_package(ROOT REQUIRED COMPONENTS MATH MINUIT2)

MESSAGE( STATUS “ROOT_INCLUDE_DIRS” ${ROOT_INCLUDE_DIRS} )
MESSAGE( STATUS “ROOT_LIBRARIES” ${ROOT_LIBRARIES} )
MESSAGE( STATUS “ROOT_CXX_FLAGS” ${ROOT_CXX_FLAGS} )

include_directories(Experiment Theory ${ROOT_INCLUDE_DIRS})

link_directories(/opt/local/libexec/root6/lib/root)

add_executable(mixing
main.cpp
teubner.f
Experiment/experiment.cpp
Experiment/experiment.h
Theory/theory.cpp
Theory/theory.h
)

target_link_libraries(mixing ${ROOT_LIBRARIES})[/quote]

BTW the output of the cmake messages are given by:

[quote]-- ROOT_INCLUDE_DIRS/opt/local/libexec/root6/include/root
– ROOT_LIBRARIES/opt/local/libexec/root6/lib/root/libCore.so/opt/local/libexec/root6/lib/root/libRIO.so/opt/local/libexec/root6/lib/root/libNet.so/opt/local/libexec/root6/lib/root/libHist.so/opt/local/libexec/root6/lib/root/libGraf.so/opt/local/libexec/root6/lib/root/libGraf3d.so/opt/local/libexec/root6/lib/root/libGpad.so/opt/local/libexec/root6/lib/root/libTree.so/opt/local/libexec/root6/lib/root/libRint.so/opt/local/libexec/root6/lib/root/libPostscript.so/opt/local/libexec/root6/lib/root/libMatrix.so/opt/local/libexec/root6/lib/root/libPhysics.so/opt/local/libexec/root6/lib/root/libMathCore.so/opt/local/libexec/root6/lib/root/libThread.so/opt/local/libexec/root6/lib/root/libMinuit2.so
– ROOT_CXX_FLAGS-pthread -stdlib=libc++ -std=c++1y -m64[/quote],
where you can see that “libMinuit2.so” is added. Do I have to use the “Clang” ROOT_CXX_FLAGS? Which I cannot because they are not compatible with my g++ maker?

I have an additional Question! The macport installation of ROOT is compiled via clang. Clang does not support Fortran mixing. I have to use Fortran codes within my project and decided to use g++ and gfortran to make my files. Is this connected to the above errors or might cause errors in the future?

Yes, you need to use somehow ROOT_CXX_FLAGS (in particular the -std=c++1y compiler option). A quick and resilient way achieve this is just adding the following line after find_package(ROOT…) :

include(${ROOT_USE_FILE})

Thanks for the reply. Sadly I’ve already been through this point.
-stdlib=libc++ is a Clang option and creates an error using g++:

[quote]build :v:️ $ make
Scanning dependencies of target mixing
[ 20%] Building CXX object CMakeFiles/mixing.dir/main.cpp.o
c++: error: unrecognized command line option '-stdlib=libc++'
make[2]: *** [CMakeFiles/mixing.dir/main.cpp.o] Error 1
make[1]: *** [CMakeFiles/mixing.dir/all] Error 2
make: *** [all] Error 2[/quote]

Is there a way to solve this error? Do I have to compile ROOT with g++ and link this version?

Sorry. I didn’t answer your question about mixing clang and gfortran. Yes you can mix. We do this when building the fortran components of ROOT itself.
So, the reason does not work, as you pointed, is that ROOT_CXX_FLAGS is set assuming you use the same compiler as was used to build ROOT itself (which is the less problematic certainly). I think you have to options:
a) use clang for building your program.
b) set by hand CMAKE_CXX_FLAGS like this:

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -std=c++1y -m64")

I used the first option and forced cmake to use the clang++ compiler.

For now everything seems to work.

Thanks for the help!