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

Copy windows debug fixes for pybind11 #681

Merged
merged 6 commits into from
Feb 24, 2021

Conversation

sloretz
Copy link
Contributor

@sloretz sloretz commented Feb 16, 2021

Hopefully fixes #680

Copies windows debug fixes from rosbag2_py for using Pybind11 on Windows
debug and RelWithDebInfo.

For more info see the original PRs

ros2/rosbag2#538
ros2/rosbag2#531

Signed-off-by: Shane Loretz sloretz@openrobotics.org
Signed-off-by: Shane Loretz sloretz@osrfoundation.org

@sloretz sloretz added the bug Something isn't working label Feb 16, 2021
@sloretz sloretz self-assigned this Feb 16, 2021
@sloretz
Copy link
Contributor Author

sloretz commented Feb 16, 2021

CI (build: --packages-up-to rclpy test: --packages-select rclpy)

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

Copy link
Contributor

@clalancette clalancette left a comment

Choose a reason for hiding this comment

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

This is clearly an improvement, as Windows Debug no longer fails. However, there are still warnings present in the Windows Debug build. @sloretz any thoughts on what's causing that?

@sloretz
Copy link
Contributor Author

sloretz commented Feb 17, 2021

This is clearly an improvement, as Windows Debug no longer fails. However, there are still warnings present in the Windows Debug build. @sloretz any thoughts on what's causing that?

Implemented workaround to make sure Py_DEBUG on rclpy_common matches setting on the Python Modules. This workaround should not be necessary on Pybind11 2.6 and beyond, because that adds Py_DEBUG as an interface compile definition to the pybind11::pybind11 target.

Anyways, if that's correct then this build should have no warnings:

Windows Debug Build Status

@sloretz
Copy link
Contributor Author

sloretz commented Feb 17, 2021

Whoops, Windows debug again: Build Status

@clalancette
Copy link
Contributor

Heh, it got worse: 2 warnings -> 4 warnings :).

@sloretz
Copy link
Contributor Author

sloretz commented Feb 17, 2021

Windows Debug again Build Status

Made Py_DEBUG definition on rclpy_common PUBLIC so it's transitive - not sure why that would be needed.

@clalancette
Copy link
Contributor

clalancette commented Feb 18, 2021

So looking at the compile line for one of the files showing the problem, I see this (I split the lines for clarity):

C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29333\bin\HostX64\x64\CL.exe
 /c /IC:\dev\ros2_ws\src\ros2\rclpy\rclpy\src\rclpy_common\include
 /IC:\dev\ros2_ws\install\include /IC:\Python38\include /Zi /nologo /W3 /WX- /diagnostics:column
 /Od /Ob0 /D WIN32 /D _WINDOWS /D RCLPY_COMMON_BUILDING_DLL /D Py_DEBUG /D RCUTILS_ENABLE_FAULT_INJECTION
 /D _CRT_SECURE_NO_WARNINGS /D DEFAULT_RMW_IMPLEMENTATION=rmw_cyclonedds_cpp /D "CMAKE_INTDIR=\"Debug\""
 /D rclpy_common_EXPORTS /D _WINDLL /D _MBCS /Gm- /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope
 /Zc:inline /Fo"rclpy_common.dir\Debug\\" /Fd"rclpy_common.dir\Debug\vc142.pdb" /Gd /TC
 /errorReport:queue C:\dev\ros2_ws\src\ros2\rclpy\rclpy\src\rclpy_common\src\common.c
 C:\dev\ros2_ws\src\ros2\rclpy\rclpy\src\rclpy_common\src\handle.c

It is clear from that command-line that Py_DEBUG is being set to an empty macro. The compile warning is this:

C:\Python38\include\pyconfig.h(321,1): warning C4005: 'Py_DEBUG': macro redefinition (compiling source file C:\dev\ros2_ws\src\ros2\rclpy\rclpy\src\rclpy_common\src\handle.c) [C:\dev\ros2_ws\build\rclpy\rclpy_common.vcxproj]
C:\dev\ros2_ws\src\ros2\rclpy\rclpy\src\rclpy_common\src\handle.c : message : see previous definition of 'Py_DEBUG' [C:\dev\ros2_ws\build\rclpy\rclpy_common.vcxproj]
C:\Python38\include\pyconfig.h(321,1): warning C4005: 'Py_DEBUG': macro redefinition (compiling source file C:\dev\ros2_ws\src\ros2\rclpy\rclpy\src\rclpy_common\src\common.c) [C:\dev\ros2_ws\build\rclpy\rclpy_common.vcxproj]
C:\dev\ros2_ws\src\ros2\rclpy\rclpy\src\rclpy_common\src\common.c : message : see previous definition of 'Py_DEBUG' [C:\dev\ros2_ws\build\rclpy\rclpy_common.vcxproj]

That warning comes from the pyconfig.h file is included, which has this bit in it:

#ifdef _DEBUG
#          define Py_DEBUG
#endif

A few questions/observations then:

  • Does Windows not allow redefining a macro, even if it is the same definition twice (as it appears to be in this case)?
  • What part of the system is setting _DEBUG on?
  • One way around this looks like to not define Py_DEBUG on the compile command-line. But that would seem to have been what we had earlier in this PR (before 35dfed7).

@sloretz
Copy link
Contributor Author

sloretz commented Feb 18, 2021

How'd you get the compile commands on Windows?

What part of the system is setting _DEBUG on?

It looks like the compiler sets _DEBUG because /MDd is set: https://docs.microsoft.com/en-us/cpp/c-runtime-library/debug?view=msvc-160

