0%

交叉编译gdb

项目需要,交叉编译本地版gdb 6.5

预读

首先明确configure的三个参数:

–build : 运行交叉编译器的环境

–host : 编译出的可执行文件的执行环境

–target : 编译出的可执行文件执行后能产生的文件的执行环境

所有值默认都等于–build,–build默认为本机环境,–target默认为–host

比如 在gcc源码目录:

$ ./configure CC=arm-linux-gcc –build=i686-pc-linux –host=arm-linux –target=mips

在intel pc上编译产生arm上运行的gcc,在arm平台运用产生的gcc编译mips上执行的程序

0. 嵌入式应用gdb调试

嵌入式应用gdb调试主要有两种方法:

PC端调试

这是主流方法,进入gdb目录,交叉编译时./configure 重要参数

--build=i686-pc-linux
--host=i686-pc-linux
--target=arm-linux

交叉编译产生的arm-linux-gdb在PC端运行

进入gdbserver目录,交叉编译./configure 时重要参数:

--build=i686-pc-linux
--host=arm-linux
--target=arm-linux

交叉编译产生的gdbserver放在arm设备上

过程:调试时,arm设备上打开gdbserver,附加至应用程序进程,在PC端通过arm-linux-gdb设置端口连接gdbserver调试。整个过程两者间通信类似于CS架构通信

arm-linux-gdb功能有限,一般可采用PC端的gdb代替之进行调试;另外PC和设备之间需要至少一种方式通信,串口与网络皆可,关于gdbserver通过串口调试方法,可自行搜索;由于作者所用设备只能通过串口调试,且串口有其他调试信息输出,故不采用此方式。

设备本地gdb调试

交叉编译时./configure 的重要参数

CC=arm-linux-gcc
--build=i686-pc-linux
--host=arm-linux
--target=arm-linux

过程:交叉编译产生arm设备上运行的gdb,直接在arm设备上运行gdb,调试应用程序。

本文主要讨论此种方法。

1. 交叉编译本地版gdb

交叉编译gdb时,与PC端的arm-linux-gcc的版本是相关的,过低版本的arm-linux-gcc不能交叉编译版本太高的gdb,本机的编译环境如下:

arm-linux-gcc:4.3.2 
gdb-src :6.5 
libncurses :5.6
arm-linux : 2.6.34

下载:

gdb 6.5a

ncurses

由于gdb依赖于termcap库,现在这个库可以通过ncurses来代替,所以先交叉编译产生libncurses,我选择的5.6版本

交叉编译ncurses

解压

$ tar zxvf ncurses-5.6.tar.gz
$ cd ncurses-5.6 

配置环境

$ CC=arm-linux-gcc ./configure --build=i686-pc-linux --host=arm-linux  --prefix=$HOME/arm/ncurses --without-ada --enable-termcap --with-shared

以上产生Makefile,其中./configure 参数含义:

CC=arm-linux-gcc 使用arm-linux-gcc交叉编译器

–prefix=$HOME/arm/ncurses 将生成ncurses的相关文件安装在$HOME/arm/ncurses目录下

–without-ada 不编译ada库

–enable-termcap 支持termcap,这个很重要

–with-shared 以动态库形式封装libncurses

make

$ make

make install

$ make install

然后在$HOME/arm/ncurses看到如下文件:

