[CMake] CMake Linking Error

Michael Hertling mhertling at online.de
Mon Mar 12 21:48:21 EDT 2012


On 03/08/2012 05:40 PM, buzz clay wrote:
> Hi,
> 
> I have not been able to find the answer to my current problem so I thought
> I'd try a new post. Before diving into the details, please be aware that
> the code I am writing compiles/runs perfectly with a personal Makefile I
> wrote.
> 
> My code is written in C++ and has many different class definitions. To run
> different simulations some classes may or may not have actual objects
> created. However, there are other portions of the code that specifically
> reference functions from nearly all classes (although this code might not
> actually be used because the object was never created). The linking errors
> that I am facing arise when I do not make an object of a given class. Other
> parts of the code need to be aware that the class exists, even if an object
> was never made. Although this seems like it would be a result of not
> including the appropriate header files, I assure you they are correct! For
> some reason, if I do not make an object of a given class cmake "ignores"
> the class and when it comes time to link everything together I get the
> following error:
> 
> Linking CXX executable collision
> Output/libOutput.a(Output.cpp.o): In function
> `Output::Output(std::vector<Ball*, std::allocator<Ball*> >*,
> std::vector<CollisionObject*, std::allocator<CollisionObject*> >*)':
> Output.cpp:(.text+0x379): undefined reference to `SWall::getY2()'
> Output.cpp:(.text+0x391): undefined reference to `SWall::getX2()'
> Output.cpp:(.text+0x3a9): undefined reference to `SWall::getY1()'
> Output.cpp:(.text+0x3c1): undefined reference to `SWall::getX1()'
> collect2: ld returned 1 exit status
> make[2]: *** [collision] Error 1
> make[1]: *** [CMakeFiles/collision.dir/all] Error 2
> make: *** [all] Error 2
> 
> PLEASE NOTE: If in my main.cpp file I simply create an SWall object and
> never use it, the errors go away and everything works perfectly. I simply
> do not understand why cmake would care whether or not I actually make an
> object of a given class!
> 
> The following is my CMakeLists.txt file in the highest level directory:
> 
> cmake_minimum_required(VERSION 2.8)
> 
> project(collision CXX)
> 
> add_subdirectory(Extraneous)
> add_subdirectory(Output)
> add_subdirectory(Simulation)
> add_subdirectory(CollisionObject)
> 
> add_definitions(-ansi -Wall -O2)
> 
> add_executable(collision test.cpp)
> 
> target_link_libraries(collision Simulation)
> target_link_libraries(collision PriorityQueue)
> target_link_libraries(collision Event)
> target_link_libraries(collision Ball)
> target_link_libraries(collision SWall)
> target_link_libraries(collision Circle)
> target_link_libraries(collision Output)
> target_link_libraries(collision SimpleMath)
> 
> INSTALL(PROGRAMS ${CMAKE_BINARY_DIR}/collision DESTINATION
> ${CMAKE_SOURCE_DIR})
> 
> All of the lower level directories simply had add_library(<libname>
> <libname.cpp>) in the CMakeLists.txt file. [...]

I.e., they don't have TARGET_LINK_LIBRARIES() commands? If so, CMake
can't know that "Output" must be linked against "SWall", and in your
final link command line, the former appears behind the latter --> un-
defined references. Express all your targets' immediate dependencies
via TARGET_LINK_LIBRARIES(), and drop the mediate ones if there are
any; CMake figures them out by itself.

Regards,

Michael


More information about the CMake mailing list