@clalancette
Copy link
Contributor

clalancette commented Feb 18, 2021

How'd you get the compile commands on Windows?

I did:

> set VERBOSE=1
> rd /Q /S build\rclpy
> python_d C:\Python38\Scripts\colcon.exe build --merge-install --cmake-args -DCMAKE_BUILD_TYPE=Debug --packages-select rclpy --event-handlers console_direct+

@sloretz
Copy link
Contributor Author

sloretz commented Feb 20, 2021

Does Windows not allow redefining a macro, even if it is the same definition twice (as it appears to be in this case)?

Yeah, can confirm with an MRE that windows complains when a compiler definition is set both on the compiler command line and in code.

Comment on lines 205 to 213
# Workaround to ensure rclpy_common has same definition for Py_DEBUG
# TODO(sloretz) remove this workaround when using pybind11 2.6+
get_target_property(_rclpy_compile_definitions _rclpy COMPILE_DEFINITIONS)
foreach(_rclpy_definition ${_rclpy_compile_definitions})
if("Py_DEBUG" STREQUAL _rclpy_definition)
target_compile_definitions(rclpy_common PUBLIC Py_DEBUG)
break()
endif()
endforeach()
Copy link
Contributor

Choose a reason for hiding this comment

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

Given what we now know, it seems like this isn't the correct workaround. That is, we specifically don't want to add Py_DEBUG to the command-line, since that ends up with the warning. It kind of looks to me like we need to remove this, and then see if there is something else that is also adding Py_DEBUG to the command-line. If it is pybind11, maybe the thing to do here is to augment clean_windows_flags to also remove that flag?

Copies windows debug fixes from rosbag2_py for using Pybind11 on Windows
debug and RelWithDebInfo.

For more info see the original PRs

ros2/rosbag2#538
ros2/rosbag2#531

Signed-off-by: Shane Loretz <sloretz@openrobotics.org>
Signed-off-by: Shane Loretz <sloretz@osrfoundation.org>
Signed-off-by: Shane Loretz <sloretz@osrfoundation.org>
Signed-off-by: Shane Loretz <sloretz@osrfoundation.org>
Signed-off-by: Shane Loretz <sloretz@osrfoundation.org>
@sloretz sloretz force-pushed the rclpy_pybind11_windows_debug_fixes branch from f9ab18e to 0d84422 Compare February 23, 2021 19:30
Signed-off-by: Shane Loretz <sloretz@osrfoundation.org>
Signed-off-by: Shane Loretz <sloretz@osrfoundation.org>
@sloretz
Copy link
Contributor Author

sloretz commented Feb 23, 2021

Windows debug is green 🎉 Build Status

That is, we specifically don't want to add Py_DEBUG to the command-line, since that ends up with the warning. It kind of looks to me like we need to remove this, and then see if there is something else that is also adding Py_DEBUG to the command-line.

Putting everything together, the Python interpreter has a special debug mode, and it uses the macro Py_DEBUG to enable or disable this mode. The source of the warning is pyconfig.h sets Py_DEBUG when _DEBUG is set, and pybind11_add_module sets Py_DEBUG via the command line when a debug Python interpreter is used. This definition being set in two places is why the warning comes up.

One might think, just don't let pybind11_add_module set Py_DEBUG and all would be fine, but Pybind11 has some extra logic to allow using the Python release interpreter when building in Debug mode. That logic also uses Py_DEBUG. If _DEBUG is set but Py_DEBUG is not, then it will undefine _DEBUG, include Python.h, then restore _DEBUG. If we remove Py_DEBUG then _DEBUG will get unset and CPython will link against release Python libs instead of the debug Python libs.

As long as Py_DEBUG is set and pybind11/pybind11.h was included instead of or before <Python.h>, then everything is happy. If code uses pybind11_add_module but includes Python.h, then there's the duplicate definition warning.

One way to fix this is to include pybind11/pybind11.h instead of Python.h, but that requires changing the language to C, and not everything is happy about that yet. Once all the PRs converting modules to use Pybind11 are in then this will be solved.

If it is pybind11, maybe the thing to do here is to augment clean_windows_flags to also remove that flag?

This seems like the best fix, but it needs to be undone once the modules are using Pybind11. I made it in a separate macro in 1932bee so I could apply it to only the modules that have not yet been converted.

@clalancette
Copy link
Contributor

Woohoo! I also tested this fix locally, and it seems to do the trick for me. I'll do a brief review here, and then we can merge. Thanks for the work.

Copy link
Contributor

@clalancette clalancette left a comment

Choose a reason for hiding this comment

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

The changes look OK to me, so approving. One question: should we open up an issue to track reverting these changes once everything is converted to PyBind11? Or are you going to track it in #665?

@sloretz
Copy link
Contributor Author

sloretz commented Feb 24, 2021

CI (build: --packages-up-to rclpy test: --packages-select rclpy)

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

@sloretz
Copy link
Contributor Author

sloretz commented Feb 24, 2021

One question: should we open up an issue to track reverting these changes once everything is converted to PyBind11? Or are you going to track it in #665?

I'll track it in #665. It should be removed in each PR as it's merged.

@sloretz sloretz mentioned this pull request Feb 24, 2021
34 tasks
@sloretz sloretz merged commit 66da648 into master Feb 24, 2021
@delete-merged-branch delete-merged-branch bot deleted the rclpy_pybind11_windows_debug_fixes branch February 24, 2021 23:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

👨‍🌾 rclpy fails during cmake configuration on windows CI
2 participants