Skip to content

Commit

Permalink
Python: Added basic structure (#932)
Browse files Browse the repository at this point in the history
Signed-off-by: ahcorde <[email protected]>
  • Loading branch information
ahcorde authored Apr 5, 2022
1 parent 6e7336c commit 266d452
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .github/ci/packages.apt
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,8 @@ libignition-utils1-cli-dev
libtinyxml2-dev
liburdfdom-dev
libxml2-utils
python3-dev
python3-distutils
python3-psutil
python3-pybind11
ruby-dev
37 changes: 35 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.10.2 FATAL_ERROR)
cmake_minimum_required(VERSION 3.12 FATAL_ERROR)

if(COMMAND CMAKE_POLICY)
CMAKE_POLICY(SET CMP0003 NEW)
Expand All @@ -21,6 +21,16 @@ set (BUILD_SDF ON CACHE INTERNAL "Build SDF" FORCE)
find_package(ignition-cmake2 2.10 REQUIRED)
set(IGN_CMAKE_VER ${ignition-cmake2_VERSION_MAJOR})

########################################
# Python interfaces vars
option(USE_SYSTEM_PATHS_FOR_PYTHON_INSTALLATION
"Install python modules in standard system paths in the system"
OFF)

option(USE_DIST_PACKAGES_FOR_PYTHON
"Use dist-packages instead of site-package to install python modules"
OFF)

if (BUILD_SDF)
ign_configure_project(
NO_IGNITION_PREFIX
Expand Down Expand Up @@ -70,7 +80,7 @@ if (BUILD_SDF)
# A module's location is usually a directory, but for
# binary modules
# it's a .so file.
execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c" "import re, ${module}; print(re.compile('/__init__.py.*').sub('',${module}.__file__))"
execute_process(COMMAND "${Python3_EXECUTABLE}" "-c" "import re, ${module}; print(re.compile('/__init__.py.*').sub('',${module}.__file__))"
RESULT_VARIABLE _${module}_status
OUTPUT_VARIABLE _${module}_location
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
Expand Down Expand Up @@ -114,6 +124,26 @@ if (BUILD_SDF)
ign_find_package(ignition-common5 COMPONENTS graphics REQUIRED_BY usd)
set(IGN_COMMON_VER ${ignition-common5_VERSION_MAJOR})

########################################
# Python interfaces
if (NOT PYTHON3_FOUND)
IGN_BUILD_WARNING("Python is missing: Python interfaces are disabled.")
message (STATUS "Searching for Python - not found.")
else()
message (STATUS "Searching for Python - found version ${Python3_VERSION}.")

set(PYBIND11_PYTHON_VERSION 3)
find_package(pybind11 2.4 QUIET)

if (${pybind11_FOUND})
find_package(Python3 ${IGN_PYTHON_VERSION} REQUIRED COMPONENTS Development)
message (STATUS "Searching for pybind11 - found version ${pybind11_VERSION}.")
else()
IGN_BUILD_WARNING("pybind11 is missing: Python interfaces are disabled.")
message (STATUS "Searching for pybind11 - not found.")
endif()
endif()

########################################
# Find PXR
ign_find_package(pxr QUIET REQUIRED_BY usd PKGCONFIG pxr)
Expand All @@ -126,6 +156,9 @@ if (BUILD_SDF)
add_subdirectory(sdf)
add_subdirectory(conf)
add_subdirectory(doc)
if (${pybind11_FOUND})
add_subdirectory(python)
endif()
endif(BUILD_SDF)

########################################
Expand Down
19 changes: 19 additions & 0 deletions examples/python/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# sdformat Python API

This example shows how to use sdformat's Python API.

In the
[examples/python](https://github.com/ignitionrobotics/sdformat/blob/main/examples/python)
folder there is a Python script that shows how to make use of this API.

> If you compiled sdformat from source you should modify your `PYTHONPATH`:
>
> ```bash
> export PYTHONPATH=$PYTHONPATH:<path to ws>/install/lib/python
> ```
Now you can run the example:
```bash
$ python3 python_sdformat.py
```
15 changes: 15 additions & 0 deletions examples/python/python_sdformat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Copyright (C) 2022 Open Source Robotics Foundation

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

# http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import sdformat
63 changes: 63 additions & 0 deletions python/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
if(WIN32 AND CMAKE_BUILD_TYPE STREQUAL "Debug")
# pybind11 logic for setting up a debug build when both a debug and release
# python interpreter are present in the system seems to be pretty much broken.
# This works around the issue.
set(PYTHON_LIBRARIES "${PYTHON_DEBUG_LIBRARIES}")
endif()


if(USE_SYSTEM_PATHS_FOR_PYTHON_INSTALLATION)
if(${CMAKE_VERSION} VERSION_LESS "3.12.0")
execute_process(
COMMAND "${PYTHON_EXECUTABLE}" -c "if True:
from distutils import sysconfig as sc
print(sc.get_python_lib(plat_specific=True))"
OUTPUT_VARIABLE Python3_SITEARCH
OUTPUT_STRIP_TRAILING_WHITESPACE)
else()
# Get install variable from Python3 module
# Python3_SITEARCH is available from 3.12 on, workaround if needed:
find_package(Python3 COMPONENTS Interpreter)
endif()

if(USE_DIST_PACKAGES_FOR_PYTHON)
string(REPLACE "site-packages" "dist-packages" IGN_PYTHON_INSTALL_PATH ${Python3_SITEARCH})
endif()
else()
# If not a system installation, respect local paths
set(IGN_PYTHON_INSTALL_PATH ${IGN_LIB_INSTALL_DIR}/python)
endif()

# Set the build location and install location for a CPython extension
function(configure_build_install_location _library_name)
# Install library for actual use
install(TARGETS ${_library_name}
DESTINATION "${IGN_PYTHON_INSTALL_PATH}"
)
endfunction()

pybind11_add_module(sdformat SHARED
src/sdf/_ignition_sdformat_pybind11.cc
)

target_link_libraries(sdformat PRIVATE
${PROJECT_LIBRARY_TARGET_NAME}
)

configure_build_install_location(sdformat)

if (BUILD_TESTING)
set(python_tests
)

foreach (test ${python_tests})
add_test(NAME ${test}.py COMMAND
"${Python3_EXECUTABLE}" "${CMAKE_SOURCE_DIR}/python/test/${test}.py")

set(_env_vars)
list(APPEND _env_vars "PYTHONPATH=${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/python/")
list(APPEND _env_vars "LD_LIBRARY_PATH=${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}:$ENV{LD_LIBRARY_PATH}")
set_tests_properties(${test}.py PROPERTIES
ENVIRONMENT "${_env_vars}")
endforeach()
endif()
21 changes: 21 additions & 0 deletions python/src/sdf/_ignition_sdformat_pybind11.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright (C) 2022 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <pybind11/pybind11.h>

PYBIND11_MODULE(sdformat, m) {
m.doc() = "sdformat Python Library.";
}

0 comments on commit 266d452

Please sign in to comment.