Skip to content

Instantly share code, notes, and snippets.

@johngroves
Forked from plusk01/ros-kinetic-macosx.md
Created September 15, 2017 04:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save johngroves/948a3f844245314334f8bffffe6cebe9 to your computer and use it in GitHub Desktop.
Save johngroves/948a3f844245314334f8bffffe6cebe9 to your computer and use it in GitHub Desktop.
Installing ROS Kinetic on Mac OS X El Capitan (10.11.6) and macOS Sierra

Installing ROS Kinetic on Mac OS X - El Capitan and macOS Sierra

Having rather painlessly installed ROS Indigo on El Capitan using Mike Purvis's script, I attempted to upgrade to ROS Kinetic. This gist outlines the problems I encoutered and how I solved them. Hopefully this guide will help others attempting to install ROS Kinetic / Gazebo 7 on El Capitan.

ROS Install OSX

Start with Mike Purvis's script, which currently is setup to install ROS Indigo. In order to install Kinetic instead of Indigo, make sure to set the ROS_DISTRO environment variable: export ROS_DISTRO=kinetic.

After you get through rosdep errors, it's quickest to just work with the catkin config ... and catkin build ... commands directly. In fact, I found it most helpful to leave my catkin workspace terminal open at ros-install-osx/kinetic_desktop_full_ws and then opening a new terminal to go try and fix errors in different files, etc. Once I finished editing and was ready to test, I would go back to my catkin workspace terminal and just run the catkin build --limit-status-rate 1 command, which comes from the install script.

rosdep and qt5

Because homebrew installs qt5 as keg-only (because qt4 is more common), rosdep has trouble verifying that qt5 is actually installed. In fact, the script will spit out that homebrew has already installed qt5, followed by rosdep saying something like: Failed to detect successful installation of [qt5]. If you know that qt5 is installed properly on your machine (homebrew says it is), then add qt5 related packages to the --skipkeys flag:

$ rosdep install --from-paths src --ignore-src --rosdistro ${ROS_DISTRO} -y --as-root pip:yes --skip-keys "libqt5-core libqt5-gui libqt5-opengl libqt5-opengl-dev libqt5-widgets qt5-qmake qtbase5-dev  python-qt5-bindings python-qt5-bindings-gl python-qt5-bindings-webkit"

(Also, note that I have --as-root pip:yes because my pip needs sudo for some reason...)

(Also, see the gazebo section below for resolving gazebo problems).

qt_gui_cpp

Had to change LIBS= ... -lQtCore and friends to LIBS= ... -L/usr/local/lib/QtPrintSupport.framework/QtPrintSupport. Note the capital L. The Official Unofficial Installation Guide talks about this. (QtCoremod.sip: fix with: ln -s /usr/local/share/sip/Qt5 /usr/local/share/sip/PyQt5)

Note Turns out that this error went away because big L links to a directory, not a library. Therefore, you might as well and just comment out the last few -lQtCore etc.

geometric_shapes / Eigen3Config.cmake

Followed Installing ROS Kinetic on Slackware 14.1 section on 'geometric_shapes':

In ros-install-osx/kinetic_desktop_full_ws/src/geometric_shapes/CMakeLists.txt, replace:

find_package(Eigen3 REQUIRED)

with:

find_package( PkgConfig )
pkg_check_modules( EIGEN3 REQUIRED eigen3 )
include_directories( ${EIGEN3_INCLUDE_DIRS} )

cv_bridge

If you get an undefined symbols error about cv::_InputArray:

