0
$\begingroup$

Rosanswers logo

When I ran my catkin_make, I understand that it should automatically copy the header files (in this case mosquitto.h) which I included in the main cpp file into devel/include and create an executable, however, it is not doing so. devel/include doesn't even exist in my catkin_ws. My header file is in catkin_ws/src/package_name/include/package_name

Error:

Linking CXX executable /home/catkin_ws/devel/lib/mqtt_pub/mqtt_pub_node
/usr/bin/ld: cannot find -lmosquitto.h
collect2: error: ld returned 1 exit status
make[2]: *** [/home/catkin_ws/devel/lib/mqtt_pub/mqtt_pub_node] Error 1
make[1]: *** [mqtt_pub/CMakeFiles/mqtt_pub_node.dir/all] Error 2
make: *** [all] Error 2
Invoking "make -j1 -l1" failed

Note that mqtt_pub_node doesn't exist. Why is it looking for something that doesn't exist? It should be automatically created. From what I know, the executable should be in devel/lib/mqtt_pub, not sure where did the system think about devel/lib/mqtt_pub/mqtt_pub_node. If I create the devel/lib/mqtt_pub/mqtt_pub_node and put my header file in it, the catkin_make is successful, but the executable would not be created.

CMakeList.txt

find_package(catkin REQUIRED COMPONENTS
roscpp
std_msgs
)

catkin_package(
INCLUDE_DIRS include
LIBRARIES mqtt_pub
CATKIN_DEPENDS roscpp std_msgs
DEPENDS system_lib
)

include_directories(
${catkin_INCLUDE_DIRS}
/catkin_ws/src/mqtt_pub/include/mqtt_pub
include
)

link_directories(
/catkin_ws/src/mqtt_pub/include/mqtt_pub
)

link_libraries(
mosquitto.h
)

add_executable(mqtt_pub_node src/mqtt_publish.cpp)
target_link_libraries(mqtt_pub_node ${catkin_LIBRARIES})

package.xml

<buildtool_depend>catkin</buildtool_depend>
<build_depend>roscpp</build_depend>
<build_depend>std_msgs</build_depend>
<run_depend>roscpp</run_depend>
<run_depend>std_msgs</run_depend>

Would appreciate the guidance in solving this issue. I'm really clueless about the error, have research online and my cmake and xml file seems to be alright. Errors in my maincpp file have been rectified. Thanks!


Originally posted by cechster on ROS Answers with karma: 3 on 2016-12-22

Post score: 0

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

First: this is not a ROS problem per se, but really a matter of using CMake correctly.

I understand that it should automatically copy the header files [..] which I included in the main cpp file into devel/include

No, that is not the case: header files will not be copied to the devel space by catkin (unless they are auto-generated, or there are statements in the CMakeLists.txt that do that). It's also not necessary: the dependents include path will automatically include the correct paths (in the src space) if the providing package properly exports those include locations.

Error:

Linking CXX executable /home/catkin_ws/devel/lib/mqtt_pub/mqtt_pub_node
/usr/bin/ld: cannot find -lmosquitto.h
collect2: error: ld returned 1 exit status
[..]

Note that mqtt_pub_node doesn't exist. Why is it looking for something that doesn't exist? It should be automatically created.

yes, it should, but only if linking actually succeeded. Which it didn't.

From what I know, the executable should be in devel/lib/mqtt_pub, not sure where did the system think about devel/lib/mqtt_pub/mqtt_pub_node [..].

the error message you refer to simply states that while linking a binary called mqtt_pub_node (which will be placed in devel/lib/mqtt_pub if linking is successful), no library called mosquitto.h could be found. In your CMakeLists.txt, you defined the name of the binary as mqtt_pub_node with the add_executable(mqtt_pub_node ..) line.

