From 17deea2ba86948c3a92aeed7cb541d05c9492c56 Mon Sep 17 00:00:00 2001 From: Steve Peters Date: Mon, 28 Oct 2024 13:50:20 -0700 Subject: [PATCH] Permit building python bindings separately from gz-math library (#636) This allows the src/python_pybind11/CMakeLists.txt file to be built as a top-level cmake project against an external gz-math library, with documentation added to the installation tutorial. The logic for finding pybind11 is also moved from the root CMakeLists.txt to src/python_pybind11/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 src/python_pybind11 folder, pybind11 is treated it as required by setting CMAKE_REQUIRE_FIND_PACKAGE_pybind11 to TRUE. Signed-off-by: Silvio Traversaro Signed-off-by: Steve Peters Co-authored-by: Silvio Traversaro --- CMakeLists.txt | 10 -------- src/CMakeLists.txt | 2 +- src/python_pybind11/CMakeLists.txt | 26 +++++++++++++++++++- tutorials/installation.md | 39 ++++++++++++++++++++++++++++-- 4 files changed, 63 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f9fc1f82a..342d44659 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -105,16 +105,6 @@ else() ) 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.2 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() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0adbed149..85582b6f3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -18,7 +18,7 @@ gz_build_tests(TYPE UNIT SOURCES ${gtest_sources}) add_subdirectory(graph) # Bindings subdirectories -if (pybind11_FOUND AND NOT SKIP_PYBIND11) +if (Python3_Development_FOUND AND NOT SKIP_PYBIND11) add_subdirectory(python_pybind11) endif() diff --git a/src/python_pybind11/CMakeLists.txt b/src/python_pybind11/CMakeLists.txt index a3c6fc314..89af730de 100644 --- a/src/python_pybind11/CMakeLists.txt +++ b/src/python_pybind11/CMakeLists.txt @@ -1,3 +1,27 @@ +# Detect if we are doing a standalone build of the bindings, using an external gz-math +if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) + cmake_minimum_required(VERSION 3.22.1) + set(GZ_MATH_VER 8) + project(gz-math${GZ_MATH_VER}-python VERSION ${GZ_MATH_VER}) + find_package(gz-math${PROJECT_VERSION_MAJOR} REQUIRED) + set(PROJECT_LIBRARY_TARGET_NAME "gz-math${PROJECT_VERSION_MAJOR}::gz-math${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.2 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() + message(STATUS "Building pybind11 interfaces") set(BINDINGS_MODULE_NAME "math${PROJECT_VERSION_MAJOR}") # Split from main extension and converted to pybind11 @@ -81,7 +105,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(GZ_PYTHON_INSTALL_PATH "${GZ_PYTHON_INSTALL_PATH}/gz") diff --git a/tutorials/installation.md b/tutorials/installation.md index 94e77b5d8..63252e1b8 100644 --- a/tutorials/installation.md +++ b/tutorials/installation.md @@ -38,9 +38,9 @@ you should use `ign-math<#>`. ### macOS -On macOS, add OSRF packages: +On macOS, after installing the [Homebrew package manager](https://brew.sh), +add OSRF packages: ``` - /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" brew tap osrf/simulation ``` @@ -92,6 +92,13 @@ The optional Eigen component of Gazebo Math requires: sudo apt-get install libeigen3-dev ``` +The optional Python bindings of Gazebo Math require: + +* [Pybind11](https://pybind11.readthedocs.io/en/stable/index.html). Refer to the [Pybind11 Documentation](https://pybind11.readthedocs.io/en/stable/installing.html) for installation instructions. On Ubuntu systems, `apt-get` can be used to install Pybind11: + ``` + sudo apt-get install python3-pybind11 + ``` + The optional Ruby tests of Gazebo Math require: * [Ruby](https://www.ruby-lang.org/). Refer to the [Ruby Documentation](https://www.ruby-lang.org/downloads/) for installation instructions. On Ubuntu systems `apt-get` can be used to install Ubuntu Package `ruby-dev`: @@ -228,6 +235,34 @@ The optional Eigen component of Gazebo Math requires: cmake --install . --config Release ``` +### cmake parameters + +| Name | Type | Default | Description | +|-----------------|------|---------|--------------------------------------------| +| `SKIP_PYBIND11` | BOOL | OFF | Set to ON to skip building python bindings | + +### Building Python bindings separately from main library + +If you want to build Python bindings separately from the main gz-math library +(for example if you want to build Python bindings for multiple versions of Python), +you can invoke cmake on the `src/python_pybind11` 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 gz-math +mkdir build_python3 +cd build_python3 +cmake ../src/python_pybind11 \ + -DPython3_EXECUTABLE=/usr/local/bin/python3.12 \ + -DCMAKE_INSTALL_PREFIX= +``` + +See the homebrew [gz-math8 formula](https://github.com/osrf/homebrew-simulation/blob/ccda47647ed9aeb38f0ea1ec8804fd1501058de1/Formula/gz-math8.rb#L12-L52) +for an example of building bindings for multiple versions of Python. + # Documentation API and tutorials can be found at [https://gazebosim.org/libs/math](https://gazebosim.org/libs/math).