hashdist / hashstack

Collection of software profiles for HashDist
https://hashdist.github.io/
51 stars 60 forks source link

curses module does not work #451

Open certik opened 10 years ago

certik commented 10 years ago
>>> import curses
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/certik/repos/hashstack/default/lib/python2.7/curses/__init__.py", line 15, in <module>
    from _curses import *
ImportError: No module named _curses
certik commented 10 years ago

The fix is along these lines:

diff --git a/pkgs/python/python.yaml b/pkgs/python/python.yaml
index 68252f2..a84260a 100644
--- a/pkgs/python/python.yaml
+++ b/pkgs/python/python.yaml
@@ -15,7 +15,7 @@ build_stages:
   - when: link == 'shared'
     name: configure
     mode: override
-    append: {LDFLAGS: "-Wl,-rpath=${ARTIFACT}/lib"}
+    append: {LDFLAGS: "-Wl,-rpath=${ARTIFACT}/lib", CPPFLAGS: "-I${NCURSES_DIR}/include/ncurses"}
     extra: ['--enable-shared']

 # Make sure extension modules were built correctly. This should be part of the
@@ -58,6 +58,11 @@ build_stages:
       $ARTIFACT/bin/python -c "import _sqlite3"
       echo "    ok"

+      # Test curses
+      echo "import _curses"
+      $ARTIFACT/bin/python -c "import _curses"
+      echo "    ok"
+

 when_build_dependency:
   - set: PYTHON

But it still doesn't even attempt to build _curses. Looking into setup.py in Python, these lines seem relevant:

        # readline
        do_readline = self.compiler.find_library_file(lib_dirs, 'readline')
        readline_termcap_library = ""
        curses_library = ""
        # Determine if readline is already linked against curses or tinfo.
        if do_readline and find_executable('ldd'):
            fp = os.popen("ldd %s" % do_readline)
            ldd_output = fp.readlines()
            ret = fp.close()
            if ret is None or ret >> 8 == 0:
                for ln in ldd_output:
                    if 'curses' in ln:
                        readline_termcap_library = re.sub(
                            r'.*lib(n?cursesw?)\.so.*', r'\1', ln
                        ).rstrip()
                        break
                    if 'tinfo' in ln: # termcap interface split out from ncurses
                        readline_termcap_library = 'tinfo'
                        break
        # Issue 7384: If readline is already linked against curses,
        # use the same library for the readline and curses modules.
        if 'curses' in readline_termcap_library:
            curses_library = readline_termcap_library
        elif self.compiler.find_library_file(lib_dirs, 'ncursesw'):
            curses_library = 'ncursesw'
        elif self.compiler.find_library_file(lib_dirs, 'ncurses'):
            curses_library = 'ncurses'
        elif self.compiler.find_library_file(lib_dirs, 'curses'):
            curses_library = 'curses'

and also

        # Curses support, requiring the System V version of curses, often
        # provided by the ncurses library.
        panel_library = 'panel'
        if curses_library.startswith('ncurses'):
            if curses_library == 'ncursesw':
                # Bug 1464056: If _curses.so links with ncursesw,
                # _curses_panel.so must link with panelw.
                panel_library = 'panelw'
            curses_libs = [curses_library]
            exts.append( Extension('_curses', ['_cursesmodule.c'],
                                   libraries = curses_libs) )
        elif curses_library == 'curses' and host_platform != 'darwin':
                # OSX has an old Berkeley curses, not good enough for
                # the _curses module.
            if (self.compiler.find_library_file(lib_dirs, 'terminfo')):
                curses_libs = ['curses', 'terminfo']
            elif (self.compiler.find_library_file(lib_dirs, 'termcap')):
                curses_libs = ['curses', 'termcap']
            else:
                curses_libs = ['curses']

            exts.append( Extension('_curses', ['_cursesmodule.c'],
                                   libraries = curses_libs) )
        else:
            missing.append('_curses')

But I didn't quite figure out why it can't find it. The configure script seems to be finding it:

2014/09/16 15:15:48 - INFO: [package:run_job] checking curses.h usability... yes
2014/09/16 15:15:48 - INFO: [package:run_job] checking curses.h presence... yes
2014/09/16 15:15:48 - INFO: [package:run_job] checking for curses.h... yes
...
2014/09/16 15:15:48 - INFO: [package:run_job] checking ncurses.h usability... yes
2014/09/16 15:15:48 - INFO: [package:run_job] checking ncurses.h presence... yes
2014/09/16 15:15:49 - INFO: [package:run_job] checking for ncurses.h... yes
certik commented 10 years ago

Ok, if I patch the setup.py, then it works. PR on the way.

vbraun commented 10 years ago

Hashstack doesn't build a wide curses, right? (configure --enable-widec). Afair Python needs a wide curses, readline needs a non-wide curses. In Sage we compile curses twice, narrow and wide.

certik commented 10 years ago

Hashstack doesn't build wide curses. How can I test if the current narrow ncurses works with Python? It compiles just fine.