编译ACE_TAO库的过程中遇到的一些问题+vxworks镜像组件定制+Relocation value does not fit in 26 bits解决办法

编译环境

  • 操作系统:windows7
  • 工具:ACE+TAO_2.0a版本源码、workbench_3.3、ARMARCH7diab编译器

编译过程中遇到的问题

  编译ACE_TAO库的方法我就不介绍了,在网上可以找到很多介绍。这里主要讲述我在编译过程遇到的一些问题以及解决办法,我遇到的问题主要有以下3个:
  1、编译错误;
  2、将编译后的库加载到vxworks_6.9镜像中时报”Relocation value does not fit in 26 bits”错误;
  3、将编译后的库加载到vxworks_6.9镜像中时有两个符号表找不到,分别是”log2”和”_d_ulltod”;

一、编译错误

  在编译过程中,一共遇到了7个error,有几个问题我没有找到正确的解决方法,目前只是让编译通过了,如果有人知道怎么解决,还请在评论中回复下,谢谢。下面就列举这7个错误:

  1、ACE_wrappers\ace\TSS_T.cpp文件第357行,所报错误为传入的参数过多,TSS_T.cpp中源代码如下图所示:
编译ACE_TAO库的过程中遇到的一些问题+vxworks镜像组件定制+Relocation value does not fit in 26 bits解决办法
可以看到在ACE_Thread::Keycreate()中传入了3个参数,而查找ACE_Thread::Keycreate()的声明发现该函数只有2个参数,在TSS_T.cpp中传入的第三个参数(void*)this是多余的,所以将(void*)this这个参数去掉即可。

  2、ACE_wrappers\ace\Message_Queue_Vx.inl文件第14行,所报错误为类型不匹配,源码如下:
编译ACE_TAO库的过程中遇到的一些问题+vxworks镜像组件定制+Relocation value does not fit in 26 bits解决办法
这里的问题是类型转换出错了,我现在改为函数直接return reinterpret_cast (tail_);

  3、ACE_wrappers\protocols\ace\Inet\Sock_IOStream.cpp文件86行,报rdbuf()最初始类的基类没有set_interceptor()成员函数,源码如下:
编译ACE_TAO库的过程中遇到的一些问题+vxworks镜像组件定制+Relocation value does not fit in 26 bits解决办法
源码中rdbuf()返回类型为buffer_type*类型,查找源文件发现buffer_type对象是有set_interceptor()成员的,所以将this->rdbuf()强转为buffer_type*就好了。这里比较奇怪,不知道为什么编译器把this->rdbuf()的返回类型当成buffer_type*的基类了,而基类是没有set_interceptor()成员的。

  4、ACE_wrappers\ace\RB_Tree.cpp文件第545,550行,报”invalid destructor name for type “class ” ACE_DES_FREE_TEMPLATE2”错误,源码如下:
编译ACE_TAO库的过程中遇到的一些问题+vxworks镜像组件定制+Relocation value does not fit in 26 bits解决办法
很自然的,我们要去到源文件中查看”ACE_DES_FREE_TEMPLATE2”是什么,经查找,这是一个宏,在Global_Macros.h头文件中定义,源码如下:
编译ACE_TAO库的过程中遇到的一些问题+vxworks镜像组件定制+Relocation value does not fit in 26 bits解决办法
通过测试,发现是else分支”(POINTER)->T_CLASS();”这一行有问题,具体错误的原因我还不清楚,好像是这个模板类得带参数才行,跟if分支一样,不过这样的话就没必要else了。我一开始以为是以为没有宏定义”ACE_EXPLICIT_TEMPLATE_DESTRUCTOR_TAKES_ARGS”,导致进入了else分支,所以我在ACE_wrappers\ace\config.h头文件中宏定义了”ACE_EXPLICIT_TEMPLATE_DESTRUCTOR_TAKES_ARGS”,但是没有用,应该是定义错地方了。为了先能编译通过,我现在把else分支改成和if分支一样了。

  5、ACE_wrappers\ace\String_Base.cpp 228,391行,报ace_min, ace_max未找到错误,这个问题比较简单,查找源文件,发现”ace_min”、”ace_max”声明在”ace/Min_Max.h”头文件中,所以在String_Base.cpp文件中包含”ace/Min_Max.h”头文件即可。

  6、ACE_wrappers\TAO\orbsvcs\orbsvcs\Property\CosPropertyService_i.cpp第1060行,报如下错误:
“Property/CosPropertyService_i.cpp”, line 1060: error (etoa:1551): argument type does not match prototype
“Property/CosPropertyService_i.cpp”, line 1060: error (etoa:1555): not a struct/union reference
“Property/CosPropertyService_i.cpp”, line 1060: internal compiler error (etoa:1000): -”./../src/eparse/cxa_eh_fe.cc”:1769
源码如下:
编译ACE_TAO库的过程中遇到的一些问题+vxworks镜像组件定制+Relocation value does not fit in 26 bits解决办法
这个问题我没有找到原因,现在直接粗暴地将1058和1059行注释掉了,编译可以通过,但是肯定不是正确地解决办法。

  以上6个错误就是我在编译ACE_TAO源码过程中遇到的问题。

