Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

tl;dr: change the catkin_package() call in the CMakeLists.txt of your kinematics package to the following:

catkin_package(
  INCLUDE_DIRS include
  LIBRARIES kinematics)

Refer to Building and installing C++ libraries and headers in the Catkin documentation for more information about exporting information from Catkin packages.


Longer explanation:

Don't know what is going wrong.

You have this in the motor_driver_pkg:

target_link_libraries(dc_motor_driver kinematics ${catkin_LIBRARIES})

Thing is, CMake assumes that if you provide the name of a library directly (as you do with kinematics) that you're referring to something it calls a target. It takes the name of the target you specify and then tries to look up information about it in its internal data structures.

If the target is defined in the same CMake context, that will work fine. It'll find the information it needs (such as the actual filename and path associated with that target) and then essentially replace the name of the target with whatever information it needs for the particular CMake statement that the target's name is being used in.

In this case that would be the absolute path to the actual file that constitutes the kinematics library (probably something like /path/to/your/catkin_ws/devel/lib/kinematics/libkinematics.so (or something like that, probably different)).

This works completely fine with catkin_make. But fails when I run catkin_make_isolated.

So the issue here is the "CMake context": catkin_make combines all of the CMakeLists.txt it finds in your workspace into one and then begins the build process (it doesn't really do this, but for this explanation we're pretending it does). That creates a single context, in which the target name kinematics actually means something, namely: the target defined in the CMakeLists.txt of your kinematics package. So when CMake encounters the target_link_libraries(dc_motor_driver kinematics ..) it can look up the name kinematics and it'll find the information it needs to make that statement succeed.

With catkin_make_isolated things are completely different: as the isolated in the name implies, catkin_make_isolated does not coalesce all CMakeLists.txt into a single context, but keeps everything .. isolated.

It should now be clear why looking up the target name kinematics fails in this case: kinematics is only a defined target in the context of the CMakeLists.txt of your kinematics package. Nowhere else. So CMake fails to lookup the information it needs with the error message you show as a result.

I understand that the motor_driver_pkg is not able to find the kinematics library

It should also be clear that motor_driver_pkg is not actually looking for anything. It's CMake.


To fix this, we need to make some information available to consuming packages that allows them to find the information (and files) they need.

For Catkin packages that would like to make libraries available to other Catkin packages, that is done by the catkin_package(..) statement, in particular with the LIBRARIES argument followed by a list of library targets of which the information should be exported.

Your kinematics package does have a catkin_package() statement there, but it's completely empty. So Catkin does not export any information from the kinematics package, leading to CMake not being able to do anything when it encounters the kinematics target name in the build script of motor_driver_pkg.

To fix this, change the CMakeLists.txt of kinematics to contain the following call to catkin_package(..):

catkin_package(LIBRARIES kinematics)

(and perhaps even catkin_package(LIBRARIES ${PROJECT_NAME}), as the name of the library is identical to the name of the project).

You'll probably also want to be able to export information about the include directories that are needed to be able to use the headers of kinematics. You'd do that as follows:

catkin_package(
  INCLUDE_DIRS include
  LIBRARIES kinematics)

Now consuming packages can just add kinematics to their find_package(catkin COMPONENTS ..) call and then the catkin_INCLUDE_DIRS and catkin_LIBRARIES will contain all the necessary bits for linking and compiling to succeed.

tl;dr: change the catkin_package() call in the CMakeLists.txt of your kinematics package to the following:

catkin_package(
  INCLUDE_DIRS include
  LIBRARIES kinematics)

Refer to Building and installing C++ libraries and headers in the Catkin documentation for more information about exporting information from Catkin packages.


Longer explanation:

Don't know what is going wrong.

You have this in the motor_driver_pkg:

target_link_libraries(dc_motor_driver kinematics ${catkin_LIBRARIES})

Thing is, CMake assumes that if you provide the name of a library directly (as you do with kinematics) that you're referring to something it calls a target. It takes the name of the target you specify and then tries to look up information about it in its internal data structures.

If the target is defined in the same CMake context, that this will work fine. It'll find the information it needs (such as the actual filename and path associated with that target) and then essentially replace the name of the target with whatever information it needs for is required by the particular CMake statement that the target's name is being used in.

In this case that would be the absolute path to the actual file that constitutes the kinematics library (probably something like /path/to/your/catkin_ws/devel/lib/kinematics/libkinematics.so (or something like that, probably could be different)).

This works completely fine with catkin_make. But fails when I run catkin_make_isolated.

So the issue here is the "CMake context": catkin_make combines all of the CMakeLists.txt it finds in your workspace into one and then begins the build process (it doesn't really do this, but for this explanation we're pretending it does). That creates a single context, in which the target name kinematics actually means something, namely: the target defined in the CMakeLists.txt of your kinematics package. So when CMake encounters the target_link_libraries(dc_motor_driver kinematics ..) it can look up the name kinematics and it'll find the information it needs to make that statement succeed.

With catkin_make_isolated things are completely different: as the isolated in the name implies, catkin_make_isolated does not coalesce all CMakeLists.txt into a single context, but keeps everything .. isolated.

It should now be clear why looking up the target name kinematics fails in this case: kinematics is only a defined target in the context of the CMakeLists.txt of your kinematics package. Nowhere else. So CMake fails to lookup the information it needs with the error message you show as a result.

I understand that the motor_driver_pkg is not able to find the kinematics library

It should also be clear that motor_driver_pkg is not actually looking for anything. It's CMake.


To fix this, we need to make some information available to consuming packages that allows them to find the information (and files) they need.

For Catkin packages that would like to make libraries available to other Catkin packages, that is done by the catkin_package(..) statement, in particular with the LIBRARIES argument followed by a list of library targets of which the information should be exported.

Your kinematics package does have a catkin_package() statement there, but it's completely empty. So Catkin does not export any information from the kinematics package, leading to CMake not being able to do anything when it encounters the kinematics target name in the build script of motor_driver_pkg.

To fix this, change the CMakeLists.txt of kinematics to contain the following call to catkin_package(..):

catkin_package(LIBRARIES kinematics)

(and perhaps even catkin_package(LIBRARIES ${PROJECT_NAME}), as the name of the library is identical to the name of the project).

You'll probably also want to be able to export information about the include directories that are needed to be able to use the headers of kinematics. You'd do that as follows:

catkin_package(
  INCLUDE_DIRS include
  LIBRARIES kinematics)

Now consuming packages can just add kinematics to their find_package(catkin COMPONENTS ..) call and then the catkin_INCLUDE_DIRS and catkin_LIBRARIES will contain all the necessary bits for linking and compiling to succeed.