From 97ad436a0d561c77422de83cebb600379cc9c94a 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 (cherry picked from commit 17deea2ba86948c3a92aeed7cb541d05c9492c56) # Conflicts: # CMakeLists.txt # src/python_pybind11/CMakeLists.txt --- CMakeLists.txt | 9 +++++++ src/CMakeLists.txt | 2 +- src/python_pybind11/CMakeLists.txt | 27 ++++++++++++++++++++- tutorials/installation.md | 39 ++++++++++++++++++++++++++++-- 4 files changed, 73 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 992d1b04b..a9f46adf5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,6 +99,7 @@ endif() if (SKIP_PYBIND11) message(STATUS "SKIP_PYBIND11 set - disabling python bindings") else() +<<<<<<< HEAD #include(GzPython) TODO: allow to specify for what it should search and then # the code below can be removed; e.g. pybind needs Interpreter and Development components # see https://pybind11.readthedocs.io/en/stable/cmake/index.html#new-findpython-mode @@ -133,6 +134,14 @@ else() GZ_BUILD_WARNING("pybind11 is missing: Python interfaces are disabled.") message (STATUS "Searching for pybind11 - not found.") endif() +======= + find_package(Python3 REQUIRED + COMPONENTS Interpreter + OPTIONAL_COMPONENTS Development + ) + if (NOT Python3_Development_FOUND) + GZ_BUILD_WARNING("Python development libraries are missing: Python interfaces are disabled.") +>>>>>>> 17deea2b (Permit building python bindings separately from gz-math library (#636)) 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 c382557a8..74235a486 100644 --- a/src/python_pybind11/CMakeLists.txt +++ b/src/python_pybind11/CMakeLists.txt @@ -1,3 +1,4 @@ +<<<<<<< HEAD if(${CMAKE_VERSION} VERSION_LESS "3.12.0") # TODO: remove once the minimum CMake version is increased if(WIN32 AND CMAKE_BUILD_TYPE STREQUAL "Debug") @@ -6,6 +7,30 @@ if(${CMAKE_VERSION} VERSION_LESS "3.12.0") # This works around the issue. set(PYTHON_LIBRARIES "${PYTHON_DEBUG_LIBRARIES}") endif() +======= +# 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() +>>>>>>> 17deea2b (Permit building python bindings separately from gz-math library (#636)) endif() message(STATUS "Building pybind11 interfaces") @@ -96,7 +121,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).