全部博文(534)
分类: C/C++
2012-08-20 19:50:01
在Solaris下编译socket程序时发生“符号参照错误”提示?
需要确保头文件包含正确,并且指定-lsocket选项如下:
cc [ flag ... ] file ... -lsocket -lnsl [ library ... ]
#include
#include
Linux下socket调用是在libc中实现的,因此不需要指定-lsocket;但Solaris下,由于存在两套socket库的实现:
3SOCKET - BSD风格socket库,大多数GNU/Linux软件使用这个库
3XNET - 标准socket库
因此Solaris socket库并不包含在libc中,需要给链接器指定-lsocket参数。
Hang on, inet_aton *is* in Solaris but not mentioned on the INET(3SOCKET)
man page.
It`s in libresolv! However, Samba doesn`t link against libresolv as a
default.
Changing the LIBS= line in the Makefile to LIBS=-lsec -lgen -lsocket -lnsl
-ldl -lresolv lets libsmb/clidgram.c compile fine unchanged. That`s a better fix.
一、linux到solaris程序的移植问题
对一个c程序来说,比较头疼的问题就是程序的移植.一个普通的socket程序,linux下编译没问题,在SunOs 5.8 Generic_108528-19上报错:
bash-2.05# make
gcc -o receive receive.o init_daemon.o readconf.o trimchar.o
Undefined first referenced
symbol in file
socket receive.o
accept receive.o
bind receive.o
inet_ntop receive.o
vsscanf readconf.o
listen receive.o
ld: fatal: Symbol referencing errors. No output written to receive
collect2: ld returned 1 exit status
make: *** [receive] Error 1
二、这里面大体蕴涵着两方面的问题:
1、编译的格式不同.linux中gcc语法要求比较宽松,而solaris比较苛刻,要求必须指明所需要的库路径.以上bind和accept相关的函数都包含在socket库里.所以要加上"-lsocket",为了防止有其他函数库也找不到,最好也加上"-lnsl".
2、加上这些选项就只有vsscanf函数报错了
查了查stevens的APUE中没有查到这个函数,怀疑非unix通用函数.
中查询却是 Basic Library Functions
用nm查找,发现函数位于libc.a中,而sorlaris中是存在于/usr/lib中的,指明"-lc"也没用.
没招了,只能改掉这个函数,采用标准的.但是到现在也不知道到底是什么原因.如果谁知道,一定告诉我.
三、查询链接库的知识点:
nm: 库文件中的符号表,当不清楚某个函数在哪个库函数中时,可以用"nm -o /lib/* /usr/lib/* /usr/lib/*/* /usr/local/lib/* 2> /dev/null|grep vssanf "来查找.
ar : 归档命令.增加,减少库函数时有用,比如看看库中有哪些object文件."ar -t lib.a"
ldd: 显示共享库的依赖情况.说明运行这个文件需要系统有哪些库函数.
四、教训:
以后写c程序一定尽量使用标准的东西.移植时省却很多麻烦
很多时候并不是系统移植的问题,操作习惯或者命令格式的使用更是移植的拦路虎.
对将要移植系统环境的熟悉程度是移植成败的关键.