The power of C, the power of MD

A problem is a chance to do your best
posts - 11, comments - 22, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

使用gSOAP开发实例(6) 在HP-UX下编译gSOAP-2.7.17

Posted on 2010-09-03 23:02 roy 阅读(2553) 评论(1)  编辑 收藏 引用 所属分类: C/C++

gSOAP 号称是跨平台的工具包,不过毕竟是属于 g 字头的,如果没有了一系列 GNU 组件的支持,在其他类 Unix 系统编译也会遇到不少困难。

 

gSOAP README 说得也不是很清楚,只提到依赖于这些组件:

1. Automake tools (make and GNU m4) to configure and build

2. Bison http://www.gnu.org/software/bison or the alternative Yacc

3. Flex http://flex.sourceforge.net

4. OpenSSL (for optional HTTPS) http://www.openssl.org

5. Zlib (for optional compression) http://www.zlib.net

6. Pthreads or win32 threads (optional)

 

实际上,我在 HP-UX 下编译 gSOAP 的时候发现,要成功编译,还需要安装 autoconf gawk make ,为解决中文乱码问题,还需要安装 libiconv 。虽然原系统就有 awk make ,但是由于版本问题,编译时出错。所以,建议大家编译最新版的 gSOAP-2.7.17 时,按一下顺序安装组件:

