21
loading...
This website collects cookies to deliver better user experience
CC="$(brew --prefix gcc)/bin/gcc-11" \
pyenv install --verbose 3.10.0
pip install
packages with C extension modules. They complained about _ctypes
being missing. And trying to import ctypes
from the Python REPL confirmed the issue:Python 3.10.0 (default, Dec 31 2021, 16:09:32) [GCC 10.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import ctypes
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/tmp/python-build.20211231145343.269699/Python-3.10.0/Lib/ctypes/__init__.py", line 8, in <module>
from _ctypes import Union, Structure, Array
ModuleNotFoundError: No module named '_ctypes'
pyenv install
command, I found this error:*** WARNING: renaming "_ctypes" since importing it failed: libffi.so.8: cannot open shared object file: No such file or directory
pyenv install
use my system gcc?". So I tried:CC="$(brew --prefix gcc)/bin/gcc-11" \
CFLAGS="$(pkg-config --cflags libffi)" \
LDFLAGS="$(pkg-config --libs libffi)" \
pyenv install --verbose 3.10.0
CC
effectively fixed my Python build, the CFLAGS
and LDFLAGS
bits might be unnecessary. So I tried without them:CC="$(brew --prefix gcc)/bin/gcc-11" \
pyenv install --verbose 3.10.0
python-build --keep --verbose 3.10.0 ./py310
CC="$(brew --prefix gcc)/bin/gcc-11" \
python-build --keep --verbose 3.10.0 ./py310-2
make
and see the ctypes warning. I could also see the object file renamed to ..._failed.so
:❯ fd "ctypes.*so"
build/lib.linux-x86_64-3.10/_ctypes.cpython-310-x86_64-linux-gnu_failed.so
build/lib.linux-x86_64-3.10/_ctypes_test.cpython-310-x86_64-linux-gnu.so
❯ fd "ctypes.*so"
build/lib.linux-x86_64-3.10/_ctypes.cpython-310-x86_64-linux-gnu.so
build/lib.linux-x86_64-3.10/_ctypes_test.cpython-310-x86_64-linux-gnu.so
libffi
, and ldd
helped highlight and reproduce that. From my broken build, I see "not found":> ldd build/lib.linux-x86_64-3.10/_ctypes.cpython-310-x86_64-linux-gnu_failed.so
linux-vdso.so.1 (0x00007ffd97fbf000)
libffi.so.8 => not found
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f478258f000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f478256c000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f478237a000)
/lib64/ld-linux-x86-64.so.2 (0x00007f47825d8000)
> ldd build/lib.linux-x86_64-3.10/_ctypes.cpython-310-x86_64-linux-gnu.so
linux-vdso.so.1 (0x00007ffcd35fb000)
libffi.so.8 => /home/linuxbrew/.linuxbrew/lib/libffi.so.8 (0x00007f306da2d000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f306da08000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f306d9e5000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f306d7f3000)
/lib64/ld-linux-x86-64.so.2 (0x00007f306dc5f000)
_ctypes.cpython-310-x86_64-linux-gnu.so
. It looked something like this (noise alert):gcc -pthread -fPIC -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -I/home/linuxbrew/.linuxbrew/opt/zlib -I/home/linuxbrew/.linuxbrew/opt/zlib -std=c99 -Wextra -Wno-unused-result -Wno-unused-parameter -Wno-missing-field-initializers -Werror=implicit-function-declaration -fvisibility=hidden -I./Include/internal -I/home/linuxbrew/.linuxbrew/Cellar/libffi/3.4.2/include -I./Include -I. -I/home/linuxbrew/.linuxbrew/opt/readline/include -I/home/aj/code/scratch/pyenv-builds/./py310/include -I/home/linuxbrew/.linuxbrew/include -I/usr/include/x86_64-linux-gnu -I/usr/local/include -I/tmp/python-build.20211231172024.425603/Python-3.10.0/Include -I/tmp/python-build.20211231172024.425603/Python-3.10.0 -c /tmp/python-build.20211231172024.425603/Python-3.10.0/Modules/_ctypes/stgdict.c -o build/temp.linux-x86_64-3.10/tmp/python-build.20211231172024.425603/Python-3.10.0/Modules/_ctypes/stgdict.o -DPy_BUILD_CORE_MODULE -DHAVE_FFI_PREP_CIF_VAR=1 -DHAVE_FFI_PREP_CLOSURE_LOC=1 -DHAVE_FFI_CLOSURE_ALLOC=1
gcc -pthread -shared -L/home/linuxbrew/.linuxbrew/opt/readline/lib -L/home/aj/code/scratch/pyenv-builds/./py310/lib -L/home/linuxbrew/.linuxbrew/lib build/temp.linux-x86_64-3.10/tmp/python-build.20211231172024.425603/Python-3.10.0/Modules/_ctypes/_ctypes.o build/temp.linux-x86_64-3.10/tmp/python-build.20211231172024.425603/Python-3.10.0/Modules/_ctypes/callbacks.o build/temp.linux-x86_64-3.10/tmp/python-build.20211231172024.425603/Python-3.10.0/Modules/_ctypes/callproc.o build/temp.linux-x86_64-3.10/tmp/python-build.20211231172024.425603/Python-3.10.0/Modules/_ctypes/cfield.o build/temp.linux-x86_64-3.10/tmp/python-build.20211231172024.425603/Python-3.10.0/Modules/_ctypes/stgdict.o -L/home/linuxbrew/.linuxbrew/opt/readline/lib -L/home/aj/code/scratch/pyenv-builds/./py310/lib -L/home/linuxbrew/.linuxbrew/lib -L/usr/lib/x86_64-linux-gnu -L/usr/local/lib -lffi -ldl -o build/lib.linux-x86_64-3.10/_ctypes.cpython-310-x86_64-linux-gnu.so
_ctypes.cpython-310-x86_64-linux-gnu.so
by varying only the gcc version, I ran both versions of gcc with the --verbose
option to look for more clues. And I found my answer in the form of gcc specs. The verbose logs from my system gcc included this bit:Using built-in specs.
Reading specs from /home/linuxbrew/.linuxbrew/Cellar/gcc/11.2.0_3/lib/gcc/11/gcc/x86_64-pc-linux-gnu/11/specs
/home/linuxbrew/.linuxbrew/Cellar/gcc/11.2.0_3/lib/gcc/11/gcc/x86_64-pc-linux-gnu/11/specs
revealed some custom options:*cpp_unique_options:
+ -isysroot /home/linuxbrew/.linuxbrew/nonexistent -idirafter /home/linuxbrew/.linuxbrew/include -idirafter /usr/include/x86_64-linux-gnu -idirafter /usr/include
*link_libgcc:
+ -L/home/linuxbrew/.linuxbrew/lib/gcc/11 -L/home/linuxbrew/.linuxbrew/lib
*link:
+ --dynamic-linker /home/linuxbrew/.linuxbrew/lib/ld.so -rpath /home/linuxbrew/.linuxbrew/lib/gcc/11
*homebrew_rpath:
-rpath /home/linuxbrew/.linuxbrew/lib
pyenv install
, I'm letting pyenv operate in the world it knows. The world where it was born.