Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use frontend group dependency & explicit dependencies in ros2launch #256

Merged

Conversation

christophebedard
Copy link
Member

@christophebedard christophebedard commented Jul 15, 2021

Closes #255

Requires ros2/launch#520

As suggested/discussed under ros2/launch#516 (comment), this uses a group dependency for the launch frontends and declares explicit dependencies on launch_xml and launch_yaml for ros2launch.

Using both a group dependency and hard/explicit dependencies allows this to work fine with binaries (with bloom) and also allows us to include any future launch frontend (or any user's custom frontend) in source builds. This is similar to how rcl depends on both the rcl_logging_packages group and the default logging implementation explicitly.

Signed-off-by: Christophe Bedard bedard.christophe@gmail.com

@christophebedard
Copy link
Member Author

@hidmic @wjwwood here's (along with ros2/launch#520) the solution I'm proposing based on your comments.

Copy link
Member

@wjwwood wjwwood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@wjwwood
Copy link
Member

wjwwood commented Jul 15, 2021

CI (--packages-above-and-dependencies launch_testing launch_xml launch_yaml ros2launch, cyclone only):

  • Linux Build Status
  • Linux-aarch64 Build Status
  • macOS Build Status
  • Windows Build Status

@wjwwood
Copy link
Member

wjwwood commented Jul 15, 2021

Anyone have any idea why we have failures on Windows now? I didn't investigate, but it could be to new missing dependencies?

@hidmic
Copy link
Contributor

hidmic commented Jul 16, 2021

Anyone have any idea why we have failures on Windows now? I didn't investigate, but it could be to new missing dependencies?

Some rclpy library dependencies are not getting picked up 🤔

@hidmic
Copy link
Contributor

hidmic commented Jul 16, 2021

Update: I cannot reproduce it on a plain Windows VM. Something's up with the CI Windows container.

@christophebedard
Copy link
Member Author

could this just be a flake?

@wjwwood
Copy link
Member

wjwwood commented Jul 16, 2021

I don't see how. If it is a flake, then it is a bug underneath.

@wjwwood
Copy link
Member

wjwwood commented Jul 16, 2021

I'll run CI again, just to check:

  • Linux Build Status
  • Linux-aarch64 Build Status
  • macOS Build Status
  • Windows Build Status

@hidmic
Copy link
Contributor

hidmic commented Jul 16, 2021

Same issue. The fun part is that other packages with tests that depend on rclpy, like test_communication, don't seem to have any issues. Let's see what happens on master:

  • Windows Build Status

@christophebedard
Copy link
Member Author

christophebedard commented Jul 17, 2021

The fun part is that other packages with tests that depend on rclpy, like test_communication, don't seem to have any issues.

yeah and launch_xml by itself doesn't depend (indirectly or directly) on rclpy:

$ colcon list -n --packages-up-to launch_xml
ament_copyright
ament_flake8
ament_index_python
ament_lint
ament_pep257
launch
launch_xml
osrf_pycommon

this is a bit confusing.

@hidmic
Copy link
Contributor

hidmic commented Jul 19, 2021

yeah and launch_xml by itself doesn't depend (indirectly or directly) on rclpy:

It does indirectly through launch_ros, when launch loads all the extensions it knows about:

test\launch_xml\test_executable.py:62: in test_executable_wrong_subtag
    parser.parse_description(root_entity)
C:\ci\ws\install\Lib\site-packages\launch\frontend\parser.py:117: in parse_description
    actions = [self.parse_action(child) for child in entity.children]
C:\ci\ws\install\Lib\site-packages\launch\frontend\parser.py:117: in <listcomp>
    actions = [self.parse_action(child) for child in entity.children]
C:\ci\ws\install\Lib\site-packages\launch\frontend\parser.py:93: in parse_action
    self.load_launch_extensions()
C:\ci\ws\install\Lib\site-packages\launch\frontend\parser.py:77: in load_launch_extensions
    entry_point.load()
c:\python38\lib\importlib\metadata.py:77: in load
    module = import_module(match.group('module'))
c:\python38\lib\importlib\__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
<frozen importlib._bootstrap>:1014: in _gcd_import
    ...
C:\ci\ws\install\Lib\site-packages\launch_ros\__init__.py:17: in <module>
    from . import actions
C:\ci\ws\install\Lib\site-packages\launch_ros\actions\__init__.py:17: in <module>
    from .composable_node_container import ComposableNodeContainer
C:\ci\ws\install\Lib\site-packages\launch_ros\actions\composable_node_container.py:27: in <module>
    from .node import Node
C:\ci\ws\install\Lib\site-packages\launch_ros\actions\node.py:61: in <module>
    from rclpy.validate_namespace import validate_namespace
C:\ci\ws\install\Lib\site-packages\rclpy\validate_namespace.py:15: in <module>
    from rclpy.exceptions import InvalidNamespaceException
C:\ci\ws\install\Lib\site-packages\rclpy\exceptions.py:15: in <module>
    from rclpy.impl.implementation_singleton import rclpy_implementation as _rclpy
C:\ci\ws\install\Lib\site-packages\rclpy\impl\implementation_singleton.py:32: in <module>
    rclpy_implementation = import_c_library('._rclpy_pybind11', package)
C:\ci\ws\install\Lib\site-packages\rpyutils\import_c_library.py:39: in import_c_library
    return importlib.import_module(name, package=package)
c:\python38\lib\importlib\__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
E   ImportError: DLL load failed while importing _rclpy_pybind11: The specified module could not be found.
E   The C extension 'C:\ci\ws\install\Lib\site-packages\rclpy\_rclpy_pybind11.cp38-win_amd64.pyd' failed to be imported while being present on the system. Please refer to 'https://index.ros.org/doc/ros2/Troubleshooting/Installation-Troubleshooting/#import-failing-even-with-library-present-on-the-system' for possible solutions

@christophebedard
Copy link
Member Author

It does indirectly through launch_ros, when launch loads all the extensions it knows about:

yeah, in practice, so isn't that kind of problematic/isn't that the reason why the test is failing?

launch_xml doesn't depend on rclpy, either directly or indirectly, according to the package.xml files. This means that, when the test gets run, PYTHONPATH doesn't contain the path to rclpy's build directory or the path to rclpy's lib/python3.8/site-packages directory. It only contains the paths to its declared direct/indirect dependencies' build/lib directories.

I don't understand why it only fails on Windows and why it seems to be working fine without this PR, and maybe I'm misunderstanding something, but this "undeclared" dependency seems problematic to me.

Note that launch_xml doesn't depend on launch_ros either. If we didn't build launch_ros in the CI run, I'm guessing it wouldn't be found by launch's extension search when running launch_xml tests, and so it wouldn't try to find rclpy libs, and thus it wouldn't fail, right?

@christophebedard
Copy link
Member Author

Note that launch_xml doesn't depend on launch_ros either. If we didn't build launch_ros in the CI run, I'm guessing it wouldn't be found by launch's extension search when running launch_xml tests, and so it wouldn't try to find rclpy libs, and thus it wouldn't fail, right?

I re-ran the original Windows job with this PR and the launch PR, but with --packages-up-to/--packages-select launch_xml launch_yaml. launch_ros isn't built since I removed ros2launch from the build args. It runs fine:

  • Windows Build Status

@christophebedard
Copy link
Member Author

This might be related to PATH instead of PYTHONPATH, but I assume it's the same problem https://github.com/ros2/rpyutils/blob/3e41fe4d71bc16f5a727a010f835fb49376b52b3/rpyutils/import_c_library.py#L35-L39

@hidmic
Copy link
Contributor

hidmic commented Jul 19, 2021

launch_xml doesn't depend on rclpy, either directly or indirectly, according to the package.xml files. This means that, when the test gets run, PYTHONPATH doesn't contain the path to rclpy's build directory or the path to rclpy's lib/python3.8/site-packages directory. It only contains the paths to its declared direct/indirect dependencies' build/lib directories.

You're absolutely right.

Note that launch_xml doesn't depend on launch_ros either. If we didn't build launch_ros in the CI run, I'm guessing it wouldn't be found by launch's extension search when running launch_xml tests, and so it wouldn't try to find rclpy libs, and thus it wouldn't fail, right?

That's also right!

This might be related to PATH instead of PYTHONPATH,

It could be. We need a Windows-specific explanation as to why launch_ros ends up in the PYTHONPATH for launch_xml while rclpy does not (neither a dependency of launch_xml as far as package.xml metadata implies).

@christophebedard
Copy link
Member Author

It could be. We need a Windows-specific explanation as to why launch_ros ends up in the PYTHONPATH for launch_xml while rclpy does not (neither a dependency of launch_xml as far as package.xml metadata implies).

I'll try to make time to look into it this week.

@wjwwood
Copy link
Member

wjwwood commented Jul 30, 2021

Has anyone had a chance to look into this?

@christophebedard
Copy link
Member Author

I haven't had time yet unfortunately. I'll try to look into it tomorrow.

@wjwwood
Copy link
Member

wjwwood commented Jul 30, 2021

Yeah, no pressure, just curious.

@christophebedard
Copy link
Member Author

I tried to reproduce and I couldn't either. I haven't had time to dig deeper.

@jacobperron
Copy link
Member

This might be related to PATH instead of PYTHONPATH, but I assume it's the same problem https://github.com/ros2/rpyutils/blob/3e41fe4d71bc16f5a727a010f835fb49376b52b3/rpyutils/import_c_library.py#L35-L39

For some context, since Python 3.8, PATH (and the current working directory) are no longer used for DLL resolution on Windows: https://docs.python.org/3/whatsnew/3.8.html#bpo-36085-whatsnew

To work around this, we introduced that utility in rpyutils, which explicitly add directories from PATH to the search path when importing a module. (TBH, the whole thing seems to subvert the security measure taken by Python, but I'm not sure how we might handle it differently for ROS 2).


I guess what's happening in this case is that the rclpy DLL directory is not in PATH at test time for launch_xml. I'm not sure why, but maybe because it doesn't have launch_ros in it's dependency tree (as pointed out earlier).

Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>
Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>
Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>
@christophebedard
Copy link
Member Author

Thanks for the info @jacobperron.

I once again tried to reproduce and couldn't. Without being able to reproduce on my local machine, I'm not really sure how to proceed, especially since this is quite time-consuming for such a minor change.

@wjwwood
Copy link
Member

wjwwood commented Nov 11, 2021

Well, let's just see what CI says again, since you rebased (I'm assuming that's all):

  • Linux Build Status
  • Linux-aarch64 Build Status
  • macOS Build Status
  • Windows Build Status

@christophebedard
Copy link
Member Author

Yeah I simply rebased.

Those CI jobs don't build/test the same packages as the jobs that failed above, like this one: https://ci.ros2.org/job/ci_windows/15054/

@christophebedard
Copy link
Member Author

Here is a run with the same packages:

  • Linux Build Status
  • Linux-aarch64 Build Status
  • macOS Build Status
  • Windows Build Status

@wjwwood
Copy link
Member

wjwwood commented Nov 11, 2021

Oh sorry, I forgot to add ros2/launch#520.

@christophebedard
Copy link
Member Author

CI is green, so... I guess it's fixed‽

The issue, as I understood it, was slightly concerning, so I hope this doesn't come back to bite us.

@jacobperron
Copy link
Member

I think the issue was the same as ros2/rclpy#831
Which we recently fixed in #278

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Declare dependencies on launch_{xml,yaml} parsers to make sure they're available
4 participants