Skip to content

Commit

Permalink
Prototype code for seeing if FindPython3 is usable for rosidl_python (#…
Browse files Browse the repository at this point in the history
…140)

* Use FindPython3 for rosidl_python

* Add in COMPONENTS keyword.

* Mark the libraries private.

* Use Python3::Interpreter in the custom command.

* Switch to target_link_libraries almost everywhere.

Signed-off-by: Chris Lalancette <[email protected]>
  • Loading branch information
sloretz authored Feb 11, 2024
1 parent c77ea6c commit 1505ac0
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 88 deletions.
13 changes: 2 additions & 11 deletions rosidl_generator_py/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.14)

project(rosidl_generator_py)

Expand All @@ -25,11 +25,6 @@ if(BUILD_TESTING)
find_package(python_cmake_module REQUIRED)
find_package(PythonExtra MODULE REQUIRED)

set(BUILDTYPE_PYTHON_EXECUTABLE "${PYTHON_EXECUTABLE}")
if(WIN32 AND "${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
set(BUILDTYPE_PYTHON_EXECUTABLE "${PYTHON_EXECUTABLE_DEBUG}")
endif()

include(cmake/register_py.cmake)
include(cmake/rosidl_generator_py_get_typesupports.cmake)

Expand Down Expand Up @@ -72,18 +67,14 @@ if(BUILD_TESTING)
string(REPLACE ";" ":" pythonpath "${pythonpath}")
endif()
ament_add_pytest_test(test_interfaces_py "test/test_interfaces.py"
PYTHON_EXECUTABLE "${BUILDTYPE_PYTHON_EXECUTABLE}"
APPEND_ENV "PYTHONPATH=${pythonpath}"
APPEND_LIBRARY_DIRS "${_append_library_dirs}"
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/rosidl_generator_py"
)

ament_add_pytest_test(test_cli_extension test/test_cli_extension.py
PYTHON_EXECUTABLE "${BUILDTYPE_PYTHON_EXECUTABLE}"
)
ament_add_pytest_test(test_cli_extension test/test_cli_extension.py)

ament_add_pytest_test(test_property_py test/test_property.py
PYTHON_EXECUTABLE "${BUILDTYPE_PYTHON_EXECUTABLE}"
APPEND_ENV "PYTHONPATH=${pythonpath}"
APPEND_LIBRARY_DIRS "${_append_library_dirs}"
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/rosidl_generator_py"
Expand Down
4 changes: 3 additions & 1 deletion rosidl_generator_py/cmake/custom_command.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
# add_subdirectory() call.
add_custom_command(
OUTPUT ${_generated_extension_files} ${_generated_py_files} ${_generated_c_files}
COMMAND ${PYTHON_EXECUTABLE} ${rosidl_generator_py_BIN}
# This assumes that python_cmake_module was found, which is always the case since this is only
# called from rosidl_generator_py_generate_interfaces.cmake
COMMAND Python3::Interpreter ${rosidl_generator_py_BIN}
--generator-arguments-file "${generator_arguments_file}"
--typesupport-impls "${_typesupport_impls}"
DEPENDS ${target_dependencies} ${rosidl_generate_interfaces_TARGET}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.

find_package(python_cmake_module REQUIRED)
find_package(PythonExtra REQUIRED)
find_package(rmw REQUIRED)
find_package(rosidl_runtime_c REQUIRED)
find_package(rosidl_typesupport_c REQUIRED)
find_package(rosidl_typesupport_interface REQUIRED)

find_package(PythonInterp 3.6 REQUIRED)

find_package(python_cmake_module REQUIRED)
find_package(PythonExtra MODULE REQUIRED)
find_package(Python3 REQUIRED COMPONENTS Interpreter Development NumPy)

# Get a list of typesupport implementations from valid rmw implementations.
rosidl_generator_py_get_typesupports(_typesupport_impls)
Expand Down Expand Up @@ -72,10 +71,10 @@ foreach(_generated_py_file ${_generated_py_files})
endforeach()

if(NOT _generated_c_files STREQUAL "")
foreach(_typesupport_impl ${_typesupport_impls})
list(APPEND _generated_extension_${_typesupport_impl}_files "${_output_path}/_${PROJECT_NAME}_s.ep.${_typesupport_impl}.c")
list(APPEND _generated_extension_files "${_generated_extension_${_typesupport_impl}_files}")
endforeach()
foreach(_typesupport_impl ${_typesupport_impls})
list(APPEND _generated_extension_${_typesupport_impl}_files "${_output_path}/_${PROJECT_NAME}_s.ep.${_typesupport_impl}.c")
list(APPEND _generated_extension_files "${_generated_extension_${_typesupport_impl}_files}")
endforeach()
endif()
set(_dependency_files "")
set(_dependencies "")
Expand Down Expand Up @@ -126,11 +125,6 @@ endif()

set(_target_suffix "__py")

set(_PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE})
if(WIN32 AND "${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
set(PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE_DEBUG})
endif()

# move custom command into a subdirectory to avoid multiple invocations on Windows
set(_subdir "${CMAKE_CURRENT_BINARY_DIR}/${rosidl_generate_interfaces_TARGET}${_target_suffix}")
file(MAKE_DIRECTORY "${_subdir}")
Expand All @@ -142,12 +136,9 @@ set_property(
${_generated_extension_files} ${_generated_py_files} ${_generated_c_files}
PROPERTY GENERATED 1)

# Export target so downstream interface packages can link to it
set(rosidl_generator_py_suffix "__rosidl_generator_py")

set(_target_name_lib "${rosidl_generate_interfaces_TARGET}${rosidl_generator_py_suffix}")
set(_target_name_lib "${rosidl_generate_interfaces_TARGET}__rosidl_generator_py")
add_library(${_target_name_lib} SHARED ${_generated_c_files})
target_link_libraries(${_target_name_lib}
target_link_libraries(${_target_name_lib} PRIVATE
${rosidl_generate_interfaces_TARGET}__rosidl_generator_c)
add_dependencies(
${_target_name_lib}
Expand All @@ -156,44 +147,23 @@ add_dependencies(
)

target_link_libraries(
${_target_name_lib}
${PythonExtra_LIBRARIES}
${_target_name_lib} PRIVATE
Python3::NumPy
Python3::Python
)
target_include_directories(${_target_name_lib}
PRIVATE
${CMAKE_CURRENT_BINARY_DIR}/rosidl_generator_c
${CMAKE_CURRENT_BINARY_DIR}/rosidl_generator_py
${PythonExtra_INCLUDE_DIRS}
)

# Check if numpy is in the include path
find_file(_numpy_h numpy/numpyconfig.h
PATHS ${PythonExtra_INCLUDE_DIRS}
)

if(APPLE OR WIN32 OR NOT _numpy_h)
# add include directory for numpy headers
set(_python_code
"import numpy"
"print(numpy.get_include())"
)
execute_process(
COMMAND "${PYTHON_EXECUTABLE}" "-c" "${_python_code}"
OUTPUT_VARIABLE _output
RESULT_VARIABLE _result
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(NOT _result EQUAL 0)
message(FATAL_ERROR
"execute_process(${PYTHON_EXECUTABLE} -c '${_python_code}') returned "
"error code ${_result}")
endif()
message(STATUS "Using numpy include directory: ${_output}")
target_include_directories(${_target_name_lib} PUBLIC "${_output}")
set(_extension_compile_flags "")
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(_extension_compile_flags -Wall -Wextra)
endif()

rosidl_get_typesupport_target(c_typesupport_target "${rosidl_generate_interfaces_TARGET}" "rosidl_typesupport_c")
target_link_libraries(${_target_name_lib} ${c_typesupport_target})
target_link_libraries(${_target_name_lib} PRIVATE ${c_typesupport_target})

foreach(_typesupport_impl ${_typesupport_impls})
find_package(${_typesupport_impl} REQUIRED)
Expand All @@ -203,10 +173,9 @@ foreach(_typesupport_impl ${_typesupport_impls})
continue()
endif()

set(_pyext_suffix "__pyext")
set(_target_name "${PROJECT_NAME}__${_typesupport_impl}${_pyext_suffix}")
set(_target_name "${PROJECT_NAME}_s__${_typesupport_impl}")

add_library(${_target_name} SHARED
python3_add_library(${_target_name} MODULE
${_generated_extension_${_typesupport_impl}_files}
)
add_dependencies(
Expand All @@ -215,65 +184,62 @@ foreach(_typesupport_impl ${_typesupport_impls})
${rosidl_generate_interfaces_TARGET}__rosidl_typesupport_c
)

set(_extension_compile_flags "")
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(_extension_compile_flags -Wall -Wextra)
endif()
set_target_properties(${_target_name} PROPERTIES DEBUG_POSTFIX "${PythonExtra_POSTFIX}")
# target_compile_options(${_target_name} PRIVATE ${_extension_compile_flags})
# TODO(sloretz) use target_compile_options when python extension passes -Wpedantic
set_target_properties(${_target_name} PROPERTIES COMPILE_OPTIONS "${_extension_compile_flags}")

set_target_properties(${_target_name} PROPERTIES
COMPILE_OPTIONS "${_extension_compile_flags}"
PREFIX ""
OUTPUT_NAME "${PROJECT_NAME}_s__${_typesupport_impl}${PythonExtra_EXTENSION_SUFFIX}"
SUFFIX "${PythonExtra_EXTENSION_EXTENSION}")
LIBRARY_OUTPUT_DIRECTORY ${_output_path}
RUNTIME_OUTPUT_DIRECTORY ${_output_path})

target_link_libraries(
${_target_name}
${_target_name} PRIVATE
${_target_name_lib}
${PythonExtra_LIBRARIES}
${rosidl_generate_interfaces_TARGET}__${_typesupport_impl}
${c_typesupport_target}
rosidl_runtime_c::rosidl_runtime_c
rosidl_typesupport_c::rosidl_typesupport_c
rosidl_typesupport_interface::rosidl_typesupport_interface
)

target_include_directories(${_target_name}
PUBLIC
PRIVATE
${CMAKE_CURRENT_BINARY_DIR}/rosidl_generator_c
${CMAKE_CURRENT_BINARY_DIR}/rosidl_generator_py
${PythonExtra_INCLUDE_DIRS}
)

target_link_libraries(${_target_name} ${c_typesupport_target})

ament_target_dependencies(${_target_name}
"rosidl_runtime_c"
"rosidl_typesupport_c"
"rosidl_typesupport_interface"
)
foreach(_pkg_name ${rosidl_generate_interfaces_DEPENDENCY_PACKAGE_NAMES})
ament_target_dependencies(${_target_name}
${_pkg_name}
)
target_link_libraries(${_target_name} PRIVATE ${${_pkg_name}__TARGETS})
endforeach()

add_dependencies(${_target_name}
${rosidl_generate_interfaces_TARGET}__${_typesupport_impl}
)
ament_target_dependencies(${_target_name}
"rosidl_runtime_c"

ament_target_dependencies(${_target_name} PUBLIC
"rosidl_generator_py"
)

if(NOT rosidl_generate_interfaces_SKIP_INSTALL)
# PYTHON_INSTALL_DIR is defined by ament_cmake_python
install(TARGETS ${_target_name}
DESTINATION "${PYTHON_INSTALL_DIR}/${PROJECT_NAME}")
endif()
endforeach()

set(PYTHON_EXECUTABLE ${_PYTHON_EXECUTABLE})

# Depend on rosidl_generator_py generated targets from our dependencies
foreach(_pkg_name ${rosidl_generate_interfaces_DEPENDENCY_PACKAGE_NAMES})
target_link_libraries(${_target_name_lib} ${${_pkg_name}_TARGETS${rosidl_generator_py_suffix}})
target_link_libraries(${_target_name_lib} PRIVATE ${${_pkg_name}_TARGETS${rosidl_generator_py_suffix}})
endforeach()

set_target_properties(${_target_name_lib} PROPERTIES COMPILE_OPTIONS "${_extension_compile_flags}")

set_target_properties(${_target_name_lib} PROPERTIES
COMPILE_OPTIONS "${_extension_compile_flags}")
LIBRARY_OUTPUT_DIRECTORY ${_output_path}
RUNTIME_OUTPUT_DIRECTORY ${_output_path})

if(NOT rosidl_generate_interfaces_SKIP_INSTALL)
install(TARGETS ${_target_name_lib}
EXPORT export_${_target_name_lib}
Expand Down

0 comments on commit 1505ac0

Please sign in to comment.