1.     autoconf-2.66 (http://ftp.gnu.org/gnu/autoconf/ )

autoconf 是一个用于生成可以自动地配置软件源代码包以适应多种 Unix 类系统的 shell 脚本的工具。

2.     automake-1.10 (http://ftp.gnu.org/gnu/automake/ )

automake 是一个从文件 Makefile.am 自动生成 Makefile.in 的工具。每个 Makefile.am 基本上是一系列 make 的宏定义( make 规则也会偶尔出现)。生成的 Makefile.in 服从 GNU Makefile 标准。

3.     m4-1.4.14 (http://ftp.gnu.org/gnu/m4/ )

m4 是一个宏处理器。

4.     gawk-3.1.8 (http://ftp.gnu.org/gnu/gawk/ )

awk 地球人都知道。 HP-UX 自带的 awk 不是 GNU 的,编译 gSOAP 时执行某些语句出错,因此在编译 gSOAP 时要使用 GNU 新版本。

5.     make-3.81 (http://ftp.gnu.org/gnu/make/ )

make 也是地球人都知道。 HP-UX 自带的 make 编译 gSOAP 时会出错。

6.     bison-2.4 (http://ftp.gnu.org/gnu/bison/ )

语法分析生成器。

7.     flex-2.5.35 (http://flex.sourceforge.net/ )

词法分析生成器。

8.     zlib-1.2.5 (http://www.zlib.net/ )

gzip LZW 压缩库。

9.     libiconv-1.13.1 (http://ftp.gnu.org/pub/gnu/libiconv/ )

字符编码转换工具,上一节有介绍。

 

openssl 原来就已经有,无需安装。如果没有或者版本很低,可以到这里下载: http://www.openssl.org/source/

 

补充事项:

1.     如何判断某个组件是否需要安装? 很简单,到 LFS 官方网站参考用户手册: http://www.linuxfromscratch.org/lfs/view/stable/ ,查看一下该组件包含的 Installed program ,然后在命令行使用 which 命令找一下,如果找不到,可以肯定需要安装

 

2.     如何判断某个组件是否需要升级? 如果通过上述方法能够找到已安装的组件,但是文件的时间比较久远,而且不支持 —help 参数查看帮助信息或者 —version 参数查看版本信息,几乎可以肯定需要升级,因为比较新的 GNU 程序一般都支持这些参数。如果通过 --version 显示版本较低,也应该升级

 

3.     上述组件的安装一般都是 ./configure && make && make install 三部曲。如果没有 root 权限,可以使用 ./configure --prefix=/path/to/your/directory 指定合法的安装路径,然后根据需要指定 PATH SHLIB_PATH 环境变量。千万要注意, HP-UX 的动态链接库的环境变量是 SHLIB_PATH ,而不是和 Linux 下的 LD_LIBRARY_PATH

 

4.     设置环境变量的时候也要注意,如果系统中已经有旧版本的组件,并且新旧版本不在同一目录, export 环境变量的时候要把新版本组件所在的 lib 目录居前 ,这样系统才能优先搜索得到

 

5.     HP-UX 下编译 flex-2.5.35 时会遇到一个棘手的问题

ld: Unsatisfied symbol "rpl_realloc" in file dfa.o

1 errors.

collect2: ld returned 1 exit status

 

rpl_realloc 为关键字搜索,发现它出现在 configure 步骤产生的 config.h 当中

/* Define to rpl_realloc if the replacement function should be used. */

#define realloc rpl_realloc

 

看样子,可能是为了避免有些系统没有 realloc ,而转用 rpl_realloc 代替。这个 rpl_realloc 不知是哪个系统的函数, HP-UX 应该可以使用 realloc 这个标准 C 函数呀!于是,把这一行注释了,重新 make 就正常了

 

6.     gSOAP-2.7.17 的编译指定要 automake-1.10 版本,如果像我那样不慎安装了 automake-1.11 ,需要自行在其 bin 目录创建两个链接,否则 gSOAP 就是傻到不认帐!

aclocal-1.10 -> aclocal-1.11

automake-1.10 -> automake-1.11

 

7.     gSOAP 的傻事还不止一件,它只认 flex 的动态库而不认静态库 ,偏偏 flex 只安装了静态库。所以,安装 flex 之后,需要手动编译以生成 libfl.so ,然后再拷贝到其 lib 目录。

gcc -shared -fPCI -o libfl.so libmain.o libyywrap.o

此外,还需要在其 lib 目录创建两个链接,其中第一个是 LFS 为保持 lex flex 的兼容性而建议的,至于第二个,完全是迁就 gSOAP 的坏脾气

libl.so -> libfl.so

libl.so.1 -> libl.so

 

如果上述准备工作全部完毕,那么即可正式编译 gSOAP 。编译步骤同样是 ./configure && make && make install ,似乎乏善可陈。但是, gSOAP-2.7.17 似乎有一个 bug ,在 HP-UX 下编译会报错:

stdsoap2_cpp.cpp: In function 'size_t frecv(soap*, char*, size_t)':

stdsoap2_cpp.cpp:876: error: invalid conversion from 'socklen_t*' to 'int*'

stdsoap2_cpp.cpp:876: error:   initializing argument 6 of 'int recvfrom(int, void*, int, int, void*, int*)'

stdsoap2_cpp.cpp: In function 'int tcp_connect(soap*, const char*, const char*, int)':

……

 

一大堆错误信息,其实是指向同一个错误: invalid conversion from 'socklen_t*' to 'int*'

 

首先,使用 find 命令查找 stdsoap2_cpp.cpp 只有一个

> find . -name "stdsoap2_cpp.cpp"

./gsoap/stdsoap2_cpp.cpp

 

然后,根据错误信息,查看该源程序的 876 行附近,函数的第六个参数,也就是最后一个参数 k SOAP_SOCKLEN_T 类型的

 

接着,查找所有的头文件,看看该类型是哪个文件定义的

> find . -name "*.h" | xargs grep -l SOAP_SOCKLEN_T

./gsoap/samples/calc_vs2005/calc_vs2005/stdsoap2.h

./gsoap/samples/wsse/stdsoap2.h

./gsoap/stdsoap2.h

./gsoap/VisualStudio2005/wsdl2h/wsdl2h/stdsoap2.h

 

很明显,就在 ./gsoap/stdsoap2.h 中。 Vi 之,在 709 行开始其定义:

   709  /* Portability: define SOAP_SOCKLEN_T */

   710  #if defined(_AIX)

   711  # if defined(_AIX43)

   712  #  define SOAP_SOCKLEN_T socklen_t

   713  # else

   714  #  define SOAP_SOCKLEN_T int

   715  # endif

   716  #elif defined(SOCKLEN_T)

   717  # define SOAP_SOCKLEN_T SOCKLEN_T

   718  #elif defined(__socklen_t_defined) || defined(_SOCKLEN_T) || defined(CYGWIN) || defined(FREEBSD) || defined(__FreeBSD__) || defined(OPENBSD) || define

d(__QNX__) || defined(QNX) || defined(OS390) || defined(HP_UX)

   719  # define SOAP_SOCKLEN_T socklen_t

   720  #elif defined(IRIX) || defined(WIN32) || defined(__APPLE__) || defined(SUN_OS) || defined(OPENSERVER) || defined(TRU64) || defined(VXWORKS)

   721  # define SOAP_SOCKLEN_T int

   722  #else

   723  # define SOAP_SOCKLEN_T size_t

   724  #endif

 

注意 718 719 行, gSOAP-2.7.17 HP-UX 下,把 SOAP_SOCKLEN_T 定义为 socklen_t ,而其它操作系统不是定义为 int 就定义为 size_t ,再联系之前的错误信息 invalid conversion from 'socklen_t*' to 'int*' ,很清楚了,只要在 719 行把 socklen_t 改为 int 就肯定能够在 HP-UX 下编译通过了。或者严谨一些,把 718 行的 defined(HP_UX) 移到 720 行最后也可以。

 

上面的问题解决了,继续编译工作,很可能会遇上另一个问题

/usr/lib/hpux32/dld.so: Unsatisfied data symbol 'yylsp' in load module '/usr/lib/hpux32/libl.so.1'.

/usr/lib/hpux32/dld.so: Unsatisfied data symbol 'yyolsp' in load module '/usr/lib/hpux32/libl.so.1'.

/usr/lib/hpux32/dld.so: Unsatisfied data symbol 'yyfnd' in load module '/usr/lib/hpux32/libl.so.1'.

……

 

这是由于系统原来就装有 flex ,但不是最新版本,结果系统搜索到旧版本的 libl.so.1 而搜索不到新版本 libl.so.1 ,这就是为什么我在前面要特别强调, export 环境变量的时候,要确保新版本所在的路径在前面,并且要在 flex lib 目录建立两个链接的原因。

 

按照上述步骤和错误处理方法,在 HP-UX 下编译 gSOAP 应该是不成问题的,推而广之,在其它 Unix 下编译 gSOAP 也应该差不多。

 

最后一个小问题是,在 HP-UX 下要使用刚刚编译出来的 soapcpp2 生成存根程序,而不要使用前四节在 linux 目录下的 soapcpp2

 

> ../../src/soapcpp2 -C -L -x stock.h

 

更进一步,如果在 HP-UX 下,需要用到 libxml2 解析 SOAP 响应消息,除了编译源代码之外,也可以直接到下列网址下载基于 HP-UX 的二进制包:

http://hpux.connect.org.uk/hppd/hpux/Gnome/libxml2-2.7.7/

 

这个地址提供了几种版本的二进制包,下载之前应该在命令行输入 uname –a 查看一下当前的操作系统信息:

> uname -a

HP-UX hostname B.11.23 U ia64 0850816723 unlimited-user license

 

根据以上信息,应当下载 Operating System HP-UX 11i v2(HP-UX 11.23) Architecture Itanium 2 的二进制包

 

下载的包是 libxml2-2.7.7-ia64-11.23.depot.gz 。把它解压后,有 root 权限的可以使用 HP-UX 专门的包管理工具安装。没有 root 权限也不要紧, depot 其实就是一个 tar 包,可以直接使用 tar 解包,把解包后的文件移动到合适的目录,再设置好 PATH SHLIB_PATH 环境变量即可。

http://blog.csdn.net/yui/archive/2010/08/09/5799465.aspx

Feedback

# re: 使用gSOAP开发实例(6) 在HP-UX下编译gSOAP-2.7.17  回复  更多评论   

2010-09-06 12:09 by 普派
没有 root 权限也不要紧, depot 其实就是一个 tar 包,可以直接使用 tar 解包,把解包后的文件移动到合适的目录,再设置好 PATH 和 SHLIB_PATH 环境变量即可

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理