Skip to content

Commit cd18496

Browse files
authored
Migrate build system to python-build (#3)
* Migrate to `python-build` * Clean-up setup.py.in * Fix linux_build.bash * Update CMakeLists.txt * Fix linux_build.bash * Fix linux_build.bash * Update build * Update tests * Fix linux_build.bash * Update CMake files * Update CI and RTD integration * Update build.yml
1 parent 8a34049 commit cd18496

26 files changed

Lines changed: 130 additions & 230 deletions

.github/workflows/build.yml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,15 @@ jobs:
4444
export libcarna_version=$(conda list --json |jq -rj '[ .[] | select( .name == "libcarna" ) ][0].version')
4545
echo "libcarna_version=$libcarna_version" >> "$GITHUB_OUTPUT"
4646
47-
- name: Build dist
47+
- name: Build wheel
4848
shell: bash
4949
run: ./linux_build.bash
5050

5151
- name: Upload wheel
5252
uses: actions/upload-artifact@v4
5353
with:
5454
name: dist-${{ inputs.python-version }}
55-
path: |
56-
dist
55+
path: build/dist/libcarna_python-*.whl
5756

5857
outputs:
5958
libcarna_version: ${{ steps.meta.outputs.libcarna_version }}
@@ -117,9 +116,6 @@ jobs:
117116
run: |
118117
eval "$(conda shell.bash hook)"
119118
conda activate ./.env
120-
cd test
121-
mkdir test
122-
mv results test/results
123119
python -m unittest -vv
124120
env:
125121
LIBCARNA_PYTHON_LOGGING: true

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
/dist
66
/LibCarna_Python.egg-info
77
/.libcarna-dev
8+
/test/results/actual
89
.ipynb_checkpoints
910
*.swp
1011
*.pyc

.readthedocs.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ build:
2020
jobs:
2121
install:
2222
- bash ./linux_build.bash
23-
- pip install dist/libcarna_python-*.whl
23+
- pip install build/dist/libcarna_python-*.whl
2424
pre_build:
2525
- pip install -r docs/requirements.txt
2626
build:

CMakeLists.txt

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ project( LibCarna-Python )
33
set( PYTHON_MODULE_NAME "libcarna" )
44
include( FindPackageHandleStandardArgs )
55

6+
set( MAJOR_VERSION 0 )
7+
set( MINOR_VERSION 2 )
8+
set( PATCH_VERSION 0 )
9+
610
set( CMAKE_CXX_STANDARD 14 )
711
set( CMAKE_CXX_STANDARD_REQUIRED ON )
812
set( CMAKE_INTERPROCEDURAL_OPTIMIZATION FALSE )
@@ -73,20 +77,31 @@ find_package( Eigen3 REQUIRED )
7377
include_directories( ${EIGEN3_INCLUDE_DIR} )
7478

7579
# LibCarna
76-
find_package( LibCarna ${REQUIRED_VERSION_LIBCARNA} REQUIRED COMPONENTS release )
80+
find_package( LibCarna "3.4.0" REQUIRED COMPONENTS release )
7781
include_directories( ${LibCarna_INCLUDE_DIR} )
7882
set( LIBCARNA_VERSION ${FOUND_VERSION} )
7983

8084
############################################
8185

82-
configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/misc/__init__.py.in
83-
${CMAKE_CURRENT_BINARY_DIR}/${PYTHON_MODULE_NAME}/__init__.py @ONLY )
86+
configure_file(
87+
${CMAKE_CURRENT_SOURCE_DIR}/misc/__init__.py.in
88+
${CMAKE_CURRENT_BINARY_DIR}/${PYTHON_MODULE_NAME}/__init__.py
89+
@ONLY
90+
)
91+
92+
configure_file(
93+
${CMAKE_CURRENT_SOURCE_DIR}/setup.py.in
94+
${CMAKE_CURRENT_BINARY_DIR}/setup.py
95+
@ONLY
96+
)
8497

