Mac Os X root linking problem (CMake and SWIG)

Dear All,

I am trying to port a C++/SWIG project that compiles on Linux to MacOs X. I installed root6 with brew following alexpearce.me/2016/02/root-on-os-x-el-capitan/ . Root works fine on my mac

[code]$ root

| Welcome to ROOT 6.08/00 http://root.cern.ch |
| © 1995-2016, The ROOT Team |
| Built for macosx64 |
| From tag v6-08-00, 4 November 2016 |

Try ‘.help’, ‘.demo’, ‘.license’, ‘.credits’, ‘.quit’/’.q’

root [0] .q
[/code]

in my cmake file I use:

find_package(ROOT REQUIRED COMPONENTS RIO Net Hist) include(${ROOT_USE_FILE})

if I print

MESSAGE(STATUS ${ROOT_INCLUDE_DIRS}) MESSAGE(STATUS ${ROOT_LIBRARIES})
i get

-- /usr/local/opt/root6/include/root
-- /usr/local/opt/root6/lib/root/libCore.so/usr/local/opt/root6/lib/root/libRIO.so/usr/local/opt/root6/lib/root/libNet.so/usr/local/opt/root6/lib/root/libHist.so/usr/local/opt/root6/lib/root/libGraf.so/usr/local/opt/root6/lib/root/libGraf3d.so/usr/local/opt/root6/lib/root/libGpad.so/usr/local/opt/root6/lib/root/libTree.so/usr/local/opt/root6/lib/root/libRint.so/usr/local/opt/root6/lib/root/libPostscript.so/usr/local/opt/root6/lib/root/libMatrix.so/usr/local/opt/root6/lib/root/libPhysics.so/usr/local/opt/root6/lib/root/libMathCore.so/usr/local/opt/root6/lib/root/libThread.so/usr/local/opt/root6/lib/root/libMultiProc.so[/code]

and here is the relevan part of the CMake file:
[code]find_package(SWIG 3.0.10 REQUIRED)
include(${SWIG_USE_FILE})
find_package(PythonLibs)

include_directories(${PYTHON_INCLUDE_PATH}
		    ${CMAKE_CURRENT_SOURCE_DIR}/include
		    ${CPP_SOURCE_FILES}
		    ${COMMON_INCLUDES}
   		    ${ROOT_INCLUDE_DIRS}
)

add_library(Liblib SHARED ${CPP_SOURCE_FILES}/source1.cpp
                          ${CPP_SOURCE_FILES}/source2.cpp
                          ${CPP_SOURCE_FILES}/source3.cpp

)

set_property(SOURCE ${SWIG_PROJECTS_DIR}/source.i PROPERTY CPLUSPLUS ON)
set_property(SOURCE ${SWIG_PROJECTS_DIR}/source.i PROPERTY SWIG_FLAG "-includeall" "-py3" "-builtin" "-externative")

swig_add_module(sourceall python ${SWIG_PROJECTS_DIR}/source.i
                ${CPP_SOURCE_FILES}/sourceall.cpp
                 ) # I need to link to an external library

