Skip to content

Commit 1505ac0

Browse files
authored
Prototype code for seeing if FindPython3 is usable for rosidl_python (#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]>
1 parent c77ea6c commit 1505ac0

File tree

3 files changed

+47
-88
lines changed

3 files changed

+47
-88
lines changed

rosidl_generator_py/CMakeLists.txt

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
cmake_minimum_required(VERSION 3.5)
1+
cmake_minimum_required(VERSION 3.14)
22

33
project(rosidl_generator_py)
44

@@ -25,11 +25,6 @@ if(BUILD_TESTING)
2525
find_package(python_cmake_module REQUIRED)
2626
find_package(PythonExtra MODULE REQUIRED)
2727

28-
set(BUILDTYPE_PYTHON_EXECUTABLE "${PYTHON_EXECUTABLE}")
29-
if(WIN32 AND "${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
30-
set(BUILDTYPE_PYTHON_EXECUTABLE "${PYTHON_EXECUTABLE_DEBUG}")
31-
endif()
32-
3328
include(cmake/register_py.cmake)
3429
include(cmake/rosidl_generator_py_get_typesupports.cmake)
3530

@@ -72,18 +67,14 @@ if(BUILD_TESTING)
7267
string(REPLACE ";" ":" pythonpath "${pythonpath}")
7368
endif()
7469
ament_add_pytest_test(test_interfaces_py "test/test_interfaces.py"
75-
PYTHON_EXECUTABLE "${BUILDTYPE_PYTHON_EXECUTABLE}"
7670
APPEND_ENV "PYTHONPATH=${pythonpath}"
7771
APPEND_LIBRARY_DIRS "${_append_library_dirs}"
7872
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/rosidl_generator_py"
7973
)
8074

81-
ament_add_pytest_test(test_cli_extension test/test_cli_extension.py
82-
PYTHON_EXECUTABLE "${BUILDTYPE_PYTHON_EXECUTABLE}"
83-
)
75+
ament_add_pytest_test(test_cli_extension test/test_cli_extension.py)
8476

8577
ament_add_pytest_test(test_property_py test/test_property.py
86-
PYTHON_EXECUTABLE "${BUILDTYPE_PYTHON_EXECUTABLE}"
8778
APPEND_ENV "PYTHONPATH=${pythonpath}"
8879
APPEND_LIBRARY_DIRS "${_append_library_dirs}"
8980
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/rosidl_generator_py"

rosidl_generator_py/cmake/custom_command.cmake

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020
# add_subdirectory() call.
2121
add_custom_command(
2222
OUTPUT ${_generated_extension_files} ${_generated_py_files} ${_generated_c_files}
23-
COMMAND ${PYTHON_EXECUTABLE} ${rosidl_generator_py_BIN}
23+
# This assumes that python_cmake_module was found, which is always the case since this is only
24+
# called from rosidl_generator_py_generate_interfaces.cmake
25+
COMMAND Python3::Interpreter ${rosidl_generator_py_BIN}
2426
--generator-arguments-file "${generator_arguments_file}"
2527
--typesupport-impls "${_typesupport_impls}"
2628
DEPENDS ${target_dependencies} ${rosidl_generate_interfaces_TARGET}

rosidl_generator_py/cmake/rosidl_generator_py_generate_interfaces.cmake

Lines changed: 42 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,14 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
find_package(python_cmake_module REQUIRED)
16+
find_package(PythonExtra REQUIRED)
1517
find_package(rmw REQUIRED)
1618
find_package(rosidl_runtime_c REQUIRED)
1719
find_package(rosidl_typesupport_c REQUIRED)
1820
find_package(rosidl_typesupport_interface REQUIRED)
1921

20-
find_package(PythonInterp 3.6 REQUIRED)
21-
22-
find_package(python_cmake_module REQUIRED)
23-
find_package(PythonExtra MODULE REQUIRED)
22+
find_package(Python3 REQUIRED COMPONENTS Interpreter Development NumPy)
2423

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

7473
if(NOT _generated_c_files STREQUAL "")
75-
foreach(_typesupport_impl ${_typesupport_impls})
76-
list(APPEND _generated_extension_${_typesupport_impl}_files "${_output_path}/_${PROJECT_NAME}_s.ep.${_typesupport_impl}.c")
77-
list(APPEND _generated_extension_files "${_generated_extension_${_typesupport_impl}_files}")
78-
endforeach()
74+
foreach(_typesupport_impl ${_typesupport_impls})
75+
list(APPEND _generated_extension_${_typesupport_impl}_files "${_output_path}/_${PROJECT_NAME}_s.ep.${_typesupport_impl}.c")
76+
list(APPEND _generated_extension_files "${_generated_extension_${_typesupport_impl}_files}")
77+
endforeach()
7978
endif()
8079
set(_dependency_files "")
8180
set(_dependencies "")
@@ -126,11 +125,6 @@ endif()
126125

127126
set(_target_suffix "__py")
128127

129-
set(_PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE})
130-
if(WIN32 AND "${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
131-
set(PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE_DEBUG})
132-
endif()
133-
134128
# move custom command into a subdirectory to avoid multiple invocations on Windows
135129
set(_subdir "${CMAKE_CURRENT_BINARY_DIR}/${rosidl_generate_interfaces_TARGET}${_target_suffix}")
136130
file(MAKE_DIRECTORY "${_subdir}")
@@ -142,12 +136,9 @@ set_property(
142136
${_generated_extension_files} ${_generated_py_files} ${_generated_c_files}
143137
PROPERTY GENERATED 1)
144138

145-
# Export target so downstream interface packages can link to it
146-
set(rosidl_generator_py_suffix "__rosidl_generator_py")
147-
148-
set(_target_name_lib "${rosidl_generate_interfaces_TARGET}${rosidl_generator_py_suffix}")
139+
set(_target_name_lib "${rosidl_generate_interfaces_TARGET}__rosidl_generator_py")
149140
add_library(${_target_name_lib} SHARED ${_generated_c_files})
150-
target_link_libraries(${_target_name_lib}
141+
target_link_libraries(${_target_name_lib} PRIVATE
151142
${rosidl_generate_interfaces_TARGET}__rosidl_generator_c)
152143
add_dependencies(
153144
${_target_name_lib}
@@ -156,44 +147,23 @@ add_dependencies(
156147
)
157148

158149
target_link_libraries(
159-
${_target_name_lib}
160-
${PythonExtra_LIBRARIES}
150+
${_target_name_lib} PRIVATE
151+
Python3::NumPy
152+
Python3::Python
161153
)
162154
target_include_directories(${_target_name_lib}
163155
PRIVATE
164156
${CMAKE_CURRENT_BINARY_DIR}/rosidl_generator_c
165157
${CMAKE_CURRENT_BINARY_DIR}/rosidl_generator_py
166-
${PythonExtra_INCLUDE_DIRS}
167158
)
168159

169-
# Check if numpy is in the include path
170-
find_file(_numpy_h numpy/numpyconfig.h
171-
PATHS ${PythonExtra_INCLUDE_DIRS}
172-
)
173-
174-
if(APPLE OR WIN32 OR NOT _numpy_h)
175-
# add include directory for numpy headers
176-
set(_python_code
177-
"import numpy"
178-
"print(numpy.get_include())"
179-
)
180-
execute_process(
181-
COMMAND "${PYTHON_EXECUTABLE}" "-c" "${_python_code}"
182-
OUTPUT_VARIABLE _output
183-
RESULT_VARIABLE _result
184-
OUTPUT_STRIP_TRAILING_WHITESPACE
185-
)
186-
if(NOT _result EQUAL 0)
187-
message(FATAL_ERROR
188-
"execute_process(${PYTHON_EXECUTABLE} -c '${_python_code}') returned "
189-
"error code ${_result}")
190-
endif()
191-
message(STATUS "Using numpy include directory: ${_output}")
192-
target_include_directories(${_target_name_lib} PUBLIC "${_output}")
160+
set(_extension_compile_flags "")
161+
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
162+
set(_extension_compile_flags -Wall -Wextra)
193163
endif()
194164

195165
rosidl_get_typesupport_target(c_typesupport_target "${rosidl_generate_interfaces_TARGET}" "rosidl_typesupport_c")
196-
target_link_libraries(${_target_name_lib} ${c_typesupport_target})
166+
target_link_libraries(${_target_name_lib} PRIVATE ${c_typesupport_target})
197167

198168
foreach(_typesupport_impl ${_typesupport_impls})
199169
find_package(${_typesupport_impl} REQUIRED)
@@ -203,10 +173,9 @@ foreach(_typesupport_impl ${_typesupport_impls})
203173
continue()
204174
endif()
205175

206-
set(_pyext_suffix "__pyext")
207-
set(_target_name "${PROJECT_NAME}__${_typesupport_impl}${_pyext_suffix}")
176+
set(_target_name "${PROJECT_NAME}_s__${_typesupport_impl}")
208177

209-
add_library(${_target_name} SHARED
178+
python3_add_library(${_target_name} MODULE
210179
${_generated_extension_${_typesupport_impl}_files}
211180
)
212181
add_dependencies(
@@ -215,65 +184,62 @@ foreach(_typesupport_impl ${_typesupport_impls})
215184
${rosidl_generate_interfaces_TARGET}__rosidl_typesupport_c
216185
)
217186

218-
set(_extension_compile_flags "")
219-
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
220-
set(_extension_compile_flags -Wall -Wextra)
221-
endif()
187+
set_target_properties(${_target_name} PROPERTIES DEBUG_POSTFIX "${PythonExtra_POSTFIX}")
188+
# target_compile_options(${_target_name} PRIVATE ${_extension_compile_flags})
189+
# TODO(sloretz) use target_compile_options when python extension passes -Wpedantic
190+
set_target_properties(${_target_name} PROPERTIES COMPILE_OPTIONS "${_extension_compile_flags}")
191+
222192
set_target_properties(${_target_name} PROPERTIES
223-
COMPILE_OPTIONS "${_extension_compile_flags}"
224-
PREFIX ""
225-
OUTPUT_NAME "${PROJECT_NAME}_s__${_typesupport_impl}${PythonExtra_EXTENSION_SUFFIX}"
226-
SUFFIX "${PythonExtra_EXTENSION_EXTENSION}")
193+
LIBRARY_OUTPUT_DIRECTORY ${_output_path}
194+
RUNTIME_OUTPUT_DIRECTORY ${_output_path})
195+
227196
target_link_libraries(
228-
${_target_name}
197+
${_target_name} PRIVATE
229198
${_target_name_lib}
230-
${PythonExtra_LIBRARIES}
231199
${rosidl_generate_interfaces_TARGET}__${_typesupport_impl}
200+
${c_typesupport_target}
201+
rosidl_runtime_c::rosidl_runtime_c
202+
rosidl_typesupport_c::rosidl_typesupport_c
203+
rosidl_typesupport_interface::rosidl_typesupport_interface
232204
)
233205

234206
target_include_directories(${_target_name}
235-
PUBLIC
207+
PRIVATE
236208
${CMAKE_CURRENT_BINARY_DIR}/rosidl_generator_c
237209
${CMAKE_CURRENT_BINARY_DIR}/rosidl_generator_py
238-
${PythonExtra_INCLUDE_DIRS}
239210
)
240211

241-
target_link_libraries(${_target_name} ${c_typesupport_target})
242-
243-
ament_target_dependencies(${_target_name}
244-
"rosidl_runtime_c"
245-
"rosidl_typesupport_c"
246-
"rosidl_typesupport_interface"
247-
)
248212
foreach(_pkg_name ${rosidl_generate_interfaces_DEPENDENCY_PACKAGE_NAMES})
249-
ament_target_dependencies(${_target_name}
250-
${_pkg_name}
251-
)
213+
target_link_libraries(${_target_name} PRIVATE ${${_pkg_name}__TARGETS})
252214
endforeach()
253215

254216
add_dependencies(${_target_name}
255217
${rosidl_generate_interfaces_TARGET}__${_typesupport_impl}
256218
)
257-
ament_target_dependencies(${_target_name}
258-
"rosidl_runtime_c"
219+
220+
ament_target_dependencies(${_target_name} PUBLIC
259221
"rosidl_generator_py"
260222
)
261223

262224
if(NOT rosidl_generate_interfaces_SKIP_INSTALL)
225+
# PYTHON_INSTALL_DIR is defined by ament_cmake_python
263226
install(TARGETS ${_target_name}
264227
DESTINATION "${PYTHON_INSTALL_DIR}/${PROJECT_NAME}")
265228
endif()
266229
endforeach()
267230

268-
set(PYTHON_EXECUTABLE ${_PYTHON_EXECUTABLE})
269231

270232
# Depend on rosidl_generator_py generated targets from our dependencies
271233
foreach(_pkg_name ${rosidl_generate_interfaces_DEPENDENCY_PACKAGE_NAMES})
272-
target_link_libraries(${_target_name_lib} ${${_pkg_name}_TARGETS${rosidl_generator_py_suffix}})
234+
target_link_libraries(${_target_name_lib} PRIVATE ${${_pkg_name}_TARGETS${rosidl_generator_py_suffix}})
273235
endforeach()
274236

237+
set_target_properties(${_target_name_lib} PROPERTIES COMPILE_OPTIONS "${_extension_compile_flags}")
238+
275239
set_target_properties(${_target_name_lib} PROPERTIES
276-
COMPILE_OPTIONS "${_extension_compile_flags}")
240+
LIBRARY_OUTPUT_DIRECTORY ${_output_path}
241+
RUNTIME_OUTPUT_DIRECTORY ${_output_path})
242+
277243
if(NOT rosidl_generate_interfaces_SKIP_INSTALL)
278244
install(TARGETS ${_target_name_lib}
279245
EXPORT export_${_target_name_lib}

0 commit comments

Comments
 (0)