Issue 27900: ctypes fails to find ncurses via ncursesw on Arch Linux (original) (raw)
The following code fails on Arch Linux:
import ctypes.util
print(ctypes.util.find_library("ncurses"))
It first looks at "ldconfig -p" (via _findSoname_ldconfig), which only contains:
libncursesw.so.6 (libc6,x86-64) => /usr/lib/libncursesw.so.6
libncursesw.so.6 (libc6) => /usr/lib32/libncursesw.so.6
libncursesw.so (libc6,x86-64) => /usr/lib/libncursesw.so
libncursesw.so (libc6) => /usr/lib32/libncursesw.so
libncurses++w.so.6 (libc6,x86-64) => /usr/lib/libncurses++w.so.6
libncurses++w.so (libc6,x86-64) => /usr/lib/libncurses++w.so
/usr/lib/libncurses.so exists, but as a text file:
INPUT(-lncursesw)
Then "_findLib_gcc" is called, which tries to link a file, and then looks at its output:
% if type gcc >/dev/null 2>&1; then CC=gcc; elif type cc >/dev/null 2>&1; then CC=cc;else exit 10; fi;LANG=C LC_ALL=C $CC -Wl,-t -o /tmp/tmp1ysftojh 2>&1 -lncurses
/usr/bin/ld: mode elf_x86_64
/usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/../../../../lib/crt1.o
/usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/../../../../lib/crti.o
/usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/crtbegin.o
-lncursesw (/usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/../../../../lib/libncursesw.so)
libgcc_s.so.1 (/usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/../../../../lib/libgcc_s.so.1)
/usr/lib/libc.so.6
(/usr/lib/libc_nonshared.a)elf-init.oS
/usr/lib/ld-linux-x86-64.so.2
/usr/lib/ld-linux-x86-64.so.2
libgcc_s.so.1 (/usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/../../../../lib/libgcc_s.so.1)
/usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/crtend.o
/usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/../../../../lib/crtn.o
/usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/../../../../lib/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
/usr/bin/ld: link errors found, deleting executable `/tmp/tmp1ysftojh'
collect2: error: ld returned 1 exit status
I don't know if "ldconfig" could be made to display the "text symlink", but with the "cc"-method, it could look for an explicit "cannot find" error instead?!
% if type gcc >/dev/null 2>&1; then CC=gcc; elif type cc >/dev/null 2>&1; then CC=cc;else exit 10; fi;LANG=C LC_ALL=C $CC -Wl,-t -o /tmp/tmp1ysftojh 2>&1 -lncursesxx
/usr/bin/ld: mode elf_x86_64
/usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/../../../../lib/crt1.o
/usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/../../../../lib/crti.o
/usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/crtbegin.o
libgcc_s.so.1 (/usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/../../../../lib/libgcc_s.so.1)
/usr/bin/ld: cannot find -lncursesxx
collect2: error: ld returned 1 exit status
The workaround is to also look for "ncursesw" explicitly.
I have noticed this with pyrepl, which uses it in https://bitbucket.org/pypy/pyrepl/src/9401662c4e6c11a4d66804361a7e7d09a1f379d7/pyrepl/_minimal_curses.py?at=default&fileviewer=file-view-default#_minimal_curses.py-19:26.