[CMake] linking libraries at many levels
Michael Wild
themiwi at gmail.com
Tue Aug 25 09:27:10 EDT 2009
On 25. Aug, 2009, at 15:06, Pol Monsó IRI wrote:
> Hello cmake users!
>
> I'm quite new to cmake as well as makefiles, and i've bumped the same
> trouble twice. I'm trying to break a source code into several
> libraries and
> a main program. The scenario has one main executable called
> calClient which
> uses functions from three libraries, let's say 1A 1B and 2C.
> Everybody uses
> library 2C, that is calClient, 1A and 1B. I've stored the source
> codes of 1A
> 1C and 2C in a subdirectory called lib/ toghether with a
> CMakeLists.txt :
>
> FIND_PACKAGE(YARP REQUIRED)
>>
>> SET(PROJECT_LIBS
>> 2C.cpp
>> 2C.h
>> 1B.cpp
>> 1B.h
>> 1A.cpp
>> 1A.hpp
>> )
>>
>> add_library(callibs ${PROJECT_LIBS})
>
>
> In the upper directory, toghether with the source code of the main
> program,
> I have:
>
> project(calibration)
>>
>> cmake_minimum_required(VERSION 2.6)
>>
>> set(CMAKE_CXX_FLAGS "-g -Wall")
DON'T EVER do something like this unless you really know what you're
doing. The proper way of doing this is to use the Debug configuration
at configure-time:
cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS=-Wall /path/to/source
>>
>> set(PROJECT_SRC
>> calClient.cpp
>> calClient.hpp
>> chaser.cpp
>> chaser.hpp
>> )
>>
>> FIND_PACKAGE(YARP REQUIRED)
>> FIND_PACKAGE(OpenCV REQUIRED)
>>
>> add_subdirectory(lib)
>>
>> INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/lib)
>> link_directories(lib)
>>
>> INCLUDE_DIRECTORIES(${OPENCV_INCLUDE_DIR})
>>
>> ADD_EXECUTABLE(calClient ${PROJECT_SRC})
>> TARGET_LINK_LIBRARIES( calClient ${OPENCV_LIBRARIES} )
>> TARGET_LINK_LIBRARIES( calClient callibs )
This should be:
TARGET_LINK_LIBRARIES( calClient
${OPENCV_LIBRARIES}
callibs
)
>
> Every header includes the headers of the files which contains the
> functions
> that it needs. So, calClient.hpp actually includes 1A, 1B and 2C.
>
> The output of the make command is then:
>
>> [ 60%] Built target callibs
>> Linking CXX executable calClient
>> CMakeFiles/calClient.dir/calClient.cpp.o: In function
>> `incrementalCalibrate(yarp::dev::IPositionControl*,
>> yarp::dev::IEncoders*)':
>> /home/pmonso/YARP/Calclient/calClient.cpp:276: undefined reference to
>> `print_double_array(double const*, int)'
>> /home/pmonso/YARP/Calclient/calClient.cpp:277: undefined reference to
>> `print_double_array(double const*, int)'
>> /home/pmonso/YARP/Calclient/calClient.cpp:295: undefined reference to
>> `print_double_array(double const*, int)'
>> CMakeFiles/calClient.dir/calClient.cpp.o: In function
>> `calibrate(yarp::dev::IPositionControl*, yarp::dev::IEncoders*)':
>> /home/pmonso/YARP/Calclient/calClient.cpp:155: undefined reference to
>> `print_double_array(double const*, int)'
>> CMakeFiles/calClient.dir/calClient.cpp.o: In function
>> `randomCalibrate(yarp::dev::IPositionControl*,
>> yarp::dev::IEncoders*)':
>> /home/pmonso/YARP/Calclient/calClient.cpp:207: undefined reference to
>> `print_double_array(double const*, int)'
>> CMakeFiles/calClient.dir/calClient.cpp.o:/home/pmonso/YARP/
>> Calclient/calClient.cpp:208:
>> more undefined references to `print_double_array(double const*,
>> int)' follow
>> collect2: ld returned 1 exit status
>> make[2]: *** [calClient] Error 1
>> make[1]: *** [CMakeFiles/calClient.dir/all] Error 2
>> make: *** [all] Error 2
>>
>
In order for this output to be useful, we'd need to see the link-line,
which you can get by invoking
make VERBOSE=1
>
> The function print_double_array is located in the 2C source and
> header files
> which, as I said, is included in calClient header as well as in
> headers of
> 1A and 1B.
>
> Does somebody know why linking fails? What I am doing wrong? It's
> driving me
> nuts!
It's probably that you invoke TARGET_LINK_LIBRARIES twice on the same
target, as pointed out above.
>
> Thanks alot for your help!
>
> pol
>
HTH
Michael
More information about the CMake
mailing list