In ROS2, both setup.py and CMakeLists.txt can be used simultaneously, but specific integration guidelines must be followed. For projects that contain a mix of Python and C++ code, the best practices are as follows:
1. Implementation of Mixed Builds
1. CMake as the Primary Build System (Recommended)
Integrate Python modules in CMake using the ament_cmake_python extension, without using setup.py separately. Example CMakeLists.txt configuration:
cmake_minimum_required(VERSION 3.5)
project(ros2_demo)
# C++ node compilation
add_executable(cpp_node src/cpp_node.cpp)
ament_target_dependencies(cpp_node rclcpp)
install(TARGETS cpp_node DESTINATION lib/${PROJECT_NAME})
# Python module integration
find_package(ament_cmake_python REQUIRED)
ament_python_install_package(${PROJECT_NAME} SCRIPTS_DESTINATION lib/${PROJECT_NAME})
# Python node installation
install(PROGRAMS
ros2_demo/new_python_node.py
DESTINATION lib/${PROJECT_NAME}
)
ament_package()
2. Coexistence but Manual Conflict Avoidance
If setup.py must be retained, the build type must be explicitly specified in package.xml:
<export>
<build_type>ament_cmake</build_type> <!-- or ament_python -->
</export>
⚠️ Note: ROS2 does not recommend using both build systems simultaneously, as it may lead to abnormal environment variable registration (such as the previous issue of needing to manually source local_setup.bash within the package).
2. Best Practices for Mixed Code Projects
1. Directory Structure Specification
ros2_demo/
├── include/ros2_demo/ # C++ header files
├── src/ # C++ source files
│ └── cpp_node.cpp
├── ros2_demo/ # Python package directory
│ ├── __init__.py
│ └── new_python_node.py
├── CMakeLists.txt # Main build script
├── package.xml # Dependency declaration
└── setup.cfg # Python installation configuration (if needed)
2. Dependency Management
- Declare all dependencies uniformly in package.xml:
<depend>rclcpp</depend> <!-- C++ dependency -->
<depend>rclpy</depend> <!-- Python dependency -->
- Link C++ dependencies in CMake using ament_target_dependencies
- Manage Python dependencies through setup.cfg or requirements.txt
3. Compilation and Installation
# Single command to compile all code
colcon build --packages-select ros2_demo
# Automatically generate unified environment variables
source install/local_setup.bash
4. Node Naming and Communication
- C++ and Python nodes should use different names (e.g., cpp_publisher and py_subscriber)
- Achieve cross-language communication through a unified topic name (e.g., echo_test_msg)
- Use ROS2 Interface Definition Language (IDL) to ensure message format consistency
3. Common Problem Solutions
- Environment variables not automatically registered: Ensure that ament_package() is included in CMakeLists.txt, and that the <build_type> in package.xml matches the actual build system.
- Python module import errors: Add the following to setup.cfg:
[develop]
script-dir=$base/lib/ros2_demo
[install]
install-scripts=$base/lib/ros2_demo
- Debugging Mixed Code
- C++: Use gdb ./install/ros2_demo/lib/ros2_demo/cpp_node
- Python: Directly use python3 -m pdb install/ros2_demo/lib/ros2_demo/new_python_node.py