Compiling CPython on Cygwin

1 Preface

The Cygwin Project provides a Linux-alike layer of applications and capabilities to the Windows operating system. Cygwin comes with a gcc compiler, and many libraries can be compiled on it or are provided as precompiled Cygwin packages. However, the most recent Python Package is python-3.9, scipy is missing, and matplotlib is compiled against numpy-1.x, which has a different ABI than recent numpy-2.x, rendering the matplotlib package no longer usable. Because of these limitations, it is desirable to make more recent versions of Python, matplotlib, scipy etc. available, by compiling these pieces of software separately. CPython can, in principle, be compiled on Cygwin. However, there are some (serious) obstacles, which made me write this post and the previous ones (Clock IDs on Cygwin and Problem with _socket und pyexpat on Cygwin). The problem in the former one has been resolved, so this is a follow-up mainly to the second one. Because the title lines of those posts were rather narrow, I am starting here again under a more general topic title, with the intention to keep things centralised. Unfortunately I cannot give detailed logs for all the steps involved here due to the limitiation if a post to 64k characters. Certainly there are many singular smaller problems described, but this shall be a general description of all my efforts, with the hope that it might help to track down the issues.

2 A Patch for Python/dynload_shlib.c

In Python/dynload_shlib.c, there is a code section:

const char *_PyImport_DynLoadFiletab[] = {
#ifdef __CYGWIN__
    ".dll",
#else  /* !__CYGWIN__ */
    "." SOABI ".so",
#ifdef ALT_SOABI
    "." ALT_SOABI ".so",
#endif
    ".abi" PYTHON_ABI_STRING ".so",
    ".so",
#endif  /* __CYGWIN__ */
    NULL,
};

This section, more precisely, its third line, is responsible for the list of extension suffixes reported by:

>>> import importlib.machinery
>>> print(importlib.machinery.EXTENSION_SUFFIXES)
['.dll']

The actual extension module DLLs carry a name like math.cpython-311.dll, i.e., with an extension suffix of .cpython-311.dll. Thus, it looks like that here’s most possibly the culprit for the majority of the various errors I reported on earlier, making them comprehensible.

I therefore propose the following change to the code above:

const char *_PyImport_DynLoadFiletab[] = {
#ifdef __CYGWIN__
    "." SOABI ".dll",
#else  /* !__CYGWIN__ */
    "." SOABI ".so",
#ifdef ALT_SOABI
    "." ALT_SOABI ".so",
#endif
    ".abi" PYTHON_ABI_STRING ".so",
    ".so",
#endif  /* __CYGWIN__ */
    NULL,
};

With this change, I recompiled CPython 3.11, 3.12 and 3.13. Although things are still a bit off from perfect, they look at least considerably better now. I will provide the details on the three Python versions considered here in the next three sections.

3 Behaviour of CPython 3.13

For Python 3.13, I applied a patch to Modules/timemodule.c, according to the replies in Clock IDs on Cygwin, in addition to the change in Python/dynload_shlib.c described above.

3.1 Configuration and Compilation

Configuration and Compilation go just fine. All extension modules except _scproxy are selected for build by ./configure --prefix /usr/local --with-system-expat:

[...]
checking for stdlib extension module _multiprocessing... yes
checking for stdlib extension module _posixshmem... yes
checking for stdlib extension module fcntl... yes
checking for stdlib extension module mmap... yes
checking for stdlib extension module _socket... yes
checking for stdlib extension module grp... yes
checking for stdlib extension module pwd... yes
checking for stdlib extension module resource... yes
checking for stdlib extension module _scproxy... n/a
checking for stdlib extension module syslog... yes
checking for stdlib extension module termios... yes
checking for stdlib extension module pyexpat... yes
checking for stdlib extension module _elementtree... yes
checking for stdlib extension module _md5... yes
checking for stdlib extension module _sha1... yes
checking for stdlib extension module _sha2... yes
checking for stdlib extension module _sha3... yes
checking for stdlib extension module _blake2... yes
checking for stdlib extension module _ctypes... yes
checking for stdlib extension module _curses... yes
checking for stdlib extension module _curses_panel... yes
checking for stdlib extension module _decimal... yes
checking for stdlib extension module _dbm... yes
checking for stdlib extension module _gdbm... yes
checking for stdlib extension module readline... yes
checking for stdlib extension module _sqlite3... yes
checking for stdlib extension module _tkinter... yes
checking for stdlib extension module _uuid... yes
checking for stdlib extension module zlib... yes
checking for stdlib extension module _bz2... yes
checking for stdlib extension module _lzma... yes
checking for stdlib extension module _ssl... yes
checking for stdlib extension module _hashlib... yes
checking for stdlib extension module _testcapi... yes
checking for stdlib extension module _testclinic... yes
checking for stdlib extension module _testclinic_limited... yes
checking for stdlib extension module _testlimitedcapi... yes
checking for stdlib extension module _testinternalcapi... yes
checking for stdlib extension module _testbuffer... yes
checking for stdlib extension module _testimportmultiple... yes
checking for stdlib extension module _testmultiphase... yes
checking for stdlib extension module _testsinglephase... yes
checking for stdlib extension module _testexternalinspection... yes
checking for stdlib extension module xxsubtype... yes
checking for stdlib extension module _xxtestfuzz... yes
checking for stdlib extension module _ctypes_test... yes
checking for stdlib extension module xxlimited... yes
checking for stdlib extension module xxlimited_35... yes
[...]

