InsightSoftwareConsortium / InsightSoftwareConsortium/ITK

External modules cannot wrap itkPyBuffer.h: Python include dir is not exported

Open
#6,865 2 comments 1 reaction 0 assignees View on GitHub
Dominant language
C++
Stars
1.7k
Forks
748
Avg merge
1d 1h
Merged PRs (30d)
64

Description

An external module that wraps `itkPyBuffer.h` cannot find `Python.h`: the Python include directory is never exported, so castxml fails outside ITK's own build tree.

## Reproduce

Build an external module that wraps `itkPyBuffer.h` (RTK does, via
`wrapping/itkPyBufferRTK.wrap`) against an ITK built with `ITK_WRAP_PYTHON=ON`:

```
FAILED: .../Wrapping/castxml_inputs/itkPyBufferRTK.xml
.../ITK/Modules/Bridge/NumPy/include/itkPyBuffer.h:30:10: fatal error: 'Python.h' file not found
30 | #include
```

The same target succeeds with the include supplied by hand:

```bash
CPATH="$CONDA_PREFIX/include/python3.14" ninja .../itkPyBufferRTK.xml # OK
```

## Cause

`Wrapping/Generators/Python/CMakeLists.txt:20` adds the Python include as a
**directory property**:

```cmake
include_directories("${Python3_INCLUDE_DIRS}")
```

and `Wrapping/Generators/CMakeLists.txt:99-104` re-reads that property and
re-applies it. Both act only inside ITK's own build tree.

An external module generates its `*.castxml.inc` from
`WRAPPER_LIBRARY_INCLUDE_DIRECTORIES` plus each dependency's
`INTERFACE_INCLUDE_DIRECTORIES`
(`Wrapping/macro_files/itk_auto_load_submodules.cmake:107,127,131`). The
exported `ITKBridgeNumPy.cmake` carries no Python include — its only Python
entry is `ITKBridgeNumPy_RUNTIME_LIBRARY_DIRS` — so the directory is absent
from the generated include list.

Measured on one such build: ITK's own `itkPyBuffer.castxml.inc` has 25 include
directories including `.../include/python3.14`; the external module's
`itkPyBufferRTK.castxml.inc` has 109 directories and none of them is Python's.

## Effect

The castxml step fails, wrapping never completes, and the module leaves a
`Config.py` in ITK's Python package with no `Python.py` and no
`_Python*.so`. Every later `import itk` in that build tree then raises

```
FileNotFoundError: .../itk/support/../RTKPython.py
```

while the lazy loader walks the factories, so unrelated consumers' Python tests
fail too.

## Possible directions

- Export the Python include with `ITKBridgeNumPy`'s interface, so any module
that consumes it inherits the directory.
- Or add `Python3_INCLUDE_DIRS` to the include list used to generate
`*.castxml.inc` for external modules.

Related in shape to #6860, where a wrapping/factory input also resolves only
inside ITK's own build tree.

Contributor guide

Open the contributing guide

Research direction

Start with Wrapping/Generators/Python/CMakeLists.txt, Wrapping/Generators/CMakeLists.txt, and Wrapping/macro_files/itk_auto_load_submodules.cmake to trace how Python3_INCLUDE_DIRS reaches generated castxml include lists and exported interfaces. Reproduce the RTK external wrapping case with ITK_WRAP_PYTHON=ON and inspect the generated *.castxml.inc files. Done means an external wrapper can find Python.h, complete castxml generation, and produce its Python module artifacts without CPATH.

Written by the indexing model from the issue text.

Assessment

Tech stack
cmake, cpp, python
Domain
build-system, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
65/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.