mvukov / rules_ros2

Build ROS 2 with Bazel
Apache License 2.0
85 stars 47 forks source link

Running ros2_bag target gives: ModuleNotFoundError: No module named 'ros2cli.cli' #92

Closed kgreenek closed 1 year ago

kgreenek commented 1 year ago

Full error:

INFO: Running command line: bazel-bin/romalcpp/rosbag --help
Traceback (most recent call last):
  File "/home/kgk/.cache/bazel/_bazel_kgk/005c1a8f9988f2707370ff28b6b79f1c/execroot/__main__/bazel-out/k8-fastbuild/bin/romalcpp/rosbag.runfiles/__main__/romalcpp/rosbag_launch.py", line 4, in <module>
    import ros2.ros2_cmd
  File "/home/kgk/.cache/bazel/_bazel_kgk/005c1a8f9988f2707370ff28b6b79f1c/execroot/__main__/bazel-out/k8-fastbuild/bin/romalcpp/rosbag.runfiles/com_github_mvukov_rules_ros2/ros2/ros2_cmd.py", line 17, in <module>
    import ros2cli.cli
ModuleNotFoundError: No module named 'ros2cli.cli'

When I inspect the runfiles for the rosbag target, I noticed that the ros2cli is nested several times for some reason. Here is a snippet of the directory structure:

$ tree bazel-bin/romalcpp/rosbag.runfiles/ros2cli/
$  ros2cli
├──  __init__.py
└──  ros2cli
    ├──  __init__.py
    └──  ros2cli
        ├──  __init__.py ⇒ /home/kgk/.cache/bazel/_bazel_kgk/005c1a8f9988f2707370ff28b6b79f1c/external/ros2cli/ros2cli/ros2cli/__init__.py
        ├──  cli.py ⇒ /home/kgk/.cache/bazel/_bazel_kgk/005c1a8f9988f2707370ff28b6b79f1c/external/ros2cli/ros2cli/ros2cli/cli.py

Notice that the cli module that we're trying to import is nested under 3 directories called ros2cli:

bazel-bin/romalcpp/rosbag.runfiles/ros2cli/ros2cli/ros2cli/cli.py
mvukov commented 1 year ago

Hi, please create a minimum example in a separate repo. Please also include a .bazelrc.

kgreenek commented 1 year ago

Aha! I had a look at your .bazelrc and played around with my project. It seems this line is necessary in order to use rules_ros2:

build --incompatible_default_to_explicit_init_py

You can verify by removing the .bazelrc in the examples directory, so it uses bazel defaults. It fails without that flag.

kgreenek commented 1 year ago

When I remove that flag, in the bazel-bin directory I still see the triple-nested ros2cli directories. However, the top directories do not have __init__.py files, so the import works. Here's what it looks like now without that flag in .bazelrc.

 ros2cli
└──  ros2cli
    └──  ros2cli
        ├──  __init__.py ⇒ /home/kgk/.cache/bazel/_bazel_kgk/005c1a8f9988f2707370ff28b6b79f1c/external/ros2cli/ros2cli/ros2cli/__init__.py
        ├──  cli.py ⇒ /home/kgk/.cache/bazel/_bazel_kgk/005c1a8f9988f2707370ff28b6b79f1c/external/ros2cli/ros2cli/ros2cli/cli.py
mvukov commented 1 year ago

I suspected it's --incompatible_default_to_explicit_init_py. Yup, you need to have that one in your .bazelrc.

ahans commented 1 year ago

When I remove that flag, in the bazel-bin directory I still see the triple-nested ros2cli directories.

That is actually the expected layout. The first ros2cli is the name of external repository the bag rule depends on. The second and third ros2cli come from the ros2cli source.

@mvukov I wonder why this repo is called ros2cli. Shouldn't it be ros2_ros2cli?

mvukov commented 1 year ago

Ah, well, it's simple: it already had ros2 in it's name/prefix :) But we can have ros2_ros2cli as well, I don't have a strong opinion about this TBH.