swig_link_libraries(sourceall Liblib ${PYTHON_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${ROOT_LIBRARIES})

but i get this error message:

[code][ 91%] Linking CXX shared library libLiblib.dylib
Undefined symbols for architecture x86_64:
“TVersionCheck::TVersionCheck(int)”, referenced from:
___cxx_global_var_init in source1.cpp.o
"TH1F::TH1F(char const*, char const*, int, double, double)", referenced from:
Source1Class::populateList(unsigned int) in source1.cpp.o
Source1Class::resetHistLimits(unsigned int, unsigned int, unsigned int) in source1.cpp.o
"TFile::TFile(char const*, char const*, char const*, int)", referenced from:

ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
[/code]

Do you have any hit or clue of what is going on?
Thanks in advace

Hi,

Looks like ${ROOT_LIBRARIES} is not what it should be (likely empty).

Axel.

[quote=“Axel”]Hi,

Looks like ${ROOT_LIBRARIES} is not what it should be (likely empty).

Axel.[/quote]

Hi,
Thanks for your reply!
I made a mistake in the first post:

[quote]if I print

MESSAGE(STATUS ${ROOT_INCLUDE_DIRS}) MESSAGE(STATUS ${ROOT_DEFINITIONS})

[/quote]

should be

[quote]if I print

MESSAGE(STATUS ${ROOT_INCLUDE_DIRS}) MESSAGE(STATUS ${ROOT_LIBRARIES})

[/quote]
i get

-- /usr/local/opt/root6/include/root -- /usr/local/opt/root6/lib/root/libCore.so/usr/local/opt/root6/lib/root/libRIO.so/usr/local/opt/root6/lib/root/libNet.so/usr/local/opt/root6/lib/root/libHist.so/usr/local/opt/root6/lib/root/libGraf.so/usr/local/opt/root6/lib/root/libGraf3d.so/usr/local/opt/root6/lib/root/libGpad.so/usr/local/opt/root6/lib/root/libTree.so/usr/local/opt/root6/lib/root/libRint.so/usr/local/opt/root6/lib/root/libPostscript.so/usr/local/opt/root6/lib/root/libMatrix.so/usr/local/opt/root6/lib/root/libPhysics.so/usr/local/opt/root6/lib/root/libMathCore.so/usr/local/opt/root6/lib/root/libThread.so/usr/local/opt/root6/lib/root/libMultiProc.so

MESSAGE(STATUS ${ROOT_DEFINITIONS}) returns

Hi,

${ROOT_LIBRARIES} seems to be missing an awful lot of spaces separating the libraries. Also I’d hope that we link as -Lwhatever -lCore etc - but I’m by far not a CMake expert, so this might just be what CMake expects despite not being what I expect :slight_smile:

Cheers, Axel.

I do not know what swig_link_libraries() does with the list of libraries. Can you enable verbosity to see the exact link command with

make VERBOSE=1

Thanks for the suggestion, it seems indeed that it is not linking with the root libraries… (sorry if i am not changing all the names of the files in this output, I have limited time know, if you find it hard to read, tell me and I’ll edit)

[ 91%] Linking CXX shared library libLpList.dylib /usr/local/Cellar/cmake/3.4.0/bin/cmake -E cmake_link_script CMakeFiles/LpList.dir/link.txt --verbose=1 /usr/bin/g++ -m64 -pipe -fsigned-char -fno-common -Qunused-arguments -pthread -std=c++11 -DR__HAVE_CONFIG -g -m64 -pipe -fsigned-char -fno-common -Qunused-arguments -pthread -std=c++11 -DR__HAVE_CONFIG -dynamiclib -Wl,-headerpad_max_install_names -o libLpList.dylib -install_name @rpath/libLpList.dylib CMakeFiles/LpList.dir/src/LpList.cpp.o CMakeFiles/LpList.dir/src/DMImage.cpp.o CMakeFiles/LpList.dir/src/DMError.cpp.o CMakeFiles/LpList.dir/src/DMCalc.cpp.o CMakeFiles/LpList.dir/src/DMPreProcessing.cpp.o CMakeFiles/LpList.dir/src/cJSON.c.o -L/usr/local/opt/root6/lib/root -L/Users/whatever/Src/Cpp/DMMaker/lib /usr/local/lib/libtiff.dylib -Wl,-rpath,/usr/local/opt/root6/lib/root -Wl,-rpath,/Users/whatever/Src/Cpp/DMMaker/lib Undefined symbols for architecture x86_64: "TVersionCheck::TVersionCheck(int)", referenced from: ___cxx_global_var_init in DMPreProcessing.cpp.o "TH1F::TH1F(char const*, char const*, int, double, double)", referenced from: DMPreProcessing::populateList(unsigned int) in DMPreProcessing.cpp.o DMPreProcessing::resetHistLimits(unsigned int, unsigned int, unsigned int) in DMPreProcessing.cpp.o "TFile::TFile(char const*, char const*, char const*, int)", referenced from: DMPreProcessing::writeFile(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in DMPreProcessing.cpp.o "TObject::operator delete(void*)", referenced from: DMPreProcessing::DMPreProcessing() in DMPreProcessing.cpp.o DMPreProcessing::populateList(unsigned int) in DMPreProcessing.cpp.o DMPreProcessing::DMPreProcessing(unsigned int) in DMPreProcessing.cpp.o DMPreProcessing::DMPreProcessing(DMPreProcessing const&) in DMPreProcessing.cpp.o DMPreProcessing::resetHistLimits(unsigned int, unsigned int, unsigned int) in DMPreProcessing.cpp.o DMPreProcessing::writeFile(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in DMPreProcessing.cpp.o "TStorage::ObjectAlloc(unsigned long)", referenced from: TObject::operator new(unsigned long) in DMPreProcessing.cpp.o "TObjArray::TObjArray(int, int)", referenced from: DMPreProcessing::DMPreProcessing() in DMPreProcessing.cpp.o DMPreProcessing::DMPreProcessing(unsigned int) in DMPreProcessing.cpp.o DMPreProcessing::DMPreProcessing(DMPreProcessing const&) in DMPreProcessing.cpp.o "TArray::OutOfBoundsError(char const*, int) const", referenced from: TArray::BoundsOk(char const*, int) const in DMPreProcessing.cpp.o "typeinfo for TH1F", referenced from: DMPreProcessing::addElement(float, unsigned int) in DMPreProcessing.cpp.o DMPreProcessing::resetHistLimits(unsigned int, unsigned int, unsigned int) in DMPreProcessing.cpp.o "typeinfo for TObject", referenced from: DMPreProcessing::DMPreProcessing(DMPreProcessing const&) in DMPreProcessing.cpp.o DMPreProcessing::operator=(DMPreProcessing const&) in DMPreProcessing.cpp.o DMPreProcessing::addElement(float, unsigned int) in DMPreProcessing.cpp.o DMPreProcessing::resetHistLimits(unsigned int, unsigned int, unsigned int) in DMPreProcessing.cpp.o "typeinfo for TObjArray", referenced from: DMPreProcessing::DMPreProcessing(DMPreProcessing const&) in DMPreProcessing.cpp.o DMPreProcessing::operator=(DMPreProcessing const&) in DMPreProcessing.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]: *** [libLpList.dylib] Error 1 make[1]: *** [CMakeFiles/LpList.dir/all] Error 2 make: *** [all] Error 2

Hi,
I see what the problem is. It is not in the SWIG module, but on the library libLpList you build. You need to add the command

target_link_libraries(libLpList ${ROOT_LIBRARIES})

Pere

It now compiles (does not work yet, but that’s not a ROOT problem). Thanks a lot! Super strange anyway that the cmake was working perfectly under linux, but not under MacOs