[CMake] yarp devices and cmake struggle

Pol Monsó IRI pmonso at iri.upc.edu
Thu Sep 10 05:41:23 EDT 2009


Hello all,

Here we are struggling again with cmake and yarp devices. Now we're trying
to break a device I already had into a directory and a subdirectory in order
to provide yarp decoupling with the device class.

So thats my directory structure
yarp-2.2.2/src/modules/wamArm/
|-- CMakeLists.txt
|-- libwamarm.a
|-- sockcmds.c
|-- sockcmds.h
|-- wamDriver
|   |-- CMakeLists.txt
|   |-- cmake_install.cmake
|   |-- constants.h
|   |-- libsockcmds.a
|   |-- libwamdrive.a
|   |-- sockcmds.cpp
|   |-- sockcmds.h
|   |-- wamDriver.cpp
|   |-- wamDriver.h
|   |-- wamDriverTest
|   `-- wamDriverTest.cpp
|-- wamarm.cpp
|-- wamarm.h
`-- wamtest.cpp

And we have three libraries there, wamarm, wamdrive and sockcmds. When
building the wamDriver directory, we create wamdrive and sockcmds libraries
and link them, as wamdrive uses sockcmds. Later, when building the wamArm
directory wamarm library is created and linked to wamdrive. Finally, we'll
be building the yarp devices which include the wamArm directory with the
ADD_SUBDIRECTORY(wamArm) statement.

Here are my CMakeLists

In the wamArm/ directory

> PROJECT(wamArm)
> cmake_minimum_required(VERSION 2.4)
> FIND_PACKAGE(YARP REQUIRED)
>
> IF (COMPILE_DEVICE_LIBRARY)
>   PREPARE_DEVICE(wamArm TYPE Wamarm INCLUDE wamarm.h WRAPPER controlboard)
> ENDIF (COMPILE_DEVICE_LIBRARY)
>

>
ADD_SUBDIRECTORY(wamDriver)
> INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/wamDriver)
> LINK_DIRECTORIES(wamDriver)
>
> ADD_LIBRARY(wamarm wamarm.h wamarm.cpp)
> LINK_LIBRARIES(wamarm wamdrive)
> LINK_LIBRARIES(wamarm sockcmds)
>

>
IF (NOT COMPILE_DEVICE_LIBRARY)
>   ADD_EXECUTABLE(wamtest wamtest.cpp)
>   TARGET_LINK_LIBRARIES(wamtest wamarm)
> ENDIF (NOT COMPILE_DEVICE_LIBRARY)
>
>
in the wamArm/wamDriver/ directory

PROJECT(wamArm)
>
> cmake_minimum_required(VERSION 2.4)
>
>   #build a shared library
>   ADD_LIBRARY(sockcmds sockcmds.cpp sockcmds.h)
>   ADD_LIBRARY(wamdrive wamDriver.cpp wamDriver.h)
>   LINK_LIBRARIES(wamdrive sockcmds)
>
> IF (NOT COMPILE_DEVICE_LIBRARY)
>   ADD_EXECUTABLE(wamDriverTest wamDriverTest.cpp)
>   TARGET_LINK_LIBRARIES(wamDriverTest wamdrive)
>   TARGET_LINK_LIBRARIES(wamDriverTest sockcmds)
> ENDIF (NOT COMPILE_DEVICE_LIBRARY)
>

The output of building both wamArm and wamDriver goes fine.

> pmonso at delucia:~/YARP/yarp-2.2.2/src/modules/wamArm/wamDriver$ make
> Scanning dependencies of target sockcmds
> [ 33%] Building CXX object CMakeFiles/sockcmds.dir/sockcmds.o
> Linking CXX static library libsockcmds.a
> [ 33%] Built target sockcmds
> Scanning dependencies of target wamdrive
> [ 66%] Building CXX object CMakeFiles/wamdrive.dir/wamDriver.o
> Linking CXX static library libwamdrive.a
> [ 66%] Built target wamdrive
> Scanning dependencies of target wamDriverTest
> [100%] Building CXX object CMakeFiles/wamDriverTest.dir/wamDriverTest.o
> Linking CXX executable wamDriverTest
> [100%] Built target wamDriverTest
>

pmonso at delucia:~/YARP/yarp-2.2.2/src/modules/wamArm$ make
> [ 20%] Built target wamarm
> [ 40%] Built target wamdrive
> Scanning dependencies of target sockcmds
> [ 60%] Building CXX object wamDriver/CMakeFiles/sockcmds.dir/sockcmds.o
> Linking CXX static library libsockcmds.a
> [ 60%] Built target sockcmds
> Scanning dependencies of target wamtest
> Linking CXX executable wamtest
> [ 80%] Built target wamtest
> Scanning dependencies of target wamDriverTest
> [100%] Building CXX object
> wamDriver/CMakeFiles/wamDriverTest.dir/wamDriverTest.o
> Linking CXX executable wamDriverTest
> [100%] Built target wamDriverTest
>

While building the device

> pmonso at delucia:~/YARP/yarp-2.2.2/src/modules$ make
> [ 80%] Built target yarpmod
> Linking CXX executable yarpmoddev
> libyarpmod.a(add_yarpmod_devices.o): In function `add_yarpmod_devices':
> add_yarpmod_devices.cpp:(.text+0x1c): undefined reference to `add_wamArm()'
> collect2: ld returned 1 exit status
> make[2]: *** [yarpmoddev] Error 1
> make[1]: *** [CMakeFiles/yarpmoddev.dir/all] Error 2
> make: *** [all] Error 2
>

Two questions arise there, why do I have to link sockcmds with wamdrive if
we already do that on the wamDriver subdirectory? Shouldn't they be linked
as were descending upon the directory structure?

and, more important, what am I missing? I'm quite new on cmake and I find it
hard to understand how is it dealing with libraries and linking.

Also, there are two more issues that I avoided as I could. Originally, the
sockcmds is in C not in C++ but I had trouble building it although I had
marked the prototypes as extern C, there were undefined references when we
were linking. And second, as wamarm class is just a wrapper for the actual
driver, there wasn't any much code so no .cpp file was needed. However,
cmake would not know what compiler to use as it couldn't guess from the
extension. The SET_TARGET_PROPERTIES(wamarm PROPERTIES LINKER_LANGUAGE CXX)
statement worked when compiling the wamArm directory, but failed when
compiling the library on the yarp devices directory.

Anyhow, I'm more concerned on the first issue there, although I don't really
know if it's a cmake issue, a yarp issue or both. Any kind of help would be
highly appreciated as well as some guidelines on the proper way to do that.

Thanks for your wisdom,

Pol Monsó
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.cmake.org/pipermail/cmake/attachments/20090910/a8770ff4/attachment-0001.htm>


More information about the CMake mailing list