diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
deleted file mode 100644
index be06278..0000000
--- a/.gitlab-ci.yml
+++ /dev/null
@@ -1,53 +0,0 @@
-stages:
- - build
- - publish
- - release
-
-.if-tag: &if-tag
- if: "$CI_COMMIT_TAG =~ /^qi-python-v/"
-
-build-wheel:
- stage: build
- rules:
- # Allow manually building on a Git commit on any branch.
- - if: $CI_COMMIT_BRANCH
- when: manual
- # Always build on a Git tag.
- - <<: *if-tag
- tags:
- - docker
- image: python:3.8
- script:
- - curl -sSL https://get.docker.com/ | sh
- - pip install cibuildwheel==2.14.1
- - cibuildwheel --output-dir wheelhouse
- artifacts:
- paths:
- - wheelhouse/
-
-publish-wheel:
- stage: publish
- image: python:latest
- rules:
- - <<: *if-tag
- needs:
- - build-wheel
- script:
- - pip install build twine
- - python -m build
- - TWINE_PASSWORD="${CI_JOB_TOKEN}"
- TWINE_USERNAME=gitlab-ci-token
- python -m twine upload
- --repository-url "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/pypi"
- wheelhouse/*
-
-create-release:
- stage: release
- rules:
- - <<: *if-tag
- script:
- - echo "Releasing $CI_COMMIT_TAG."
- release:
- tag_name: $CI_COMMIT_TAG
- name: 'lib$CI_COMMIT_TITLE'
- description: '$CI_COMMIT_TAG_MESSAGE'
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..3250f1e
--- /dev/null
+++ b/README.md
@@ -0,0 +1,103 @@
+# qi package - Python binding for Libqi
+
+This repository contains the Python bindings of [LibQi](https://github.com/funwithagents/libqi), the library used to communicate with robots using Naoqi (Nao & Pepper).
+
+These LibQi python bindings correspond to the `qi` Python module.
+
+## Up-to-date repository for compatibility with recent Python versions and OS
+
+- This repository is a fork of the official [libqi-python](https://github.com/aldebaran/libqi-python) repository (that seems to be not maintained by Aldebaran anymore).
+- I created it mainly to update the code of the package to be able to build it with recent versions of Python (3.10+) on MacOS and Linux
+
+## Pre-built packages
+
+- Check the [Releases](https://github.com/funwithagents/libqi-python/releases) to directly retrieve python wheels compatible with recent version of Python, for MacOS and Linux
+- To install the packages
+ - download the wheel file (.whl) corresponding to your python version and OS
+ - install the package using `pip install path/to/wheel.whl`
+
+## Building from sources
+
+
+MacOS
+
+💡 This has been tested on a Mac with arm64 architecture & MacOS Sequoia (15.3.1)
+
+- setup you python installation (you can use pyenv if you want to be able to choose a specific Python version)
+ - `pyenv install 3.13`
+ - `pyenv global 3.13`
+- setup a python environment and switch to it (for example using venv)
+ - `python -m venv ~/py-venv/py3.13-buildlibqipython`
+ - `source ~/py-venv/py3.13-buildlibqipython/bin/activate`
+- install needed python packages
+ - `pip install -r requirements_macos.txt`
+- clone this repository and go to the root of it
+- generate (if not already done) your conan profile
+ - `conan profile detect`
+- check you conan profile
+ - `cat ~/.conan2/profiles/default`
+ - it should display something similar to this
+
+ ```
+ [settings]
+ arch=armv8
+ build_type=Release
+ compiler=apple-clang
+ compiler.cppstd=gnu17
+ compiler.libcxx=libc++
+ compiler.version=16
+ os=Macos
+ ```
+
+- execute the build script with all the needed steps
+ - `chmod +x execute_build_wheel_macos.sh`
+ - `./execute_build_wheel_macos.sh`
+
+🥳 **Congratulations**
+It should have generated the python wheel :
+- in folder `./dist/fixed/`
+- with name similar to `qi-3.1.6-cp313-cp313-macosx_15_0_arm64.whl`
+
+
+
+Linux
+
+💡 This has been tested on a x86_64 architecture & Ubuntu 22.04
+
+- install c++ compiler
+ - `sudo apt-get install build-essential`
+- setup you python installation (you can use pyenv if you want to be able to choose a specific Python version)
+ - `pyenv install 3.13`
+ - `pyenv global 3.13`
+- setup a python environment and switch to it (for example using venv)
+ - `python -m venv ~/py-venv/py3.13-buildlibqipython`
+ - `source ~/py-venv/py3.13-buildlibqipython/bin/activate`
+- install needed python packages
+ - `pip install -r requirements_linux.txt`
+- clone this repository and go to the root of it
+- generate (if not already done) your conan profile
+ - `conan profile detect`
+- check you conan profile
+ - `cat ~/.conan2/profiles/default`
+ - it should display something similar to this
+
+ ```
+ [settings]
+ arch=x86_64
+ build_type=Release
+ compiler=gcc
+ compiler.cppstd=gnu17
+ compiler.libcxx=libstdc++11
+ compiler.version=11
+ os=Linux
+ ```
+
+- execute the build script with all the needed steps
+ - `chmod +x execute_build_wheel_linux.sh`
+ - `./execute_build_wheel_linux.sh`
+
+🥳 **Congratulations**
+It should have generated the python wheel :
+- in folder `./dist/fixed/`
+- with name similar to `qi-3.1.6-cp313-cp313-manylinux_2_34_x86_64.whl`
+
diff --git a/README.rst b/README.rst
deleted file mode 100644
index 8d35691..0000000
--- a/README.rst
+++ /dev/null
@@ -1,199 +0,0 @@
-===================================
-LibQiPython - LibQi Python bindings
-===================================
-
-This repository contains the official Python bindings of the `LibQi`__, the ``qi``
-Python module.
-
-__ LibQi_repo_
-
-Building
-========
-
-To build the project, you need:
-
-- a compiler that supports C++17.
-
- - on Ubuntu: `apt-get install build-essential`.
-
-- CMake with at least version 3.23.
-
- - on PyPI (**recommended**): `pip install "cmake>=3.23"`.
- - on Ubuntu: `apt-get install cmake`.
-
-- Python with at least version 3.7 and its development libraries.
-
- - On Ubuntu: `apt-get install libpython3-dev`.
-
-- a Python `virtualenv`.
-
- - On Ubuntu:
-
- .. code-block:: console
-
- apt-get install python3-venv
- python3 -m venv ~/my-venv # Use the path of your convenience.
- source ~/my-venv/bin/activate
-
-.. note::
- The CMake project offers several configuration options and exports a set
- of targets when installed. You may refer to the ``CMakeLists.txt`` file
- for more details about available parameters and exported targets.
-
-.. note::
- The procedures described below assume that you have downloaded the project
- sources, that your current working directory is the project sources root
- directory and that you are working inside your virtualenv.
-
-Conan
-^^^^^
-
-Additionally, `libqi-python` is available as a Conan 2 project, which means you
-can use Conan to fetch dependencies.
-
-You can install and/or upgrade Conan 2 and create a default profile in the
-following way:
-
-.. code-block:: console
-
- # install/upgrade Conan 2
- pip install --upgrade conan~=2
- # create a default profile
- conan profile detect
-
-Install dependencies from Conan and build with CMake
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The procedure to build the project using Conan to fetch dependencies is the
-following.
-
-Most dependencies are available on Conan Center repository and should not
-require any additional steps to make them available. However, you might need to
-first get and export the `libqi` recipe into your local Conan cache.
-
-.. code-block:: console
-
- # GitHub is available, but you can also use internal GitLab.
- QI_REPOSITORY="https://github.com/aldebaran/libqi.git"
- QI_VERSION="4.0.1" # Checkout the version your project need.
- QI_PATH="$HOME/libqi" # Or whatever path you want.
- git clone \
- --depth=1 `# Only fetch one commit.` \
- --branch "qi-framework-v${QI_VERSION}" \
- "${QI_REPOSITORY}" \
- "${QI_PATH}"
- conan export "${QI_PATH}" \
- --version "${QI_VERSION}" # Technically not required but some
- # versions of libqi require it
- # because of a bug.
-
-You can then install the `libqi-python` dependencies in Conan.
-
-.. code-block:: console
-
- conan install . \
- --build=missing `# Build dependencies binaries that are missing in Conan.` \
- -s build_type=Debug `# Build in debug mode.` \
- -c tools.build:skip_test=true `# Skip tests building for dependencies.` \
- -c '&:tools.build:skip_test=false' # Do not skip tests for the project.
-
-This will generate a build directory containing a configuration with a
-toolchain file that allows CMake to find dependencies inside the Conan cache.
-
-You can then invoke CMake directly inside the build configuration directory to
-configure and build the project. Fortunately, Conan also generates a CMake
-preset that simplifies the process. The name of the preset may differ on
-your machine. You may need to find the preset generated by Conan first by
-calling:
-
-.. code-block:: console
-
- cmake --list-presets
-
-Here, we'll assume that the preset is named `conan-linux-x86_64-gcc-debug`.
-To start building, you need to configure with CMake and then build:
-
-.. code-block:: console
-
- cmake --preset conan-linux-x86_64-gcc-debug
- cmake --build --preset conan-linux-x86_64-gcc-debug
-
-Tests can now be invoked using CTest_, but they require a runtime environment
-from Conan so that all dependencies are found:
-
-.. code-block:: console
-
- source build/linux-x86_64-gcc-debug/generators/conanrun.sh
- ctest --preset conan-linux-x86_64-gcc-debug --output-on-failure
- source build/linux-x86_64-gcc-debug/generators/deactivate_conanrun.sh
-
-Finally, you can install the project in the directory of your choice.
-
-The project defines a single install component, the ``Module`` component.
-
-.. code-block:: console
-
- # `cmake --install` does not support presets sadly.
- cmake \
- --install build/linux-x86_64-gcc-debug \
- --component Module --prefix ~/my-libqi-python-install
-
-Wheel (PEP 517)
----------------
-
-You may build this project as a wheel package using PEP 517.
-
-It uses a scikit-build_ backend which interfaces with CMake.
-
-You may need to provide a toolchain file so that CMake finds the required
-dependencies, such as a toolchain generated by Conan:
-
-.. code-block:: console
-
- conan install . \
- --build=missing `# Build dependencies binaries that are missing in Conan.` \
- -c tools.build:skip_test=true # Skip any test.
-
-You now can use the ``build`` Python module to build the wheel using PEP 517.
-
-.. code-block:: console
-
- pip install -U build
- python -m build \
- --config-setting cmake.define.CMAKE_TOOLCHAIN_FILE=$PWD/build/linux-x86_64-gcc-release/generators/conan_toolchain.cmake
-
-When built that way, the native libraries present in the wheel are most likely incomplete.
-You will need to use ``auditwheel`` or ``delocate`` to fix it.
-
-.. note::
- `auditwheel` requires the `patchelf` utility program on Linux. You may need
- to install it (on Ubuntu: `apt-get install patchelf`).
-
-.. code-block:: console
-
- pip install -U auditwheel # or `delocate` on MacOS.
- auditwheel repair \
- --strip `# Strip debugging symbols to get a lighter archive.` \
- `# The desired platform, which may differ depending on your build host.` \
- `# With Ubuntu 20.04, we can target manylinux_2_31. Newer versions of` \
- `# Ubuntu will have to target newer versions of manylinux.` \
- `# If you don't need a manylinux archive, you can also target the` \
- `# 'linux_x86_64' platform.` \
- --plat manylinux_2_31_x86_64 \
- `# Path to the wheel archive.` \
- dist/qi-*.whl
- # The wheel will be by default placed in a `./wheelhouse/` directory.
-
-Crosscompiling
---------------
-
-The project supports cross-compiling as explained in the `CMake manual about
-toolchains`__. You may simply set the ``CMAKE_TOOLCHAIN_FILE`` variable to the
-path of the CMake file of your toolchain.
-
-__ CMake_toolchains_
-
-.. _LibQi_repo: https://github.com/aldebaran/libqi
-.. _scikit-build: https://scikit-build.readthedocs.io/en/latest/
-.. _CMake_toolchains: https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html
-.. _CTest: https://cmake.org/cmake/help/latest/manual/ctest.1.html
diff --git a/conanfile.py b/conanfile.py
index d2a74aa..2258f07 100644
--- a/conanfile.py
+++ b/conanfile.py
@@ -1,5 +1,7 @@
from conan import ConanFile, tools
-from conan.tools.cmake import cmake_layout
+from conan.tools.cmake import CMakeToolchain, cmake_layout
+from conan.tools.files import copy
+import os
BOOST_COMPONENTS = [
"atomic",
@@ -64,7 +66,7 @@ class QiPythonConan(ConanFile):
"gtest/[~1.14]",
]
- generators = "CMakeToolchain", "CMakeDeps"
+ generators = "CMakeDeps"
# Binary configuration
settings = "os", "compiler", "build_type", "arch"
@@ -97,3 +99,15 @@ def layout(self):
# The cmake_layout() sets the folders and cpp attributes to follow the
# structure of a typical CMake project.
cmake_layout(self)
+
+ def generate(self):
+ tc = CMakeToolchain(self)
+ tc.variables["CMAKE_SKIP_RPATH"] = True
+ tc.generate()
+
+ for dep in self.dependencies.values():
+ if not dep.package_folder:
+ continue # skip if the dependency doesn't have a resolved package
+ copy(self, "*.dll", src=dep.package_folder, dst=self.build_folder)
+ copy(self, "*.dylib*", src=dep.package_folder, dst=self.build_folder)
+ copy(self, "*.so*", src=dep.package_folder, dst=self.build_folder)
diff --git a/execute_build_wheel_linux.sh b/execute_build_wheel_linux.sh
new file mode 100755
index 0000000..907fb52
--- /dev/null
+++ b/execute_build_wheel_linux.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+# Set needed variables for libqi repository dependency
+QI_REPOSITORY="https://github.com/funwithagents/libqi.git"
+QI_VERSION="4.0.5"
+QI_PATH="$PWD/../libqi"
+rm -rf $QI_PATH
+# Clone liqi respository
+git clone --depth=1 --branch "qi-framework-v${QI_VERSION}" "${QI_REPOSITORY}" "${QI_PATH}"
+# Link the libqi dependency by loading its conanfile into conan cache
+conan export "${QI_PATH}" --version "${QI_VERSION}"
+
+# Build
+conan install . --build=missing -c tools.build:skip_test=true -c '&:tools.build:skip_test=true'
+cmake --list-presets # => it should list the preset "conan-linux-x86_64-gcc-release"
+cmake --preset conan-linux-x86_64-gcc-release
+cmake --build --preset conan-linux-x86_64-gcc-release -j8
+
+# Generate wheel
+python -m build --config-setting cmake.define.CMAKE_TOOLCHAIN_FILE=$PWD/build/linux-x86_64-gcc-release/generators/conan_toolchain.cmake
+
+# Retrieve python version as "3Y" for 3.Y.Z ("313" for python 3.13.Z)
+python_version=$(python --version 2>&1 | awk '{print $2}' | cut -d'.' -f1,2 | sed 's/\.//g')
+# Retrieve the platform compatibility for the wheel, using auditwheel show
+constraint_tag=$(auditwheel show ./dist/qi-3.1.6-cp${python_version}-cp${python_version}-linux_x86_64.whl | grep 'This constrains the platform tag to' | sed -E 's/.*"([^"]+)".*/\1/')
+
+# Repair wheel (using all the dependency libs that have been previously copied by conan)
+LD_LIBRARY_PATH=$PWD/build/linux-x86_64-gcc-release/lib/ auditwheel repair --strip --plat ${constraint_tag} dist/qi-3.1.6-cp${python_version}-cp${python_version}-linux_x86_64.whl -w ./dist/fixed/
diff --git a/execute_build_wheel_macos.sh b/execute_build_wheel_macos.sh
new file mode 100755
index 0000000..394f442
--- /dev/null
+++ b/execute_build_wheel_macos.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+# Set needed variables for libqi repository dependency
+QI_REPOSITORY="https://github.com/funwithagents/libqi.git"
+QI_VERSION="4.0.5"
+QI_PATH="$PWD/../libqi"
+rm -rf $QI_PATH
+# Clone liqi respository
+git clone --depth=1 --branch "qi-framework-v${QI_VERSION}" "${QI_REPOSITORY}" "${QI_PATH}"
+# Link the libqi dependency by loading its conanfile into conan cache
+conan export "${QI_PATH}" --version "${QI_VERSION}"
+
+# Build
+conan install . --build=missing -c tools.build:skip_test=true -c '&:tools.build:skip_test=true'
+cmake --list-presets # => it should list the preset "conan-macos-armv8-apple-clang-release"
+cmake --preset conan-macos-armv8-apple-clang-release
+cmake --preset conan-macos-armv8-apple-clang-release
+# Generate wheel
+python -m build --config-setting cmake.define.CMAKE_TOOLCHAIN_FILE=$PWD/build/macos-armv8-apple-clang-release/generators/conan_toolchain.cmake
+
+# Retrieve python version as "3Y" for 3.Y.Z ("313" for python 3.13.Z)
+python_version=$(python --version 2>&1 | awk '{print $2}' | cut -d'.' -f1,2 | sed 's/\.//g')
+# Retrieve macOS major version
+macos_version=$(sw_vers -productVersion)
+macos_major_version=$(echo $macos_version | cut -d'.' -f1)
+
+# Repair wheel (using all the dependency libs that have been previously copied by conan)
+DYLD_LIBRARY_PATH=$PWD/build/macos-armv8-apple-clang-release/lib delocate-wheel -w ./dist/fixed/ --check-archs ./dist/qi-3.1.6-cp${python_version}-cp${python_version}-macosx_${macos_major_version}_0_arm64.whl
diff --git a/pyproject.toml b/pyproject.toml
index 6ccd0da..d49f24e 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -7,8 +7,8 @@ build-backend = "scikit_build_core.build"
[project]
name = "qi"
description = "LibQi Python bindings"
-version = "3.1.5"
-readme = "README.rst"
+version = "3.1.6"
+readme = "README.md"
requires-python = ">=3.7"
license = { "file" = "COPYING" }
keywords=[
@@ -37,16 +37,19 @@ classifiers=[
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
+ "Programming Language :: Python :: 3.12",
+ "Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3 :: Only",
]
maintainers = [
+ { name = "Thibault Hervier", email = "thibault@fr2g.io" },
{ email = "framework@aldebaran.com" },
{ name = "Vincent Palancher", email = "vincent.palancher@aldebaran.com" },
{ name = "Jérémy Monnon", email = "jmonnon@aldebaran.com" },
]
[project.urls]
-repository = "https://github.com/aldebaran/libqi-python"
+repository = "https://https://github.com/funwithagents/libqi-python"
[tool.scikit-build]
# Rely only on CMake install, not on Python packages detection.
@@ -55,13 +58,3 @@ wheel.packages = []
[tool.scikit-build.cmake.define]
# Disable building tests by default when building a wheel.
BUILD_TESTING = "OFF"
-
-[tool.cibuildwheel]
-build = "cp*manylinux*x86_64"
-build-frontend = "build"
-
-[tool.cibuildwheel.linux]
-before-all = ["ci/cibuildwheel_linux_before_all.sh {package}"]
-
-[tool.cibuildwheel.linux.config-settings]
-"cmake.args" = ["--preset=conan-release"]
diff --git a/qipython/common.hpp b/qipython/common.hpp
index 3335f66..0836b2e 100644
--- a/qipython/common.hpp
+++ b/qipython/common.hpp
@@ -116,8 +116,11 @@ boost::optional extractKeywordArg(pybind11::dict kwargs,
/// finalizing or not.
inline boost::optional interpreterIsFinalizing()
{
-// `_Py_IsFinalizing` is only available on CPython 3.7+
-#if PY_VERSION_HEX >= 0x03070000
+// `Py_IsFinalizing` is only available on CPython 3.13+
+#if PY_VERSION_HEX >= 0x030d0000
+ return boost::make_optional(Py_IsFinalizing() != 0);
+// `_Py_IsFinalizing` is only available from CPython 3.7
+#elif PY_VERSION_HEX >= 0x03070000
return boost::make_optional(_Py_IsFinalizing() != 0);
#else
// There is no way of knowing on older versions.
diff --git a/requirements_linux.txt b/requirements_linux.txt
new file mode 100644
index 0000000..52d3328
--- /dev/null
+++ b/requirements_linux.txt
@@ -0,0 +1,7 @@
+cmake
+conan
+qibuild
+numpy
+build
+patchelf
+auditwheel
diff --git a/requirements_macos.txt b/requirements_macos.txt
new file mode 100644
index 0000000..6ac2dd2
--- /dev/null
+++ b/requirements_macos.txt
@@ -0,0 +1,7 @@
+cmake
+conan
+qibuild
+numpy
+build
+patchelf
+delocate