catkin_package(
INCLUDE_DIRS include
LIBRARIES mqtt_pub
CATKIN_DEPENDS roscpp std_msgs
DEPENDS system_lib
)
include_directories(
  ${catkin_INCLUDE_DIRS}
  /catkin_ws/src/mqtt_pub/include/mqtt_pub
  include
)
link_directories(
  /catkin_ws/src/mqtt_pub/include/mqtt_pub
)
link_libraries(
mosquitto.h
)
add_executable(mqtt_pub_node src/mqtt_publish.cpp)
target_link_libraries(mqtt_pub_node ${catkin_LIBRARIES})

Multiple things are not as they should be here:

  1. mosquitto.h is not a library (obviously), it's a header. In your CMakeLists.txt you are asking CMake to link_libraries(..) against that header. That will obviously not work, resulting in the error that you are seeing. Note that this will never work, not even if search paths were setup correctly

  2. location of your workspace is slghtly unorthodox (directly under /home). That is definitely legal, but perhaps placing it in your user's home directory (ie: /home/$USER) would be better

  3. I doubt your catkin workspace is located at /catkin_ws, as that would be in the root of your file system. From the error messages, it should be at least /home/catkin_ws, but see my previous comment

  4. it's typically recommended to place your package's include directories before anything else, as that allows you to provide files that override system includes

  5. the use of link_directories(..) is typically not recommended with CMake. Prefer to use absolute paths to libraries, as that will avoid surprises if anyone ever overrides your linker's search path

  6. your catkin_package(..) invocation states that your package depends on something called system_lib. That is probably not correct

  7. in the same catkin_package(..) invocation a LIBRARY called mqtt_pub is exported, but that library is not build by your CMakeLists.txt (or at least, not in the snippet that you included)

  8. nowhere do you (or CMake) search for anything MQTT related, neither is that dependency made explicit anywhere. Assuming that headers and / or libraries exist on a system is not very robust (they may not exist, have different names or may not be installed): always try to search for what your program needs

  9. link_libraries(..) is also not recommended. In general it's better to be as precise and explicit about dependencies as possible, so the per target version target_link_libraries(..) is preferred

Would appreciate the guidance in solving this issue. I'm really clueless about the error, have research online and my cmake and xml file seems to be alright.

Suggestion for a correct CMakeLists.txt:

cmake_minimum_required(VERSION 2.8.3)

project(mqtt_pub)

find_package(catkin REQUIRED COMPONENTS
  roscpp
  std_msgs
)

# make sure we have Mosquitto on our system somewhere, our project
# depends on it.
#
# Note: this requires a 'FindMosquitto.cmake' file to be present
# on the CMake module search path. An example of such a file can be
# found at https://github.com/tarantool/mqtt/blob/master/cmake/FindMosquitto.cmake
find_package(Mosquitto REQUIRED)

catkin_package(
  INCLUDE_DIRS include
  CATKIN_DEPENDS roscpp std_msgs
)

include_directories(
  include
  ${MOSQUITTO_INCLUDE_DIR}
  ${catkin_INCLUDE_DIRS}
)

add_executable(mqtt_pub_node src/mqtt_publish.cpp)
target_link_libraries(mqtt_pub_node ${catkin_LIBRARIES} ${MOSQUITTO_LIBRARIES})

# add install(..) if necessary

Note that this assumes that Mosquitto has been installed somewhere on the system, or at least in a location that CMake / FindMosquitto.cmake knows about / can find. Refer to the CMake documentation for how to configure that.

Finally: unfortunately there doesn't seem to be a rosdep rule for Mosquitto yet, so you can't add that build and run dependency to your package.xml. If you'd like to do that (instead of blindly assuming that Mosquitto is installed on the system your package is/gets built on), then you'd have to contribute such a rule and then add the appropriate bits to your package manifest.


Originally posted by gvdhoorn with karma: 86574 on 2016-12-22

This answer was ACCEPTED on the original site

Post score: 1


Original comments

Comment by cechster on 2016-12-22:
Thank you for your prompt reply! Will try out your suggestions.

Regarding point 2 & 3, opps sorry, I accidentally missed out when typing out the $User. Yes my catkin_ws is in home/$user/catkin_ws

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.