and the result of the make step is:

Checked 112 modules (33 built-in, 78 shared, 1 n/a on cygwin-3.6.4-x86_64, 0 disabled, 0 missing, 0 failed on import)

3.2 Testing In-Tree

make test finishes, but a lot of tests are skipped, and a bunch of errors appear.

3.3 Installation

make install produces some errors as well:

[...]
PYTHONPATH=/usr/local/lib/python3.13  \
	./python.exe -E -Wi /usr/local/lib/python3.13/compileall.py \
	-o 0 -o 1 -o 2 -j0 -d /usr/local/lib/python3.13 -f \
	-x 'bad_coding|badsyntax|site-packages' \
	/usr/local/lib/python3.13
Listing '/usr/local/lib/python3.13'...
Listing '/usr/local/lib/python3.13/__phello__'...
Traceback (most recent call last):
Traceback (most recent call last):
  File "<string>", line 1, in <module>
    from multiprocessing.forkserver import main; main(15, 16, ['__main__'], **{'sys_path': ['/usr/local/lib/python3.13', '/usr/local/lib/python313.zip', '/home/Friedrich/N/Builds/2025/CPython/Python-3.13.7/Lib', '/home/Friedrich/N/Builds/2025/CPython/Python-3.13.7/build/lib.cygwin-3.6.4-x86_64-3.13', '/home/Friedrich/.local/lib/python3.13/site-packages', '/usr/local/lib/python3.13/site-packages']})
                                                 ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/Friedrich/N/Builds/2025/CPython/Python-3.13.7/Lib/multiprocessing/forkserver.py", line 265, in main
    fds = reduction.recvfds(s, MAXFDS_TO_SEND + 1)
  File "/home/Friedrich/N/Builds/2025/CPython/Python-3.13.7/Lib/multiprocessing/reduction.py", line 164, in recvfds
    raise RuntimeError('received %d items of ancdata' %
                       len(ancdata))
