如何编译可以在Windows下运行的带有Python支持的ARM Linux GDB

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何编译可以在Windows下运行的带有Python支持的ARM Linux GDB相关的知识,希望对你有一定的参考价值。

参考技术A 做这件事情的目的是为了在QtCreator里调试ARM Linux程序的时候,能看清楚QString、QList这些Qt特有的对象的内容,而不是一个完全看不懂的结构体。
目前(2014年8月)Linaro、CodeSourcery的GCC工具链里的GDB都不支持Python。想知道你用的GDB支持不支持,试一试就行,这样表示不支持:
(gdb) python
>print 'Hello GDB!'
>(按Ctrl+D)Python scripting is not supported in this copy of GDB.
这样表示支持:
(gdb) python
>print 'Hello GDB!'
>(按Ctrl+D)Hello GDB!
这件事情乍一看也很简单,只要把GDB源码下载下来,然后再配置,打开Python支持就行了。实际上会遇到的问题是,在MinGW下,又要与“\”和“:”这两个Windows路径里的刺头斗争了。我觉得我之前挺傻,编译MinGW下Qt的时候,就去硬磕源码和configure脚本去了。这次GDB的configure是自动生成的,不是给人看的,configure.ac看起来也很费劲,根本磕不下去,于是我换了个思路,在ubuntu下交叉编译吧,sudo apt-get install mingw32,这是Ubuntu下的MinGW交叉编译器。
然后是依赖,这样的GDB要依赖expat和python的开发版本。如果是ubuntu底下直接编译,apt-cache search一下他们的开发版本,然后sudo apt-get install一下就好了;给MinGW交叉编译就麻烦了。先说expat,这个好办,把http://downloads.sourceforge.net/project/expat/expat/2.1.0/expat-2.1.0.tar.gz下载下来,然后:
./configure --prefix=[安装目录,如/home/cdu/mingw-gdb/expat] --host=i586-mingw32msvc
make
make install
会提示一些警告,无视即可。
Python就无语了,目前的GDB貌似最高支持Python 2.7,而2.7版本的Python本身不支持MinGW…… 好在有高手做了Patch,也写了说明,可以参考这文章:http://mdqinc.com/blog/2011/10/cross-compiling-python-for-windows-with-mingw32/
但是,就算这样,编译也充满挑战,要修复很多问题,出来的Python还少“nt”模块。就在我觉得没办法的时候,突然发现Windows版Qt提供的MinGW居然内置了Python开发包,位置在Tools/mingw48_32/opt,赶紧把它拷贝到Linux下,比如/home/cdu/mingw-gdb/python。当然,你也必须确保ubuntu下有可用的python。
然后,给GDB打一个补丁:
--- gdb-7.8/gdb/configure 2014-07-29 20:37:42.000000000 +0800
+++ gdb-7.8-old/gdb/configure 2014-08-30 00:08:27.122042706 +0800
@@ -8263,21 +8263,22 @@
# 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_config_tool=`echo $python_prog | sed "s#python.exe#python-config#g"`
+ python_includes=`$python_config_tool --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_config_tool --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_config_tool --exec-prefix`
if test $? != 0; then
have_python_config=failed
if test "$with_python" != auto; then
@@ -8343,12 +8344,12 @@
return 0;

_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+#if ac_fn_c_try_link "$LINENO"; then :
have_libpython=$version
found_usable_python=yes
PYTHON_CPPFLAGS=$new_CPPFLAGS
PYTHON_LIBS=$new_LIBS
-fi
+#fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
CPPFLAGS=$save_CPPFLAGS
这个补丁的目的是强制为检测到python。
然后给拷贝到Linux下的python开发包打一个补丁:
--- python-old/bin/python-config 2013-04-18 02:43:01.000000000 +0800
+++ python/bin/python-config 2014-08-30 00:53:16.630060288 +0800
@@ -1,4 +1,4 @@
-#!/temp/x32-480-posix-dwarf-r2/mingw32/opt/bin/python2.7.exe
+#!/usr/bin/python

import sys
import os
@@ -31,26 +31,23 @@

for opt in opt_flags:
if opt == '--prefix':
- print sysconfig.PREFIX
+ print '../python'

elif opt == '--exec-prefix':
- print sysconfig.EXEC_PREFIX
+ print '../python'

elif opt in ('--includes', '--cflags'):
- flags = ['-I' + sysconfig.get_python_inc(),
- '-I' + sysconfig.get_python_inc(plat_specific=True)]
+ flags = ['-I' + os.path.split(os.path.realpath(__file__))[0] + '/../include/python2.7']
if opt == '--cflags':
- flags.extend(getvar('CFLAGS').split())
+ flags += ['-fno-strict-aliasing -DMS_WIN32 -DMS_WINDOWS -DHAVE_USABLE_WCHAR_T -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes']
print ' '.join(flags)

