This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

FYI: WIP patch to build GDB with Python on MinGW


Hello,

Just in case someone else would like to build their GDB with Python
support enable on MinGW. This is Work In Progress, and is only shared
here in the hopes that it might be useful.

This is also to share some of the obstacles I've faced, and the way
I have solved them, for now.

  1. The python install has a completely different layout on Windows,
     compared to Unix platforms.
       a. python.exe is in the root directory
       b. the python library in the <root>/Lib directory
          and is named libpython27.a (not '.' in the version number,
          unlike on Unix where it's libpython2.7.a).  Note that despite
          the .a filename extension, it's NOT an archive (it sorta points
          to the DLL, so at the end GDB is linked against the DLL which
          is in the <root> directory).
       c. python includes are in <root>/include

  2. python-config.py is broken on Windows.
     The immediate issue is that some sysconfig variables are missing,
     and I think that this is because Python was not built using
     the standard configure/make procedure

Resolutions:

  1a: Easy - if python is not in <root>/bin, then try <root>.

  1b: Not an issue once we've dealt with 2.

  1c: We cannot continue including the Python files using
      #include "python-2.7/Python.h" anymore, since the `python-2.7'
      subdirectory does not exist in the Windows install.
      We were using a non-standard approach thanks to some configury
      that edited the python include path used when compiling.
      So I removed that piece of configury and changed all the includes.

      This opens the door for unexpected conflicts, given the filenames
      chosen by the Python implementation.  And sure enough, had a
      "cute" issue: GDB has gdb/python/python.h, and Python has
      <root>/include/Python.h.  The Windows filesystem being case
      insensitve, GCC started picking up gdb/python/python.h when
      we meant to include Python.h.

      I fixed that by renaming python.h into gdb-python.h.

  2. For now, I wrote my own python-wconfig.py program, which works
     for windows and by-passes the unix one.  I don't know whether this
     is the best decision in the long term, or not, but it allowed me
     to side-step issues such as backslashes, paths with drive letters
     in them, etc, when mixing a cygwin environment to do the build,
     with a MinGW compiler.  I will see how ugly the the hacking on
     python-config.py turns out to be.

Problems still not fixed:

  . The HAVE_LIBPYTHON2_x macros are currently not set, because of
    the fact that libpython2.7.a is missing a dot in the version number.
    Easily fixable, just ugly.

  . This was suggested by Doug:
    Change the compilation arguments such that the python include path
    is last.  In case of conflict, the compiler should pick the non-python
    file.

With this patch applied, I was able to build GDB with Python, and
obtain something that seems to work:

        (gdb) python import time
        (gdb) python print time.clock()
        1.50167540471e-06
        (gdb) 

The one caveat is that it seems that Python does not like being
installed in a non-standard location.  Even if I did not move it
after GDB was build, GDB aborts early during the call to Py_initialize
after having printed the following message:

        $ ./gdb/gdb
        ImportError: No module named site

The ImportError happens much before the GDB code is called, I'm assuming
during Python DLL mapping, since the following program reproduces the same
issue.

        #include "Python.h"
        #include "stdio.h"
        
        int
        main (void)
        {
          printf ("Initializing Python...\n");
          Py_SetProgramName ("[...]/python.exe");
          Py_Initialize ();
          printf ("+++ done.\n");
          return 0;
        }

So I had to start GDB with the following command:

        PYTHONPATH=/[...]/python/Lib ./gdb/gdb
-- 
Joel
diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
index b183e06..8f19ffe 100644
--- a/gdb/cli/cli-cmds.c
+++ b/gdb/cli/cli-cmds.c
@@ -48,7 +48,7 @@
 #include "cli/cli-setshow.h"
 #include "cli/cli-cmds.h"
 
-#include "python/python.h"
+#include "python/gdb-python.h"
 
 #ifdef TUI
 #include "tui/tui.h"	/* For tui_active et.al.  */
