Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Permit building python bindings separately from gz-math library #636

Merged
merged 8 commits into from
Oct 28, 2024
Merged
10 changes: 0 additions & 10 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down
2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down
26 changes: 25 additions & 1 deletion src/python_pybind11/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 gz-math
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
cmake_minimum_required(VERSION 3.22.1)
set(GZ_MATH_VER 8)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm afraid about keeping this number in sync with bumps. As a workaround we can put a comment in the main CMakeLists.txt pointing to here. In the mid-term, it would be nice to integrate our CMake code to grab the version/name from git directly, probably using something like https://github.com/LecrisUT/CMakeExtraUtils/blob/main/cmake/DynamicVersion.md

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not a big fan of using git for version information as fails for tarballs. Something a bit ugly but effective could be to grep the major version from the parent folder CMakeLists.txt .

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or we could extract the version numbers from package.xml, since we also have a workflow to keep those versions in sync

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prototype for extracting version numbers from package.xml: #639

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've also opened gazebosim/gz-cmake#456 adding the python script from #639 and a cmake helper function. If you don't mind approving this PR for now so we can start to fix CI, I will follow-up by using the gz-cmake helper once it has been merged and released

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
Expand Down Expand Up @@ -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")
Expand Down
39 changes: 37 additions & 2 deletions tutorials/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
```

Expand Down Expand Up @@ -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`:
Expand Down Expand Up @@ -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=<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).
Expand Down