by cawan (cawan[at]ieee.org or chuiyewleong[at]hotmail.com)
on 21/11/2012
GDB is a useful tool to debug applications running in linux system. For the case of
embedded linux system, it is important have a version of GDB that can run in proper
in the embedded environment. As oppose to x86 environment which is mostly being used
in PC platform, embedded system adopts a large variety of RISC architecture to run
the system. There are ARM, MIPS, PPC... and each of them might run in little or big
endian mode. So, it is a little bit hard to have a generic version of GDB that can
run in all embedded platforms. Therefore, it is crucial to harness the power of cross
compilation in all the ways in order to make use of those useful tools such as GDB in
embedded environment. Regarding to the fundamental knowledge of cross compilation,
please refer my previous paper in this blog, "What is Cross Compilation ? Cross
Compilation Demystified For Embedded Linux System". So, let us start to cross compile
the GDB for our embedded platform right now. The embedded platform that we are going
to use is MIPS 24k, little-endian mode, 500MHz, with 256MB DDR2 RAM.
Host:# ./configure --help
`configure' configures this package to adapt to many kinds of systems.
Usage: ./configure [OPTION]... [VAR=VALUE]...
To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE. See below for descriptions of some of the useful variables.
Defaults for the options are specified in brackets.
Configuration:
-h, --help display this help and exit
--help=short display options specific to this package
--help=recursive display the short help of all the included packages
-V, --version display version information and exit
-q, --quiet, --silent do not print `checking...' messages
--cache-file=FILE cache test results in FILE [disabled]
-C, --config-cache alias for `--cache-file=config.cache'
-n, --no-create do not create output files
--srcdir=DIR find the sources in DIR [configure dir or `..']
Installation directories:
--prefix=PREFIX install architecture-independent files in PREFIX
[/usr/local]
--exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
[PREFIX]
By default, `make install' will install all the files in
`/usr/local/bin', `/usr/local/lib' etc. You can specify
an installation prefix other than `/usr/local' using `--prefix',
for instance `--prefix=$HOME'.
For better control, use the options below.
Fine tuning of the installation directories:
--bindir=DIR user executables [EPREFIX/bin]
--sbindir=DIR system admin executables [EPREFIX/sbin]
--libexecdir=DIR program executables [EPREFIX/libexec]
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
--datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
--datadir=DIR read-only architecture-independent data [DATAROOTDIR]
--infodir=DIR info documentation [DATAROOTDIR/info]
--localedir=DIR locale-dependent data [DATAROOTDIR/locale]
--mandir=DIR man documentation [DATAROOTDIR/man]
--docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE]
--htmldir=DIR html documentation [DOCDIR]
--dvidir=DIR dvi documentation [DOCDIR]
--pdfdir=DIR pdf documentation [DOCDIR]
--psdir=DIR ps documentation [DOCDIR]
Program names:
--program-prefix=PREFIX prepend PREFIX to installed program names
--program-suffix=SUFFIX append SUFFIX to installed program names
--program-transform-name=PROGRAM run sed PROGRAM on installed program names
System types:
--build=BUILD configure for building on BUILD [guessed]
--host=HOST cross-compile to build programs to run on HOST [BUILD]
--target=TARGET configure for building compilers for TARGET [HOST]
Optional Features:
--disable-option-checking ignore unrecognized --enable/--with options
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--enable-gold use gold instead of ld
--enable-libada build libada directory
--enable-libssp build libssp directory
--enable-build-with-cxx build with C++ compiler instead of C compiler
--disable-ppl-version-check disable check for PPL version
--disable-cloog-version-check disable check for CLooG version
--enable-lto enable link time optimization support
--enable-stage1-languages[=all] choose additional languages to build during
stage1. Mostly useful for compiler development.
--enable-objc-gc enable use of Boehm's garbage collector with the
GNU Objective-C runtime
--enable-bootstrap enable bootstrapping [yes if native build]
--enable-serial-[{host,target,build}-]configure
force sequential configuration of
sub-packages for the host, target or build
machine, or all sub-packages
--enable-maintainer-mode enable make rules and dependencies not useful
(and sometimes confusing) to the casual installer
--enable-stage1-checking[=all] choose additional checking for stage1
of the compiler
--enable-werror enable -Werror in bootstrap stage2 and later
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
--with-build-libsubdir=DIR Directory where to find libraries for build system
--with-mpc=PATH specify prefix directory for installed MPC package.
Equivalent to --with-mpc-include=PATH/include
plus --with-mpc-lib=PATH/lib
--with-mpc-include=PATH
specify directory for installed MPC include files
--with-mpc-lib=PATH specify directory for the installed MPC library
--with-mpfr-dir=PATH this option has been REMOVED
--with-mpfr=PATH specify prefix directory for installed MPFR package.
Equivalent to --with-mpfr-include=PATH/include
plus --with-mpfr-lib=PATH/lib
--with-mpfr-include=PATH
specify directory for installed MPFR include files
--with-mpfr-lib=PATH specify directory for the installed MPFR library
--with-gmp-dir=PATH this option has been REMOVED
--with-gmp=PATH specify prefix directory for the installed GMP package.
Equivalent to --with-gmp-include=PATH/include
plus --with-gmp-lib=PATH/lib
--with-gmp-include=PATH specify directory for installed GMP include files
--with-gmp-lib=PATH specify directory for the installed GMP library
--with-host-libstdcxx=L Use linker arguments L to link with libstdc++
when linking with PPL
--with-stage1-ldflags=FLAGS Linker flags for stage1
-with-stage1-libs=LIBS Libraries for stage1
--with-boot-libs=LIBS Libraries for stage2 and later
--with-boot-ldflags=FLAGS Linker flags for stage2 and later
--with-ppl=PATH Specify prefix directory for the installed PPL package
Equivalent to --with-ppl-include=PATH/include
plus --with-ppl-lib=PATH/lib
--with-ppl-include=PATH Specify directory for installed PPL include files
--with-ppl-lib=PATH Specify the directory for the installed PPL library
--with-cloog=PATH Specify prefix directory for the installed CLooG-PPL package
Equivalent to --with-cloog-include=PATH/include
plus --with-cloog-lib=PATH/lib
--with-cloog-include=PATH Specify directory for installed CLooG include files
--with-cloog-lib=PATH Specify the directory for the installed CLooG library
--with-libelf=PATH Specify prefix directory for the installed libelf package
Equivalent to --with-libelf-include=PATH/include
plus --with-libelf-lib=PATH/lib
--with-libelf-include=PATH Specify directory for installed libelf include files
--with-libelf-lib=PATH Specify the directory for the installed libelf library
--with-build-sysroot=SYSROOT
use sysroot as the system root during the build
--with-debug-prefix-map='A=B C=D ...'
map A to B, C to D ... in debug information
--with-build-config='NAME NAME2...'
Use config/NAME.mk build configuration
--with-build-time-tools=PATH
use given path to find target tools during the build
Some influential environment variables:
CC C compiler command
CFLAGS C compiler flags
LDFLAGS linker flags, e.g. -L
nonstandard directory
LIBS libraries to pass to the linker, e.g. -l
CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I
you have headers in a nonstandard directory
CXX C++ compiler command
CXXFLAGS C++ compiler flags
CPP C preprocessor
AR AR for the host
AS AS for the host
DLLTOOL DLLTOOL for the host
LD LD for the host
LIPO LIPO for the host
NM NM for the host
RANLIB RANLIB for the host
STRIP STRIP for the host
WINDRES WINDRES for the host
WINDMC WINDMC for the host
OBJCOPY OBJCOPY for the host
OBJDUMP OBJDUMP for the host
CC_FOR_TARGET
CC for the target
CXX_FOR_TARGET
CXX for the target
GCC_FOR_TARGET
GCC for the target
GCJ_FOR_TARGET
GCJ for the target
GFORTRAN_FOR_TARGET
GFORTRAN for the target
AR_FOR_TARGET
AR for the target
AS_FOR_TARGET
AS for the target
DLLTOOL_FOR_TARGET
DLLTOOL for the target
LD_FOR_TARGET
LD for the target
LIPO_FOR_TARGET
LIPO for the target
NM_FOR_TARGET
NM for the target
OBJDUMP_FOR_TARGET
OBJDUMP for the target
RANLIB_FOR_TARGET
RANLIB for the target
STRIP_FOR_TARGET
STRIP for the target
WINDRES_FOR_TARGET
WINDRES for the target
WINDMC_FOR_TARGET
WINDMC for the target
Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.
Report bugs to the package provider.
Host:#
Well, let's define --host, --target, and CC for our first try of GDB cross
compilation.
Host:# ./configure --host=mips-linux-gnu --target=mips-linux-gnu CC="mips-linux-gnu-gcc -EL"
Host:# make
After a while, we get the following error.
configure: WARNING: no enhanced curses library found; disabling TUI
checking for library containing tgetent... no
configure: error: no termcap library found
make[1]: *** [configure-gdb] Error 1
make[1]: Leaving directory `/home/smp383/mips-4.3/bin/gdb-7.1'
make: *** [all] Error 2
No termcap library found... It seems GDB needs termcap library to complete the
cross compilation. So, we need to cross compile a termcap library first.
Host:# wget http://gnuwin32.sourceforge.net/downlinks/termcap-src-zip.php
Host:# ls *.zip
termcap-1.3.1-src.zip
Host:# mkdir libtermcap
Host:# cp termcap-1.3.1-src.zip ./libtermcap/
Host:# cd libtermcap/
Host:# ls
termcap-1.3.1-src.zip
Host:# unzip termcap-1.3.1-src.zip
Archive: termcap-1.3.1-src.zip
TermCap 1.3.1: sources
TermCap: terminal-capability library
inflating: src/COPYING
inflating: src/ChangeLog
inflating: src/INSTALL
inflating: src/Makefile
inflating: src/Makefile.in
inflating: src/NEWS
inflating: src/README
inflating: src/config.cache
inflating: src/config.log
inflating: src/config.status
inflating: src/configure
inflating: src/configure.in
inflating: src/configure_help.txt
inflating: src/install-sh
inflating: src/makefile.mingw
inflating: src/mkinstalldirs
inflating: src/termcap.c
inflating: src/termcap.h
inflating: src/termcap.info
inflating: src/termcap.info-1
inflating: src/termcap.info-2
inflating: src/termcap.info-3
inflating: src/termcap.info-4
inflating: src/termcap.src
inflating: src/termcap.texi
inflating: src/texinfo.te_
inflating: src/tparam.c
inflating: src/version.c
inflating: manifest/termcap-1.3.1-src.ver
inflating: manifest/termcap-1.3.1-src.mft
Host:# ls
manifest src termcap-1.3.1-src.zip
Host:# cd src
Host:# ls
ChangeLog configure.in makefile.mingw termcap.info termcap.texi
config.cache COPYING mkinstalldirs termcap.info-1 texinfo.te_
config.log INSTALL NEWS termcap.info-2 tparam.c
config.status install-sh README termcap.info-3 version.c
configure Makefile termcap.c termcap.info-4
configure_help.txt Makefile.in termcap.h termcap.src
Host:# ./configure --help
bash: ./configure: Permission denied
Host:# ls -l ./configure
-rw-r--r-- 1 root root 30285 1995-07-27 03:52 ./configure
Host:# chmod 755 ./configure
Host:# ls -l ./configure
-rwxr-xr-x 1 root root 30285 1995-07-27 03:52 ./configure
Host:# ./configure --help
Usage: configure [options] [host]
Options: [defaults in brackets after descriptions]
Configuration:
--cache-file=FILE cache test results in FILE
--help print this message
--no-create do not create output files
--quiet, --silent do not print `checking...' messages
--version print the version of autoconf that created configure
Directory and file names:
--prefix=PREFIX install architecture-independent files in PREFIX
[/usr/local]
--exec-prefix=PREFIX install architecture-dependent files in PREFIX
[same as prefix]
--srcdir=DIR find the sources in DIR [configure dir or ..]
--program-prefix=PREFIX prepend PREFIX to installed program names
--program-suffix=SUFFIX append SUFFIX to installed program names
--program-transform-name=PROGRAM run sed PROGRAM on installed program names
Host type:
--build=BUILD configure for building on BUILD [BUILD=HOST]
--host=HOST configure for HOST [guessed]
--target=TARGET configure for TARGET [TARGET=HOST]
Features and packages:
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
--x-includes=DIR X include files are in DIR
--x-libraries=DIR X library files are in DIR
--enable and --with options recognized:
--enable-install-termcap install the termcap data file
--with-termcap=FILE use data file FILE instead of /etc/termcap
Host:# ./configure --host=mips-linux-gnu --target=mips-linux-gnu CC="mips-linux-gnu-gcc -EL"
configure: warning: CC=mips-linux-gnu-gcc -EL: invalid host type
loading cache ./config.cache
checking for gcc... (cached) gcc
checking whether we are using GNU C... (cached) yes
checking for ranlib... (cached) ranlib
checking for a BSD compatible install... /usr/bin/install -c
checking how to run the C preprocessor... (cached) gcc -E
checking for string.h... (cached) no
checking for unistd.h... (cached) no
checking whether cross-compiling... (cached) no
checking for ANSI C header files... (cached) yes
updating cache ./config.cache
creating ./config.status
creating Makefile
Host:# make
gcc -c -DTERMCAP_FILE=\"/etc/termcap\" -I. -I. -g termcap.c
termcap.c:44: warning: conflicting types for built-in function ‘malloc’
termcap.c:45: warning: conflicting types for built-in function ‘realloc’
termcap.c: In function ‘memory_out’:
termcap.c:96: warning: incompatible implicit declaration of built-in function ‘exit’
termcap.c: In function ‘tgetent’:
termcap.c:511: warning: incompatible implicit declaration of built-in function ‘strcpy’
termcap.c:541: warning: incompatible implicit declaration of built-in function ‘strlen’
termcap.c:549: warning: incompatible implicit declaration of built-in function ‘strcpy’
termcap.c:550: warning: incompatible implicit declaration of built-in function ‘strlen’
termcap.c:559: warning: incompatible implicit declaration of built-in function ‘free’
termcap.c:567: warning: incompatible implicit declaration of built-in function ‘free’
termcap.c:597: warning: incompatible implicit declaration of built-in function ‘free’
termcap.c: In function ‘gobble_line’:
termcap.c:747: warning: incompatible implicit declaration of built-in function ‘bcopy’
gcc -c -DTERMCAP_FILE=\"/etc/termcap\" -I. -I. -g tparam.c
tparam.c:32: warning: conflicting types for built-in function ‘malloc’
tparam.c:33: warning: conflicting types for built-in function ‘realloc’
tparam.c: In function ‘memory_out’:
tparam.c:52: warning: incompatible implicit declaration of built-in function ‘exit’
tparam.c: In function ‘tparam1’:
tparam.c:161: warning: incompatible implicit declaration of built-in function ‘bcopy’
tparam.c:222: warning: incompatible implicit declaration of built-in function ‘strlen’
tparam.c:300: warning: incompatible implicit declaration of built-in function ‘abort’
tparam.c:310: warning: incompatible implicit declaration of built-in function ‘strcat’
gcc -c -DTERMCAP_FILE=\"/etc/termcap\" -I. -I. -g version.c
ar rc libtermcap.a termcap.o tparam.o version.o
ranlib libtermcap.a
Well, the libtermcap.a is generated, but based on the output message, the binary
is suspicious to be MIPS compatible. Let's check.
Host:# ls *.o
termcap.o tparam.o version.o
Host:# file termcap.o
termcap.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
Yes, our suspicion is correct, the binary is in x86 format. Let us define the CC flag
in explicit way under the make process.
Host:# make distclean
rm -f *.a *.o core
rm -f Makefile config.status config.cache config.log
Host:# ./configure --host=mips-linux-gnu --target=mips-linux-gnu CC="mips-linux-gnu-gcc -EL"
configure: warning: CC=mips-linux-gnu-gcc -EL: invalid host type
creating cache ./config.cache
checking for gcc... gcc
checking whether we are using GNU C... yes
checking whether gcc accepts -g... yes
checking for ranlib... ranlib
checking for a BSD compatible install... /usr/bin/install -c
checking how to run the C preprocessor... gcc -E
checking for string.h... yes
checking for unistd.h... yes
checking whether cross-compiling... no
checking for ANSI C header files... yes
updating cache ./config.cache
creating ./config.status
creating Makefile
Host:# make CC="mips-linux-gnu-gcc -EL"
mips-linux-gnu-gcc -EL -c -DHAVE_STRING_H=1 -DHAVE_UNISTD_H=1 -DSTDC_HEADERS=1
-DTERMCAP_FILE=\"/etc/termcap\" -I. -I. -g termcap.c
mips-linux-gnu-gcc -EL -c -DHAVE_STRING_H=1 -DHAVE_UNISTD_H=1 -DSTDC_HEADERS=1
-DTERMCAP_FILE=\"/etc/termcap\" -I. -I. -g tparam.c
mips-linux-gnu-gcc -EL -c -DHAVE_STRING_H=1 -DHAVE_UNISTD_H=1 -DSTDC_HEADERS=1
-DTERMCAP_FILE=\"/etc/termcap\" -I. -I. -g version.c
ar rc libtermcap.a termcap.o tparam.o version.o
ranlib libtermcap.a
Host:# file termcap.o
termcap.o: ELF 32-bit LSB relocatable, MIPS, MIPS32 rel2 version 1 (SYSV), not stripped
Host:#
Well, we got our libtermcap.a now. Let us back to the cross compilation process of
GDB. In order to let the cross compiler can locate the exact location of our termcap
library, let us define it in explicit way.
Host:# make distclean
Host:# ./configure --host=mips-linux-gnu --target=mips-linux-gnu CC="mips-linux-gnu-gcc -EL"
--with-libtermcap="$PWD"
Host:# make
However, after a while, we still get the same error. It seems the explicit definition
of termcap library didn't work properly. Let's us get to the respective configuration
file and do the explicit definition of termcap library again.
Host:# find . -type f -name "configure" -exec grep -il "no termcap library found" {} \;
./gdb/configure
Host:# cd gdb
Host:# ./configure --host=mips-linux-gnu --target=mips-linux-gnu CC="mips-linux-gnu-gcc -EL"
--with-libtermcap="/home/smp383/mips-4.3/bin/gdb-7.1"
Unfortunately, the error still there... It seems the problem can't be solved in graceful
way. So, we should consider to modify the configuration file directly. Let's start now.
Host:# nano configure
Well, the string "no termcap library found" is at line 8714. After some reading on
that portion of codes, it seems the variable "ac_cv_search_tgetent" needs to be
defined. At line 8644, it is defined as "../libtermcap/libtermcap.a". But, it seems
line 8644 will not getting executed in the case statement. Hence, we should hard
define it at the outer section of the case statement. So, let us put a new line of
"ac_cv_search_tgetent="../libtermcap.a" at line 8638. Therefore, from line 8635 to
line 8645 of the configuration file should look something similar to this.
# Since GDB uses Readline, we need termcap functionality. In many
# cases this will be provided by the curses library, but some systems
# have a seperate termcap library, or no curses library at all.
ac_cv_search_tgetent="../libtermcap.a"
case $host_os in
cygwin*)
if test -d $srcdir/libtermcap; then
LIBS="../libtermcap/libtermcap.a $LIBS"
ac_cv_search_tgetent="../libtermcap/libtermcap.a"
fi ;;
Fine, let us start the make process again.
Host:# make
...
...
make[4]: Leaving directory `/home/smp383/mips-4.3/bin/gdb-7.1/gdb/gdbserver'
make[3]: Leaving directory `/home/smp383/mips-4.3/bin/gdb-7.1/gdb'
make[2]: Leaving directory `/home/smp383/mips-4.3/bin/gdb-7.1/gdb'
make[1]: Nothing to be done for `all-target'.
make[1]: Leaving directory `/home/smp383/mips-4.3/bin/gdb-7.1'
Host:#
Excellent, the cross compilation process has been completed. Let's check the generated
binary is MIPS compatible or not.
Host:# cd gdb
Host:# file gdb
gdb: ELF 32-bit LSB executable, MIPS, MIPS32 rel2 version 1, for GNU/Linux 2.6.12,
dynamically linked (uses shared libs), not stripped
Host:#
It seems everything so far is fine. Let us test it in MIPS environment.
tango3[gdb-7.1]# cd gdb
tango3[gdb]# ./gdb
GNU gdb (GDB) 7.1
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "mips-linux-gnu".
For bug reporting instructions, please see:
Setting up the environment for debugging gdb.
No symbol table is loaded. Use the "file" command.
Make breakpoint pending on future shared library load? (y or [n])
[answered N; input not from terminal]
No symbol table is loaded. Use the "file" command.
Make breakpoint pending on future shared library load? (y or [n])
[answered N; input not from terminal]
/root/cawan/mips-4.3/bin/gdb-7.1/gdb/.gdbinit:8: Error in sourced command file:
No breakpoint number 0.
(gdb)
Excellent, the GDB version 7.1 is successfully running in our MIPS platform now.
pdf version:
http://www.scribd.com/doc/114002450/How-to-Cross-Compile-GDB-and-Run-in-Embedded-System
Hi,
ReplyDeleteTried cross compiling gdb 7.6 but I'm stuck at libtermcap.
I'm unable to find the case statement you mentioned here.
Hello,
ReplyDeleteI have the same libtermcap problem...
I ran into the same problem but it was my mistake i was not reading correctly the configure file is not the configure file in the main directory it is the one inside GDB directory.
ReplyDeleteThanks
Hi,
ReplyDeleteThank you for the good work, however concerning the termcap library, it is much easier and more cleaner to tell the configure script options for the linker. So you can simply specify the flag "CFLAGS" in the configuration by adding this:
CFLAGS="-L -ltermcap" for the result:
./configure --host=arm-926ejs-linux-gnueabi --target=arm-926ejs-linux-gnueabi CC=arm-926ejs-linux-gnueabi-gcc --with-libtermcap=/home/hilt0n/devel/sysapps/source/termcap-1.3.1 CFLAGS="-L/home/hilt0n/devel/sysapps/source/termcap-1.3.1 -ltermcap"
With that, there is no need to modify the configure script.
Some part with html balise have disappeared:
ReplyDeleteCFLAGS="-L[path to libtermcap directory] -ltermcap"
I believe that LDFLAGS would be better. From the help
ReplyDeleteLDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory
so
LDFLAGS=-L
Just did this for my build and it worked.