diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 98f1428808..7c7f327e2e 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -48,8 +48,7 @@ jobs:
name: build
run: |
conda activate "${{ steps.reqs.outputs.envname }}"
- cmake -S . -B ./build -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCONDA_BUILD=ON -DCMAKE_INSTALL_PREFIX="$CONDA_PREFIX"
- cmake --build ./build --target install
+ pip install .
- name: test
run: |
conda activate "${{ steps.reqs.outputs.envname }}"
@@ -81,10 +80,7 @@ jobs:
python-version: ${{ matrix.python-version }}
environment-file: scripts/requirements-test.yml
activate-environment: cil_dev
- - name: build
- run: |
- cmake -S . -B ./build -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCONDA_BUILD=ON -DCMAKE_INSTALL_PREFIX="$CONDA_PREFIX"
- cmake --build ./build --target install
+ - run: pip install .
- name: test
run: python -m unittest discover -v ./Wrappers/Python/test
conda-matrix:
@@ -179,11 +175,7 @@ jobs:
conda-merge ../scripts/requirements-test.yml docs_environment.yml > environment.yml
conda env update -n test
conda list
- - name: build cil
- working-directory: .
- run: |
- cmake -S . -B ./build -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCONDA_BUILD=ON -DCMAKE_INSTALL_PREFIX="$CONDA_PREFIX"
- cmake --build ./build --target install
+ - run: pip install ..
- name: checkout docs
uses: actions/checkout@v4
with:
diff --git a/.gitignore b/.gitignore
index db3970f85a..81b4942ab4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,8 @@
-/build/
+/build*
__pycache__/
-/Wrappers/Python/build/
/Wrappers/Python/cil/version.py
-/build*
+/Wrappers/Python/cil-*.dist-info/
+/Wrappers/Python/cil/include/
+/Wrappers/Python/cil/lib/
*.vscode*
*.egg*
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ffad4c4127..93488ba57d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -29,6 +29,7 @@
- Added tests for Normaliser processor
- Update minimum cmake version to 3.5
- Dependencies:
+ - Move from CMake to `pip install` (#2145)
- matplotlib-base is an optional dependency, instead of required (#2093)
- `unittest-parametrize has been added as a dependency for tests (#1990)
- olefile and dxchange are an optional dependency, instead of required (#2149)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 261c61cb66..1054e3d78c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -21,7 +21,10 @@ else()
cmake_minimum_required(VERSION 3.5)
endif()
-project(cil LANGUAGES CXX)
+if(NOT SKBUILD_PROJECT_NAME)
+ set(SKBUILD_PROJECT_NAME cil)
+endif()
+project(${SKBUILD_PROJECT_NAME} LANGUAGES CXX)
cmake_policy(PUSH)
@@ -46,6 +49,5 @@ if(NOT DEFINED CMAKE_BUILD_TYPE)
endif()
add_subdirectory(src/Core)
-add_subdirectory(Wrappers/Python)
cmake_policy(POP)
diff --git a/Dockerfile b/Dockerfile
index 5dc5f25bca..5c508e0d71 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -29,7 +29,5 @@ ENV TENSORBOARD_PROXY_URL=/user-redirect/proxy/6006/
# build & install CIL
COPY --chown="${NB_USER}" . src
-RUN cmake -S ./src -B ./build -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCONDA_BUILD=ON -DCMAKE_INSTALL_PREFIX="${CONDA_DIR}" \
- && cmake --build ./build --target install \
- && rm -rf src build \
+RUN pip install ./src && rm -rf src \
&& fix-permissions "${CONDA_DIR}" /home/${NB_USER}
diff --git a/README.md b/README.md
index 5cdd6b3dea..75e80d2e23 100644
--- a/README.md
+++ b/README.md
@@ -31,6 +31,7 @@ conda create --name cil -c conda-forge -c https://software.repos.intel.com/pytho
```
where:
+
- `astra-toolbox=*=py*` enables CIL support for [ASTRA toolbox](http://www.astra-toolbox.com) CPU projector (2D Parallel beam only) (GPLv3 license)
- `astra-toolbox=*=cuda*` (requires an NVIDIA GPU) enables CIL support for [ASTRA toolbox](http://www.astra-toolbox.com) GPU projectors (GPLv3 license)
- `tigre` (requires an NVIDIA GPU) enables support for [TIGRE](https://github.com/CERN/TIGRE) toolbox projectors (BSD license)
@@ -86,7 +87,8 @@ docker run --rm --gpus all -p 8888:8888 -it ghcr.io/tomographicimaging/cil:lates
## Getting Started with CIL
### CIL Training
-We typically run training courses at least twice a year - check https://ccpi.ac.uk/training/ for our upcoming events!
+
+We typically run training courses at least twice a year - check for our upcoming events!
### CIL on binder
@@ -116,60 +118,45 @@ The use of `--recurse-submodule` is necessary if the user wants the examples dat
git submodule update --init --recursive
```
-### Build dependencies
+### Building with `pip`
+
+#### Install Dependencies
To create a conda environment with all the dependencies for building CIL run the following shell script:
```sh
-bash scripts/create_local_env_for_cil_development.sh
+bash ./scripts/create_local_env_for_cil_development.sh
```
Or with the CIL build and test dependencies:
```sh
-bash scripts/create_local_env_for_cil_development.sh -t
+bash ./scripts/create_local_env_for_cil_development.sh -t
```
-And then install CIL in to this environment using CMake.
+And then install CIL in to this environment using `pip`.
Alternatively, one can use the `scripts/requirements-test.yml` to create a conda environment with all the
appropriate dependencies on any OS, using the following command:
```sh
-conda env create -f scripts/requirements-test.yml
+conda env create -f ./scripts/requirements-test.yml
```
-### Build with CMake
-
-CMake and a C++ compiler are required to build the source code. Let's suppose that the user is in the source directory, then the following commands should work:
+#### Build CIL
-```sh
-cmake -S . -B ./build -DCMAKE_INSTALL_PREFIX= -DPython_EXECUTABLE=
-cmake --build ./build --target install
-```
+A C++ compiler is required to build the source code. Let's suppose that the user is in the source directory, then the following commands should work:
-If targeting an active conda environment then the `` can be set to the `CONDA_PREFIX` environment variable (e.g. `${CONDA_PREFIX}` in Bash, or `%CONDA_PREFIX%` in the Anaconda Prompt on Windows). Similarly, `` can be set to the active conda environment by passing `${CONDA_PREFIX}/bin/python` on linux or `%CONDA_PREFIX%\python` in windows.
-
-#### Linux
-```sh
-cmake -S . -B ./build -DCMAKE_INSTALL_PREFIX=${CONDA_PREFIX} -DPython_EXECUTABLE=${CONDA_PREFIX}/bin/python
-```
-#### Windows
```sh
-cmake -S . -B .\build -DCMAKE_INSTALL_PREFIX=%CONDA_PREFIX% -DPython_EXECUTABLE=%CONDA_PREFIX%\python
+pip install --no-deps .
```
-If not installing to a conda environment then the user will also need to set the locations of the IPP library and includes, and the path to CIL.
-
-By default the location of the IPP library and includes is `${CMAKE_INSTALL_PREFIX}/lib` and `${CMAKE_INSTALL_PREFIX}/include` respectively. To pass the location of the IPP library and headers please pass the following parameters:
+If not installing inside a conda environment, then the user might need to set the locations of optional libraries:
```sh
-cmake -S . -B ./build -DCMAKE_INSTALL_PREFIX= -DPython_EXECUTABLE= -DIPP_ROOT=
+pip install . -Ccmake.define.IPP_ROOT="" -Ccmake.define.OpenMP_ROOT=""
```
-The user will then need to add the path `/lib` to the environment variable `PATH` or `LD_LIBRARY_PATH`, depending on system OS.
-
-
### Building with Docker
In the repository root, simply update submodules and run `docker build`:
@@ -179,7 +166,6 @@ git submodule update --init --recursive
docker build . -t ghcr.io/tomographicimaging/cil
```
-
### Testing
One installed, CIL functionality can be tested using the following command:
@@ -189,10 +175,8 @@ export TESTS_FORCE_GPU=1 # optional, makes GPU test failures noisy
python -m unittest discover -v ./Wrappers/Python/test
```
-
## Citing CIL
-
If you use CIL in your research, please include citations to **both** the software on Zenodo, and a CIL paper:
E. Pasca, J. S. Jørgensen, E. Papoutsellis, E. Ametova, G. Fardell, K. Thielemans, L. Murgatroyd, M. Duff and H. Robarts (2023)
@@ -200,7 +184,6 @@ Core Imaging Library (CIL)
Zenodo [software archive]
**DOI:** https://doi.org/10.5281/zenodo.4746198
-
In most cases, the first CIL paper will be the appropriate choice:
J. S. Jørgensen, E. Ametova, G. Burca, G. Fardell, E. Papoutsellis, E. Pasca, K. Thielemans, M. Turner, R. Warr, W. R. B. Lionheart and P. J. Withers (2021)
diff --git a/Wrappers/Python/CMakeLists.txt b/Wrappers/Python/CMakeLists.txt
deleted file mode 100644
index 9cb60e0f60..0000000000
--- a/Wrappers/Python/CMakeLists.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-find_package(Python COMPONENTS Interpreter REQUIRED)
-
-if(PYTHON_DEST_DIR)
- file(TO_CMAKE_PATH "${PYTHON_DEST_DIR}" PYTHON_DEST)
-endif()
-
-message("CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}")
-if(NOT DEFINED)
- set(CMAKE_BUILD_TYPE "RelWithDebInfo")
-endif()
-
-# TODO: add to add_custom_command DEPENDS the list of python files of the project.
-# file(GLOB_RECURSE DEPS ${CMAKE_CURRENT_SOURCE_DIR}/cil/*.py )
-message("SETUPTOOLS_SCM_PRETEND_VERSION_FOR_CIL: $ENV{SETUPTOOLS_SCM_PRETEND_VERSION_FOR_CIL}")
-message("CMAKE_SOURCE_DIR: ${CMAKE_SOURCE_DIR}")
-if(PYTHON_DEST_DIR)
- message(STATUS "CIL install using ${Python_EXECUTABLE} -m pip install -t ${PYTHON_DEST}")
- add_custom_target(pythonsetup ALL
- COMMAND ${Python_EXECUTABLE} -m pip install ${CMAKE_SOURCE_DIR} -t ${PYTHON_DEST} --upgrade
- DEPENDS cilacc)
-else()
- message(STATUS "CIL install using ${Python_EXECUTABLE} -m pip install")
- add_custom_target(pythonsetup ALL
- COMMAND ${Python_EXECUTABLE} -m pip install ${CMAKE_SOURCE_DIR} --upgrade
- DEPENDS cilacc)
-endif()
-# install the data if not a conda build. With conda the data is in the dependency package cil-data
-if (NOT CONDA_BUILD)
- install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/ DESTINATION ${CMAKE_INSTALL_PREFIX}/share/cil)
-endif()
diff --git a/Wrappers/Python/cil/framework/cilacc.py b/Wrappers/Python/cil/framework/cilacc.py
index fa96ba4c51..88e7046dc0 100644
--- a/Wrappers/Python/cil/framework/cilacc.py
+++ b/Wrappers/Python/cil/framework/cilacc.py
@@ -16,18 +16,10 @@
# Authors:
# CIL Developers, listed at: https://github.com/TomographicImaging/CIL/blob/master/NOTICE.txt
import ctypes
-import platform
-from ctypes import util
-# check for the extension
+from pathlib import Path
-if platform.system() == 'Linux':
- dll = 'libcilacc.so'
-elif platform.system() == 'Windows':
- dll_file = 'cilacc.dll'
- dll = util.find_library(dll_file)
-elif platform.system() == 'Darwin':
- dll = 'libcilacc.dylib'
-else:
- raise ValueError('Not supported platform, ', platform.system())
-
-cilacc = ctypes.cdll.LoadLibrary(dll)
+try:
+ cilacc_path = next((Path(__file__).parent.parent / 'lib').resolve().glob("*cilacc.*"))
+except StopIteration:
+ raise FileNotFoundError("cilacc library not found")
+cilacc = ctypes.cdll.LoadLibrary(str(cilacc_path))
diff --git a/Wrappers/Python/cil/optimisation/operators/GradientOperator.py b/Wrappers/Python/cil/optimisation/operators/GradientOperator.py
index ae6bbc6922..56dd9b1b1b 100644
--- a/Wrappers/Python/cil/optimisation/operators/GradientOperator.py
+++ b/Wrappers/Python/cil/optimisation/operators/GradientOperator.py
@@ -18,7 +18,7 @@
from cil.optimisation.operators import LinearOperator
from cil.optimisation.operators import FiniteDifferenceOperator
-from cil.framework import BlockGeometry, ImageGeometry
+from cil.framework import BlockGeometry, ImageGeometry, cilacc
import logging
from cil.utilities.multiprocessing import NUM_THREADS
import numpy as np
@@ -258,7 +258,7 @@ def adjoint(self, x, out=None):
out.fill(tmp)
else:
out += tmp
- return out
+ return out
else:
tmp = self.domain_geometry().allocate()
for i, axis_index in enumerate(self.ind):
@@ -267,20 +267,7 @@ def adjoint(self, x, out=None):
tmp += self.FD.adjoint(x.get_item(i))
return tmp
-import ctypes, platform
-from ctypes import util
-# check for the extension
-if platform.system() == 'Linux':
- dll = 'libcilacc.so'
-elif platform.system() == 'Windows':
- dll_file = 'cilacc.dll'
- dll = util.find_library(dll_file)
-elif platform.system() == 'Darwin':
- dll = 'libcilacc.dylib'
-else:
- raise ValueError('Not supported platform, ', platform.system())
-
-cilacc = ctypes.cdll.LoadLibrary(dll)
+import ctypes
c_float_p = ctypes.POINTER(ctypes.c_float)
@@ -457,7 +444,7 @@ def adjoint(self, x, out=None):
status = self.fd(out_p, *args)
if status != 0:
raise RuntimeError('Call to C gradient operator failed')
-
+
out.fill(ndout)
#reset input data
@@ -466,4 +453,3 @@ def adjoint(self, x, out=None):
ndx[i]*= el
return out
-
diff --git a/docs/source/developer_guide.rst b/docs/source/developer_guide.rst
index ea78b8bb7e..f1472925f9 100644
--- a/docs/source/developer_guide.rst
+++ b/docs/source/developer_guide.rst
@@ -137,8 +137,7 @@ Example:
cd CIL
sh scripts/create_local_env_for_cil_development_tests.sh -n NUMPY_VERSION -p PYTHON_VERSION -e ENVIRONMENT_NAME
conda activate ENVIRONMENT_NAME
- cmake -S . -B ./build -DCMAKE_INSTALL_PREFIX=${CONDA_PREFIX}
- cmake --build ./build --target install
+ pip install .
cd docs
conda update -n base -c defaults conda
conda env update -f docs_environment.yml # with the name field set to ENVIRONMENT_NAME
diff --git a/pyproject.toml b/pyproject.toml
index 24adcdac4a..846644715e 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,20 @@
[build-system]
-requires = ["setuptools>=64", "setuptools_scm>=8"]
-build-backend = "setuptools.build_meta"
+requires = [
+ "setuptools>=64",
+ "setuptools_scm>=8",
+ "scikit-build-core>=0.10",
+ #"ipp-devel==2021.12.*", # PyPI conflicts with conda package
+]
+build-backend = "scikit_build_core.build"
+
+[tool.scikit-build]
+minimum-version = "build-system.requires"
+cmake.version = ">=3.16"
+metadata.version.provider = "scikit_build_core.metadata.setuptools_scm"
+sdist.include = ["Wrappers/Python/cil/version.py"]
+sdist.exclude = ["scripts", "docs", "Wrappers/Python/data", "Wrappers/Python/test", ".*"]
+[tool.scikit-build.wheel.packages]
+cil = "Wrappers/Python/cil"
[tool.setuptools_scm]
version_file = "Wrappers/Python/cil/version.py"
diff --git a/recipe/bld.bat b/recipe/bld.bat
index 696c6a1870..97fb90517d 100644
--- a/recipe/bld.bat
+++ b/recipe/bld.bat
@@ -4,13 +4,5 @@ set SETUPTOOLS_SCM_PRETEND_VERSION_FOR_CIL=%PKG_VERSION%
if not "%GIT_DESCRIBE_NUMBER%"=="0" (
set SETUPTOOLS_SCM_PRETEND_VERSION_FOR_CIL=%PKG_VERSION%.dev%GIT_DESCRIBE_NUMBER%+%GIT_DESCRIBE_HASH%
)
-
-:: -G "Visual Studio 16 2019" specifies the the generator
-:: -T v142 specifies the toolset
-
-cmake -S "%RECIPE_DIR%\.." -B "%SRC_DIR%\build_framework" -G "Visual Studio 16 2019" -T "v142" -DCONDA_BUILD=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo -DLIBRARY_LIB=%CONDA_PREFIX%\lib -DLIBRARY_INC=%CONDA_PREFIX% -DCMAKE_INSTALL_PREFIX=%PREFIX% -DPython_EXECUTABLE=%CONDA_PREFIX%\python
-
-if errorlevel 1 exit 1
-
-cmake --build "%SRC_DIR%\build_framework" --target install --config RelWithDebInfo
+pip install . --no-deps
if errorlevel 1 exit 1
diff --git a/recipe/build.sh b/recipe/build.sh
index 0a1c1c629f..872bff219b 100755
--- a/recipe/build.sh
+++ b/recipe/build.sh
@@ -1,23 +1,16 @@
#!/usr/bin/env bash
set -euxo pipefail
+extra_args="-G Ninja"
if test $(python -c "from __future__ import print_function; import platform; print(platform.system())") = Darwin ; then
echo "Darwin"
- extra_args="-DOPENMP_LIBRARIES=${CONDA_PREFIX}/lib -DOPENMP_INCLUDES=${CONDA_PREFIX}/include"
+ extra_args="$extra_args -DOPENMP_LIBRARIES=${CONDA_PREFIX}/lib -DOPENMP_INCLUDES=${CONDA_PREFIX}/include"
else
echo "something else"
- extra_args=""
fi
export SETUPTOOLS_SCM_PRETEND_VERSION_FOR_CIL="${PKG_VERSION}"
if test "${GIT_DESCRIBE_NUMBER}" != "0"; then
export SETUPTOOLS_SCM_PRETEND_VERSION_FOR_CIL="${PKG_VERSION}.dev${GIT_DESCRIBE_NUMBER}+${GIT_DESCRIBE_HASH}"
fi
-cmake ${RECIPE_DIR}/../ ${extra_args} \
- -DCONDA_BUILD=ON \
- -DCMAKE_BUILD_TYPE=RelWithDebInfo \
- -DLIBRARY_LIB=${CONDA_PREFIX}/lib \
- -DLIBRARY_INC=${CONDA_PREFIX}/include \
- -DCMAKE_INSTALL_PREFIX=${PREFIX} \
- -DPython_EXECUTABLE=${CONDA_PREFIX}/bin/python
-cmake --build . --target install
+pip install . --no-deps -Ccmake.args="${extra_args}"
diff --git a/recipe/meta.yaml b/recipe/meta.yaml
index a84600143d..7f2bb87005 100644
--- a/recipe/meta.yaml
+++ b/recipe/meta.yaml
@@ -34,7 +34,7 @@ test:
- pip install unittest-parametrize
- python -m unittest discover -v -s Wrappers/Python/test # [win]
- python -m unittest discover -s Wrappers/Python/test -v # [not win]
-
+
requirements:
build:
@@ -50,9 +50,11 @@ requirements:
- _openmp_mutex # [linux]
- openmp # [osx]
- vc 14 # [win]
- - ipp-include {{ ipp_version }}
- - ipp-devel {{ ipp_version }}
- - ipp {{ ipp_version }}
+ - ninja # [not win]
+ - ipp-include {{ ipp_version }}
+ - ipp-devel {{ ipp_version }}
+ - ipp {{ ipp_version }}
+ - scikit-build-core >=0.10
run:
- python
diff --git a/src/Core/CMakeLists.txt b/src/Core/CMakeLists.txt
index 82f0c8e0b0..51aaa92851 100644
--- a/src/Core/CMakeLists.txt
+++ b/src/Core/CMakeLists.txt
@@ -26,7 +26,7 @@ find_package(OpenMP REQUIRED)
add_definitions(${OpenMP_CXX_FLAGS})
if (WIN32)
- set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Ddll_EXPORTS")
+ add_definitions("/Ddll_EXPORTS")
endif()
if (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNUCC")
@@ -68,29 +68,8 @@ add_library(cilacc SHARED ${cilacc_SOURCES})
target_link_libraries(cilacc ${cilacc_LIBRARIES})
include_directories(cilacc PUBLIC ${cilacc_INCLUDES})
-## Install
-#include(GNUInstallDirs)
-#install(TARGETS cilacc
-# RUNTIME DESTINATION bin
-# LIBRARY DESTINATION lib
-# ARCHIVE DESTINATION lib
-# CONFIGURATIONS ${CMAKE_BUILD_TYPE}
-# )
-
-if (UNIX)
-message ("I'd install into ${CMAKE_INSTALL_PREFIX}/lib")
install(TARGETS cilacc
- LIBRARY DESTINATION lib
- CONFIGURATIONS ${CMAKE_BUILD_TYPE}
- )
-elseif(WIN32)
-message ("I'd install into ${CMAKE_INSTALL_PREFIX} lib bin")
- install(TARGETS cilacc
- RUNTIME DESTINATION Library/bin
- ARCHIVE DESTINATION lib
- CONFIGURATIONS ${CMAKE_BUILD_TYPE}
- )
-endif()
-
-install(DIRECTORY ${PROJECT_SOURCE_DIR}/src/Core/include/
- DESTINATION ${CMAKE_INSTALL_PREFIX}/include/cil)
+ LIBRARY DESTINATION ${SKBUILD_PROJECT_NAME}/lib
+ RUNTIME DESTINATION ${SKBUILD_PROJECT_NAME}/lib)
+install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/
+ DESTINATION ${SKBUILD_PROJECT_NAME}/include/${SKBUILD_PROJECT_NAME})