Undefined symbols for architecture x86_64:
  "cv::_InputArray::_InputArray(cv::Mat const&)", referenced from:
      cv_bridge::toCvCopyImpl(cv::Mat const&, std_msgs::Header_<std::__1::allocator<void> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in cv_bridge.cpp.o
      cv_bridge::matFromImage(sensor_msgs::CompressedImage_<std::__1::allocator<void> > const&) in cv_bridge.cpp.o
      cv_bridge::CvImage::toCompressedImageMsg(sensor_msgs::CompressedImage_<std::__1::allocator<void> >&, cv_bridge::Format) const in cv_bridge.cpp.o
      cv_bridge::cvtColorForDisplay(boost::shared_ptr<cv_bridge::CvImage const> const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, cv_bridge::CvtColorForDisplayOptions) in cv_bridge.cpp.o
  "cv::_InputArray::_InputArray(std::__1::vector<cv::Mat, std::__1::allocator<cv::Mat> > const&)", referenced from:
      cv_bridge::matFromImage(sensor_msgs::Image_<std::__1::allocator<void> > const&) in cv_bridge.cpp.o
  "cv::_InputArray::_InputArray(double const&)", referenced from:
      cv_bridge::cvtColorForDisplay(boost::shared_ptr<cv_bridge::CvImage const> const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, cv_bridge::CvtColorForDisplayOptions) in cv_bridge.cpp.o
  "cv::mixChannels(cv::_InputArray const&, cv::_InputArray const&, std::__1::vector<int, std::__1::allocator<int> > const&)", referenced from:
      cv_bridge::matFromImage(sensor_msgs::Image_<std::__1::allocator<void> > const&) in cv_bridge.cpp.o
  "cv::_OutputArray::_OutputArray(cv::Mat&)", referenced from:
      cv_bridge::toCvCopyImpl(cv::Mat const&, std_msgs::Header_<std::__1::allocator<void> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in cv_bridge.cpp.o
      cv_bridge::cvtColorForDisplay(boost::shared_ptr<cv_bridge::CvImage const> const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, cv_bridge::CvtColorForDisplayOptions) in cv_bridge.cpp.o
  "cv::imencode(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, cv::_InputArray const&, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&, std::__1::vector<int, std::__1::allocator<int> > const&)", referenced from:
      cv_bridge::CvImage::toCompressedImageMsg(sensor_msgs::CompressedImage_<std::__1::allocator<void> >&, cv_bridge::Format) const in cv_bridge.cpp.o
  "vtable for cv::_InputArray", referenced from:
      cv_bridge::cvtColorForDisplay(boost::shared_ptr<cv_bridge::CvImage const> const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, cv_bridge::CvtColorForDisplayOptions) in cv_bridge.cpp.o
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [/Users/plusk01/Downloads/ros-install-osx/kinetic_desktop_full_ws/devel/.private/cv_bridge/lib/libcv_bridge.dylib] Error 1
make[1]: *** [src/CMakeFiles/cv_bridge.dir/all] Error 2
make: *** [all] Error 2
cd /Users/plusk01/Downloads/ros-install-osx/kinetic_desktop_full_ws/build/cv_bridge; catkin build --get-env cv_bridge | catkin env -si  /usr/bin/make --jobserver-fds=6,7 -j; cd -
...............................................................................................................................................................................................................................................................................
Failed     << cv_bridge:make                                  [ Exited with code 2 ]  

You need to add a header to the cv_bridge.cpp file. Edit ros-install-osx/kinetic_desktop_full_ws/src/vision_opencv/cv_bridge/src/cv_bridge.cpp and place #include <opencv2/opencv.hpp> after all the other includes in the file.

(I also did brew uninstall opencv and brew install opencv3 --with-contrib, though I don't doing that is actually part of the solution.)

pcl_ros

Another Eigen3Config.cmake error. Like geometric_shapes above, we need to edit the CMakeLists.txt and use pkg-config instead of find_package():

Edit ros-install-osx/kinetic_desktop_full_ws/src/perception_pcl/pcl_ros/CMakeLists.txt, replace:

find_package(Eigen3 REQUIRED)

with:

find_package( PkgConfig )
pkg_check_modules( EIGEN3 REQUIRED eigen3 )
include_directories( ${EIGEN3_INCLUDE_DIRS} )

Of course, having done this I get the following warning for pcl_ros, but it seems to build okay...

CMake Warning at /opt/ros/kinetic/share/catkin/cmake/catkin_package.cmake:166 (message):
  catkin_package() DEPENDS on 'Eigen3' but neither 'Eigen3_INCLUDE_DIRS' nor
  'Eigen3_LIBRARIES' is defined.

(In fact, I saw similar warnings to this all over the place, even in packages that I didn't touch...)

gazebo

When running the rosdep install command, a rosdep yaml is consulted that contains the a lookup for how to install the dependencies for a given package. The OS X Homebrew yaml shows the packages we are interested, here.

When I ran the rosdep intsall command, I got an error when installing gazebo complaining about missing Qt4. Well, I'm pretty sure most of ROS and the world has moved on to Qt5, but after some investigation, I found that the above rosdep yaml tells your computer to brew install gazebo, which seems to install gazebo version 1. For Kinetic, we at least want version 7. So I manually ran brew install gazebo7 and then added gazebo to the --skip-keys switch on rosdep install command:

$ rosdep install --from-paths src --ignore-src --rosdistro kinetic -y --skip-keys "libqt5-core libqt5-gui libqt5-opengl libqt5-opengl-dev libqt5-widgets qt5-qmake qtbase5-dev python-qt5-bindings python-qt5-bindings-gl python-qt5-bindings-webkit gazebo"

rviz

During making rviz, it fails it spits out a wall of warnings, with no errors that can be seen other than make: *** [all] Error 2. By going to the path that is shown at the bottom of this error, we can get a better idea of the actual error:

cd /Users/plusk01/Downloads/ros-install-osx/kinetic_desktop_full_ws/build/rviz

Once here, run make. We see there is a linker error: ld: library not found for -lQtCore. This is similar to before with qt_gui_cpp above. There is probably a better way to solve this, but my solution was to just comment out the lQtCore and friends from the LIBS make variable. To find where this is, I ran find . -type f -exec grep --color=auto -H -- 'Compiling generated code for rviz_sip Python bindings...' {} + to show me the files that have this string in it, since this was the last make command before the linker error. After finding the file (src/python_bindings/sip/CMakeFiles/librviz_sip.dir/build.make), I open it and look for the location where that text is found. The command just after the text is:

cd /Users/plusk01/Downloads/ros-install-osx/kinetic_desktop_full_ws/devel/.private/rviz/bin/sip/rviz_sip && make

So I go to that directory and find a Makefile. I edit the Makefile and comment out -lQtCore and friends:

LIBS = -L/Users/plusk01/Downloads/ros-install-osx/kinetic_desktop_full_ws/devel/.private/rviz/lib -L/usr/local/Cellar/qt5/5.6.1-1/lib -lrviz # -lQtCore -lQtGui -lQtWidgets -lQtPrintSupport

Going back to my terminal where I try and build everything, I type catkin build --limit-status-rate 1 to try to build again.

After a Successful Build and Installation

After solving all the linker, cmake, and compiler errors I get a successful build! I then go back to Mike Purvis's install script and see if there is anything that needs to be ran after the catkin build --limit-status-rate 1 command. The only thing left to do is to source /opt/ros/kinetic/setup.bash so that I can start running ROS. To test, I run roslaunch gazebo_ros mud_world.launch. It works!

Resources


Miscellaneous

  catkin config --install  --install-space ${ROS_INSTALL_DIR} --cmake-args \
    -DCATKIN_ENABLE_TESTING=1 \
    -DCMAKE_BUILD_TYPE=Release \
    -DPYTHON_LIBRARY=$(python -c "import sys; print sys.prefix")/lib/libpython2.7.dylib \
    -DPYTHON_INCLUDE_DIR=$(python -c "import sys; print sys.prefix")/include/python2.7 \
    -DCMAKE_MODULE_PATH=/usr/local/share/cmake/Modules/
vi /opt/ros/kinetic/share/python_qt_binding/cmake/sip_configure.py
/usr/local/Cellar/sip/4.18.1/bin/sip -c ~/Downloads/ros-install-osx/kinetic_desktop_full_ws/build/qt_gui_cpp/sip/qt_gui_cpp_sip -b ~/Downloads/ros-install-osx/kinetic_desktop_full_ws/build/qt_gui_cpp/sip/qt_gui_cpp_sip/pyqtscripting.sbf -I /usr/local/share/sip/PyQt5 -w -x VendorID -t WS_MACX -t Qt_5_6_1 -x Py_v3 qt_gui_cpp.sip

pkg-config --exists eigen3

/Users/plusk01/Downloads/ros-install-osx/kinetic_desktop_full_ws/build/qt_gui_cpp/sip/qt_gui_cpp_sip - the path to a Makefile where I changed qt to qt5

relink qt4: /usr/local/lib

LDFLAGS=-L/usr/local/opt/qt5/lib CMAKE_MODULE_PATH=/usr/local/share/cmake/Modules/FindEigen3.cmake CPPFLAGS=-I/usr/local/opt/qt5/include CMAKE_PREFIX_PATH=/usr/local/opt/qt5/lib/cmake/:/usr/local/share/cmake/ LD_LIBRARY_PATH=:/usr/local/opt/qt5/lib CXXFLAGS=-I/usr/local/opt/qt5/include

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment