Skip to content

Commit

Permalink
Release 3.1.4.
Browse files Browse the repository at this point in the history
  • Loading branch information
nyibbang committed Dec 4, 2023
2 parents d9884d6 + cd66e15 commit ea58ec4
Show file tree
Hide file tree
Showing 20 changed files with 643 additions and 327 deletions.
55 changes: 55 additions & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
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
variables:
LIBQI_REPOSITORY_URL: "https://gitlab-ci-token:$CI_JOB_TOKEN@$CI_SERVER_HOST/qi/libqi"
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'
101 changes: 54 additions & 47 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,16 +66,14 @@ endif()
##############################################################################
# Find Python
##############################################################################
# First search for Python with Interpreter+Devel components, to allow the module
# to look for the interpreter that goes with the Python development library.
# Then if it could not find both, try looking for the development component
# only, but this time force the module to find it or fail (REQUIRED).
# Some of our toolchains (when crosscompiling for instance) have the Python
# library but not an interpreter that can run on the host.
find_package(Python COMPONENTS Development Interpreter)
if(NOT Python_FOUND)
find_package(Python REQUIRED COMPONENTS Development)
endif()
find_package(
Python REQUIRED
COMPONENTS
Development.Module
OPTIONAL_COMPONENTS
Interpreter
Development.Embed
)

##############################################################################
# Find Boost
Expand Down Expand Up @@ -117,6 +115,7 @@ target_sources(

PUBLIC
qipython/common.hpp
qipython/common.hxx
qipython/pyapplication.hpp
qipython/pyasync.hpp
qipython/pyclock.hpp
Expand Down Expand Up @@ -323,47 +322,55 @@ if(BUILD_TESTING)
qi::qi
)

add_executable(test_qipython)
target_sources(
test_qipython
PRIVATE
tests/common.hpp
tests/test_qipython.cpp
tests/test_guard.cpp
tests/test_types.cpp
tests/test_signal.cpp
tests/test_property.cpp
tests/test_object.cpp
tests/test_module.cpp
)
target_link_libraries(
test_qipython
if(Python_Development.Embed_FOUND)
add_executable(test_qipython)
target_sources(
test_qipython
PRIVATE
tests/common.hpp
tests/test_qipython.cpp
tests/test_guard.cpp
tests/test_types.cpp
tests/test_signal.cpp
tests/test_property.cpp
tests/test_object.cpp
tests/test_module.cpp
)
target_link_libraries(
test_qipython
PRIVATE
qi_python_objects
cxx_standard
Python::Python
Boost::headers
pybind11::pybind11
GTest::gmock
)
gtest_discover_tests(
test_qipython
DISCOVERY_MODE PRE_TEST
)

add_executable(test_qipython_local_interpreter)
target_sources(
test_qipython_local_interpreter
PRIVATE
tests/test_qipython_local_interpreter.cpp
)
target_link_libraries(
test_qipython_local_interpreter
PRIVATE
qi_python_objects
cxx_standard
Python::Python
Boost::headers
pybind11::pybind11
qi_python_objects
cxx_standard
GTest::gmock
)
gtest_discover_tests(test_qipython)

add_executable(test_qipython_local_interpreter)
target_sources(
test_qipython_local_interpreter
PRIVATE
tests/test_qipython_local_interpreter.cpp
)
target_link_libraries(
test_qipython_local_interpreter
PRIVATE
Python::Python
pybind11::pybind11
qi_python_objects
cxx_standard
GTest::gmock
)
gtest_discover_tests(test_qipython_local_interpreter)
)
gtest_discover_tests(
test_qipython_local_interpreter
DISCOVERY_MODE PRE_TEST
)
endif()

if(NOT Python_Interpreter_FOUND)
message(WARNING "tests: a compatible Python Interpreter was NOT found, Python tests are DISABLED.")
Expand Down
97 changes: 81 additions & 16 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,30 @@ __ LibQi_repo_
Building
========

The libqi-python project requires a compiler that supports C++17 to build.
To build the project, you need:

It is built with CMake >= 3.23.
- 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
Expand All @@ -21,13 +42,13 @@ It is built with CMake >= 3.23.

.. note::
The procedures described below assume that you have downloaded the project
sources and that your current working directory is the project sources root
directory.
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
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
Expand All @@ -46,11 +67,35 @@ Install dependencies from Conan and build with CMake
The procedure to build the project using Conan to fetch dependencies is the
following.

You must first install the project dependencies in Conan.
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
conan install . --build=missing -s build_type=Debug
# 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.
Expand All @@ -73,20 +118,24 @@ To start building, you need to configure with CMake and then build:
cmake --preset conan-linux-x86_64-gcc-debug
cmake --build --preset conan-linux-x86_64-gcc-debug
You can then invoke tests using CTest_:
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 preset sadly.
cmake --install build/linux-x86_64-gcc-debug
# `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)
Expand All @@ -101,34 +150,50 @@ dependencies, such as a toolchain generated by Conan:

.. code-block:: console
conan install . --build=missing
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
export CMAKE_TOOLCHAIN_FILE=$PWD/build/linux-x86_64-gcc-release/generators/conan_toolchain.cmake
python -m build
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
auditwheel repair --plat manylinux_2_31_x86_64 dist/qi-*.whl
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 in your toolchain.
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/
.. _setuptools: https://setuptools.readthedocs.io/en/latest/setuptools.html
.. _CMake_toolchains: https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html
.. _CTest: https://cmake.org/cmake/help/latest/manual/ctest.1.html
30 changes: 30 additions & 0 deletions ci/cibuildwheel_linux_before_all.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/bin/sh
set -x -e

PACKAGE=$1

pip install 'conan>=2' 'cmake>=3.23' ninja

# Perl dependencies required to build OpenSSL.
yum install -y perl-IPC-Cmd perl-Digest-SHA

# Install Conan configuration.
conan config install "$PACKAGE/ci/conan"

# Clone and export libqi to Conan cache.
QI_VERSION=$(sed -nE '/^\s*requires\s*=/,/^\s*]/{ s/\s*"qi\/([^"]+)".*/\1/p }' "$PACKAGE/conanfile.py")

GIT_SSL_NO_VERIFY=true \
git clone --depth=1 \
--branch "qi-framework-v${QI_VERSION}" \
"$LIBQI_REPOSITORY_URL" \
/work/libqi
conan export /work/libqi --version="${QI_VERSION}"

# Install dependencies of libqi-python from Conan, including libqi.
#
# Build everything from sources, so that we do not reuse precompiled binaries.
# This is because the GLIBC from the manylinux images are often older than the
# ones that were used to build the precompiled binaries, which means the binaries
# cannot by executed.
conan install "$PACKAGE" --build="*"
7 changes: 7 additions & 0 deletions ci/conan/global.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
core:default_profile=default
core:default_build_profile=default
tools.build:skip_test=true
tools.cmake.cmaketoolchain:generator=Ninja
# Only use the build_type as a variable for the build folder name, so
# that the generated CMake preset is named "conan-release".
tools.cmake.cmake_layout:build_folder_vars=["settings.build_type"]
Loading

0 comments on commit ea58ec4

Please sign in to comment.