Enable building GDB without installed libtermcap

Message ID 54EF5C56.9010101@redhat.com
State New, archived
Headers

Commit Message

Pedro Alves Feb. 26, 2015, 5:48 p.m. UTC
  On 02/24/2015 06:13 PM, Bernd Edlinger wrote:

> Ok, thanks for this hint!
> 
> That is probably exactly what I need.
> 
> This makes the patch much smaller.
> 
> Maybe the name windows-termcap.c is a bit misleading,
> because my target is mostly some embedded linux.
> 

(meanwhile the file has been renamed to stub-termcap.c)

> How about this:
> --- a/gdb/configure.ac
> +++ b/gdb/configure.ac
> @@ -621,7 +621,7 @@ esac
>  AC_SEARCH_LIBS(tgetent, [termcap tinfo curses ncurses])
>  
>  if test "$ac_cv_search_tgetent" = no; then
> -  AC_MSG_ERROR([no termcap library found])
> +  CONFIG_OBS="$CONFIG_OBS windows-termcap.o"
>  fi

Yes, but I think we should remove the mingw specific fallback
a bit above too.

>  
>  AC_ARG_WITH([system-readline],
> diff --git a/gdb/windows-termcap.c b/gdb/windows-termcap.c
> index caafc47..b6e0d08 100644
> --- a/gdb/windows-termcap.c
> +++ b/gdb/windows-termcap.c
> @@ -32,6 +32,8 @@ extern char* tgetstr (char *name, char **area);
>  extern int tputs (char *string, int nlines, int (*outfun) ());
>  extern char *tgoto (const char *cap, int col, int row);
>  
> +char PC, *BC, *UP;
> +

I was doing what I suggest above, and tripped on the need for this
too, without realizing you had this here already.  GDB is converting
to C++ (and people build with -fno-common too, e.g., 
https://sourceware.org/ml/gdb-patches/2015-02/msg00364.html), and
there's a problem with just defining these symbols unconditionally
here.  See patch below for details, and let me know what you (all) think.

----
[PATCH] Fallback to stub-termcap.c on all hosts

Currently building gdb is impossible without an installed termcap or
curses library.  But, GDB already has a very minimal termcap in the
tree to handle this situation for Windows -- gdb/stub-termcap.c.  This
patch makes that the fallback for all hosts.

Testing this on GNU/Linux (by simply hacking away the termcap/curses
detection in gdb/configure.ac), I tripped on:

 ../readline/libreadline.a(terminal.o): In function `_rl_init_terminal_io':
 /home/pedro/gdb/mygit/src/readline/terminal.c:527: undefined reference to `PC'
 /home/pedro/gdb/mygit/src/readline/terminal.c:528: undefined reference to `BC'
 /home/pedro/gdb/mygit/src/readline/terminal.c:529: undefined reference to `UP'
 /home/pedro/gdb/mygit/src/readline/terminal.c:538: undefined reference to `PC'
 /home/pedro/gdb/mygit/src/readline/terminal.c:539: undefined reference to `BC'
 /home/pedro/gdb/mygit/src/readline/terminal.c:540: undefined reference to `UP'

These are globals that are normally defined by termcap (or ncurses'
termcap emulation).

Now, we could just define replacements in stub-termcap.c, but
readline/terminal.c (at least the copy in our tree) has this "beauty":

 #if !defined (__linux__) && !defined (NCURSES_VERSION)
 #  if defined (__EMX__) || defined (NEED_EXTERN_PC)
 extern
 #  endif /* __EMX__ || NEED_EXTERN_PC */
 char PC, *BC, *UP;
 #endif /* !__linux__ && !NCURSES_VERSION */

which can result in readline defining the globals too.  That will
usually work out in C, given that "-fcommon" is usually the default
for C compilers, but that won't work for C++, or C with -fno-common
(link fails with "multiple definition" errors)...

Mirroring those #ifdef conditions in the stub termcap screams
"brittle" to me -- I can see them changing in latter readline
versions.

My idea to work around that is to simply use __attribute__((weak)).
Of all supported hosts
(https://sourceware.org/gdb/wiki/Systems#Supported_Hosts),
Windows/PE/COFF would be the one that I'd be worried about WRT use of
weak, but the limited weak support in PE/COFF seems to work here.  A
cross build using x86_64-w64-mingw32 on Fedora 20 builds fine with
this.

gdb/ChangeLog:
2015-02-26  Bernd Edlinger  <bernd.edlinger@hotmail.de>
	    Pedro Alves  <palves@redhat.com>

	* configure.ac: Remove the mingw32-specific stub-termcap.o
	fallback, and instead fallback to the stub termcap on all hosts.
	* configure: Regenerate.
	* stub-termcap.c (PC, BC, UP): Define as weak symbols.
---
 gdb/configure.ac   |  7 +------
 gdb/stub-termcap.c | 13 ++++++++++++-
 2 files changed, 13 insertions(+), 7 deletions(-)
  

Comments

Eli Zaretskii Feb. 26, 2015, 6 p.m. UTC | #1
> Date: Thu, 26 Feb 2015 17:48:06 +0000
> From: Pedro Alves <palves@redhat.com>
> CC: GDB Patches <gdb-patches@sourceware.org>, Doug Evans <dje@google.com>,        Mike Frysinger <vapier@gentoo.org>
> 
> My idea to work around that is to simply use __attribute__((weak)).
> Of all supported hosts
> (https://sourceware.org/gdb/wiki/Systems#Supported_Hosts),
> Windows/PE/COFF would be the one that I'd be worried about WRT use of
> weak, but the limited weak support in PE/COFF seems to work here.  A
> cross build using x86_64-w64-mingw32 on Fedora 20 builds fine with
> this.

With what version of GCC?  Quick testing indicates that 4.8.1 supports
that, but 3.4.2 doesn't.

Which version of GCC is the minimal one we want to support?

Or how about making this conditional on C++?
  
Pedro Alves Feb. 26, 2015, 6:44 p.m. UTC | #2
On 02/26/2015 06:00 PM, Eli Zaretskii wrote:
>> Date: Thu, 26 Feb 2015 17:48:06 +0000
>> From: Pedro Alves <palves@redhat.com>
>> CC: GDB Patches <gdb-patches@sourceware.org>, Doug Evans <dje@google.com>,        Mike Frysinger <vapier@gentoo.org>
>>
>> My idea to work around that is to simply use __attribute__((weak)).
>> Of all supported hosts
>> (https://sourceware.org/gdb/wiki/Systems#Supported_Hosts),
>> Windows/PE/COFF would be the one that I'd be worried about WRT use of
>> weak, but the limited weak support in PE/COFF seems to work here.  A
>> cross build using x86_64-w64-mingw32 on Fedora 20 builds fine with
>> this.
> 
> With what version of GCC?  Quick testing indicates that 4.8.1 supports
> that, but 3.4.2 doesn't.

Ah.  This was:
  gcc version 4.8.3 20140522 (Fedora MinGW 4.8.3-1.fc20) (GCC)

> 
> Which version of GCC is the minimal one we want to support?

Hard to say at this point.  I'd hope we'd move to requiring
something more recent than 3.4.x.  From past discussions, I was
assuming we'd start by requiring 4.2 at least when finally require
C++.

> Or how about making this conditional on C++?

Some want to build with -fno-common, even in C mode.  Given
that this stub file never needed these variables while it was
Windows-only, how about we simply not define the variables
if compiling for mingw/cygwin, but define them as weak
everywhere else?  The worse that can happen is some host that
didn't use to build for lack of termcap will now fail to build
due to lack of weak.  In practical terms, you just end up with
no gdb, just like before, so no worse.

Thanks,
Pedro Alves
  
Eli Zaretskii Feb. 26, 2015, 6:55 p.m. UTC | #3
> Date: Thu, 26 Feb 2015 18:44:53 +0000
> From: Pedro Alves <palves@redhat.com>
> CC: bernd.edlinger@hotmail.de, gdb-patches@sourceware.org, dje@google.com,
>         vapier@gentoo.org
> 
> > Which version of GCC is the minimal one we want to support?
> 
> Hard to say at this point.  I'd hope we'd move to requiring
> something more recent than 3.4.x.  From past discussions, I was
> assuming we'd start by requiring 4.2 at least when finally require
> C++.

I don't have that.  Someone should check if it supports this
attribute.

> Given that this stub file never needed these variables while it was
> Windows-only, how about we simply not define the variables if
> compiling for mingw/cygwin, but define them as weak everywhere else?

Works for me, thanks.
  
Bernd Edlinger Feb. 26, 2015, 7:15 p.m. UTC | #4
Hi,



On Thu, 26 Feb 2015 17:48:06, Pedro Alves wrote:
>
> Yes, but I think we should remove the mingw specific fallback
> a bit above too.
>

yes, and probably these lines too:

  cygwin*)
    if test -d $srcdir/libtermcap; then
      LIBS="../libtermcap/libtermcap.a $LIBS"
      ac_cv_search_tgetent="../libtermcap/libtermcap.a"
    fi ;;


reason: this block is never executed, because
$srcdir/libtermcap points to binutils-gdb/gdb/libtermcap
but it inclues ../libtermcap/libtermcap.a, which assumes
binutils-gdb/libtermcap. However if libtermcap was
there, it is built after gdb, so this would fail anyway.



Thanks
Bernd.
  

Patch

diff --git a/gdb/configure.ac b/gdb/configure.ac
index 6ac8adb..79fc115 100644
--- a/gdb/configure.ac
+++ b/gdb/configure.ac
@@ -610,18 +610,13 @@  case $host_os in
   go32* | *djgpp*)
     ac_cv_search_tgetent="none required"
     ;;
-  *mingw32*)
-    if test x"$curses_found" != xyes; then
-      ac_cv_search_tgetent="none required"
-      CONFIG_OBS="$CONFIG_OBS stub-termcap.o"
-    fi ;;
 esac
 
 # These are the libraries checked by Readline.
 AC_SEARCH_LIBS(tgetent, [termcap tinfo curses ncurses])
 
 if test "$ac_cv_search_tgetent" = no; then
-  AC_MSG_ERROR([no termcap library found])
+  CONFIG_OBS="$CONFIG_OBS stub-termcap.o"
 fi
 
 AC_ARG_WITH([system-readline],
diff --git a/gdb/stub-termcap.c b/gdb/stub-termcap.c
index cc8632c..8704695 100644
--- a/gdb/stub-termcap.c
+++ b/gdb/stub-termcap.c
@@ -32,9 +32,20 @@  extern char* tgetstr (char *name, char **area);
 extern int tputs (char *string, int nlines, int (*outfun) ());
 extern char *tgoto (const char *cap, int col, int row);
 
+/* These are global termcap variables that readline references.
+   Actually, depending on preprocessor conditions that we don't want
+   to mirror here (as they may change depending on readline versions),
+   readline may define these globals as well, relying on the linker
+   merging them if needed (-fcommon).  That doesn't work with
+   -fno-common or C++, so instead we define the symbols as weak.  */
+char PC __attribute__((weak));
+char *BC __attribute__((weak));
+char *UP __attribute__((weak));
+
 /* Each of the files below is a minimal implementation of the standard
    termcap function with the same name, suitable for use in a Windows
-   console window.  */
+   console window, or when a real termcap/curses library isn't
+   available.  */
 
 int
 tgetent (char *buffer, char *termtype)