Skip to content

Commit ea58ec4

Browse files
committed
Release 3.1.4.
2 parents d9884d6 + cd66e15 commit ea58ec4

20 files changed

+643
-327
lines changed

.gitlab-ci.yml

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
stages:
2+
- build
3+
- publish
4+
- release
5+
6+
.if-tag: &if-tag
7+
if: "$CI_COMMIT_TAG =~ /^qi-python-v/"
8+
9+
build-wheel:
10+
stage: build
11+
rules:
12+
# Allow manually building on a Git commit on any branch.
13+
- if: $CI_COMMIT_BRANCH
14+
when: manual
15+
# Always build on a Git tag.
16+
- <<: *if-tag
17+
tags:
18+
- docker
19+
image: python:3.8
20+
variables:
21+
LIBQI_REPOSITORY_URL: "https://gitlab-ci-token:$CI_JOB_TOKEN@$CI_SERVER_HOST/qi/libqi"
22+
script:
23+
- curl -sSL https://get.docker.com/ | sh
24+
- pip install cibuildwheel==2.14.1
25+
- cibuildwheel --output-dir wheelhouse
26+
artifacts:
27+
paths:
28+
- wheelhouse/
29+
30+
publish-wheel:
31+
stage: publish
32+
image: python:latest
33+
rules:
34+
- <<: *if-tag
35+
needs:
36+
- build-wheel
37+
script:
38+
- pip install build twine
39+
- python -m build
40+
- TWINE_PASSWORD="${CI_JOB_TOKEN}"
41+
TWINE_USERNAME=gitlab-ci-token
42+
python -m twine upload
43+
--repository-url "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/pypi"
44+
wheelhouse/*
45+
46+
create-release:
47+
stage: release
48+
rules:
49+
- <<: *if-tag
50+
script:
51+
- echo "Releasing $CI_COMMIT_TAG."
52+
release:
53+
tag_name: $CI_COMMIT_TAG
54+
name: 'lib$CI_COMMIT_TITLE'
55+
description: '$CI_COMMIT_TAG_MESSAGE'

CMakeLists.txt

Lines changed: 54 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -66,16 +66,14 @@ endif()
6666
##############################################################################
6767
# Find Python
6868
##############################################################################
69-
# First search for Python with Interpreter+Devel components, to allow the module
70-
# to look for the interpreter that goes with the Python development library.
71-
# Then if it could not find both, try looking for the development component
72-
# only, but this time force the module to find it or fail (REQUIRED).
73-
# Some of our toolchains (when crosscompiling for instance) have the Python
74-
# library but not an interpreter that can run on the host.
75-
find_package(Python COMPONENTS Development Interpreter)
76-
if(NOT Python_FOUND)
77-
find_package(Python REQUIRED COMPONENTS Development)
78-
endif()
69+
find_package(
70+
Python REQUIRED
71+
COMPONENTS
72+
Development.Module
73+
OPTIONAL_COMPONENTS
74+
Interpreter
75+
Development.Embed
76+
)
7977

8078
##############################################################################
8179
# Find Boost
@@ -117,6 +115,7 @@ target_sources(
117115

118116
PUBLIC
119117
qipython/common.hpp
118+
qipython/common.hxx
120119
qipython/pyapplication.hpp
121120
qipython/pyasync.hpp
122121
qipython/pyclock.hpp
@@ -323,47 +322,55 @@ if(BUILD_TESTING)
323322
qi::qi
324323
)
325324

326-
add_executable(test_qipython)
327-
target_sources(
328-
test_qipython
329-
PRIVATE
330-
tests/common.hpp
331-
tests/test_qipython.cpp
332-
tests/test_guard.cpp
333-
tests/test_types.cpp
334-
tests/test_signal.cpp
335-
tests/test_property.cpp
336-
tests/test_object.cpp
337-
tests/test_module.cpp
338-
)
339-
target_link_libraries(
340-
test_qipython
325+
if(Python_Development.Embed_FOUND)
326+
add_executable(test_qipython)
327+
target_sources(
328+
test_qipython
329+
PRIVATE
330+
tests/common.hpp
331+
tests/test_qipython.cpp
332+
tests/test_guard.cpp
333+
tests/test_types.cpp
334+
tests/test_signal.cpp
335+
tests/test_property.cpp
336+
tests/test_object.cpp
337+
tests/test_module.cpp
338+
)
339+
target_link_libraries(
340+
test_qipython
341+
PRIVATE
342+
qi_python_objects
343+
cxx_standard
344+
Python::Python
345+
Boost::headers
346+
pybind11::pybind11
347+
GTest::gmock
348+
)
349+
gtest_discover_tests(
350+
test_qipython
351+
DISCOVERY_MODE PRE_TEST
352+
)
353+
354+
add_executable(test_qipython_local_interpreter)
355+
target_sources(
356+
test_qipython_local_interpreter
357+
PRIVATE
358+
tests/test_qipython_local_interpreter.cpp
359+
)
360+
target_link_libraries(
361+
test_qipython_local_interpreter
341362
PRIVATE
342-
qi_python_objects
343-
cxx_standard
344363
Python::Python
345-
Boost::headers
346364
pybind11::pybind11
365+
qi_python_objects
366+
cxx_standard
347367
GTest::gmock
348-
)
349-
gtest_discover_tests(test_qipython)
350-
351-
add_executable(test_qipython_local_interpreter)
352-
target_sources(
353-
test_qipython_local_interpreter
354-
PRIVATE
355-
tests/test_qipython_local_interpreter.cpp
356-
)
357-
target_link_libraries(
358-
test_qipython_local_interpreter
359-
PRIVATE
360-
Python::Python
361-
pybind11::pybind11
362-
qi_python_objects
363-
cxx_standard
364-
GTest::gmock
365-
)
366-
gtest_discover_tests(test_qipython_local_interpreter)
368+
)
369+
gtest_discover_tests(
370+
test_qipython_local_interpreter
371+
DISCOVERY_MODE PRE_TEST
372+
)
373+
endif()
367374

368375
if(NOT Python_Interpreter_FOUND)
369376
message(WARNING "tests: a compatible Python Interpreter was NOT found, Python tests are DISABLED.")

README.rst

Lines changed: 81 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,30 @@ __ LibQi_repo_
1010
Building
1111
========
1212

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

15-
It is built with CMake >= 3.23.
15+
- a compiler that supports C++17.
16+
17+
- on Ubuntu: `apt-get install build-essential`.
18+
19+
- CMake with at least version 3.23.
20+
21+
- on PyPI (**recommended**): `pip install "cmake>=3.23"`.
22+
- on Ubuntu: `apt-get install cmake`.
23+
24+
- Python with at least version 3.7 and its development libraries.
25+
26+
- On Ubuntu: `apt-get install libpython3-dev`.
27+
28+
- a Python `virtualenv`.
29+
30+
- On Ubuntu:
31+
32+
.. code-block:: console
33+
34+
apt-get install python3-venv
35+
python3 -m venv ~/my-venv # Use the path of your convenience.
36+
source ~/my-venv/bin/activate
1637
1738
.. note::
1839
The CMake project offers several configuration options and exports a set
@@ -21,13 +42,13 @@ It is built with CMake >= 3.23.
2142

2243
.. note::
2344
The procedures described below assume that you have downloaded the project
24-
sources and that your current working directory is the project sources root
25-
directory.
45+
sources, that your current working directory is the project sources root
46+
directory and that you are working inside your virtualenv.
2647

2748
Conan
2849
^^^^^
2950

30-
Additionally, libqi-python is available as a Conan 2 project, which means you
51+
Additionally, `libqi-python` is available as a Conan 2 project, which means you
3152
can use Conan to fetch dependencies.
3253

3354
You can install and/or upgrade Conan 2 and create a default profile in the
@@ -46,11 +67,35 @@ Install dependencies from Conan and build with CMake
4667
The procedure to build the project using Conan to fetch dependencies is the
4768
following.
4869

49-
You must first install the project dependencies in Conan.
70+
Most dependencies are available on Conan Center repository and should not
71+
require any additional steps to make them available. However, you might need to
72+
first get and export the `libqi` recipe into your local Conan cache.
5073

5174
.. code-block:: console
5275
53-
conan install . --build=missing -s build_type=Debug
76+
# GitHub is available, but you can also use internal GitLab.
77+
QI_REPOSITORY="https://github.com/aldebaran/libqi.git"
78+
QI_VERSION="4.0.1" # Checkout the version your project need.
79+
QI_PATH="$HOME/libqi" # Or whatever path you want.
80+
git clone \
81+
--depth=1 `# Only fetch one commit.` \
82+
--branch "qi-framework-v${QI_VERSION}" \
83+
"${QI_REPOSITORY}" \
84+
"${QI_PATH}"
85+
conan export "${QI_PATH}" \
86+
--version "${QI_VERSION}" # Technically not required but some
87+
# versions of libqi require it
88+
# because of a bug.
89+
90+
You can then install the `libqi-python` dependencies in Conan.
91+
92+
.. code-block:: console
93+
94+
conan install . \
95+
--build=missing `# Build dependencies binaries that are missing in Conan.` \
96+
-s build_type=Debug `# Build in debug mode.` \
97+
-c tools.build:skip_test=true `# Skip tests building for dependencies.` \
98+
-c '&:tools.build:skip_test=false' # Do not skip tests for the project.
5499
55100
This will generate a build directory containing a configuration with a
56101
toolchain file that allows CMake to find dependencies inside the Conan cache.
@@ -73,20 +118,24 @@ To start building, you need to configure with CMake and then build:
73118
cmake --preset conan-linux-x86_64-gcc-debug
74119
cmake --build --preset conan-linux-x86_64-gcc-debug
75120
76-
You can then invoke tests using CTest_:
121+
Tests can now be invoked using CTest_, but they require a runtime environment
122+
from Conan so that all dependencies are found:
77123

78124
.. code-block:: console
79125
126+
source build/linux-x86_64-gcc-debug/generators/conanrun.sh
80127
ctest --preset conan-linux-x86_64-gcc-debug --output-on-failure
128+
source build/linux-x86_64-gcc-debug/generators/deactivate_conanrun.sh
81129
82130
Finally, you can install the project in the directory of your choice.
83131

84132
The project defines a single install component, the ``Module`` component.
85133

86134
.. code-block:: console
87135
88-
# "cmake --install" does not support preset sadly.
89-
cmake --install build/linux-x86_64-gcc-debug
136+
# `cmake --install` does not support presets sadly.
137+
cmake \
138+
--install build/linux-x86_64-gcc-debug \
90139
--component Module --prefix ~/my-libqi-python-install
91140
92141
Wheel (PEP 517)
@@ -101,34 +150,50 @@ dependencies, such as a toolchain generated by Conan:
101150

102151
.. code-block:: console
103152
104-
conan install . --build=missing
153+
conan install . \
154+
--build=missing `# Build dependencies binaries that are missing in Conan.` \
155+
-c tools.build:skip_test=true # Skip any test.
105156
106157
You now can use the ``build`` Python module to build the wheel using PEP 517.
107158

108159
.. code-block:: console
109160
110-
export CMAKE_TOOLCHAIN_FILE=$PWD/build/linux-x86_64-gcc-release/generators/conan_toolchain.cmake
111-
python -m build
161+
pip install -U build
162+
python -m build \
163+
--config-setting cmake.define.CMAKE_TOOLCHAIN_FILE=$PWD/build/linux-x86_64-gcc-release/generators/conan_toolchain.cmake
112164
113165
When built that way, the native libraries present in the wheel are most likely incomplete.
114166
You will need to use ``auditwheel`` or ``delocate`` to fix it.
115167

168+
.. note::
169+
`auditwheel` requires the `patchelf` utility program on Linux. You may need
170+
to install it (on Ubuntu: `apt-get install patchelf`).
171+
116172
.. code-block:: console
117173
118-
auditwheel repair --plat manylinux_2_31_x86_64 dist/qi-*.whl
174+
pip install -U auditwheel # or `delocate` on MacOS.
175+
auditwheel repair \
176+
--strip `# Strip debugging symbols to get a lighter archive.` \
177+
`# The desired platform, which may differ depending on your build host.` \
178+
`# With Ubuntu 20.04, we can target manylinux_2_31. Newer versions of` \
179+
`# Ubuntu will have to target newer versions of manylinux.` \
180+
`# If you don't need a manylinux archive, you can also target the` \
181+
`# 'linux_x86_64' platform.` \
182+
--plat manylinux_2_31_x86_64 \
183+
`# Path to the wheel archive.` \
184+
dist/qi-*.whl
119185
# The wheel will be by default placed in a `./wheelhouse/` directory.
120186
121187
Crosscompiling
122188
--------------
123189

124190
The project supports cross-compiling as explained in the `CMake manual about
125191
toolchains`__. You may simply set the ``CMAKE_TOOLCHAIN_FILE`` variable to the
126-
path of the CMake file in your toolchain.
192+
path of the CMake file of your toolchain.
127193

128194
__ CMake_toolchains_
129195

130196
.. _LibQi_repo: https://github.com/aldebaran/libqi
131197
.. _scikit-build: https://scikit-build.readthedocs.io/en/latest/
132-
.. _setuptools: https://setuptools.readthedocs.io/en/latest/setuptools.html
133198
.. _CMake_toolchains: https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html
134199
.. _CTest: https://cmake.org/cmake/help/latest/manual/ctest.1.html
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#!/bin/sh
2+
set -x -e
3+
4+
PACKAGE=$1
5+
6+
pip install 'conan>=2' 'cmake>=3.23' ninja
7+
8+
# Perl dependencies required to build OpenSSL.
9+
yum install -y perl-IPC-Cmd perl-Digest-SHA
10+
11+
# Install Conan configuration.
12+
conan config install "$PACKAGE/ci/conan"
13+
14+
# Clone and export libqi to Conan cache.
15+
QI_VERSION=$(sed -nE '/^\s*requires\s*=/,/^\s*]/{ s/\s*"qi\/([^"]+)".*/\1/p }' "$PACKAGE/conanfile.py")
16+
17+
GIT_SSL_NO_VERIFY=true \
18+
git clone --depth=1 \
19+
--branch "qi-framework-v${QI_VERSION}" \
20+
"$LIBQI_REPOSITORY_URL" \
21+
/work/libqi
22+
conan export /work/libqi --version="${QI_VERSION}"
23+
24+
# Install dependencies of libqi-python from Conan, including libqi.
25+
#
26+
# Build everything from sources, so that we do not reuse precompiled binaries.
27+
# This is because the GLIBC from the manylinux images are often older than the
28+
# ones that were used to build the precompiled binaries, which means the binaries
29+
# cannot by executed.
30+
conan install "$PACKAGE" --build="*"

ci/conan/global.conf

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
core:default_profile=default
2+
core:default_build_profile=default
3+
tools.build:skip_test=true
4+
tools.cmake.cmaketoolchain:generator=Ninja
5+
# Only use the build_type as a variable for the build folder name, so
6+
# that the generated CMake preset is named "conan-release".
7+
tools.cmake.cmake_layout:build_folder_vars=["settings.build_type"]

0 commit comments

Comments
 (0)