ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
1

colcon not adding Python module built with cmake to PYTHONPATH

asked 2022-01-18 16:07:49 -0600

johnw gravatar image

updated 2022-01-20 12:00:46 -0600

My package is building a Python module using SWIG and cmake. It is a pure cmake package, using the <build_type>cmake</build_type> tag in package.xml. The build succeeds, and the PATH and CMAKE_PREFIX_PATH are updated, but PYTHONPATH is not. I can see the Python package installed to install/<package_dir>/lib/python3/dist-packages, so I know the Python package is being installed properly. --merge-install also correctly installs the package but does not update PYTHONPATH. The same package works properly with catkin_make_isolated.

Why is colcon not finding the Python package?

colcon-core version 0.7.1 colcon-cmake version 0.2.26

edit retag flag offensive close merge delete

Comments

Hi @johnw Just an observation the question’s title doesn’t connect well with the tags and actual question. This may limit the number of people that review the question

osilva gravatar image osilva  ( 2022-01-19 05:38:41 -0600 )edit
1

@osilva apparently the title got borked, I've fixed it.

johnw gravatar image johnw  ( 2022-01-20 12:00:25 -0600 )edit

that makes so much sense @johnw. Thank you for updating.

osilva gravatar image osilva  ( 2022-01-20 12:08:47 -0600 )edit

2 Answers

Sort by » oldest newest most voted
1

answered 2022-05-31 11:21:28 -0600

johnw gravatar image

updated 2022-06-02 14:53:43 -0600

jayess gravatar image

It turns out we had already solved this problem in a different project. See https://github.com/tesseract-robotics... for an example.

The solution is to use colcon hooks to update PYTHONPATH.

First, add the following to CMakeLists.txt:

file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/share/ament_index/resource_index/packages/${PROJECT_NAME} "")
  install(FILES ${CMAKE_CURRENT_BINARY_DIR}/share/ament_index/resource_index/packages/${PROJECT_NAME} DESTINATION share/ament_index/resource_index/packages)
  file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/share/${PROJECT_NAME}/hook/ament_prefix_path.dsv "prepend-non-duplicate;AMENT_PREFIX_PATH;")
  install(FILES ${CMAKE_CURRENT_BINARY_DIR}/share/${PROJECT_NAME}/hook/ament_prefix_path.dsv DESTINATION share/${PROJECT_NAME}/hook)

if (${PYTHON_VERSION_MAJOR} LESS 3)
  file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/share/${PROJECT_NAME}/hook/python_path.dsv "prepend-non-duplicate;PYTHONPATH;lib/python2.7/dist-packages")
  install(FILES ${CMAKE_CURRENT_BINARY_DIR}/share/${PROJECT_NAME}/hook/python_path.dsv DESTINATION share/${PROJECT_NAME}/hook)
else()
  file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/share/${PROJECT_NAME}/hook/python_path.dsv "prepend-non-duplicate;PYTHONPATH;lib/python3/dist-packages")
  install(FILES ${CMAKE_CURRENT_BINARY_DIR}/share/${PROJECT_NAME}/hook/python_path.dsv DESTINATION share/${PROJECT_NAME}/hook)
endif()

This assumes that PROJECT_NAMEexactly matches the ROS package name. See https://github.com/tesseract-robotics... for an example.

Then create a colcon.pkg file with the following contents, replacing <PROJECT_NAME> with the name of the package. It must match the CMakeLists PROJECT_NAME exactly.

{
    "hooks": ["share/<PROJECT_NAME>/hook/ament_prefix_path.dsv", "share/<PROJECT_NAME>/hook/python_path.dsv"]
}

Once the hook is created, the PYTHONPATH should be updated when the colcon setup scripts are sourced.

edit flag offensive delete link more
0

answered 2022-04-01 16:41:23 -0600

agoins gravatar image

I had the same issue but I was using pybind11 to make my python wrapper. The problem is that the PYTHONPATH is updated by addition bash files in each package (located in the share/<package>/hooks folder), which get built if you depend on ament_python. However, if you are using CMake, you can't have two build types ament_cmake and ament_python, which means the PYTHONPATH isn't sourced properly. I found this tutorial helpful for building a dual CMake and Python package. There are two additional things you will have to do:

  1. Make sure to install the python wrapper in the correct directory. The default path for ROS2 is install/<package>/lib/python3.8/site-packages as opposed to the old python3/dist-packages
  2. Make sure that your exported wrapper is not the same name as your package name. I had a problem importing my wrapper when they were named the same, but once I changed my wrapper name, everything imported fine in Python.
edit flag offensive delete link more

Comments

Thanks for the interesting solution. We took a slightly different approach, please see my answer.

johnw gravatar image johnw  ( 2022-05-31 11:23:08 -0600 )edit

Question Tools

2 followers

Stats

Asked: 2022-01-18 16:07:49 -0600

Seen: 1,423 times

Last updated: Jun 02 '22