diab和gnu交叉使用问题

diab和gnu交叉使用问题

从周一1225下午,到现在周四1228上午,主要和笑哥解决一个现场移植问题,这个问题的产生很少见。我们知道一般开发一套程序,用于构建的工具链一般是同一套,你要么使用微软自己的ICC,要么使用vxworks下独有的diab,又或者使用开源的gnu工具链。此次的问题在于,我司提供给客户基于gnu的操作系统和开发环境,目的就是让客户基于我们的开发环境来编译构建运行在我司deltaos操作系统下的应用程序以及库。然而,客户一直在vxworks下的开发环境windriver下开发,使用的工具链则是diab。现在呢,他们想要在deltaos上跑一个dkm.out程序,但他们却是直接使用在windriver下构建好了的程序,却没有经过移到deltaos下的开发环境下进行编译。不知道为什么要这样做!但显然带来了一个根本问题:用diab编译出来的out文件,可以在使用gnu编译的deltaos下运行吗?
实际情况是:dkm.out文件在下载运行时,会二次链接生成elf文件。而在生成的过程中报错了:有很多未定义但引用了的符号。
现在就开始解决!
我们首先想的是把dkm项目重新用deltaos-IDE构建,但它链接的ticon库(ticon,类似于qtGui的图形库,比windml更高层一点,因其小巧常用在嵌入式中)仍使用他们给的使用diab编译的库。 (为什么ticon库不用deltaos-IDE重新编译,询问他们得知用gnu编译的ticon库不稳定。但我认为,既然是移植,为什么不把所有的源码都用deltaos-IDE编译一遍呢?)
这样来的话,就报了一个错误,生成ctdt.c文件的时候,报了diab和gnu不兼容的错误。我不是很清楚ctdt.c文件的作用,解决的方法也比较粗暴,就是把报错的地方屏蔽了。因为我看之前辉姐有这么尝试过。屏蔽后,该问题不出现。
但是,又爆了另外一个错误:ticon库里面有了多重定义。我们使用链接参数--allow-multiple-definition解决了此问题,就是说如果出现了多重定义,那么连接的时候,我只需链接第一个找到的接口就行了。
至此,dkm.out在deltaos-IDE中生成成功。但注意:链接的ticon库仍使用他们给的使用diab编译的库。因此,我们把它放到deltaos下运行,但仍然报了有很多未定义但引用了的符号的问题。
我们假设diab和gnu编出来的中间文件是可以兼容并生成可执行文件的,报错很多未定义但引用了的符号,是因为我们的deltaos里面没有,而vxworks有的原因。那么现在的问题也就清晰了些,找到未定义引用的符号到底在哪里!
我们一直在找,最开始我们尝试对这些未定义引用的符号在vx6.9的source insight里面搜索,但是发现它们是c++符号,而c++符号编译器为了保证符号唯一性,对c++符号做了处理,导致和源码完全没法对应上。后面我们发现了一个工具c++filt,但不好用。而后又发现nm工具,发现只要在他后面加上参数—demangle,就可以看到他在源码里面的符号,因此我们分别使用:nm -n vxworks和 nm -n --demangle vxworks,从而得到了未定义引用符号和其匹配的源码符号。
但现在问题又来了,即使找到了可匹配的源码符号,但是我们在vx6.9里面很多都根本搜不到啊!最后发现在客户给我们的partialImage.o里面有,但我们并不知partialImage.o有什么用!只知道他是用于生成ctdt.c的。我想尝试分析构建信息,知道partialImage.o是通过哪些库和文件生成的,但问题是客户给我们的项目在vx6.9一直构建不成功。
静下心,好好想想一个符号可能来自哪些地方?
从底层来讲,程序要运行,所有的符号都应该映射到内存的某个地址。
从应用程序来讲,他可能存在于驻留于内存的几个程序或者动态库中。那dkm找不到的符号,肯定没在dkm中,而驻留在内存的只有dkm和vxworks,或者dkm和deltaos。很显然,这些未定义引用符号,vxworks有,而deltaos没有。vxworks由什么组成:项目本身源码,bsp,以及各种各样的库,亦或者是内建函数?通过搜索项目和bsp,没有,排除掉!再搜索vx6.9源码,也没有。奇了怪了!
好吧,不管了,至少partialImage.o里面有。最后,决定简单粗暴地把partialImage.o链接到deltaos里面去,然后修改了一系列编译链接错了,最终生成了deltaos.elf文件,但这个操作系统没法跑起来,解决失败。
似乎走进了死胡同,但还好又发现了一个问题,有可能客户所说的他们用的是vx6.9是错的。该项目可能需要用vx6.8编译。因为之前把该项目导入vx6.9时曾报过提示警告,但是当时没有注意,现在想来,可能客户说错了。对,至少我们应该用vx6.8编译该vxworks项目来试一下。如果能编译成功,我们就能看到partialImage.o的构建信息,更重要的是,也许vx6.8源码里,就能找到那些未定义引用的符号了呢?
事实证明,客户用的是vx6.8,所有的符号都在vx6.8里面找到了,通过vxworks链接的库,我们也知道了这些未定义符号存在于哪些库中,并链接了这些库到deltaos中,对于还是找不到符号的,我们还在symtbl.c中添加。
最后,客户同意并把ticon的库用gnu工具链重新编译了一下。然后就过了。。。。
这说明,不同工具链间交叉使用还是存在问题,主要是你连接的库都不一样,还有语法规则。特别是C++,对工具链的相关性更为明显。
反思:
其实在此次解决问题的过程中,我们大多是通过构建信息,运行错误,以及elf的反汇编来得到信息。但因为对elf格式不熟悉,以及binutils工具不熟悉,导致花费了些时间,这是我需要加强的地方。
如果你想快速解决一个问题,那么你至少应该具有快速分析及整合已有信息的能力,并找到突破口,步步为营,按逻辑思考,才可慢慢接近真相。

你可能感兴趣的:(diab和gnu交叉使用问题)