XmlTree linker errors with Cinder-Warping on Linux

I’m trying to build Cinder-Warping on Linux with CMake. The CMakeLists.txt file:

which works fine in OS X, but in Linux is fails with a linker error related to XmlTree:

[100%] Linking CXX executable Debug/BasicWarping
libCinder-Warping.a(Warp.cpp.o): In function `ph::warping::Warp::toXml() const':
cinder/blocks/Cinder-Warping/src/Warp.cpp:151: undefined reference to `cinder::XmlTree::push_back(cinder::XmlTree const&)'
cinder/blocks/Cinder-Warping/src/Warp.cpp:165: undefined reference to `cinder::XmlTree::push_back(cinder::XmlTree const&)'
cinder/blocks/Cinder-Warping/src/Warp.cpp:172: undefined reference to `cinder::XmlTree::push_back(cinder::XmlTree const&)'
cinder/blocks/Cinder-Warping/src/Warp.cpp:179: undefined reference to `cinder::XmlTree::push_back(cinder::XmlTree const&)'
cinder/blocks/Cinder-Warping/src/Warp.cpp:181: undefined reference to `cinder::XmlTree::push_back(cinder::XmlTree const&)'
...

Although libcinder.a should contain the necessary symbols:

$ nm libcinder.a | grep XmlTree | grep push_back
0000000000003260 T _ZN6cinder7XmlTree9push_backERKS0_

I built the FlickrTestMultithreaded sample, which also uses XmlTree, but it compiles fine.

Do you have any idea what might be causing this? Any suggestions would be appreciated.

Some more information:

Cinder is build with -DCINDER_BOOST_USE_SYSTEM=1, which implies -D_GLIBCXX_USE_CXX11_ABI=1

Tried with clang 3.8.1 and g++ 6.3.1.

Reduced the code to return only one error for this line in Warp.cpp, which is the only setAttribute call in the file:

xml.setAttribute( std::string, int );

These are the references in the object file, Warp.cpp.o, I’m not sure why there are two, maybe because of the templated fuction.

 U _ZN6cinder7XmlTree12setAttributeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_
 W _ZN6cinder7XmlTree12setAttributeIiEERS0_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKT_

This is the reference in libcinder:

T _ZN6cinder7XmlTree12setAttributeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_

I suspect this is an ABI error, but could not solve it so far.

Turns out the issue was order dependent linking.
It was solved by moving the following line in cinderMakeApp.cmake :

target_link_libraries( ${ARG_APP_NAME} cinder ${ARG_LIBRARIES} )

after the section where blocks are handled, like this:

foreach( block ${ARG_BLOCKS} )
...
endforeach()

target_link_libraries( ${ARG_APP_NAME} cinder ${ARG_LIBRARIES} )

I hope it helps someone in the future.

Hi Gabor,

not entirely sure right now why your initial attempt works on OS X ( I would expect it not work as is the case on Linux ) but in any case the proper way to do it would be to privately link the block target with Cinder at the end of your block config. This would then allow the same config / block to be used in a CMake project that doesn’t use the cinderMakeApp macro to link with Cinder.

You can see how this looks here . This should already fix the error you were getting but it might still be logical / cleaner ( in terms of linking order ) to also adopt the change you made in the macro upstream.

HTH,
Petros

1 Like

Thanks Petros for a more proper way to solve this issue.