From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29339 invoked by alias); 21 Jan 2011 01:14:48 -0000 Received: (qmail 29315 invoked by uid 22791); 21 Jan 2011 01:14:45 -0000 X-SWARE-Spam-Status: No, hits=-2.0 required=5.0 tests=AWL,BAYES_00,TW_BJ X-Spam-Check-By: sourceware.org Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 21 Jan 2011 01:14:36 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 4EDF02BAC41 for ; Thu, 20 Jan 2011 20:14:34 -0500 (EST) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id BjRANRZaYMnm for ; Thu, 20 Jan 2011 20:14:34 -0500 (EST) Received: from joel.gnat.com (localhost.localdomain [127.0.0.1]) by rock.gnat.com (Postfix) with ESMTP id 311B72BAC19 for ; Thu, 20 Jan 2011 20:14:34 -0500 (EST) Received: by joel.gnat.com (Postfix, from userid 1000) id A39CE1459AD; Thu, 20 Jan 2011 20:14:33 -0500 (EST) Date: Fri, 21 Jan 2011 05:57:00 -0000 From: Joel Brobecker To: gdb-patches@sourceware.org Subject: FYI: WIP patch to build GDB with Python on MinGW Message-ID: <20110121011433.GA2440@adacore.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="tThc/1wpZn/ma/RB" Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-06-14) Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2011-01/txt/msg00432.txt.bz2 --tThc/1wpZn/ma/RB Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-length: 3970 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 /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 directory). c. python includes are in /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 /bin, then try . 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 /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 --tThc/1wpZn/ma/RB Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="python-migw32.diff" Content-length: 15792 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 . */ + +#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 . */ - -#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 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; --tThc/1wpZn/ma/RB--