RuntimeError: received 0 items of ancdata
  File "/usr/local/lib/python3.13/compileall.py", line 469, in <module>
    exit_status = int(not main())
                          ~~~~^^
  File "/usr/local/lib/python3.13/compileall.py", line 446, in main
    if not compile_dir(dest, maxlevels, args.ddir,
           ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                       args.force, args.rx, args.quiet,
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ...<5 lines>...
                       limit_sl_dest=args.limit_sl_dest,
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                       hardlink_dupes=args.hardlink_dupes):
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/compileall.py", line 109, in compile_dir
    results = executor.map(partial(compile_file,
                                   ddir=ddir, force=force,
    ...<8 lines>...
                           files,
                           chunksize=4)
  File "/usr/local/lib/python3.13/concurrent/futures/process.py", line 837, in map
    results = super().map(partial(_process_chunk, fn),
                          itertools.batched(zip(*iterables), chunksize),
                          timeout=timeout)
  File "/usr/local/lib/python3.13/concurrent/futures/_base.py", line 608, in map
    fs = [self.submit(fn, *args) for args in zip(*iterables)]
          ~~~~~~~~~~~^^^^^^^^^^^
  File "/usr/local/lib/python3.13/concurrent/futures/process.py", line 808, in submit
    self._adjust_process_count()
    ~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/usr/local/lib/python3.13/concurrent/futures/process.py", line 767, in _adjust_process_count
    self._spawn_process()
    ~~~~~~~~~~~~~~~~~~~^^
  File "/usr/local/lib/python3.13/concurrent/futures/process.py", line 785, in _spawn_process
    p.start()
    ~~~~~~~^^
  File "/usr/local/lib/python3.13/multiprocessing/process.py", line 121, in start
    self._popen = self._Popen(self)
                  ~~~~~~~~~~~^^^^^^
  File "/usr/local/lib/python3.13/multiprocessing/context.py", line 301, in _Popen
    return Popen(process_obj)
  File "/usr/local/lib/python3.13/multiprocessing/popen_forkserver.py", line 35, in __init__
    super().__init__(process_obj)
    ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/multiprocessing/popen_fork.py", line 20, in __init__
    self._launch(process_obj)
    ~~~~~~~~~~~~^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/multiprocessing/popen_forkserver.py", line 57, in _launch
    with open(w, 'wb', closefd=True) as f:
         ~~~~^^^^^^^^^^^^^^^^^^^^^^^
BrokenPipeError: [Errno 32] Broken pipe
make: [Makefile:2659: libinstall] Error 1 (ignored)
PYTHONPATH=/usr/local/lib/python3.13  \
	./python.exe -E -Wi /usr/local/lib/python3.13/compileall.py \
	-o 0 -o 1 -o 2 -j0 -d /usr/local/lib/python3.13/site-packages -f \
	-x badsyntax /usr/local/lib/python3.13/site-packages
Listing '/usr/local/lib/python3.13/site-packages'...
Listing '/usr/local/lib/python3.13/site-packages/pip'...
Traceback (most recent call last):
Traceback (most recent call last):
  File "<string>", line 1, in <module>
    from multiprocessing.forkserver import main; main(15, 16, ['__main__'], **{'sys_path': ['/usr/local/lib/python3.13', '/usr/local/lib/python313.zip', '/home/Friedrich/N/Builds/2025/CPython/Python-3.13.7/Lib', '/home/Friedrich/N/Builds/2025/CPython/Python-3.13.7/build/lib.cygwin-3.6.4-x86_64-3.13', '/home/Friedrich/.local/lib/python3.13/site-packages', '/usr/local/lib/python3.13/site-packages']})
                                                 ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/Friedrich/N/Builds/2025/CPython/Python-3.13.7/Lib/multiprocessing/forkserver.py", line 265, in main
    fds = reduction.recvfds(s, MAXFDS_TO_SEND + 1)
  File "/home/Friedrich/N/Builds/2025/CPython/Python-3.13.7/Lib/multiprocessing/reduction.py", line 164, in recvfds
    raise RuntimeError('received %d items of ancdata' %
                       len(ancdata))
RuntimeError: received 0 items of ancdata
  File "/usr/local/lib/python3.13/compileall.py", line 469, in <module>
    exit_status = int(not main())
                          ~~~~^^
  File "/usr/local/lib/python3.13/compileall.py", line 446, in main
    if not compile_dir(dest, maxlevels, args.ddir,
           ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                       args.force, args.rx, args.quiet,
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ...<5 lines>...
                       limit_sl_dest=args.limit_sl_dest,
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                       hardlink_dupes=args.hardlink_dupes):
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/compileall.py", line 109, in compile_dir
    results = executor.map(partial(compile_file,
                                   ddir=ddir, force=force,
    ...<8 lines>...
                           files,
                           chunksize=4)
  File "/usr/local/lib/python3.13/concurrent/futures/process.py", line 837, in map
    results = super().map(partial(_process_chunk, fn),
                          itertools.batched(zip(*iterables), chunksize),
                          timeout=timeout)
  File "/usr/local/lib/python3.13/concurrent/futures/_base.py", line 608, in map
    fs = [self.submit(fn, *args) for args in zip(*iterables)]
          ~~~~~~~~~~~^^^^^^^^^^^
  File "/usr/local/lib/python3.13/concurrent/futures/process.py", line 808, in submit
    self._adjust_process_count()
    ~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/usr/local/lib/python3.13/concurrent/futures/process.py", line 767, in _adjust_process_count
    self._spawn_process()
    ~~~~~~~~~~~~~~~~~~~^^
  File "/usr/local/lib/python3.13/concurrent/futures/process.py", line 785, in _spawn_process
    p.start()
    ~~~~~~~^^
  File "/usr/local/lib/python3.13/multiprocessing/process.py", line 121, in start
    self._popen = self._Popen(self)
                  ~~~~~~~~~~~^^^^^^
  File "/usr/local/lib/python3.13/multiprocessing/context.py", line 301, in _Popen
    return Popen(process_obj)
  File "/usr/local/lib/python3.13/multiprocessing/popen_forkserver.py", line 35, in __init__
    super().__init__(process_obj)
    ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/multiprocessing/popen_fork.py", line 20, in __init__
    self._launch(process_obj)
    ~~~~~~~~~~~~^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/multiprocessing/popen_forkserver.py", line 57, in _launch
    with open(w, 'wb', closefd=True) as f:
         ~~~~^^^^^^^^^^^^^^^^^^^^^^^
BrokenPipeError: [Errno 32] Broken pipe
make: [Makefile:2660: libinstall] Error 1 (ignored)
[...]

Otherwise, the make install step looks good.

3.4 Testing After Installation

After installing, I revisited the test by issuing python3.13 -m test. I permitted in the Windows Firewall settings which popped up any kind of communication, and restarted python3.13 -m test. In both runs, the test hangs in test.test_ansyncio.test_events, until I cancel it by ^C, which produces no further output.

4 Behaviour of CPython 3.12

4.1 Configuration and Compilation

With the patch to Python/dynload_slib.c (presented in the beginning of this post), configuration and compilation go fine:

  1. LDFLAGS=-L$(pwd) ./configure --prefix /usr/local --with-system-expat
  2. Changing the payload of Modules/Setup.local by:
*disabled*
ossaudiodev
  1. make: All extension modules except spwd (“missing bits”) and ossaudiodev (as deactivated via Modules/Setup.local) are built.

I exempted ossaudiodev because it fails to compile. Without the -L$(pwd) addition to the LDFLAGS, in several places during linking the Python 3.12 library requested by -lpython3.12 cannot be found.

4.2 In-Tree Testing

make test fails. Its logs are skipped here for brevity.

4.3 Installation

Nevertheless the in-tree testing failed, I continued with make install, which yields errors similar to those referenced for 3.13 above:

PYTHONPATH=/usr/local/lib/python3.12  \
	./python.exe -E -Wi /usr/local/lib/python3.12/compileall.py \
	-o 0 -o 1 -o 2 -j0 -d /usr/local/lib/python3.12 -f \
	-x 'bad_coding|badsyntax|site-packages|test/test_lib2to3/data' \
	/usr/local/lib/python3.12
Listing '/usr/local/lib/python3.12'...
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/Friedrich/N/Builds/2025/CPython/Python-3.12.11/Lib/multiprocessing/forkserver.py", line 260, in main
Traceback (most recent call last):
  File "/usr/local/lib/python3.12/compileall.py", line 468, in <module>
    fds = reduction.recvfds(s, MAXFDS_TO_SEND + 1)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/Friedrich/N/Builds/2025/CPython/Python-3.12.11/Lib/multiprocessing/reduction.py", line 164, in recvfds
    exit_status = int(not main())
                          ^^^^^^
  File "/usr/local/lib/python3.12/compileall.py", line 445, in main
    raise RuntimeError('received %d items of ancdata' %
RuntimeError: received 0 items of ancdata
    if not compile_dir(dest, maxlevels, args.ddir,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/compileall.py", line 109, in compile_dir
    results = executor.map(partial(compile_file,
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/concurrent/futures/process.py", line 851, in map
    results = super().map(partial(_process_chunk, fn),
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/concurrent/futures/_base.py", line 608, in map
    fs = [self.submit(fn, *args) for args in zip(*iterables)]
          ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/concurrent/futures/process.py", line 822, in submit
    self._adjust_process_count()
  File "/usr/local/lib/python3.12/concurrent/futures/process.py", line 781, in _adjust_process_count
    self._spawn_process()
  File "/usr/local/lib/python3.12/concurrent/futures/process.py", line 799, in _spawn_process
    p.start()
  File "/usr/local/lib/python3.12/multiprocessing/process.py", line 121, in start
    self._popen = self._Popen(self)
                  ^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/multiprocessing/context.py", line 301, in _Popen
    return Popen(process_obj)
           ^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/multiprocessing/popen_forkserver.py", line 35, in __init__
    super().__init__(process_obj)
  File "/usr/local/lib/python3.12/multiprocessing/popen_fork.py", line 19, in __init__
    self._launch(process_obj)
  File "/usr/local/lib/python3.12/multiprocessing/popen_forkserver.py", line 57, in _launch
    with open(w, 'wb', closefd=True) as f:
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
BrokenPipeError: [Errno 32] Broken pipe
make: [Makefile:2432: libinstall] Error 1 (ignored)
PYTHONPATH=/usr/local/lib/python3.12  \
	./python.exe -E -Wi /usr/local/lib/python3.12/compileall.py \
	-o 0 -o 1 -o 2 -j0 -d /usr/local/lib/python3.12/site-packages -f \
	-x badsyntax /usr/local/lib/python3.12/site-packages
Listing '/usr/local/lib/python3.12/site-packages'...
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/Friedrich/N/Builds/2025/CPython/Python-3.12.11/Lib/multiprocessing/forkserver.py", line 260, in main
Traceback (most recent call last):
  File "/usr/local/lib/python3.12/compileall.py", line 468, in <module>
    fds = reduction.recvfds(s, MAXFDS_TO_SEND + 1)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/Friedrich/N/Builds/2025/CPython/Python-3.12.11/Lib/multiprocessing/reduction.py", line 164, in recvfds
    exit_status = int(not main())
                          ^^^^^^
  File "/usr/local/lib/python3.12/compileall.py", line 445, in main
    raise RuntimeError('received %d items of ancdata' %
RuntimeError: received 0 items of ancdata
    if not compile_dir(dest, maxlevels, args.ddir,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/compileall.py", line 109, in compile_dir
    results = executor.map(partial(compile_file,
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/concurrent/futures/process.py", line 851, in map
    results = super().map(partial(_process_chunk, fn),
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/concurrent/futures/_base.py", line 608, in map
    fs = [self.submit(fn, *args) for args in zip(*iterables)]
          ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/concurrent/futures/process.py", line 822, in submit
    self._adjust_process_count()
  File "/usr/local/lib/python3.12/concurrent/futures/process.py", line 781, in _adjust_process_count
    self._spawn_process()
  File "/usr/local/lib/python3.12/concurrent/futures/process.py", line 799, in _spawn_process
    p.start()
  File "/usr/local/lib/python3.12/multiprocessing/process.py", line 121, in start
    self._popen = self._Popen(self)
                  ^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/multiprocessing/context.py", line 301, in _Popen
    return Popen(process_obj)
           ^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/multiprocessing/popen_forkserver.py", line 35, in __init__
    super().__init__(process_obj)
  File "/usr/local/lib/python3.12/multiprocessing/popen_fork.py", line 19, in __init__
    self._launch(process_obj)
  File "/usr/local/lib/python3.12/multiprocessing/popen_forkserver.py", line 57, in _launch
    with open(w, 'wb', closefd=True) as f:
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
BrokenPipeError: [Errno 32] Broken pipe
make: [Makefile:2433: libinstall] Error 1 (ignored)

4.4 Testing After Installation

python3.12 -m test gets stuck at test.test_asyncio.test_events, until I interrupt it with ^C.

5 Behaviour of CPython 3.11

5.1 Configuration and Compilation

I applied the patch to Python/dynload_shlib.c here as well, ./configure --prefix /usr/local --with-system-expat runs smoothly, and make completes with:

The necessary bits to build these optional modules were not found:
spwd
To find the necessary bits, look in setup.py in detect_modules() for the module's name.


Failed to build these modules:
_ctypes               _xxsubinterpreters    ossaudiodev

The failures are provided in detail as the following subsections.

5.1.1 Make Failure for _xxsubinterpreters

building '_xxsubinterpreters' extension
gcc -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -std=c11 -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Werror=implicit-function-declaration -fvisibility=hidden -I./Include/internal -I./Include -I. -I/usr/local/include -I/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Include -I/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13 -c /home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_xxsubinterpretersmodule.c -o build/temp.cygwin-3.6.4-x86_64-3.11/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_xxsubinterpretersmodule.o
In file included from ./Include/Python.h:44,
                 from /home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_xxsubinterpretersmodule.c:8:
/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_xxsubinterpretersmodule.c:1768:27: error: initializer element is not constant
 1768 |     PyVarObject_HEAD_INIT(&PyType_Type, 0)
      |                           ^
./Include/object.h:81:8: note: in definition of macro ‘PyObject_HEAD_INIT’
   81 |     1, type },
      |        ^~~~
/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_xxsubinterpretersmodule.c:1768:5: note: in expansion of macro ‘PyVarObject_HEAD_INIT’
 1768 |     PyVarObject_HEAD_INIT(&PyType_Type, 0)
      |     ^~~~~~~~~~~~~~~~~~~~~
/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_xxsubinterpretersmodule.c:1768:27: note: (near initialization for ‘ChannelIDtype.ob_base.ob_base.ob_type’)
 1768 |     PyVarObject_HEAD_INIT(&PyType_Type, 0)
      |                           ^
./Include/object.h:81:8: note: in definition of macro ‘PyObject_HEAD_INIT’
   81 |     1, type },
      |        ^~~~
/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_xxsubinterpretersmodule.c:1768:5: note: in expansion of macro ‘PyVarObject_HEAD_INIT’
 1768 |     PyVarObject_HEAD_INIT(&PyType_Type, 0)
      |     ^~~~~~~~~~~~~~~~~~~~~

5.1.2 Make Failure for ossaudiodev

building 'ossaudiodev' extension
gcc -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -std=c11 -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Werror=implicit-function-declaration -fvisibility=hidden -I./Include/internal -I./Include -I. -I/usr/local/include -I/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Include -I/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13 -c /home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/ossaudiodev.c -o build/temp.cygwin-3.6.4-x86_64-3.11/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/ossaudiodev.o
In file included from ./Include/Python.h:44,
                 from /home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/ossaudiodev.c:26:
/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/ossaudiodev.c:967:27: error: initializer element is not constant
  967 |     PyVarObject_HEAD_INIT(&PyType_Type, 0)
      |                           ^
./Include/object.h:81:8: note: in definition of macro ‘PyObject_HEAD_INIT’
   81 |     1, type },
      |        ^~~~
/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/ossaudiodev.c:967:5: note: in expansion of macro ‘PyVarObject_HEAD_INIT’
  967 |     PyVarObject_HEAD_INIT(&PyType_Type, 0)
      |     ^~~~~~~~~~~~~~~~~~~~~
/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/ossaudiodev.c:967:27: note: (near initialization for ‘OSSAudioType.ob_base.ob_base.ob_type’)
  967 |     PyVarObject_HEAD_INIT(&PyType_Type, 0)
      |                           ^
./Include/object.h:81:8: note: in definition of macro ‘PyObject_HEAD_INIT’
   81 |     1, type },
      |        ^~~~
/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/ossaudiodev.c:967:5: note: in expansion of macro ‘PyVarObject_HEAD_INIT’
  967 |     PyVarObject_HEAD_INIT(&PyType_Type, 0)
      |     ^~~~~~~~~~~~~~~~~~~~~
/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/ossaudiodev.c:1001:27: error: initializer element is not constant
 1001 |     PyVarObject_HEAD_INIT(&PyType_Type, 0)
      |                           ^
./Include/object.h:81:8: note: in definition of macro ‘PyObject_HEAD_INIT’
   81 |     1, type },
      |        ^~~~
/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/ossaudiodev.c:1001:5: note: in expansion of macro ‘PyVarObject_HEAD_INIT’
 1001 |     PyVarObject_HEAD_INIT(&PyType_Type, 0)
      |     ^~~~~~~~~~~~~~~~~~~~~
/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/ossaudiodev.c:1001:27: note: (near initialization for ‘OSSMixerType.ob_base.ob_base.ob_type’)
 1001 |     PyVarObject_HEAD_INIT(&PyType_Type, 0)
      |                           ^
./Include/object.h:81:8: note: in definition of macro ‘PyObject_HEAD_INIT’
   81 |     1, type },
      |        ^~~~
/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/ossaudiodev.c:1001:5: note: in expansion of macro ‘PyVarObject_HEAD_INIT’
 1001 |     PyVarObject_HEAD_INIT(&PyType_Type, 0)
      |     ^~~~~~~~~~~~~~~~~~~~~

5.1.3 Make Failure for _ctypes

building '_ctypes' extension
gcc -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -std=c11 -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Werror=implicit-function-declaration -fvisibility=hidden -I./Include/internal -I./Include -I. -I/usr/local/include -I/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Include -I/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13 -c /home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/_ctypes.c -o build/temp.cygwin-3.6.4-x86_64-3.11/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/_ctypes.o
gcc -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -std=c11 -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Werror=implicit-function-declaration -fvisibility=hidden -I./Include/internal -I./Include -I. -I/usr/local/include -I/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Include -I/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13 -c /home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/callbacks.c -o build/temp.cygwin-3.6.4-x86_64-3.11/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/callbacks.o
gcc -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -std=c11 -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Werror=implicit-function-declaration -fvisibility=hidden -I./Include/internal -I./Include -I. -I/usr/local/include -I/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Include -I/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13 -c /home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/callproc.c -o build/temp.cygwin-3.6.4-x86_64-3.11/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/callproc.o
gcc -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -std=c11 -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Werror=implicit-function-declaration -fvisibility=hidden -I./Include/internal -I./Include -I. -I/usr/local/include -I/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Include -I/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13 -c /home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/cfield.c -o build/temp.cygwin-3.6.4-x86_64-3.11/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/cfield.o
gcc -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -std=c11 -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Werror=implicit-function-declaration -fvisibility=hidden -I./Include/internal -I./Include -I. -I/usr/local/include -I/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Include -I/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13 -c /home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/stgdict.c -o build/temp.cygwin-3.6.4-x86_64-3.11/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/stgdict.o
gcc -shared -Wl,--enable-auto-image-base build/temp.cygwin-3.6.4-x86_64-3.11/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/_ctypes.o build/temp.cygwin-3.6.4-x86_64-3.11/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/callbacks.o build/temp.cygwin-3.6.4-x86_64-3.11/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/callproc.o build/temp.cygwin-3.6.4-x86_64-3.11/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/cfield.o build/temp.cygwin-3.6.4-x86_64-3.11/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/stgdict.o -L. -L/usr/local/lib -L. -ldl -lpython3.11 -o build/lib.cygwin-3.6.4-x86_64-3.11/_ctypes.cpython-311.dll
/usr/lib/gcc/x86_64-pc-cygwin/13/../../../../x86_64-pc-cygwin/bin/ld: build/temp.cygwin-3.6.4-x86_64-3.11/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/_ctypes.o:_ctypes.c:(.rdata$.refptr.ffi_type_pointer[.refptr.ffi_type_pointer]+0x0): undefined reference to `ffi_type_pointer'
/usr/lib/gcc/x86_64-pc-cygwin/13/../../../../x86_64-pc-cygwin/bin/ld: build/temp.cygwin-3.6.4-x86_64-3.11/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/callbacks.o: in function `CThunkObject_dealloc':
/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/callbacks.c:39:(.text+0xc4): undefined reference to `ffi_closure_free'
/usr/lib/gcc/x86_64-pc-cygwin/13/../../../../x86_64-pc-cygwin/bin/ld: build/temp.cygwin-3.6.4-x86_64-3.11/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/callbacks.o: in function `_ctypes_alloc_callback':
/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/callbacks.c:363:(.text+0x735): undefined reference to `ffi_closure_alloc'
/usr/lib/gcc/x86_64-pc-cygwin/13/../../../../x86_64-pc-cygwin/bin/ld: /home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/callbacks.c:398:(.text+0x7e8): undefined reference to `ffi_prep_cif'
/usr/lib/gcc/x86_64-pc-cygwin/13/../../../../x86_64-pc-cygwin/bin/ld: /home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/callbacks.c:438:(.text+0x802): undefined reference to `ffi_prep_closure'
/usr/lib/gcc/x86_64-pc-cygwin/13/../../../../x86_64-pc-cygwin/bin/ld: build/temp.cygwin-3.6.4-x86_64-3.11/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/callbacks.o:callbacks.c:(.rdata$.refptr.ffi_type_void[.refptr.ffi_type_void]+0x0): undefined reference to `ffi_type_void'
/usr/lib/gcc/x86_64-pc-cygwin/13/../../../../x86_64-pc-cygwin/bin/ld: build/temp.cygwin-3.6.4-x86_64-3.11/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/callproc.o: in function `_call_function_pointer':
/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/callproc.c:890:(.text+0x180f): undefined reference to `ffi_prep_cif'
/usr/lib/gcc/x86_64-pc-cygwin/13/../../../../x86_64-pc-cygwin/bin/ld: /home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/callproc.c:923:(.text+0x1841): undefined reference to `ffi_call'
/usr/lib/gcc/x86_64-pc-cygwin/13/../../../../x86_64-pc-cygwin/bin/ld: /home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/callproc.c:923:(.text+0x19a7): undefined reference to `ffi_call'
/usr/lib/gcc/x86_64-pc-cygwin/13/../../../../x86_64-pc-cygwin/bin/ld: /home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/callproc.c:923:(.text+0x1a8e): undefined reference to `ffi_call'
/usr/lib/gcc/x86_64-pc-cygwin/13/../../../../x86_64-pc-cygwin/bin/ld: build/temp.cygwin-3.6.4-x86_64-3.11/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/callproc.o:callproc.c:(.rdata$.refptr.ffi_type_sint32[.refptr.ffi_type_sint32]+0x0): undefined reference to `ffi_type_sint32'
/usr/lib/gcc/x86_64-pc-cygwin/13/../../../../x86_64-pc-cygwin/bin/ld: build/temp.cygwin-3.6.4-x86_64-3.11/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/cfield.o:cfield.c:(.rdata$.refptr.ffi_type_uint32[.refptr.ffi_type_uint32]+0x0): undefined reference to `ffi_type_uint32'
/usr/lib/gcc/x86_64-pc-cygwin/13/../../../../x86_64-pc-cygwin/bin/ld: build/temp.cygwin-3.6.4-x86_64-3.11/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/cfield.o:cfield.c:(.rdata$.refptr.ffi_type_uint16[.refptr.ffi_type_uint16]+0x0): undefined reference to `ffi_type_uint16'
/usr/lib/gcc/x86_64-pc-cygwin/13/../../../../x86_64-pc-cygwin/bin/ld: build/temp.cygwin-3.6.4-x86_64-3.11/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/cfield.o:cfield.c:(.rdata$.refptr.ffi_type_sint16[.refptr.ffi_type_sint16]+0x0): undefined reference to `ffi_type_sint16'
/usr/lib/gcc/x86_64-pc-cygwin/13/../../../../x86_64-pc-cygwin/bin/ld: build/temp.cygwin-3.6.4-x86_64-3.11/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/cfield.o:cfield.c:(.rdata$.refptr.ffi_type_float[.refptr.ffi_type_float]+0x0): undefined reference to `ffi_type_float'
/usr/lib/gcc/x86_64-pc-cygwin/13/../../../../x86_64-pc-cygwin/bin/ld: build/temp.cygwin-3.6.4-x86_64-3.11/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/cfield.o:cfield.c:(.rdata$.refptr.ffi_type_longdouble[.refptr.ffi_type_longdouble]+0x0): undefined reference to `ffi_type_longdouble'
/usr/lib/gcc/x86_64-pc-cygwin/13/../../../../x86_64-pc-cygwin/bin/ld: build/temp.cygwin-3.6.4-x86_64-3.11/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/cfield.o:cfield.c:(.rdata$.refptr.ffi_type_double[.refptr.ffi_type_double]+0x0): undefined reference to `ffi_type_double'
/usr/lib/gcc/x86_64-pc-cygwin/13/../../../../x86_64-pc-cygwin/bin/ld: build/temp.cygwin-3.6.4-x86_64-3.11/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/cfield.o:cfield.c:(.rdata$.refptr.ffi_type_sint8[.refptr.ffi_type_sint8]+0x0): undefined reference to `ffi_type_sint8'
/usr/lib/gcc/x86_64-pc-cygwin/13/../../../../x86_64-pc-cygwin/bin/ld: build/temp.cygwin-3.6.4-x86_64-3.11/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/cfield.o:cfield.c:(.rdata$.refptr.ffi_type_uint8[.refptr.ffi_type_uint8]+0x0): undefined reference to `ffi_type_uint8'
/usr/lib/gcc/x86_64-pc-cygwin/13/../../../../x86_64-pc-cygwin/bin/ld: build/temp.cygwin-3.6.4-x86_64-3.11/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/cfield.o:cfield.c:(.rdata$.refptr.ffi_type_sint64[.refptr.ffi_type_sint64]+0x0): undefined reference to `ffi_type_sint64'
/usr/lib/gcc/x86_64-pc-cygwin/13/../../../../x86_64-pc-cygwin/bin/ld: build/temp.cygwin-3.6.4-x86_64-3.11/home/Friedrich/N/Builds/2025/CPython/Python-3.11.13/Modules/_ctypes/cfield.o:cfield.c:(.rdata$.refptr.ffi_type_uint64[.refptr.ffi_type_uint64]+0x0): undefined reference to `ffi_type_uint64'
collect2: error: ld returned 1 exit status

I found in my Cygwin the following libffi-related Cygwin packages already installed:

  1. libffi6-3.2.1-2
  2. libffi8-3.4.7-1
  3. libffi-devel-3.4.7-1

libffi6 is a requirement for many other Cygwin bits, so I cannot remove it.

It might be possible to add -lcygffi-8 to the LDFLAGS (proposition by ChatGPT), but I didn’t try that yet (cygffi-8 is the actual name of the library’s .dll file).

5.2 In-Tree Testing

make test produces a lot of errors. What I recognised are linkage errors to a missing python3.13 library -lpython3.13, which might be overcome by using LDFLAGS=-L$(pwd).

5.3 Installation

make install completed. It tries several times to compile the failing extension modules, but apart from this, I didn’t spot any errors.

5.4 Testing After Installation

python3.11 -m test -v hangs in the middle of test test.test_asyncio.test_events.

6 Final Remarks

Per default Cygwin implements POSIX permissions by mapping them to some kind of Windows NT ACLs. I am using Cygwin without this feature. All file permissions are in this case almost in their entirety defined by the filename and the presence of a shebang line (see File permissions). This is relevant as it explains some failures related to file permissions being checked (the respective log transcript were trimmed).

The actual course of work which led to this report started at Python 3.11 and stepped on upwards to 3.13, in the opposite direction as chosen for presentation in this report. This work started after the change proposed in the beginning of this post has been discovered. I iterated previously backwards from 3.13 down to 3.11 to finally make this discovery; the corresponding preliminary results have been skipped here entirely.

When I did the build attempts described here, Python 3.13.8 was not yet available, and the same applies to Python 3.14. I might report on these versions separately. From the similarity of the problems reported here for Python 3.11 to 3.13.7, it can be expected, that the version increment from 3.13.7 to 3.13.8 and the introduction of 3.14 do not introduce a completely different behaviour.

Finally, it looks like if Python 3.13 is from the gamut of versions tested here the most Cygwin-compatible one. It can build almost all stdlib modules. 3.13 and 3.12 however seem to introduce some errors appearing in the make install step, which are not present with 3.11.

There are some repeated patterns, like for instance:

RuntimeError: received 0 items of ancdata

or

BrokenPipeError: [Errno 32] Broken pipe

and there seem to be some more common problems during testing. Thus, there is hope that many of the errors which are just reported here in summary can be deduced to a few fundamental, common causes.

1 Like