diff --git a/gdb/cli/cli-script.c b/gdb/cli/cli-script.c
index 5903015..2cec354 100644
--- a/gdb/cli/cli-script.c
+++ b/gdb/cli/cli-script.c
@@ -34,7 +34,7 @@
 #include "cli/cli-script.h"
 #include "gdb_assert.h"
 
-#include "python/python.h"
+#include "python/gdb-python.h"
 
 /* Prototypes for local functions.  */
 
diff --git a/gdb/configure b/gdb/configure
index a4bda14..268f448 100755
--- a/gdb/configure
+++ b/gdb/configure
@@ -10538,6 +10538,13 @@ else
       # Assume the python binary is ${with_python}/bin/python.
       python_prog="${with_python}/bin/python"
       python_prefix=
+      # If python does not exit ${with_python}/bin, then try in
+      # ${with_python}.  On Windows/MinGW, this is where the Python
+      # executable is.
+      if test ! -x "${python_prog}"; then
+        python_prog="${with_python}/python"
+        python_prefix=
+      fi
       if test ! -x "${python_prog}"; then
         # Fall back to gdb 7.0/7.1 behaviour.
         python_prog=missing
@@ -10670,24 +10677,34 @@ fi
   esac
 
   if test "${python_prog}" != missing; then
+    # FIXME: Add comment.
+    case "$host_os" in
+      mingw*)
+        python_config_prog="python-wconfig.py"
+        sed "s,@PREFIX@,`dirname $python_prog`," \
+          ${srcdir}/python/python-wconfig.in > $python_config_prog
+        ;;
+      *) python_config_prog="${srcdir}/python/python-config.py";;
+    esac
+
     # We have a python program to use, but it may be too old.
     # Don't flag an error for --with-python=auto (the default).
     have_python_config=yes
-    python_includes=`${python_prog} ${srcdir}/python/python-config.py --includes`
+    python_includes=`${python_prog} ${python_config_prog} --includes`
     if test $? != 0; then
       have_python_config=failed
       if test "${with_python}" != auto; then
         as_fn_error "failure running python-config --includes" "$LINENO" 5
       fi
     fi
-    python_libs=`${python_prog} ${srcdir}/python/python-config.py --ldflags`
+    python_libs=`${python_prog} ${python_config_prog} --ldflags`
     if test $? != 0; then
       have_python_config=failed
       if test "${with_python}" != auto; then
         as_fn_error "failure running python-config --ldflags" "$LINENO" 5
       fi
     fi
-    python_prefix=`${python_prog} ${srcdir}/python/python-config.py --exec-prefix`
+    python_prefix=`${python_prog} ${python_config_prog} --exec-prefix`
     if test $? != 0; then
       have_python_config=failed
       if test "${with_python}" != auto; then
