1,编译环境:(使用的是大家公用的服务器,为了不影响其他人的编译环境,所以后续自己安装工具的路径都是自己用户下的目录,并设置自己用户的PATH)
Ubuntu 12.04.5 LTS (GNU/Linux 3.13.0-32-generic x86_64)
gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
GNU Make 3.81
arm-none-linux-gnueabi-gcc (Sourcery CodeBench Lite 2014.05-29) 4.8.3 20140320 (prerelease)
2,gdb源代码:
可以去gun上下载,http://www.gnu.org/prep/ftp.html里面列出了下载的镜像站点,我们可以找一个国内的下载,比如https://mirrors.ustc.edu.cn/gnu/,gdb就在https://mirrors.ustc.edu.cn/gnu/gdb/,从列表里可以找到,我下载了目前最新版gdb-8.2.tar.gz这个版本。
3,编译gdb:
hanqiang@ubuntu:~/tools/src$ tar zxf gdb-8.2.tar.gz
hanqiang@ubuntu:~/tools/src$ cd gdb-8.2/
hanqiang@ubuntu:~/tools/src/gdb-8.2$ mkdir build
hanqiang@ubuntu:~/tools/src/gdb-8.2$ cd build/
hanqiang@ubuntu:~/tools/src/gdb-8.2/build$ ../configure --prefix=/home/sysapp/hanqiang/tools/gdb --target=arm-linux
hanqiang@ubuntu:~/tools/src/gdb-8.2/build$ make -j32
出现以下错误
configure: error: *** A compiler with support for C++11 language features is required.
gcc版本不支持 C++11,需要使用一个更高的gcc版本
于是去gun上下载一个高版本并编译安装,安装方法参考linux下gcc-6.5编译安装
hanqiang@ubuntu:~/tools/src/gdb-8.2/build$ make -j32
出现以下错误
/home/sysapp/hanqiang/tools/gcc/lib/gcc/x86_64-pc-linux-gnu/6.5.0/../../../../lib64/libstdc++.a(chrono.o): In function `std::chrono::_V2::system_clock::now()':
/home/sysapp/hanqiang/tools/src/gcc-6.5.0/build/x86_64-pc-linux-gnu/libstdc++-v3/src/c++11/../../../../../libstdc++-v3/src/c++11/chrono.cc:62: undefined reference to `clock_gettime'
/home/sysapp/hanqiang/tools/gcc/lib/gcc/x86_64-pc-linux-gnu/6.5.0/../../../../lib64/libstdc++.a(chrono.o): In function `std::chrono::_V2::steady_clock::now()':
/home/sysapp/hanqiang/tools/src/gcc-6.5.0/build/x86_64-pc-linux-gnu/libstdc++-v3/src/c++11/../../../../../libstdc++-v3/src/c++11/chrono.cc:90: undefined reference to `clock_gettime'
collect2: error: ld returned 1 exit status
hanqiang@ubuntu:~/tools/src/gdb-8.2/build$ make -j32 LDFLAGS=-lrt
hanqiang@ubuntu:~/tools/src/gdb-8.2/build$ make install
出现以下错误
/home/sysapp/hanqiang/tools/src/gdb-8.2/missing: line 81: makeinfo: command not found
到gun上下载一个texinfo,然后编译一下,把编译出来的bin目录加到PATH最后面就行,编译方法也简单,configure --prefix=安装路径;make;make install
hanqiang@ubuntu:~/tools/src/gdb-8.2/build$ make install
4,编译gdbserver(我的目的是编译在Android上运行的arm-linux-gdbserver)
hanqiang@ubuntu:~/tools/src/gdb-8.2/build$ cd ..
hanqiang@ubuntu:~/tools/src/gdb-8.2$ cd gdb/gdbserver/
hanqiang@ubuntu:~/tools/src/gdb-8.2/gdb/gdbserver$ mkdir build
hanqiang@ubuntu:~/tools/src/gdb-8.2/gdb/gdbserver$ cd build/
hanqiang@ubuntu:~/tools/src/gdb-8.2/gdb/gdbserver/build$ ../configure --prefix=/home/sysapp/hanqiang/tools/gdb --host=arm-linux --target=arm-linux
hanqiang@ubuntu:~/tools/src/gdb-8.2/gdb/gdbserver/build$ make CC=arm-none-linux-gnueabi-gcc CXX=arm-none-linux-gnueabi-g++ CXXFLAGS=-static
(说明一下:
我是编译要在android中运行的,所以加了CXXFLAGS=-static,后面还会详细说明)
出现以下错误
arm-none-linux-gnueabi-g++: error: unrecognized command line option '-Wsuggest-override'
arm-none-linux-gnueabi-g++: error: unrecognized command line option '-Wduplicated-cond'
打开gdb-8.2/gdb/gdbserver/build/Makefile文件,搜索-Wsuggest-override和-Wduplicated-cond,发现它们都在WARN_CFLAGS = 那里的,把这两个参数删掉
hanqiang@ubuntu:~/tools/src/gdb-8.2/gdb/gdbserver/build$ make CC=arm-none-linux-gnueabi-gcc CXX=arm-none-linux-gnueabi-g++ CXXFLAGS=-static
出现以下错误
/home/sysapp/hanqiang/tools/arm-2014.05/arm-none-linux-gnueabi/include/c++/4.8.3/bits/c++0x_warning.h:32:2: error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support is currently experimental, and must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
提示需要加参数 -std=c++11
hanqiang@ubuntu:~/tools/src/gdb-8.2/gdb/gdbserver/build$ make CC=arm-none-linux-gnueabi-gcc CXX=arm-none-linux-gnueabi-g++ CXXFLAGS="-static -std=c++11"
出现以下错误
../linux-arm-low.c:130:21: fatal error: sys/reg.h: No such file or directory
#include <sys/reg.h>
打开gdb-8.2/gdb/gdbserver/build/config.h文件,搜索HAVE_SYS_REG_H,在这行前面加//注释掉这行
hanqiang@ubuntu:~/tools/src/gdb-8.2/gdb/gdbserver/build$ make CC=arm-none-linux-gnueabi-gcc CXX=arm-none-linux-gnueabi-g++ CXXFLAGS="-static -std=c++11"
hanqiang@ubuntu:~/tools/src/gdb-8.2/gdb/gdbserver/build$ make install
5,其他说明
1)我们编译的是8.2版本的,编译命令make CC=arm-none-linux-gnueabi-gcc CXX=arm-none-linux-gnueabi-g++ CXXFLAGS="-static -std=c++11"中注意要加CXX=arm-none-linux-gnueabi-g++ CXXFLAGS=,开始我只用的make CC=arm-none-linux-gnueabi-gcc这个命令,会报以下错误
In file included from ../../common/common-defs.h:90:0,
from ../server.h:22,
from ../linux-arm-low.c:19:
../linux-arm-low.c: In function ‘CORE_ADDR arm_sigreturn_next_pc(regcache*, int, int*)’:
../linux-arm-low.c:782:29: error: ‘__NR_sigreturn’ was not declared in this scope
gdb_assert (svc_number == __NR_sigreturn || svc_number == __NR_rt_sigreturn);
^
../../common/gdb_assert.h:33:13: note: in definition of macro ‘gdb_assert’
((void) ((expr) ? 0 : \
^~~~
../linux-arm-low.c: In function ‘CORE_ADDR get_next_pcs_syscall_next_pc(arm_get_next_pcs*)’:
../linux-arm-low.c:836:21: error: ‘__NR_sigreturn’ was not declared in this scope
if (svc_number == __NR_sigreturn || svc_number == __NR_rt_sigreturn)
^~~~~~~~~~~~~~
make: *** [linux-arm-low.o] Error 1
看编译工具下/home/sysapp/hanqiang/tools/arm-2014.05/arm-none-linux-gnueabi/libc/usr/include/asm/unistd.h也有__NR_sigreturn的定义,为什么找不到呢,后来留意到编译命令CXX linux-arm-low.o使用的是CXX,而不是CC,所以增加了CXX=arm-none-linux-gnueabi-g++之后就可以了,另外,需要注意,既然使用的是CXX,那就需要改CXXFLAGS,而不是CFLAGS,但是CC=arm-none-linux-gnueabi-gcc也必须保留,删掉也会编译不了
2)由于我的目的是编译在Android上运行的arm-linux-gdbserver,可以通过file查看一下gdbserver的属性,应该是statically linked才好。
hanqiang@ubuntu:~/tools/src/gdb-8.2/gdb/gdbserver/build$ file gdbserver
gdbserver: ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, for GNU/Linux 2.6.16, not stripped
可以看到是statically linked,说明是好的。
如果还想进一步确认一下,可以使用下面不加-static的命令编译试一下
hanqiang@ubuntu:~/tools/src/gdb-8.2/gdb/gdbserver/build$ make clean
hanqiang@ubuntu:~/tools/src/gdb-8.2/gdb/gdbserver/build$ make CC=arm-none-linux-gnueabi-gcc CXX=arm-none-linux-gnueabi-g++ CXXFLAGS="-std=c++11"
再看属性
hanqiang@ubuntu:~/tools/src/gdb-8.2/gdb/gdbserver/build$ file gdbserver
gdbserver: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.16, not stripped
可以看到是dynamically linked (uses shared libs)
hanqiang@ubuntu:~/tools/src/gdb-8.2/gdb/gdbserver/build$ readelf -a gdbserver | grep "\.so"
[Requesting program interpreter: /lib/ld-linux.so.3]
0x00000001 (NEEDED) Shared library: [libdl.so.2]
0x00000001 (NEEDED) Shared library: [libstdc++.so.6]
0x00000001 (NEEDED) Shared library: [libm.so.6]
0x00000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x00000001 (NEEDED) Shared library: [libc.so.6]
000000: Version: 1 File: libdl.so.2 Cnt: 1
0x0020: Version: 1 File: libgcc_s.so.1 Cnt: 1
0x0040: Version: 1 File: libstdc++.so.6 Cnt: 7
0x00c0: Version: 1 File: libc.so.6 Cnt: 3
它需要加载很多so,如果放到android中运行是无法运行的,会提示以下错误
/system/bin/sh: ./gdbserver: No such file or directory
实际不是找不到gdbserver,而是找不到它所依赖的so库文件
需要特别说明的是,如果交叉编译工具使用的是releases.linaro.org上的版本,即使使用的是-static参数,编译出来的仍然是动态链接的dynamically linked (uses shared libs),需要libdl.so.2,目前发现只能使用https://sourcery.mentor.com/GNUToolchain/package12813/public/arm-none-linux-gnueabi/arm-2014.05-29-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2版本的
3)最后,为了减小文件大小,可以strip一下
hanqiang@ubuntu:~/tools/gdb/bin$ file arm-linux-gdbserver
arm-linux-gdbserver: ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, for GNU/Linux 2.6.16, not stripped
hanqiang@ubuntu:~/tools/gdb/bin$ arm-none-linux-gnueabi-strip arm-linux-gdbserver
hanqiang@ubuntu:~/tools/gdb/bin$ file arm-linux-gdbserver
arm-linux-gdbserver: ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, for GNU/Linux 2.6.16, stripped
4)参考文章
http://blog.csdn.net/hejianhua/article/details/7254836
https://blog.csdn.net/chenbang110/article/details/7505907
https://blog.csdn.net/namecyf/article/details/7299413