Enable Scikit-Build-Core Support
Description
This PR introduces support for scikit-build-core, streamlining the build process and improving compatibility.
This is a minimal version of the PR, excluding manylinux support, to facilitate a faster review. The full PR can be found here.
Key Changes
Enable scikit-build-core support
- Updated
pyproject.tomlto usescikit-build-coreinstead of legacy methods.
CMake and Build Updates
- Updated
CMakeLists.txtto supportskbuild, ensuring compatibility with bothscikit-build-coreand native CMake builds. - Added
GenerateScript.cmaketo handle executable files (openmc) on both Linux and macOS. - Updated
OpenMCConfig.cmake.into integratescikit-build-core.
Git and Packaging Improvements
- Removed ignoring of
.h5files from.gitignoreas they are needed. - Removed
MANIFEST.inas it is no longer required.
CI and Docs Updates
- Updated Dockerfile: Removed the need to run CMake before
pip installasscikit-build-corenow handles it. - Updated CI configuration files to fix build and test issues.
- Added necessary APT packages for ReadTheDocs to compile dependencies properly.
Python API Enhancements
- Added functions to
__init__.pyto retrieve OpenMC installation configuration from the Python side.
Sponsored By
This contribution is kindly sponsored by @proximafusion, supporting the ongoing development and modernization of OpenMC’s Python packaging and build system.
Thanks for keeping this PR up to date @ahnaf-tahmid-chowdhury
We appear to have lost some coverage in the src folder and includes folder on this PR
It's strange. The coverage is showing files with less coverage that are not even touched in this PR. I'm not sure how to fix this or if it's a bug.
oh that last run appears to be 1.5 % dropped coverage, I think previous ones were a bigger drop.
Congratulations Ahnaf looks like all thest tests are pass and the coverage is also good.
This PR is realy for review. Feedback welcome
Hey @ahnaf-tahmid-chowdhury thanks for this, I'm planning on testing this with @rossmacdonald98 and @SteSeg to fix our workflow (see #3369 ) without having to wait for a new release or recompile from source
This branch and the pip install mechanism can be tried with with command
pip install git+https://github.com/ahnaf-tahmid-chowdhury/OpenMC.git@skbuild-minimal
Let us know if you uncover any issues
I tried to merge openmc-dev:develop into ahnaf-tahmid-chowdhury:skbuild-minimal but ran into this issue:
python version Python 3.13.2
python -m pip install git+https://github.com/LIBRA-project/openmc@pip-with-fix
Collecting git+https://github.com/LIBRA-project/openmc@pip-with-fix
Cloning https://github.com/LIBRA-project/openmc (to revision pip-with-fix) to /tmp/pip-req-build-ukvixuvp
Running command git clone --filter=blob:none --quiet https://github.com/LIBRA-project/openmc /tmp/pip-req-build-ukvixuvp
Running command git checkout -b pip-with-fix --track origin/pip-with-fix
Switched to a new branch 'pip-with-fix'
branch 'pip-with-fix' set up to track 'origin/pip-with-fix'.
Resolved https://github.com/LIBRA-project/openmc to commit 4c4ac3408b3eb8e762751d6783dd00c529046b11
Running command git submodule update --init --recursive -q
Installing build dependencies ... done
Getting requirements to build wheel ... done
Installing backend dependencies ... done
Preparing metadata (pyproject.toml) ... done
Collecting numpy (from openmc==0.0.0)
Downloading numpy-2.2.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (62 kB)
Collecting h5py (from openmc==0.0.0)
Downloading h5py-3.13.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (2.5 kB)
Collecting scipy (from openmc==0.0.0)
Using cached scipy-1.15.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (61 kB)
Collecting ipython (from openmc==0.0.0)
Downloading ipython-9.1.0-py3-none-any.whl.metadata (4.4 kB)
Collecting matplotlib (from openmc==0.0.0)
Using cached matplotlib-3.10.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (11 kB)
Collecting pandas (from openmc==0.0.0)
Using cached pandas-2.2.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (89 kB)
Collecting lxml (from openmc==0.0.0)
Downloading lxml-5.4.0-cp313-cp313-manylinux_2_28_x86_64.whl.metadata (3.5 kB)
Collecting uncertainties (from openmc==0.0.0)
Downloading uncertainties-3.2.3-py3-none-any.whl.metadata (7.0 kB)
Requirement already satisfied: setuptools in /home/remidm/anaconda3/envs/temp-openmc-build/lib/python3.13/site-packages (from openmc==0.0.0) (75.8.0)
Collecting endf (from openmc==0.0.0)
Downloading endf-0.1.4.tar.gz (80 kB)
Installing build dependencies ... done
Getting requirements to build wheel ... done
Preparing metadata (pyproject.toml) ... done
Collecting decorator (from ipython->openmc==0.0.0)
Using cached decorator-5.2.1-py3-none-any.whl.metadata (3.9 kB)
Collecting ipython-pygments-lexers (from ipython->openmc==0.0.0)
Using cached ipython_pygments_lexers-1.1.1-py3-none-any.whl.metadata (1.1 kB)
Collecting jedi>=0.16 (from ipython->openmc==0.0.0)
Using cached jedi-0.19.2-py2.py3-none-any.whl.metadata (22 kB)
Collecting matplotlib-inline (from ipython->openmc==0.0.0)
Using cached matplotlib_inline-0.1.7-py3-none-any.whl.metadata (3.9 kB)
Collecting pexpect>4.3 (from ipython->openmc==0.0.0)
Using cached pexpect-4.9.0-py2.py3-none-any.whl.metadata (2.5 kB)
Collecting prompt_toolkit<3.1.0,>=3.0.41 (from ipython->openmc==0.0.0)
Downloading prompt_toolkit-3.0.51-py3-none-any.whl.metadata (6.4 kB)
Collecting pygments>=2.4.0 (from ipython->openmc==0.0.0)
Using cached pygments-2.19.1-py3-none-any.whl.metadata (2.5 kB)
Collecting stack_data (from ipython->openmc==0.0.0)
Using cached stack_data-0.6.3-py3-none-any.whl.metadata (18 kB)
Collecting traitlets>=5.13.0 (from ipython->openmc==0.0.0)
Using cached traitlets-5.14.3-py3-none-any.whl.metadata (10 kB)
Collecting contourpy>=1.0.1 (from matplotlib->openmc==0.0.0)
Downloading contourpy-1.3.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (5.5 kB)
Collecting cycler>=0.10 (from matplotlib->openmc==0.0.0)
Using cached cycler-0.12.1-py3-none-any.whl.metadata (3.8 kB)
Collecting fonttools>=4.22.0 (from matplotlib->openmc==0.0.0)
Using cached fonttools-4.57.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (102 kB)
Collecting kiwisolver>=1.3.1 (from matplotlib->openmc==0.0.0)
Using cached kiwisolver-1.4.8-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (6.2 kB)
Collecting packaging>=20.0 (from matplotlib->openmc==0.0.0)
Using cached packaging-25.0-py3-none-any.whl.metadata (3.3 kB)
Collecting pillow>=8 (from matplotlib->openmc==0.0.0)
Using cached pillow-11.2.1-cp313-cp313-manylinux_2_28_x86_64.whl.metadata (8.9 kB)
Collecting pyparsing>=2.3.1 (from matplotlib->openmc==0.0.0)
Using cached pyparsing-3.2.3-py3-none-any.whl.metadata (5.0 kB)
Collecting python-dateutil>=2.7 (from matplotlib->openmc==0.0.0)
Using cached python_dateutil-2.9.0.post0-py2.py3-none-any.whl.metadata (8.4 kB)
Collecting pytz>=2020.1 (from pandas->openmc==0.0.0)
Downloading pytz-2025.2-py2.py3-none-any.whl.metadata (22 kB)
Collecting tzdata>=2022.7 (from pandas->openmc==0.0.0)
Downloading tzdata-2025.2-py2.py3-none-any.whl.metadata (1.4 kB)
Collecting parso<0.9.0,>=0.8.4 (from jedi>=0.16->ipython->openmc==0.0.0)
Using cached parso-0.8.4-py2.py3-none-any.whl.metadata (7.7 kB)
Collecting ptyprocess>=0.5 (from pexpect>4.3->ipython->openmc==0.0.0)
Using cached ptyprocess-0.7.0-py2.py3-none-any.whl.metadata (1.3 kB)
Collecting wcwidth (from prompt_toolkit<3.1.0,>=3.0.41->ipython->openmc==0.0.0)
Using cached wcwidth-0.2.13-py2.py3-none-any.whl.metadata (14 kB)
Collecting six>=1.5 (from python-dateutil>=2.7->matplotlib->openmc==0.0.0)
Using cached six-1.17.0-py2.py3-none-any.whl.metadata (1.7 kB)
Collecting executing>=1.2.0 (from stack_data->ipython->openmc==0.0.0)
Using cached executing-2.2.0-py2.py3-none-any.whl.metadata (8.9 kB)
Collecting asttokens>=2.1.0 (from stack_data->ipython->openmc==0.0.0)
Using cached asttokens-3.0.0-py3-none-any.whl.metadata (4.7 kB)
Collecting pure-eval (from stack_data->ipython->openmc==0.0.0)
Using cached pure_eval-0.2.3-py3-none-any.whl.metadata (6.3 kB)
Downloading h5py-3.13.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.9 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.9/4.9 MB 32.1 MB/s eta 0:00:00
Downloading numpy-2.2.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (16.1 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 16.1/16.1 MB 37.0 MB/s eta 0:00:00
Downloading ipython-9.1.0-py3-none-any.whl (604 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 604.1/604.1 kB 22.2 MB/s eta 0:00:00
Downloading lxml-5.4.0-cp313-cp313-manylinux_2_28_x86_64.whl (4.9 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.9/4.9 MB 38.7 MB/s eta 0:00:00
Using cached matplotlib-3.10.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (8.6 MB)
Using cached pandas-2.2.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (12.7 MB)
Using cached scipy-1.15.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (37.3 MB)
Downloading uncertainties-3.2.3-py3-none-any.whl (60 kB)
Downloading contourpy-1.3.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (322 kB)
Using cached cycler-0.12.1-py3-none-any.whl (8.3 kB)
Using cached fonttools-4.57.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.8 MB)
Using cached jedi-0.19.2-py2.py3-none-any.whl (1.6 MB)
Using cached kiwisolver-1.4.8-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.5 MB)
Using cached packaging-25.0-py3-none-any.whl (66 kB)
Using cached pexpect-4.9.0-py2.py3-none-any.whl (63 kB)
Using cached pillow-11.2.1-cp313-cp313-manylinux_2_28_x86_64.whl (4.6 MB)
Downloading prompt_toolkit-3.0.51-py3-none-any.whl (387 kB)
Using cached pygments-2.19.1-py3-none-any.whl (1.2 MB)
Using cached pyparsing-3.2.3-py3-none-any.whl (111 kB)
Using cached python_dateutil-2.9.0.post0-py2.py3-none-any.whl (229 kB)
Downloading pytz-2025.2-py2.py3-none-any.whl (509 kB)
Using cached traitlets-5.14.3-py3-none-any.whl (85 kB)
Downloading tzdata-2025.2-py2.py3-none-any.whl (347 kB)
Using cached decorator-5.2.1-py3-none-any.whl (9.2 kB)
Using cached ipython_pygments_lexers-1.1.1-py3-none-any.whl (8.1 kB)
Using cached matplotlib_inline-0.1.7-py3-none-any.whl (9.9 kB)
Using cached stack_data-0.6.3-py3-none-any.whl (24 kB)
Using cached asttokens-3.0.0-py3-none-any.whl (26 kB)
Using cached executing-2.2.0-py2.py3-none-any.whl (26 kB)
Using cached parso-0.8.4-py2.py3-none-any.whl (103 kB)
Using cached ptyprocess-0.7.0-py2.py3-none-any.whl (13 kB)
Using cached six-1.17.0-py2.py3-none-any.whl (11 kB)
Using cached pure_eval-0.2.3-py3-none-any.whl (11 kB)
Using cached wcwidth-0.2.13-py2.py3-none-any.whl (34 kB)
Building wheels for collected packages: openmc, endf
Building wheel for openmc (pyproject.toml) ... error
error: subprocess-exited-with-error
× Building wheel for openmc (pyproject.toml) did not run successfully.
│ exit code: 1
╰─> [63 lines of output]
2025-04-23 13:03:43,589 - scikit_build_core - INFO - RUN: /tmp/pip-build-env-j5ei7hhk/normal/lib/python3.13/site-packages/cmake/data/bin/cmake -E capabilities
2025-04-23 13:03:43,591 - scikit_build_core - INFO - CMake version: 4.0.0
*** scikit-build-core 0.11.1 using CMake 4.0.0 (wheel)
2025-04-23 13:03:43,593 - scikit_build_core - INFO - Build directory: /tmp/tmpzh05vedz/build
*** Configuring CMake...
2025-04-23 13:03:43,599 - scikit_build_core - INFO - RUN: ninja --version
2025-04-23 13:03:43,600 - scikit_build_core - INFO - Ninja version: 1.11.1
2025-04-23 13:03:43,601 - scikit_build_core - INFO - RUN: /tmp/pip-build-env-j5ei7hhk/normal/lib/python3.13/site-packages/cmake/data/bin/cmake -S. -B/tmp/tmpzh05vedz/build -DCMAKE_BUILD_TYPE:STRING=Release -C/tmp/tmpzh05vedz/build/CMakeInit.txt -DCMAKE_INSTALL_PREFIX=/tmp/tmpzh05vedz/wheel/platlib/openmc -DCMAKE_MAKE_PROGRAM=ninja
loading initial cache file /tmp/tmpzh05vedz/build/CMakeInit.txt
-- The C compiler identification is GNU 13.3.0
-- The CXX compiler identification is GNU 13.3.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/gcc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/g++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found Git: /usr/bin/git (found version "2.43.0")
-- Using git describe for versioning
CMake Warning at cmake/Modules/GetVersionFromGit.cmake:46 (message):
No git tags found. Version set to 0.0.0.
Run 'git fetch --tags' to ensure proper versioning.
For more information, see OpenMC developer documentation.
Call Stack (most recent call first):
CMakeLists.txt:7 (include)
-- OpenMC version: 0.0.0
-- OpenMC dev state: false
-- OpenMC commit hash: 4c4ac3408b3eb8e762751d6783dd00c529046b11
-- OpenMC commit count:
-- OPENMC_USE_OPENMP ON
-- OPENMC_BUILD_TESTS ON
-- OPENMC_ENABLE_PROFILE OFF
-- OPENMC_ENABLE_COVERAGE OFF
-- OPENMC_USE_DAGMC OFF
-- OPENMC_USE_LIBMESH OFF
-- OPENMC_USE_MPI OFF
-- OPENMC_USE_MCPL OFF
-- OPENMC_USE_UWUW OFF
-- Found OpenMP_C: -fopenmp (found version "4.5")
-- Found OpenMP_CXX: -fopenmp (found version "4.5")
-- Found OpenMP: TRUE (found version "4.5")
-- Could NOT find ZLIB (missing: ZLIB_LIBRARY ZLIB_INCLUDE_DIR)
-- Could NOT find PNG (missing: PNG_LIBRARY PNG_PNG_INCLUDE_DIR)
CMake Error at /tmp/pip-build-env-j5ei7hhk/normal/lib/python3.13/site-packages/cmake/data/share/cmake-4.0/Modules/FindPackageHandleStandardArgs.cmake:227 (message):
Could NOT find HDF5 (missing: HDF5_LIBRARIES HDF5_INCLUDE_DIRS
HDF5_HL_LIBRARIES C HL)
Call Stack (most recent call first):
/tmp/pip-build-env-j5ei7hhk/normal/lib/python3.13/site-packages/cmake/data/share/cmake-4.0/Modules/FindPackageHandleStandardArgs.cmake:591 (_FPHSA_FAILURE_MESSAGE)
/tmp/pip-build-env-j5ei7hhk/normal/lib/python3.13/site-packages/cmake/data/share/cmake-4.0/Modules/FindHDF5.cmake:1024 (find_package_handle_standard_args)
CMakeLists.txt:173 (find_package)
-- Configuring incomplete, errors occurred!
*** CMake configuration failed
[end of output]
note: This error originates from a subprocess, and is likely not a problem with pip.
ERROR: Failed building wheel for openmc
Building wheel for endf (pyproject.toml) ... done
Created wheel for endf: filename=endf-0.1.4-cp313-cp313-linux_x86_64.whl size=114793 sha256=b6a015388bae35b446b1bf35dafced1ed062b20156ed93079796c7fbbdcc2aba
Stored in directory: /home/remidm/.cache/pip/wheels/39/cf/5b/92b26adc097196ccabee43fa54b2fd84d088001e7ac2354671
Successfully built endf
Failed to build openmc
ERROR: Failed to build installable wheels for some pyproject.toml based projects (openmc)
Hello, @RemDelaporteMathurin. This is a short PR that only introduces the scikit-build-core setup. You may need to install dependencies before running the setup.
Yes in the future (follow up PR) these will be bundled in the wheel but for now if you install via pip and this branch I guess these are needed.
sudo apt install g++ cmake libhdf5-dev libpng-dev
Yes in the future (follow up PR) these will be bundled in the wheel but for now if you install via pip and this branch I guess these are needed.
sudo apt install g++ cmake libhdf5-dev libpng-dev
Installed these dependencies and I still have the error. Is there a list somewhere?
For minimal setup you may only need hdf5 installed. For detail setup you may consider reviewing the CI workflows. There is a Manylinux dockerfile available at #3087 that might also help.
Thanks @ahnaf-tahmid-chowdhury for making the changes now that mcpl is linked via a pip install
We need to do the same thing for mcpl that we have done for ncrystal.
I have already created PR #3429 to make this PR working again.
Everything is working now.
Here's a minimal Dockerfile I used to produce the wheel for python 3.13/ubuntu25.04, works great:
FROM ubuntu:25.04
RUN apt update -y \
&& apt install -y python3 python-is-python3 python3-venv python3-dev \
git g++ cmake libhdf5-dev libpng-dev curl
RUN python -m venv venv \
&& . venv/bin/activate \
&& pip install git+https://github.com/ahnaf-tahmid-chowdhury/OpenMC.git@skbuild-minimal
What are the difficulties that need solving to add DAGMC+dependencies to the wheel?
Glad to hear it is working for you.
What are the difficulties that need solving to add DAGMC+dependencies to the wheel?
No difficulties, Ahnaf and myself have already added DAGMC + Embree + Moab to a wheel. We have not included it in this PR as we are trying to keep it minimal. If this one is merged then we would follow up with a PR that adds DAGMC to the wheel. However for a sneak preview you could take a peak that this branch and this repo for method and resulting wheels. One difference is that we have used manylinux dockerfiles to ensure compatibility with other flavors of linux.
Ah looks like the recent changes to the coverage need merging into this PR
CI error is Run # Merge C++ and Python LCOV into a single file for upload cat: coverage-cpp.lcov: No such file or directory
I think this is the PR that got the CI working again https://github.com/openmc-dev/openmc/pull/3594
Key things being changed, added, or removed:
-
Build System Update: The
pyproject.tomlfile is updated to usescikit-build-coreas the build backend. -
CMake Build Updates:
-
CMakeLists.txtand related files have been adapted to supportskbuild, ensuring compatibility with both scikit-build-core and regular CMake builds. - A new
GenerateScript.cmakeis added for handling executable files on Linux and macOS. -
OpenMCConfig.cmake.inupdated for integration with the new build system.
-
-
Packaging & Project Files:
-
.gitignoreis updated to stop ignoring.h5files, as they are now required. -
MANIFEST.inhas been removed since it's no longer necessary.
-
-
Continuous Integration & Documentation:
- The Dockerfile is updated to give scikit-build-core responsibility for CMake steps.
- Continuous integration and documentation build configs are updated to fix issues and ensure all dependencies are built properly.
- Additional APT packages are added for ReadTheDocs builds.
-
Python API Enhancements: Functions added to
__init__.pyto dynamically retrieve installation configuration details from Python. - General Modernization: Old methods are deprecated/removed in favor of newer, streamlined approaches.
This is just the foundation. More features will be added later, such as using CMake’s built-in modules for target generation, adding an openmc-config CLI, supporting manylinux images for PyPI, and improving the handling of external packages.