@@ -10722,7 +10739,7 @@ fi
   have_libpython=no
   if test "${have_python_config}" = yes; then
     python_version=`echo " ${python_libs} " \
-                         | sed -e 's,^.* -l\(python[0-9]*[.][0-9]*\) .*$,\1,'`
+                         | sed -e 's,^.* -l\(python[0-9]*[.]\?[0-9]*\).*$,\1,'`
     case "${python_version}" in
     python*)
 
@@ -10739,7 +10756,7 @@ $as_echo_n "checking for ${version}... " >&6; }
   found_usable_python=no
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#include "${version}/Python.h"
+#include "Python.h"
 int
 main ()
 {
@@ -10781,7 +10798,7 @@ $as_echo_n "checking for ${version}... " >&6; }
   found_usable_python=no
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#include "${version}/Python.h"
+#include "Python.h"
 int
 main ()
 {
@@ -10818,7 +10835,7 @@ $as_echo_n "checking for ${version}... " >&6; }
   found_usable_python=no
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#include "${version}/Python.h"
+#include "Python.h"
 int
 main ()
 {
@@ -10855,7 +10872,7 @@ $as_echo_n "checking for ${version}... " >&6; }
   found_usable_python=no
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#include "${version}/Python.h"
+#include "Python.h"
 int
 main ()
 {
@@ -10892,7 +10909,7 @@ $as_echo_n "checking for ${version}... " >&6; }
   found_usable_python=no
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#include "${version}/Python.h"
+#include "Python.h"
 int
 main ()
 {
diff --git a/gdb/configure.ac b/gdb/configure.ac
index 96a3436..a8fbb62 100644
--- a/gdb/configure.ac
+++ b/gdb/configure.ac
@@ -650,7 +650,7 @@ AC_DEFUN([AC_TRY_LIBPYTHON],
   CPPFLAGS="$CPPFLAGS $new_CPPFLAGS"
   LIBS="$LIBS $new_LIBS"
   found_usable_python=no
-  AC_LINK_IFELSE(AC_LANG_PROGRAM([[#include "${version}/Python.h"]],
+  AC_LINK_IFELSE(AC_LANG_PROGRAM([[#include "Python.h"]],
                                  [[Py_Initialize ();]]),
                  [have_libpython_var=${version}
                   found_usable_python=yes],
@@ -707,6 +707,13 @@ else
       # Assume the python binary is ${with_python}/bin/python.
       python_prog="${with_python}/bin/python"
       python_prefix=
+      # If python does not exit ${with_python}/bin, then try in
+      # ${with_python}.  On Windows/MinGW, this is where the Python
+      # executable is.
+      if test ! -x "${python_prog}"; then
+        python_prog="${with_python}/python"
+        python_prefix=
+      fi
       if test ! -x "${python_prog}"; then
         # Fall back to gdb 7.0/7.1 behaviour.
         python_prog=missing
@@ -759,24 +766,34 @@ else
   esac
 
   if test "${python_prog}" != missing; then
+    # FIXME: Add comment.
+    case "$host_os" in
+      mingw*)
+        python_config_prog="python-wconfig.py"
+        sed "s,@PREFIX@,`dirname $python_prog`," \
+          ${srcdir}/python/python-wconfig.in > $python_config_prog
+        ;;
+      *) python_config_prog="${srcdir}/python/python-config.py";;
+    esac
+
     # We have a python program to use, but it may be too old.
     # Don't flag an error for --with-python=auto (the default).
     have_python_config=yes
-    python_includes=`${python_prog} ${srcdir}/python/python-config.py --includes`
+    python_includes=`${python_prog} ${python_config_prog} --includes`
     if test $? != 0; then
       have_python_config=failed
       if test "${with_python}" != auto; then
         AC_ERROR(failure running python-config --includes)
       fi
     fi
-    python_libs=`${python_prog} ${srcdir}/python/python-config.py --ldflags`
+    python_libs=`${python_prog} ${python_config_prog} --ldflags`
     if test $? != 0; then
       have_python_config=failed
       if test "${with_python}" != auto; then
         AC_ERROR(failure running python-config --ldflags)
       fi
     fi
-    python_prefix=`${python_prog} ${srcdir}/python/python-config.py --exec-prefix`
+    python_prefix=`${python_prog} ${python_config_prog} --exec-prefix`
     if test $? != 0; then
       have_python_config=failed
       if test "${with_python}" != auto; then
@@ -811,7 +828,7 @@ else
   have_libpython=no
   if test "${have_python_config}" = yes; then
     python_version=`echo " ${python_libs} " \
