From 0f9b0526ec6bf47b8472dd8fffc9f302509881f5 Mon Sep 17 00:00:00 2001 From: Steve Peters Date: Fri, 8 Nov 2024 14:47:06 -0800 Subject: [PATCH] Permit building python bindings separately from main library (#554) This allows the python/CMakeLists.txt file to be built as a top-level cmake project against an external gz-transport library, with documentation added to the installation tutorial. 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: Silvio Traversaro Signed-off-by: Steve Peters Co-authored-by: Silvio Traversaro (cherry picked from commit 250e95f0757af410adfaab213b3077c0a501252e) # Conflicts: # python/CMakeLists.txt --- CMakeLists.txt | 16 ++---- python/CMakeLists.txt | 31 ++++++++++-- tutorials/02_installation.md | 94 +++++++++++++++++++++--------------- 3 files changed, 87 insertions(+), 54 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index eef3b1073..6c10ff528 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,19 +58,11 @@ if (SKIP_PYBIND11) message(STATUS "SKIP_PYBIND11 set - disabling python bindings") find_package(Python3 COMPONENTS Interpreter) else() - find_package(Python3 COMPONENTS Interpreter Development) + find_package(Python3 + COMPONENTS Interpreter + OPTIONAL_COMPONENTS Development) 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() @@ -164,7 +156,7 @@ add_subdirectory(conf) #============================================================================ # gz transport python bindings #============================================================================ -if (pybind11_FOUND AND NOT SKIP_PYBIND11) +if (Python3_Development_FOUND AND NOT SKIP_PYBIND11) add_subdirectory(python) endif() diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index ea5f46b7d..34c25c669 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -1,8 +1,33 @@ +<<<<<<< HEAD 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}") +======= +# Detect if we are doing a standalone build of the bindings, using an external gz-transport +if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) + cmake_minimum_required(VERSION 3.22.1) + set(GZ_TRANSPORT_VER 14) + project(gz-transport${GZ_TRANSPORT_VER}-python VERSION ${GZ_TRANSPORT_VER}) + find_package(gz-transport${PROJECT_VERSION_MAJOR} REQUIRED) + set(PROJECT_LIBRARY_TARGET_NAME "gz-transport${PROJECT_VERSION_MAJOR}::gz-transport${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() +>>>>>>> 250e95f0 (Permit building python bindings separately from main library (#554)) endif() if(USE_SYSTEM_PATHS_FOR_PYTHON_INSTALLATION) @@ -27,7 +52,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") @@ -83,10 +108,10 @@ if (BUILD_TESTING AND NOT WIN32) foreach (test ${python_tests}) if (pytest_FOUND) add_test(NAME ${test}.py COMMAND - "${Python3_EXECUTABLE}" -m pytest "${CMAKE_SOURCE_DIR}/python/test/${test}.py" --junitxml "${CMAKE_BINARY_DIR}/test_results/${test}.xml") + "${Python3_EXECUTABLE}" -m pytest "${CMAKE_CURRENT_SOURCE_DIR}/test/${test}.py" --junitxml "${CMAKE_BINARY_DIR}/test_results/${test}.xml") else() add_test(NAME ${test}.py COMMAND - "${Python3_EXECUTABLE}" "${CMAKE_SOURCE_DIR}/python/test/${test}.py") + "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/test/${test}.py") endif() set(_env_vars) list(APPEND _env_vars "CMAKE_BINARY_DIR=${CMAKE_BINARY_DIR}/bin") diff --git a/tutorials/02_installation.md b/tutorials/02_installation.md index d32d3997c..be66a0aba 100644 --- a/tutorials/02_installation.md +++ b/tutorials/02_installation.md @@ -45,13 +45,10 @@ library and rebuilding dependencies due to the use of c++11. For purposes of this documentation, Assuming OS X 10.9 or greater is in use. Here are the instructions: -Install homebrew, which should also prompt you to install the XCode -command-line tools: -``` -/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" -``` +After installing the [Homebrew package manager](https://brew.sh), +which should also prompt you to install the XCode command-line tools +add OSRF packages and run the install command: -Run the following commands: ``` brew tap osrf/simulation brew install gz-transport<#> @@ -81,7 +78,9 @@ which version you need. # Source Install -## Ubuntu Linux +## Install Prerequisites + +### Ubuntu Linux For compiling the latest version of Gazebo Transport you will need an Ubuntu distribution equal to 20.04 (Focal) or newer. @@ -97,10 +96,29 @@ Install prerequisites. A clean Ubuntu system will need: sudo apt-get install git cmake pkg-config python ruby-ronn libprotoc-dev libprotobuf-dev protobuf-compiler uuid-dev libzmq3-dev libgz-msgs10-dev libgz-utils2-cli-dev ``` +### macOS + +After installing the [Homebrew package manager](https://brew.sh), +which should also prompt you to install the XCode command-line tools +add OSRF packages and run the command to install dependencies: + +``` +brew tap osrf/simulation +brew install --only-dependencies gz-transport<#> +``` + +Be sure to replace `<#>` with a number value, such as 10 or 11, depending on +which version you need. + +## Clone, Configure, and Build + Clone the repository ``` -git clone https://github.com/gazebosim/gz-transport +git clone https://github.com/gazebosim/gz-transport -b gz-transport<#> ``` +Be sure to replace `<#>` with a number value, such as 10 or 11, depending on +which version you need. From version 12 use `gz-transport<#>` for lower versions +use `ign-transport<#>` Configure and build ``` @@ -111,6 +129,13 @@ cmake .. make ``` +Optionally, install +``` +sudo make install +``` + +### Configuration options + Configure Gazebo Transport (choose either method a or b below): A. Release mode (recommended): This will generate optimized code, but will not have @@ -159,6 +184,28 @@ modify your `LD_LIBRARY_PATH`: echo "export LD_LIBRARY_PATH=/local/lib:$LD_LIBRARY_PATH" >> ~/.bashrc ``` +### Build python bindings separately from main library + +If you want to build Python bindings separately from the main gz-transport 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= +``` + +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. + ### Uninstalling Source-based Install If you need to uninstall Gazebo Transport or switch back to a @@ -170,37 +217,6 @@ cd /tmp/gz-transport/build sudo make uninstall ``` -### macOS - -1. Clone the repository - ``` - git clone https://github.com/gazebosim/gz-transport -b gz-transport<#> - ``` - Be sure to replace `<#>` with a number value, such as 10 or 11, depending on - which version you need. From version 12 use `gz-transport<#>` for lower versions - use `ign-transport<#>` - -2. Install dependencies - ``` - brew install --only-dependencies gz-transport<#> - ``` - Be sure to replace `<#>` with a number value, such as 10 or 11, depending on - which version you need. - -3. Configure and build - ``` - cd gz-transport - mkdir build - cd build - cmake .. - make - ``` - -4. Optionally, install - ``` - sudo make install - ``` - ## Windows ### Prerequisites