elif opt in ('--libs', '--ldflags'):
- libs = getvar('LIBS').split() + getvar('SYSLIBS').split()
- libs.append('-lpython'+pyver)
+ libs = ['-lm -lpython2.7 -Wl,--out-implib=libpython2.7.dll.a']
# add the prefix/lib/pythonX.Y/config dir, but only if there is no
# shared library in prefix/lib/.
if opt == '--ldflags':
if not getvar('Py_ENABLE_SHARED'):
- libs.insert(0, '-L' + getvar('LIBPL'))
- libs.extend(getvar('LINKFORSHARED').split())
+ libs.insert(0, '-L' + os.path.split(os.path.realpath(__file__))[0] + '/../lib/python2.7/config')
print ' '.join(libs)

因为Linux下是无法运行开发包中的python.exe的,所以这个补丁借用了ubuntu的python。里面的cflags和ldflags都是在Windows底下运行原始python-config获得的。prefix和exec-prefix设成“../python”,可以在编译完以后,把python开发包拷贝到gdb安装目录里面的python子目录,这样运行GDB的时候就不需要设定PYTHONHOME环境变量了。
最后一个事情,确保你的Linux下有arm交叉编译器,我的是arm-linux-gnueabihf,是啥target就写啥。
准备工作做完了,开始配置和编译:
./configure --with-expat --host=i586-mingw32msvc --target=arm-linux-gnueabihf --with-libexpat-prefix=[expat安装位置] --with-python=[python开发包安装位置/bin/python.exe]
make
make DESTDIR=[GDB安装位置] install
然后把GDB安装位置下面的所有文件拷贝到Windows下,再把python开发包拷贝到同目录下的python子目录,大功告成。
如果提示没找到libpython2.7.dll,那就把GDB安装目录的python/bin下的拷贝到bin下。
如果发现生成的exe文件太大了,那就strip一下。
2015年9月12日追加:
在windows下调试时,一般会提示说加载不了共享库,让你用"set sysroot"或"set solib-search-path"之类设定路径的。这个问题可以通过.gdbinit文件,用上面这两条命令来设定路径解决,如果想一劳永逸,可以在编译的时候加上host_configargs环境变量来解决这个问题:
host_configargs=--with-sysroot=E:\MinGW\opt\sysroot-arm ./configure ...
或者
export host_configargs=--with-sysroot=E:\MinGW\opt\sysroot-arm
./configure ...

后面的路径是你放在windows下的sysroot的位置。

如何在 Windows 下编译 OpenSSL

解压缩OpenSSL包,在对它进行修改便可以编译了。在解压缩后,所有的源代码放在openssl- 1.0.1e目录下,在此目录下,有两个文件INSTALL.W32, INSTALL.W64需要被关注。打开其中的任何一个文件,你会看到如何编译OpenSSL的各个步骤。
1)打开VS Studio命令行工具,如图1所示。若编译64位OpenSSL库,请打开Visual Studio x64 Win64 Command Prompt,反之亦然。
2)配置编译文件及安装目录;
编译Win32:perl Configure VC-WIN32 --prefix=c:\\some\\openssl\\dir
编译Win64:perl Configure VC-WIN64A
“c:\\some\\openssl\\dir”目录可以改成任何你希望的安装目录
3)搭建编译环境:
ms\\do_nasm
ms\\do_ms
对于64位编译,将ms\\do_ms替换成ms\\do_win64a
4)编译OpenSSL
nmake -f ms\\ntdll.mak
5)安装编译生成的库到“c:\\some\\openssl\\dir”
nmake -f ms\\ntdll.mak install
参考技术A 1、使用VS2005下的Visual Studio 2005 Command Prompt进入控制台模式(这个模式会自动设置各种环境变量)
2、解压缩openssl的包,进入openssl的目录
3、perl configure VC-WIN32
尽量在这个目录下执行该命令,否则找不到Configure文件,或者指定完整的Configure文件路径。
4、ms\do_ms
在解压目录下执行ms\do_ms命令
5、nmake -f ms\ntdll.mak编译后在openssl解压目录下执行,完成编译后。输出的文件在out32dll里面,包括应用程序的可执行文件、lib文件和dll文件
注意:在运行第五步时,cl编译器会抱怨说.\crypto\des\enc_read.c文件的read是The POSIX name for this item is deprecated(不被推荐的),建议使用_read。呵呵,我可不想将OpenSSL中的所有的read函数修改为_read。再看cl的错误代码 error C2220,于是上MSDN上查找:
warning treated as error - no object file generated
/WX tells the compiler to treat all warnings as errors. Since an error occurred, no object or executable file was generated.
是由于设置了/WX选项,将所有的警告都作为错误对待,所以。。。
于是打开OpenSSL目录下的MS目录下的ntdll.mak文件,将CFLAG的/WX选项去掉,存盘。。

以上是关于如何编译可以在Windows下运行的带有Python支持的ARM Linux GDB的主要内容,如果未能解决你的问题,请参考以下文章

Python的下载和安装

《head first python》windows环境下,如何解决sudo不是内部命令问题。

如何在 Windows 下编译 OpenSSL

如何在Windows系统中设置Python程序定时运行

c语言在windows下如何取得机器名

如何将 Windows 中的 CodeBlocks MingW 编译到 Ubuntu 或 Centos