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

时间:2023-02-08 13:00:32

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

 

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

 

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

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

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

3. Flexhttp://flex.sourceforge.net

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

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

6. Pthreads or win32threads (optional)

 

实际上,我在HP-UX下编译gSOAP的时候发现,要成功编译,还需要安装autoconfgawkmake,为解决中文乱码问题,还需要安装libiconv。虽然原系统就有awkmake,但是可能由于版本问题,编译时会出错。所以,建议大家编译最新版的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时执行某些语句出错,因此要使用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/)

gzipLZW压缩库。

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指定合法的安装路径,然后根据需要指定PATHSHLIB_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 exitstatus

 

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

/* Define to rpl_realloc if thereplacement 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为保持lexflex的兼容性而建议的,至于第二个,完全是迁就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)':

……

 

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

 

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

> find . -name"stdsoap2_cpp.cpp"

./gsoap/stdsoap2_cpp.cpp

 

然后,根据错误信息,查看该源程序的876行附近,函数的第六个参数,也就是最后一个参数kSOAP_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

 

注意718719行,gSOAP-2.7.17HP-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 loadmodule '/usr/lib/hpux32/libl.so.1'.

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

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

……

 

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

 

按照上述步骤和错误处理方法,在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

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

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