ncurses/
 ├── bin
 │   ├── captoinfo -> tic
 │   ├── clear
 │   ├── infocmp
 │   ├── infotocap -> tic
 │   ├── ncurses5-config
 │   ├── reset -> tset
 │   ├── tack
 │   ├── tic
 │   ├── toe
 │   ├── tput
 │   └── tset
 ├── include
 │   └── ncurses
 ├── lib
 │   ├── libform.a
 │   ├── libform_g.a
 │   ├── libform.so -> libform.so.5
 │   ├── libform.so.5 -> libform.so.5.6
 │   ├── libform.so.5.6
 │   ├── libmenu.a
 │   ├── libmenu_g.a
 │   ├── libmenu.so -> libmenu.so.5
 │   ├── libmenu.so.5 -> libmenu.so.5.6
 │   ├── libmenu.so.5.6
 │   ├── libncurses.a
 │   ├── libncurses++.a
 │   ├── libncurses_g.a
 │   ├── libncurses.so -> libncurses.so.5
 │   ├── libncurses.so.5 -> libncurses.so.5.6
 │   ├── libncurses.so.5.6
 │   ├── libpanel.a
 │   ├── libpanel_g.a
 │   ├── libpanel.so -> libpanel.so.5
 │   ├── libpanel.so.5 -> libpanel.so.5.6
 │   ├── libpanel.so.5.6
 │   └── terminfo -> ../share/terminfo
 ├── man
 │   ├── man1
 │   ├── man3
 │   ├── man5
 │   └── man7
 └── share
     ├── tabset
     └── terminfo

编译gdb

./configure

$ CC='arm-linux-gcc'  LDFLAGS=-L$HOME/arm/ncurses/lib CPPFLAGS=-I$HOME/arm/ncurses/include ./configure  --build=i686-pc-linux  --host=arm-linux --target=arm-linux --enable-shared --prefix=$HOME/arm/gdb --without-x --disable-gdbtk --disable-tui

参数含义:

libncurses 路径

LDFLAGS=-L$HOME/arm/ncurses/lib 

CPPFLAGS=-I$HOME/arm/ncurses/include

–enable-shared 动态编译

–prefix=$HOME/arm/gdb 安装目录

–without-x 取消x windows 支持

–disable-gdbtk 取消gdbtk,应该也是图形界面相关的

–disable-tui 取消tui 界面

这点要说明一下,CC LDFLAGS CPPFLAGS这些编译参数本是放到./configure后的,但是当我放到./configure后提示错误:configure: error: can only configure for one host and one target at a time ,应该是configure的nonopt变量设置问题,我只好放到了前面,其实到后面会发现其是不起作用的。

以上生成Makefile

make

$ make

然后出现几个问题;

  • no termcap library found

明明添加了ncurses的库路径为什么不行?它既然是找libtermcap,给它在$HOME/arm/ncurses/lib下建个指向libncurses.so的软连接

$ ln -s $HOME/arm/ncurses/lib/libncurses.so $HOME/arm/ncurses/lib/libtermcap.so

结果仍然提示上述错误。

这应该是configure时配置的FLAGS不起作用;

因此将上面的make修正为

$ make LDFLAGS=-L$HOME/arm/ncurses/lib CPPFLAGS=-I$HOME/arm/ncurses/include

编译顺利进行

  • gdb/gdb_curses.h头文件错误

将代码修改为如下:

    #if defined (HAVE_NCURSES_H)
    #include 
    #elif defined (HAVE_CURSESX_H)
    #include 
    #elif defined (HAVE_CURSES_H)
    #include 
    #endif
    
    #if defined (HAVE_TERM_H)
    #include 
    #else
    /* On MinGW, a real termcap library is usually not present.  Stub versions
       of the termcap functions will be built from win32-termcap.c.  Readline
       provides its own extern declarations when there's no termcap.h; do the
       same here for the termcap functions used in GDB.  */
    extern int tgetnum (const char *);
    #endif

编译通过

make install

$ make install

安装后在$HOME/arm/gdb目录下会看到bin等目录,其下有 gdb gdbserver run三个文件,表示安装成功。

刚生成的gdb有10M左右,嵌入式设备Flash不大,可以将其strip下,减下肥

$ arm-linux-strip gdb

此时gdb只有2M多了

放置gdb

将$HOME/arm/gdb/bin/gdb 拷贝至设备/usr/bin目录,将$HOME/arm/ncurses/libncurse.so,libtermcap.so拷贝至设备/usr/lib目录即可

< 完 >

坚持原创技术分享,您的支持将鼓励我继续创作!

Welcome to my other publishing channels