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

Prototype code for seeing if FindPython3 is usable for rosidl_python #140

Merged
merged 10 commits into from
Feb 11, 2024
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}
clalancette marked this conversation as resolved.
Show resolved Hide resolved
--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})
clalancette marked this conversation as resolved.
Show resolved Hide resolved

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