二、Relocation value does not fit in 26 bits问题

  编译完成后,将编译生成的库文件加载到vxworks_6.9镜像时,存在Relocation value does not fit in 26 bits问题,原因是缺省的编译都是26位地址的,当程序变大的时候会由于调用时跨度太大导致地址越界,解决办法是在编译时增加长跳转标志。对于GNU和diab编译器,其标志是不一样的。

  • 针对GNU编译器、且目标平台为PowerPC,使用make ADDED_CFLAGS=”-mlongcall” ADDED_C++FLAGS=”-mlongcall”指令,若目标平台为ARM或者MIPS,则将”-mlongcall”改成”-mlong-calls”;
  • 对于diab编译器,使用make ADDED_CFLAGS=”-Xcode-absolute-far ” ADDED_C++FLAGS=”-Xcode-absolute-far”指令即可。

以上可参考文档《VxWorks_Architecture_Supplement_6.2》。

三、加载库时提示找不到符号表

  解决Relocation value does not fit in 26 bits问题后,再次加载,发现又报了”log2”和”_d_ulltod”这两个符号找不到的问题,”log2”是ACE_TAO源码库中的函数,在ace\ACE.inl文件中,所以怀疑是这个内联函数没有被编译进去,查找资料最后发现要将内联函数一起进行编译的话,需要将”inline”标志置1,所以我在ACE_wrappers_new\include\makeinclude\platform_macros.GNU文件中添加了一行代码:inline=1,再次编译,只有”_d_ulltod”这个符号找不到了。

  我的vxworks_6.9镜像是通过风河的workbench_3.3编译的,在讲如何解决找不到”_d_ulltod”符号这个问题之前,我们先说另一个问题。我们都知道,通过选择不同的组件,我们可以定制不同的vxworks镜像,这样生成出来的镜像可以只包含我们我们所需要的功能,不至于臃肿,包含了一堆我们不需要的东西。那么,这些组件是怎么来的呢?workbench中有一系列的后缀为”cdf”的文件,每一个cdf文件中就包含了组件信息,这些文件在($wind_river_install_path)\vxworks-6.9\target\config\comps\vxWorks路径下,workbench就是通过cdf文件来管理组件配置的,关于cdf文件的基本结构以及用户如何自定义组件,可参考文档《vxWorks程序开发实践》第10.1.3小节,我就不做搬运工了。

  回到找不到”_d_ulltod”符号这个问题上来,一开始怀疑跟log2一样,没有将实现部分编译进去,但是在ACE_TAO源码库中,没有找到”_d_dlltod”的实现部分,到网上查发现这应该是一个底层系统函数,也就是说ACE_TAO是直接调用这个函数的,所以怀疑这个函数应该是没有被编译到vxworks_6.9镜像中,在workbench目录中搜索包含”_d_ulltod”字段的文件,发现在workspace_insatll_path\vxworks-6.9\target\config\comps\vxWorks\arch\arm\arch.cdf文件中,如下图所示:
编译ACE_TAO库的过程中遇到的一些问题+vxworks镜像组件定制+Relocation value does not fit in 26 bits解决办法
原来“_d_ulltod”在INCLUDE_ARM_DIAB_INTRINSIC_SWFP_MATH组件中,这样的话,我们只要将INCLUDE_ARM_DIAB_INTRINSIC_SWFP_MATH添加到镜像中,重新编译就OK了,然而问题来了,在kernel Configuration界面上,居然找不到INCLUDE_ARM_DIAB_INTRINSIC_SWFP_MATH组件,如下图所示:
编译ACE_TAO库的过程中遇到的一些问题+vxworks镜像组件定制+Relocation value does not fit in 26 bits解决办法
搜索出来为空,真的很忧伤啊!于是怀疑是不是INCLUDE_ARM_DIAB_INTRINSIC_SWFP_MATH组件没有被包含进去,
查找workspace_insatll_path\vxworks-6.9\target\config\comps\vxWorks目录下的所有文件,果然没发现有哪个folder包含了INCLUDE_ARM_DIAB_INTRINSIC_SWFP_MATH组件,那现在我们就需要自己定义cdf文件,这个文件定义了一个Folder,包含了INCLUDE_ARM_DIAB_INTRINSIC_SWFP_MATH组件。于是我在workspace_insatll_path\vxworks-6.9\target\config\comps\vxWorks\arch\arm\目录下,新建了99arm_diab_swfp.cdf文件,文件内容如下:
编译ACE_TAO库的过程中遇到的一些问题+vxworks镜像组件定制+Relocation value does not fit in 26 bits解决办法
问题又来了,我添加完99arm_diab_swfp.cdf文件后,依然不能找到INCLUDE_ARM_DIAB_INTRINSIC_SWFP_MATH组件,再继续在网上找资料,找到了一个文档《vxworks_kernel_proprammers_guide_6.2》,在其中我找到了原因,原来cdf文件被读取的时机有两种:
1、新建镜像工程的时候;
2、原cdf文件被修改。
官方不建议修改原cdf文件,而且我自己试了下,在原cdf文件中添加新的组件不会被识别,但如果注释掉一个组件,那这个组件倒真的没有了。我后来新建了镜像工程,终于成功了,如下图所示:
编译ACE_TAO库的过程中遇到的一些问题+vxworks镜像组件定制+Relocation value does not fit in 26 bits解决办法

  这里插一下cdf文件的命名规则,cdf文件名前两位为10进制数,从00到99,其中00-50被系统保留,用户只能用51-99范围,数字越高,优先级越高,比如你在51demo.cdf和91demo.cdf两个文件中定义了同名组件,那么51demo.cdf中的组件会被91demo.cdf文件中的组件覆盖。
  
  《vxworks_kernel_proprammers_guide_6.2》中对cdf的介绍比《vxWorks程序开发实践》中更详细,只不过是英文的。

以上就是我遇到的问题,希望能给遇到类似问题的朋友提供一点参考,水平有限,有任何建议,欢迎提出,谢谢!