8598
file( GLOB PYTHON_AUX_FILES "${CMAKE_CURRENT_SOURCE_DIR}/misc/libcarna/*.py" )
8699
file( COPY ${PYTHON_AUX_FILES} DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/${PYTHON_MODULE_NAME}" )
87100

88101
file( GLOB LICENSES "${LibCarna_LICENSE_DIR}/LICENSE*" )
89-
file( COPY ${LICENSES} DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/licenses/" )
102+
file( COPY ${LICENSES} DESTINATION "${CMAKE_CURRENT_BINARY_DIR}" )
103+
file( COPY ${CMAKE_CURRENT_SOURCE_DIR}/README.md DESTINATION "${CMAKE_CURRENT_BINARY_DIR}" )
104+
file( COPY ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE DESTINATION "${CMAKE_CURRENT_BINARY_DIR}" )
90105

91106
############################################
92107
# Project
@@ -165,11 +180,3 @@ install( FILES
165180
${CMAKE_CURRENT_BINARY_DIR}/${PYTHON_MODULE_NAME}/__init__.py
166181
DESTINATION ${INSTALL_LIBRARY_DIR}
167182
)
168-
169-
############################################
170-
# Process unit tests
171-
############################################
172-
173-
if( BUILD_TEST )
174-
add_subdirectory( test )
175-
endif()

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2025 Leonid Kostrykin
3+
Copyright (c) 2021-2025 Leonid Kostrykin
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

environment.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ dependencies:
1818
- cmake
1919
- eigen >=3.0.5
2020
- libxcrypt # requied for Python 3.10
21-
- pyyaml
2221
- setuptools
22+
- python-build
23+
- pip
2324

2425
# ---------------------------------------------------------------------------
2526
# Runtime dependencies (general)

linux_build.bash

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,51 @@ set -ex
33

44
# Create or update conda environment
55
export ROOT="$PWD"/$(dirname "$0")
6-
if [ ! -d "$ROOT/.env" ]; then
7-
conda env create -f "$ROOT/environment.yml" --prefix "$ROOT/.env"
6+
if [ ! -d "$ROOT"/.env ]; then
7+
conda env create -f "$ROOT"/environment.yml --prefix "$ROOT"/.env
88
else
9-
conda env update -f "$ROOT/environment.yml" --prefix "$ROOT/.env" --prune
9+
conda env update -f "$ROOT"/environment.yml --prefix "$ROOT"/.env --prune
1010
fi
1111

1212
# Activate conda environment
1313
eval "$(conda shell.bash hook)"
14-
conda activate "$ROOT/.env"
14+
conda activate "$ROOT"/.env
1515

16-
# Setup and check dependencies
17-
export PYBIND11_PREFIX="$CONDA_PREFIX/share/cmake/pybind11"
18-
export CMAKE_MODULE_PATH="$CONDA_PREFIX/share/cmake/Modules"
16+
# Create build directory
17+
mkdir -p "$ROOT"/build
1918

20-
# Default to not building the test suite
21-
if [ -z "$LIBCARNA_PYTHON_BUILD_TEST" ]; then
22-
export LIBCARNA_PYTHON_BUILD_TEST="OFF"
23-
else
24-
pip install -r test/requirements.txt
19+
# Build native extension
20+
cd "$ROOT"/build
21+
cmake -DCMAKE_BUILD_TYPE=Release \
22+
-DPYTHON_EXECUTABLE="$(which python)" \
23+
-Dpybind11_DIR="$CONDA_PREFIX/share/cmake/pybind11" \
24+
-DCMAKE_MODULE_PATH="$CONDA_PREFIX/share/cmake/Modules" \
25+
"$ROOT"
26+
if [ -z "$LIBCARNA_SKIP_NATIVE" ]; then
27+
make VERBOSE=1
2528
fi
2629

27-
# Build wheel and test
28-
cd "$ROOT"
29-
python setup.py bdist_wheel
30+
# Build wheel
31+
python -m build --no-isolation
32+
33+
# Install wheel
34+
rm -rf venv
35+
python -m venv venv --system-site-package
36+
source venv/bin/activate
37+
pip install --no-deps dist/*.whl
38+
39+
# Optionally, run the test suite
40+
if [ -v LIBCARNA_PYTHON_BUILD_TEST ]; then
41+
cd "$ROOT"
42+
pip install -r test/requirements.txt
43+
python -m unittest
44+
fi
3045

3146
# Optionally, build the documentation
3247
if [ -v LIBCARNA_PYTHON_BUILD_DOCS ]; then
48+
cd "$ROOT"
3349
pip install -r docs/requirements.txt
34-
export LIBCARNA_PYTHON_PATH="$ROOT/build/make_release"
35-
rm -rf $ROOT/docs/build
50+
rm -rf docs/build
3651
sphinx-build -M html docs docs/build
37-
cp $ROOT/docs/build/html/examples/*.ipynb $ROOT/examples/
52+
cp docs/build/html/examples/*.ipynb examples/
3853
fi

misc/__init__.py.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
version = '@MAJOR_VERSION@.@MINOR_VERSION@.@PATCH_VERSION@'
1+
version = '@FULL_VERSION@'
22
libcarna_version = '@LIBCARNA_VERSION@'
33

44

setup.py

Lines changed: 0 additions & 124 deletions
This file was deleted.

setup.py.in

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
from setuptools import setup
2+
3+
4+
if __name__ == '__main__':
5+
with open('README.md', encoding='utf-8') as io:
6+
long_description = io.read()
7+
8+
setup(
9+
name = 'LibCarna-Python',
10+
version = '@FULL_VERSION@',
11+
description = 'General-purpose real-time 3D visualization',
12+
long_description = long_description,
13+
long_description_content_type = 'text/markdown',
14+
author = 'Leonid Kostrykin',
15+
author_email = 'leonid.kostrykin@bioquant.uni-heidelberg.de',
16+
url = 'https://github.com/kostrykin/LibCarna-Python',
17+
include_package_data = True,
18+
license = 'MIT',
19+
license_files = [
20+
'LICENSE',
21+
'LICENSE-Carna',
22+
'LICENSE-LibCarna',
23+
'LICENSE-Eigen',
24+
'LICENSE-GLEW',
25+
],
26+
package_dir = {
27+
'libcarna': 'libcarna',
28+
},
29+
packages = ['libcarna'],
30+
package_data = {
31+
'libcarna': ['*.so'],
32+
},
33+
classifiers = [
34+
'Development Status :: 4 - Beta',
35+
'Environment :: GPU',
36+
'Operating System :: POSIX :: Linux',
37+
'Programming Language :: C++',
38+
'Programming Language :: Python',
39+
'Topic :: Education',
40+
'Topic :: Multimedia :: Graphics :: 3D Rendering',
41+
'Topic :: Scientific/Engineering :: Visualization',
42+
],
43+
install_requires = [
44+
'numpy',
45+
'numpngw >=0.1.4, <0.2',
46+
'scikit-video >=1.1.11, <1.2',
47+
'scipy',
48+
'scikit-image',
49+
'tifffile',
50+
'pooch',
51+
'matplotlib',
52+
'typing_extensions', # required for Python 3.10
53+
],
54+
)
55+

0 commit comments

Comments
 (0)