Skip to content

Commit

Permalink
Permit building python bindings separately from libsdformat library (#…
Browse files Browse the repository at this point in the history
…1491)

This allows the src/python_pybind11/CMakeLists.txt file to be
built as a top-level cmake project against an external sdformat
library, with documentation added to the README.

The logic for finding pybind11 is also moved from the root
CMakeLists.txt to python/CMakeLists.txt to reduce code
duplication. When invoked through the root CMakeLists.txt,
pybind11 is treated as an optional dependency, but when
invoked from the python folder, pybind11 is treated as
required by setting the variable
CMAKE_REQUIRE_FIND_PACKAGE_pybind11 to TRUE.

Signed-off-by: Steve Peters <[email protected]>
Signed-off-by: Silvio Traversaro <[email protected]>
Co-authored-by: Silvio Traversaro <[email protected]>
  • Loading branch information
scpeters and traversaro authored Nov 5, 2024
1 parent bf36eb7 commit 3dcdd55
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 13 deletions.
12 changes: 1 addition & 11 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -97,16 +97,6 @@ if (BUILD_SDF)
)
if (NOT Python3_Development_FOUND)
GZ_BUILD_WARNING("Python development libraries are missing: Python interfaces are disabled.")
else()
set(PYBIND11_PYTHON_VERSION 3)
find_package(pybind11 2.4 CONFIG QUIET)

if (pybind11_FOUND)
message (STATUS "Searching for pybind11 - found version ${pybind11_VERSION}.")
else()
GZ_BUILD_WARNING("pybind11 is missing: Python interfaces are disabled.")
message (STATUS "Searching for pybind11 - not found.")
endif()
endif()
endif()

Expand Down Expand Up @@ -159,7 +149,7 @@ if (BUILD_SDF)
add_subdirectory(sdf)
add_subdirectory(conf)
add_subdirectory(doc)
if (pybind11_FOUND AND NOT SKIP_PYBIND11)
if (Python3_Development_FOUND AND NOT SKIP_PYBIND11)
add_subdirectory(python)
endif()
endif(BUILD_SDF)
Expand Down
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,32 @@ sdformat supported cmake parameters at configuring time:

| Name | Type | Default | Description |
|-----------------------|------|----------|--------------------------------------|
| `SKIP_PYBIND11` | BOOL | False | Skip generating Python bindings via pybind11 |
| `USE_INTERNAL_URDF` | BOOL | False | Use an internal copy of urdfdom 1.0.0 instead of looking for one installed in the system |
| `USE_UPSTREAM_CFLAGS` | BOOL | True | Use the sdformat team compilation flags instead of the common set defined by cmake. |

### Build python bindings separately from main library

If you want to build Python bindings separately from the main libsdformat library
(for example if you want to build Python bindings for multiple versions of Python),
you can invoke cmake on the `python` folder instead of the root folder.
Specify the path to the python executable with which you wish to build bindings
in the `Python3_EXECUTABLE` cmake variable.
Specify the install path for the bindings in the `CMAKE_INSTALL_PREFIX`
variable, and be sure to set your `PYTHONPATH` accordingly after install.

```bash
cd sdformat
mkdir build_python3
cd build_python3
cmake ../python \
-DPython3_EXECUTABLE=/usr/local/bin/python3.12 \
-DCMAKE_INSTALL_PREFIX=<prefix>
```

See the homebrew [sdformat15 formula](https://github.com/osrf/homebrew-simulation/blob/027d06f5be49da1e40d01180aedae7f76dc7ff47/Formula/sdformat15.rb#L12-L56)
for an example of building bindings for multiple versions of Python.

## Uninstallation

To uninstall the software installed with the previous steps:
Expand Down
27 changes: 25 additions & 2 deletions python/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
# Detect if we are doing a standalone build of the bindings, using an external sdformat
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
cmake_minimum_required(VERSION 3.22.1)
set(SDF_VER 15)
project(sdformat${SDF_VER}-python VERSION ${SDF_VER})
find_package(sdformat${SDF_VER} REQUIRED)
set(PROJECT_LIBRARY_TARGET_NAME "sdformat${PROJECT_VERSION_MAJOR}::sdformat${PROJECT_VERSION_MAJOR}")
# require python dependencies to be found
find_package(Python3 COMPONENTS Interpreter Development REQUIRED)
set(CMAKE_REQUIRE_FIND_PACKAGE_pybind11 TRUE)
include(GNUInstallDirs)
include(CTest)
endif()

set(PYBIND11_PYTHON_VERSION 3)
find_package(pybind11 2.4 CONFIG QUIET)

if (pybind11_FOUND)
message (STATUS "Searching for pybind11 - found version ${pybind11_VERSION}.")
else()
message(WARNING "pybind11 is missing: Python interfaces are disabled.")
return()
endif()

if(USE_SYSTEM_PATHS_FOR_PYTHON_INSTALLATION)
if(NOT Python3_SITEARCH)
# Get variable from Python3 module
Expand All @@ -12,7 +36,7 @@ if(USE_SYSTEM_PATHS_FOR_PYTHON_INSTALLATION)
endif()
else()
# If not a system installation, respect local paths
set(GZ_PYTHON_INSTALL_PATH ${GZ_LIB_INSTALL_DIR}/python)
set(GZ_PYTHON_INSTALL_PATH ${CMAKE_INSTALL_LIBDIR}/python)
endif()

# Set the build location and install location for a CPython extension
Expand Down Expand Up @@ -108,7 +132,6 @@ if (BUILD_TESTING AND NOT WIN32)

target_link_libraries(sdformattest PRIVATE
${PROJECT_LIBRARY_TARGET_NAME}
gz-utils${GZ_UTILS_VER}::gz-utils${GZ_UTILS_VER}
)

set(python_tests
Expand Down

0 comments on commit 3dcdd55

Please sign in to comment.