Skip to content

Commit 4717b70

Browse files
committed
Rebase to master and add github workflow
1 parent 459a18b commit 4717b70

File tree

4 files changed

+92
-41
lines changed

4 files changed

+92
-41
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
name: 'ROOT Python wheels'
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
branch:
7+
description: 'The branch for which the Python wheel has to be generated'
8+
type: string
9+
required: true
10+
default: "experimental-pip-install-root"
11+
12+
jobs:
13+
python_wheel:
14+
runs-on: ubuntu-latest
15+
env:
16+
WORKDIR: /home/runner/work/root
17+
steps:
18+
- name: Checkout
19+
uses: actions/checkout@v4
20+
with:
21+
ref: ${{ inputs.branch }}
22+
23+
- name: Install Kerberos utilities
24+
run: sudo apt-get install -y krb5-user
25+
26+
- name: Install XRootD client
27+
run: sudo apt-get -y install xrootd-client
28+
29+
- name: Build wheels
30+
uses: pypa/cibuildwheel@v3.0.1
31+
32+
# Upload artifact to github
33+
- uses: actions/upload-artifact@v4
34+
with:
35+
name: cibw-wheels-test
36+
path: ./wheelhouse/*.whl
37+
38+
- name: Upload wheel to EOS
39+
env:
40+
RWEBEOS_KT: ${{ secrets.RWEBEOS_KT }}
41+
KT_FILE_NAME: /tmp/decoded.keytab
42+
EOS_PATH: /eos/project/r/root-eos/www/experimental-python-wheels
43+
EOS_ENDPOINT: root://eosproject-r.cern.ch
44+
KRB5CCNAME: /tmp/krb5cc
45+
working-directory: ${{ env.WORKDIR }}
46+
run: |
47+
echo +++ Content
48+
ls
49+
echo +++ Retrieving the secret
50+
echo ${RWEBEOS_KT} | base64 -d > ${KT_FILE_NAME}
51+
echo +++ Creating the token
52+
kinit -p ${{ secrets.KRB5USER }}@${{ secrets.KRB5REALM }} -kt ${KT_FILE_NAME}
53+
echo +++ Running the copy
54+
xrdcp -rf wheelhouse ${EOS_ENDPOINT}/${EOS_PATH}/

bindings/pyroot/pythonizations/CMakeLists.txt

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -168,25 +168,13 @@ file(COPY ${ROOT_headers_dir}/ DESTINATION ${CMAKE_BINARY_DIR}/include/ROOT)
168168
set(libname ROOTPythonizations)
169169

170170
add_library(${libname} SHARED ${cpp_sources})
171-
# It is crucial to add the path to the other ROOT libraries for compatibility with pip build backends.
172-
# After the `pip install` step, the target install user directory will look like:
173-
# site-packages/
174-
# -- cppyy/
175-
# -- cppyy_backend/
176-
# -- libcppyy.so
177-
# -- libcppyy_backend.so
178-
# -- libROOTPythonizations.so
179-
# -- ROOT/
180-
# With most of the ROOT libraries being stored in `ROOT/lib`. The RPATH must then be updated for the CPython extension
181-
# shared libraries.
182-
set_target_properties(${libname} PROPERTIES INSTALL_RPATH "${CMAKE_INSTALL_RPATH}:$ORIGIN/ROOT/lib")
183171

184172
# Insert the ROOTPythonizationsPySources in the dependency graph
185173
add_dependencies(${libname} ROOTPythonizationsPySources)
186174

187175
# Set the suffix to '.so' and the prefix to 'lib'
188176
set_target_properties(${libname} PROPERTIES ${ROOT_LIBRARY_PROPERTIES_NO_VERSION})
189-
target_link_libraries(${libname} PUBLIC Core Tree cppyy)
177+
target_link_libraries(${libname} PUBLIC ROOT::Core ROOT::Tree cppyy)
190178
if(MSVC)
191179
set_target_properties(${libname} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
192180
set_target_properties(${libname} PROPERTIES SUFFIX ".pyd")
@@ -240,6 +228,18 @@ else()
240228
LIBRARY_OUTPUT_DIRECTORY ${pymoduledir_build})
241229
endif()
242230

231+
# It is crucial to add the path to the other ROOT libraries for compatibility with pip build backends.
232+
# After the `pip install` step, the target install user directory will look like:
233+
# site-packages/
234+
# -- cppyy/
235+
# -- cppyy_backend/
236+
# -- libcppyy.so
237+
# -- libcppyy_backend.so
238+
# -- ROOT/
239+
# -- -- libROOTPythonizations.so
240+
# With most of the ROOT libraries being stored in `ROOT/lib`. The RPATH must then be updated for the CPython extension
241+
# shared libraries.
242+
243243
if(NOT MSVC)
244244
# Make sure that relative RUNPATH to main ROOT libraries is always correct.
245245

@@ -254,7 +254,8 @@ if(NOT MSVC)
254254
else()
255255
set_target_properties(${libname} PROPERTIES
256256
BUILD_RPATH "$ORIGIN/${pymoduledir_to_libdir_build}"
257-
INSTALL_RPATH "$ORIGIN/${pymoduledir_to_libdir_install}"
257+
# ATTENTION: NEXT PART IS CRUCIAL SEE COMMENT ABOVE
258+
INSTALL_RPATH "$ORIGIN/${pymoduledir_to_libdir_install}:${CMAKE_INSTALL_RPATH}:$ORIGIN/lib"
258259
)
259260
endif()
260261

pyproject.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ requires = ["cmake", "setuptools<72", "wheel", "ninja", "numpy"]
33

44
[project]
55
name = "ROOT"
6-
version = "0.1a6"
6+
version = "0.1a7"
77

88
requires-python = ">=3.8"
99
authors = [
@@ -22,9 +22,10 @@ root = "ROOT._rootcli:main"
2222
[tool.cibuildwheel]
2323
# Increase pip debugging output
2424
build-verbosity = 1
25-
build="cp3{8,9,10,11,12,13}-manylinux_x86_64"
25+
#build="cp3{8,9,10,11,12,13}-manylinux_x86_64"
26+
build="cp313-manylinux_x86_64"
2627
manylinux-x86_64-image = "manylinux_2_28"
2728

2829
# Install system libraries
2930
[tool.cibuildwheel.linux]
30-
before-all = "dnf install -y epel-release && /usr/bin/crb enable && dnf install -y openssl-devel libX11-devel libXpm-devel libXft-devel libXext-devel libuuid-devel"
31+
before-all = "dnf install -y epel-release && /usr/bin/crb enable && dnf install -y openssl-devel libX11-devel libXpm-devel libXft-devel libXext-devel libuuid-devel libjpeg-devel giflib-devel"

setup.py

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
-- cppyy_backend/
1212
-- libcppyy.so
1313
-- libcppyy_backend.so
14-
-- libROOTPythonizations.so
1514
-- ROOT/
15+
-- -- libROOTPythonizations.so
1616
```
1717
1818
A custom extension module is injected in the setuptools setup to properly
@@ -42,17 +42,18 @@ def run(self):
4242
_build.run(self)
4343

4444
# Configure ROOT build
45-
base_opts = shlex.split("cmake -GNinja")
45+
base_opts = shlex.split("cmake -GNinja -Dccache=ON")
4646
mode_opts = shlex.split(
4747
"-Dbuiltin_nlohmannjson=ON -Dbuiltin_tbb=ON -Dbuiltin_xrootd=ON " # builtins
4848
"-Dbuiltin_lz4=ON -Dbuiltin_lzma=ON -Dbuiltin_zstd=ON -Dbuiltin_xxhash=ON" # builtins
4949
"-Druntime_cxxmodules=ON -Drpath=ON -Dfail-on-missing=ON " # Generic build configuration
5050
"-Dgminimal=ON -Dasimage=ON -Dopengl=OFF " # Graphics
51-
"-Dpyroot=ON -Ddataframe=ON -Dxrootd=ON -Dimt=ON "
52-
"-Droofit=ON")
53-
dirs_opts = shlex.split(
54-
f"-DCMAKE_INSTALL_PREFIX={INSTALL_DIR} -B {BUILD_DIR} -S {SOURCE_DIR}")
51+
"-Dpyroot=ON -Ddataframe=ON -Dxrootd=ON -Dssl=ON -Dimt=ON "
52+
"-Droofit=ON"
53+
)
54+
dirs_opts = shlex.split(f"-DCMAKE_INSTALL_PREFIX={INSTALL_DIR} -B {BUILD_DIR} -S {SOURCE_DIR}")
5555
configure_command = base_opts + mode_opts + dirs_opts
56+
print(f"\n\n{' '.join(configure_command)}\n\n")
5657
subprocess.run(configure_command, check=True)
5758

5859
# Run build with CMake
@@ -62,7 +63,7 @@ def run(self):
6263

6364
class ROOTInstall(_install):
6465
def _get_install_path(self):
65-
if hasattr(self, 'bdist_dir') and self.bdist_dir:
66+
if hasattr(self, "bdist_dir") and self.bdist_dir:
6667
install_path = self.bdist_dir
6768
else:
6869
install_path = self.install_lib
@@ -83,16 +84,13 @@ def run(self):
8384
self.copy_tree(INSTALL_DIR, os.path.join(install_path, "ROOT"))
8485

8586
# Copy cppyy packages separately
86-
self.copy_tree(os.path.join(lib_dir, "cppyy"),
87-
os.path.join(install_path, "cppyy"))
88-
self.copy_tree(os.path.join(lib_dir, "cppyy_backend"),
89-
os.path.join(install_path, "cppyy_backend"))
87+
self.copy_tree(os.path.join(lib_dir, "cppyy"), os.path.join(install_path, "cppyy"))
88+
self.copy_tree(os.path.join(lib_dir, "cppyy_backend"), os.path.join(install_path, "cppyy_backend"))
9089

9190
# Finally copy CPython extension libraries
92-
extlibs = ["libcppyy.so", "libcppyy_backend.so",
93-
"libROOTPythonizations.so"]
94-
for ext in extlibs:
95-
self.copy_file(os.path.join(lib_dir, ext), install_path)
91+
self.copy_file(os.path.join(lib_dir, "libcppyy.so"), install_path)
92+
self.copy_file(os.path.join(lib_dir, "libcppyy_backend.so"), install_path)
93+
self.copy_file(os.path.join(lib_dir, "ROOT", "libROOTPythonizations.so"), os.path.join(install_path, "ROOT"))
9694

9795
def get_outputs(self):
9896
outputs = _install.get_outputs(self)
@@ -103,31 +101,28 @@ class DummyExtension(Extension):
103101
"""
104102
Dummy CPython extension for setuptools setup.
105103
106-
In order to generate the wheel with CPython extension metadata (i.e.
104+
In order to generate the wheel with CPython extension metadata (i.e.
107105
producing one wheel per supported Python version), setuptools requires that
108106
at least one CPython extension is declared in the `ext_modules` kwarg passed
109107
to the `setup` function. Usually, declaring a CPython extension triggers
110108
compilation of the corresponding sources, but in this case we already do
111109
that in the CMake build step. This class defines a dummy extension that
112110
can be declared to setuptools while avoiding any further compilation step.
113111
"""
112+
114113
def __init__(_):
115114
super().__init__(name="Dummy", sources=[])
116115

117116

118-
pkgs = (
119-
find_packages('bindings/pyroot/pythonizations/python') +
120-
find_packages('bindings/pyroot/cppyy/cppyy/python', include=['cppyy'])
117+
pkgs = find_packages("bindings/pyroot/pythonizations/python") + find_packages(
118+
"bindings/pyroot/cppyy/cppyy/python", include=["cppyy"]
121119
)
122120

123121
s = setup(
124122
long_description=LONG_DESCRIPTION,
125-
package_dir={'': 'bindings/pyroot/pythonizations/python',
126-
'cppyy': 'bindings/pyroot/cppyy/cppyy/python'},
123+
package_dir={"": "bindings/pyroot/pythonizations/python", "cppyy": "bindings/pyroot/cppyy/cppyy/python"},
127124
packages=pkgs,
128125
# Crucial to signal this is not a pure Python package
129126
ext_modules=[DummyExtension()],
130-
cmdclass={
131-
'build': ROOTBuild,
132-
'install': ROOTInstall},
127+
cmdclass={"build": ROOTBuild, "install": ROOTInstall},
133128
)

0 commit comments

Comments
 (0)