-                         | sed -e 's,^.* -l\(python[[0-9]]*[[.]][[0-9]]*\) .*$,\1,'`
+                         | sed -e 's,^.* -l\(python[[0-9]]*[[.]]\?[[0-9]]*\).*$,\1,'`
     case "${python_version}" in
     python*)
       AC_TRY_LIBPYTHON(${python_version}, have_libpython,
diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c
index 23e42c1..e552df8 100644
--- a/gdb/cp-valprint.c
+++ b/gdb/cp-valprint.c
@@ -36,7 +36,7 @@
 #include "valprint.h"
 #include "cp-support.h"
 #include "language.h"
-#include "python/python.h"
+#include "python/gdb-python.h"
 
 /* Controls printing of vtbl's.  */
 static void
diff --git a/gdb/eval.c b/gdb/eval.c
index de25b39..07eea7a 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -42,7 +42,7 @@
 #include "valprint.h"
 #include "gdb_obstack.h"
 #include "objfiles.h"
-#include "python/python.h"
+#include "python/gdb-python.h"
 #include "wrapper.h"
 
 #include "gdb_assert.h"
diff --git a/gdb/main.c b/gdb/main.c
index 6be4805..2845965 100644
--- a/gdb/main.c
+++ b/gdb/main.c
@@ -41,7 +41,7 @@
 #include "main.h"
 #include "source.h"
 #include "cli/cli-cmds.h"
-#include "python/python.h"
+#include "python/gdb-python.h"
 #include "objfiles.h"
 
 /* The selected interpreter.  This will be used as a set command
diff --git a/gdb/python/gdb-python.h b/gdb/python/gdb-python.h
new file mode 100644
index 0000000..58d97fc
--- /dev/null
+++ b/gdb/python/gdb-python.h
@@ -0,0 +1,44 @@
+/* Python/gdb header for generic use in gdb
+
+   Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef GDB_PYTHON_H
+#define GDB_PYTHON_H
+
+#include "value.h"
+
+extern int gdbpy_global_auto_load;
+
+extern void finish_python_initialization (void);
+
+void eval_python_from_control_command (struct command_line *);
+
+void source_python_script (FILE *stream, const char *file);
+
+int apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr,
+			      int embedded_offset, CORE_ADDR address,
+			      struct ui_file *stream, int recurse,
+			      const struct value *val,
+			      const struct value_print_options *options,
+			      const struct language_defn *language);
+
+void preserve_python_values (struct objfile *objfile, htab_t copied_types);
+
+void load_auto_scripts_for_objfile (struct objfile *objfile);
+
+#endif /* GDB_PYTHON_H */
diff --git a/gdb/python/py-auto-load.c b/gdb/python/py-auto-load.c
index e822838..733f190 100644
--- a/gdb/python/py-auto-load.c
+++ b/gdb/python/py-auto-load.c
@@ -27,7 +27,7 @@
 #include "observer.h"
 #include "progspace.h"
 #include "objfiles.h"
-#include "python.h"
+#include "gdb-python.h"
 #include "cli/cli-cmds.h"
 
 /* Internal-use flag to enable/disable auto-loading.
diff --git a/gdb/python/py-prettyprint.c b/gdb/python/py-prettyprint.c
index 7532aa5..0895e46 100644
--- a/gdb/python/py-prettyprint.c
+++ b/gdb/python/py-prettyprint.c
@@ -24,7 +24,7 @@
 #include "language.h"
 #include "valprint.h"
 
-#include "python.h"
+#include "gdb-python.h"
 
 #ifdef HAVE_PYTHON
 #include "python-internal.h"
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index 80d0763..809e918 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -41,25 +41,14 @@
    around technique as above.  */
 #undef _FILE_OFFSET_BITS
 
+#include "Python.h"
+#include "frameobject.h"
 #if HAVE_LIBPYTHON2_4
-#include "python2.4/Python.h"
-#include "python2.4/frameobject.h"
 /* Py_ssize_t is not defined until 2.5.
    Logical type for Py_ssize_t is Py_intptr_t, but that fails in 64-bit
    compilation due to several apparent mistakes in python2.4 API, so we
    use 'int' instead.  */
 typedef int Py_ssize_t;
-#elif HAVE_LIBPYTHON2_5
-#include "python2.5/Python.h"
-#include "python2.5/frameobject.h"
-#elif HAVE_LIBPYTHON2_6
-#include "python2.6/Python.h"
-#include "python2.6/frameobject.h"
-#elif HAVE_LIBPYTHON2_7
-#include "python2.7/Python.h"
-#include "python2.7/frameobject.h"
-#else
-#error "Unable to find usable Python.h"
 #endif
 
 /* If Python.h does not define WITH_THREAD, then the various
diff --git a/gdb/python/python-wconfig.in b/gdb/python/python-wconfig.in
new file mode 100644
index 0000000..7e92b06
--- /dev/null
+++ b/gdb/python/python-wconfig.in
@@ -0,0 +1,18 @@
+import sys
+import distutils
+from distutils.sysconfig import get_config_var
+
+prefix=r"@PREFIX@"
+
+for arg in sys.argv[1:]:
+    if arg in ("--exec-prefix", "--prefix"):
+        print prefix
+    elif arg == "--includes":
+        print "-I%s/include" % prefix
+    elif arg == "--ldflags":
+        version = get_config_var('VERSION')
+        print "-L%s/libs -lpython%s" % (prefix, version)
+    else:
+        print "Error: Invalid switch %s" % arg
+        sys.exit(1)
+
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 81e7ef1..9f79c99 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -39,7 +39,7 @@ static int gdbpy_should_print_stack = 1;
 
 #ifdef HAVE_PYTHON
 
-#include "python.h"
+#include "gdb-python.h"
 #include "libiberty.h"
 #include "cli/cli-decode.h"
 #include "charset.h"
diff --git a/gdb/python/python.h b/gdb/python/python.h
deleted file mode 100644
index 58d97fc..0000000
--- a/gdb/python/python.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Python/gdb header for generic use in gdb
-
-   Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
-
-   This file is part of GDB.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
-
-#ifndef GDB_PYTHON_H
-#define GDB_PYTHON_H
-
-#include "value.h"
-
-extern int gdbpy_global_auto_load;
-
-extern void finish_python_initialization (void);
-
-void eval_python_from_control_command (struct command_line *);
-
-void source_python_script (FILE *stream, const char *file);
-
-int apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr,
-			      int embedded_offset, CORE_ADDR address,
-			      struct ui_file *stream, int recurse,
-			      const struct value *val,
-			      const struct value_print_options *options,
-			      const struct language_defn *language);
-
-void preserve_python_values (struct objfile *objfile, htab_t copied_types);
-
-void load_auto_scripts_for_objfile (struct objfile *objfile);
-
-#endif /* GDB_PYTHON_H */
diff --git a/gdb/top.c b/gdb/top.c
index 5e9d841..1c10300 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -47,7 +47,7 @@
 #include "main.h"
 #include "event-loop.h"
 #include "gdbthread.h"
-#include "python/python.h"
+#include "python/gdb-python.h"
 
 /* readline include files.  */
 #include "readline/readline.h"
diff --git a/gdb/valprint.c b/gdb/valprint.c
index f65fe27..16edd2d 100644
--- a/gdb/valprint.c
+++ b/gdb/valprint.c
@@ -34,7 +34,7 @@
 #include "doublest.h"
 #include "exceptions.h"
 #include "dfp.h"
-#include "python/python.h"
+#include "python/gdb-python.h"
 #include "ada-lang.h"
 
 #include <errno.h>
diff --git a/gdb/value.c b/gdb/value.c
index db83ea2..642af4d 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -40,7 +40,7 @@
 #include "valprint.h"
 #include "cli/cli-decode.h"
 
-#include "python/python.h"
+#include "python/gdb-python.h"
 
 #include "tracepoint.h"
 
diff --git a/gdb/varobj.c b/gdb/varobj.c
index 0c90645..bac7d76 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -37,7 +37,7 @@
 #include "inferior.h"
 
 #if HAVE_PYTHON
-#include "python/python.h"
+#include "python/gdb-python.h"
 #include "python/python-internal.h"
 #else
 typedef int PyObject;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]