TTreeFormula Linking Error

Hi,

I am attempting to use the following method in a class and compile a library with the classes for use in ROOT later.

/**Checks the provided expression by use of a TTreeFormula.
 *
 * \param[in] expr The expression to check.
 * \return True if valid.
 */
bool ClassName::ValidEvtExpr(const std::string &expr) {
   TTreeFormula formula("ExprTest", expr.c_str(), tree_);
   if (formula.GetNdim() == 0) return false;
   return true;
}

The compilation is successful, but I receive the following error message at linking:

[100%] Linking CXX shared library libLibrary.dylib
Undefined symbols for architecture x86_64:
  "TTreeFormula::TTreeFormula(char const*, char const*, TTree*)", referenced from:
      ClassName::ValidEvtExpr(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) in ClassName.cpp.o
  "TTreeFormula::~TTreeFormula()", referenced from:
      ClassName::ValidEvtExpr(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) in ClassName.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [source/libLibrary.dylib] Error 1
make[1]: *** [source/CMakeFiles/Library.dir/all] Error 2
make: *** [all] Error 2

I am compiling on Mac OS 10.12, with ROOT 6.08.06 compiled on the local machine, cmake 3.7.2 and clang-802.0.38.

Hi,

what is the command you use to link?

Cheers,
D

The makefile is built by cmake. Here is the verbose output when running make:

[100%] Linking CXX shared library libLibrary.dylib
cd /Users/user/class/build/source && /opt/local/bin/cmake -E cmake_link_script CMakeFiles/ClassName.dir/link.txt --verbose=1
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++    -m64 -pipe -fsigned-char -fno-common -Qunused-arguments -pthread -std=c++14 -dynamiclib -Wl,-headerpad_max_install_names  -o libLibrary.dylib -install_name @rpath/libLibrary.dylib CMakeFiles/ClassName.dir/ClassName.cpp.o CMakeFiles/ClassName.dir/ClassHist.cpp.o CMakeFiles/ClassName.dir/Utility.cpp.o CMakeFiles/ClassName.dir/Telescope.cpp.o CMakeFiles/ClassName.dir/AngularResponse.cpp.o CMakeFiles/ClassName.dir/Library.cxx.o  -L/opt/root/root-6.08.06/lib -Wl,-rpath,/opt/root/root-6.08.06/lib /opt/root/root-6.08.06/lib/libCore.so /opt/root/root-6.08.06/lib/libRIO.so /opt/root/root-6.08.06/lib/libNet.so /opt/root/root-6.08.06/lib/libHist.so /opt/root/root-6.08.06/lib/libGraf.so /opt/root/root-6.08.06/lib/libGraf3d.so /opt/root/root-6.08.06/lib/libGpad.so /opt/root/root-6.08.06/lib/libTree.so /opt/root/root-6.08.06/lib/libRint.so /opt/root/root-6.08.06/lib/libPostscript.so /opt/root/root-6.08.06/lib/libMatrix.so /opt/root/root-6.08.06/lib/libPhysics.so /opt/root/root-6.08.06/lib/libMathCore.so /opt/root/root-6.08.06/lib/libThread.so /opt/root/root-6.08.06/lib/libMultiProc.so
Undefined symbols for architecture x86_64:
  "TTreeFormula::TTreeFormula(char const*, char const*, TTree*)", referenced from:
      ClassName::ValidEvtExpr(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in ClassName.cpp.o
  "TTreeFormula::~TTreeFormula()", referenced from:
      ClassName::ValidEvtExpr(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in ClassName.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [source/libLibrary.dylib] Error 1
make[1]: *** [source/CMakeFiles/ClassName.dir/all] Error 2 
make: *** [all] Error 2

And here is the cmake file from that directory:

#Generate a ROOT dictionary.
ROOT_GENERATE_DICTIONARY(LibraryDict 
   ../include/ClassName.hpp
   ../include/ClassHist.hpp
   ../include/Utility.hpp
   ../include/Telescope.hpp
   ../include/AngularResponse.hpp
   LINKDEF ../include/Library_LinkDef.h)

#Install the ROOT 6 PCM and rootmap files.
if (${ROOT_VERSION} VERSION_GREATER "6.0")
   install(
      FILES
         ${CMAKE_CURRENT_BINARY_DIR}/libLibraryDict_rdict.pcm
         ${CMAKE_CURRENT_BINARY_DIR}/libLibraryDict.rootmap
      DESTINATION lib/)
endif (${ROOT_VERSION} VERSION_GREATER "6.0")


#Create the Library library with the ROOT dictionary.
add_library(Library SHARED
   ClassName.cpp ClassHist.cpp Utility.cpp Telescope.cpp AngularResponse.cpp
   LibraryDict)

#Link to ROOT.
target_link_libraries(Library ${ROOT_LIBRARIES})

#Set the install directory.
install(TARGETS Library DESTINATION lib/)

You need to link against the TreePlayer library, where you specify ${ROOT_LIBRARIES}.

Axel.

Ahh yes, I’ve run into this a couple times with various libraries. Is there some documentation about which classes live in which libraries?

For others who run into this issue the following cmake line after finding the ROOT package resolves the issue:

EDIT: This is a better solution than my original solution below:

find_package(ROOT COMPONENTS TreePlayer)

Original solution:

list(APPEND ROOT_LIBRARIES TreePlayer)

Hi,

That’s https://sft.its.cern.ch/jira/browse/ROOT-8431 - please leave a ping and subscribe to / vote for the bug :slight_smile:

Axel.

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