从上学期就一直在拜读已故UNIX网络专家W. Richard Stevens博士的巨著《UNIX 网络编程:第3版》,但始终没有很好的做好学习笔记,许多代码没有认真编译运行,许多内容理解的也不够深刻。由于刚刚在chinaunix上开通了博客,且目前在学习socket IPC相关内容,于是从今天开始,准备从头再仔细的慢慢的学习一遍。
从网上下载了书的源码,按照README把用到的库编译好,只运行了./configure;cd lib; make; cd ../libfree; make。在/home/lhw/unpv13e目录下生成了静态库libunp.a。头文件unp.h在/home/lhw/unpv13e/key目录下。
我什么也没管,直接编译下面的文件,错误一堆:
root@lhw-laptop:/home/lhw/unpv13e/unixdomain# gcc -o unixbind unixbind.c
unixbind.c:1:17: 错误: unp.h:没有该文件或目录
unixbind.c: 在函数‘main’中:
unixbind.c:7: 错误: ‘socklen_t’未声明(在此函数内第一次使用)
unixbind.c:7: 错误: (即使在一个函数内多次出现,每个未声明的标识符在其
unixbind.c:7: 错误: 所在的函数内也只报告一次。)
unixbind.c:7: 错误: expected ‘;’ before ‘len’
unixbind.c:8: 错误: ‘addr1’的存储大小未知
unixbind.c:8: 错误: ‘addr2’的存储大小未知
unixbind.c:13: 错误: ‘AF_LOCAL’未声明(在此函数内第一次使用)
unixbind.c:13: 错误: ‘SOCK_STREAM’未声明(在此函数内第一次使用)
unixbind.c:17: 警告: 隐式声明与内建函数‘bzero’不兼容
unixbind.c:19: 警告: 隐式声明与内建函数‘strncpy’不兼容
unixbind.c:20: 错误: ‘SA’未声明(在此函数内第一次使用)
unixbind.c:20: 错误: expected expression before ‘)’ token
unixbind.c:22: 错误: ‘len’未声明(在此函数内第一次使用)
unixbind.c:23: 错误: expected expression before ‘)’ token
unixbind.c:24: 警告: 隐式声明与内建函数‘printf’不兼容
unixbind.c:26: 警告: 隐式声明与内建函数‘exit’不兼容
因为没找到unp.h,源文件里的很多系统头文件和自定义包裹函数找不到。于是把头文件加进去:
root@lhw-laptop:/home/lhw/unpv13e/unixdomain# gcc -o unixbind unixbind.c -I/home/lhw/unpv13e/lib
/tmp/ccIDbv9m.o: In function `main':
unixbind.c:(.text+0x35): undefined reference to `err_quit'
collect2: ld 返回 1
错误出现在.o文件中,且是ld返回了1,看来是编译通过,但链接过程出错了。运行如下命令试试:
root@lhw-laptop:/home/lhw/unpv13e/unixdomain# gcc -c unixbind.c -lunp -I/home/lhw/unpv13e/key
成功,看来错误真是出在链接过程。链接时没找到err_quit,奥,原来编译器没找到自定义的库。
root@lhw-laptop:/home/lhw/unpv13e/unixdomain# gcc -o unixbind unixbind.c -I/home/lhw/unpv13e/key -L/home/lhw/unpv13e
/tmp/ccqXBY3m.o: In function `main':
unixbind.c:(.text+0x35): undefined reference to `err_quit'
collect2: ld 返回 1
root@lhw-laptop:/home/lhw/unpv13e/unixdomain# gcc -o unixbind unixbind.c -lunp -I/home/lhw/unpv13e/key -L/home/lhw/unpv13e
好了,成功了。
root@lhw-laptop:/home/lhw/unpv13e/unixdomain# ./unixbind
usage: unixbind <pathname>
如下编译也可以
root@lhw-laptop:/home/lhw/unpv13e/unixdomain#gcc -o unixbind unixbind.c ../libunp.a -I../lib
为了避免每次都有些库和头文件的路径,我把unp.h复制到/usr/local/include,因为unp.h中有#include "../config.h",于是我把它改成#include "config.h",然后又把config.h复制到/usr/local/include。 这样如下编译即可:
root@lhw-laptop:/home/lhw/unpv13e/unixdomain# gcc -o unixbind2 unixbind.c ../libunp.a
我又把库libunp.a服知道/usr/local/lib。这样如下编译即可:
root@lhw-laptop:/home/lhw/unpv13e/unixdomain# gcc -o unixbind2 unixbind.c -lunp
我们还可以利用各目录下自带的Makefile文件自动编译,生成可执行文件unixbind和目标文件unixbind.o。如下:
root@lhw-laptop:/home/lhw/unpv13e/unixdomain# make unixbind
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o unixbind.o unixbind.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -o unixbind unixbind.o ../libunp.a -lpthread
|
下面是/home/lhw/unpv13e/unixdomain/Makefile的内容,$@表示规则的目标文件名。
include ../Make.defines
PROGS = daytimetcpcli daytimetcpsrv2 mycat openfile \
tfcred01 unixbind unixstrcli01 unixstrserv01 unixstrserv02
all: ${PROGS}
daytimetcpcli: daytimetcpcli.o
${CC} ${CFLAGS} -o $@ daytimetcpcli.o ${LIBS}
daytimetcpsrv2: daytimetcpsrv2.o
${CC} ${CFLAGS} -o $@ daytimetcpsrv2.o ${LIBS}
mycat: mycat.o myopen.o
${CC} ${CFLAGS} -o $@ mycat.o myopen.o ${LIBS}
openfile: openfile.o
${CC} ${CFLAGS} -o $@ openfile.o ${LIBS}
tfcred01: tfcred01.o
${CC} ${CFLAGS} -o $@ tfcred01.o ${LIBS}
unixbind: unixbind.o
${CC} ${CFLAGS} -o $@ unixbind.o ${LIBS}
unixdgcli01: unixdgcli01.o
${CC} ${CFLAGS} -o $@ unixdgcli01.o ${LIBS}
unixdgserv01: unixdgserv01.o
${CC} ${CFLAGS} -o $@ unixdgserv01.o ${LIBS}
unixstrcli01: unixstrcli01.o
${CC} ${CFLAGS} -o $@ unixstrcli01.o ${LIBS}
unixstrserv01: unixstrserv01.o sigchldwaitpid.o
${CC} ${CFLAGS} -o $@ unixstrserv01.o sigchldwaitpid.o ${LIBS}
unixstrserv02: unixstrserv02.o strecho.o sigchldwaitpid.o readcred.o
${CC} ${CFLAGS} -o $@ unixstrserv02.o strecho.o sigchldwaitpid.o \
readcred.o ${LIBS}
clean:
rm -f ${PROGS} ${CLEANFILES}
----------------------------------------------------------------------------------------
从下面的命令输出可以验证:链接时,并没有把库文件中所有的目标都链接到目标文件unixbind.o中,而只是把用到的那个文件或函数链接进去。
root@lhw-laptop:/home/lhw/unpv13e/unixdomain# gcc -o unixbind unixbind.c -lunp; gcc -o unixbind2 unixbind.c ../libunp.a; gcc -c unixbind.c
root@lhw-laptop:/home/lhw/unpv13e/unixdomain# ls -l unixbind unixbind2 unixbind.o ../libunp.a
-rw-r--r-- 1 root root 418208 2009-11-02 11:54 ../libunp.a
-rwxr-xr-x 1 root root 14021 2009-11-02 12:23 unixbind
-rwxr-xr-x 1 root root 14021 2009-11-02 12:23 unixbind2
-rw-r--r-- 1 root root 1476 2009-11-02 12:23 unixbind.o
|
我第一次编译的时候,用的是/home/lhw/unpv13e/key目录里的头文件,出现了重定义错误:
root@lhw-laptop:/home/lhw/unpv13e/unixdomain# gcc -o unixbind unixbind.c -I /home/lhw/unpv13e/key
In file included from unixbind.c:1:
/home/lhw/unpv13e/key/unp.h:122: 错误: ‘struct in_pktinfo’重定义
看来在unp.h里包含的系统头文件里已定义过struct in_pktinfo,我到unp.h里把struct in_pktinfo的定义注释了:
/* The structure returned by recvfrom_flags() */
//struct in_pktinfo {
// struct in_addr ipi_addr; /* dst IPv4 address */
// int ipi_ifindex;/* received interface index */
//};我起先是在开头和结尾处用/*...*/注掉的,结果颜色不对,一想,奥,原来/*...*不能嵌套,于是换成了4个//。大家不要笑话我,注意点。
重新编译后就不会出现重定义错误了。
上面只是出现的一个小错误,下面看看库文件是怎么制作的。
下面是/home/lhw/unpv13e/lib/Makefile的内容:
------------------------------/home/lhw/unpv13e/lib/Makefile----------------------------------
include ../Make.defines
all: ${LIB_OBJS}
ar rv ${LIBUNP_NAME} $?
${RANLIB} ${LIBUNP_NAME}
clean:
rm -f ${PROGS} ${CLEANFILES}
------------------------------/home/lhw/unpv13e/lib/Makefile----------------------------------
自动变量$?表示所有比目标文件更新的依赖文件列表,如果目标所静态库文件(如本文件),代表的是库成员(.o文件)
下面是/home/lhw/unpv13e/lib/Makefile的内容
------------------------------/home/lhw/unpv13e/libfree/Makefile--------------------------------
include ../Make.defines
all: ${LIBFREE_OBJS}
ar rv ${LIBUNP_NAME} $?
${RANLIB} ${LIBUNP_NAME}
test_inet_pton: test_inet_pton.o
${CC} ${CFLAGS} -o $@ test_inet_pton.o ${LIBS}
clean:
rm -f ${PROGS} ${CLEANFILES}
------------------------------/home/lhw/unpv13e/libfree/Makefile--------------------------------
下面是/home/lhw/unpv13e/Make.defines的内容
#
# This file is generated by autoconf from "Make.defines.in".
#
# This is the "Make.defines" file that almost every "Makefile" in the
# source directories below this directory include.
# The "../" in the pathnames actually refer to this directory, since
# "make" is executed in all the subdirectories of this directory.
#
# System = i686-pc-linux-gnu
CC = gcc
CFLAGS = -I../lib -g -O2 -D_REENTRANT -Wall
LIBS = ../libunp.a -lpthread
LIBS_XTI = ../libunpxti.a ../libunp.a -lpthread
RANLIB = ranlib
# Following is the main library, built from all the object files
# in the lib/ and libfree/ directories.
LIBUNP_NAME = ../libunp.a
# Following is the XTI library, built from all the object files
# in the libxti/ directory.
LIBUNPXTI_NAME = ../libunpxti.a
# Following are all the object files to create in the lib/ directory.
LIB_OBJS = connect_nonb.o connect_timeo.o daemon_inetd.o daemon_init.o dg_cli.o dg_echo.o error.o get_ifi_info.o gf_time.o host_serv.o family_to_level.o mcast_leave.o mcast_join.o mcast_get_if.o mcast_get_loop.o mcast_get_ttl.o mcast_set_if.o mcast_set_loop.o mcast_set_ttl.o my_addrs.o read_fd.o readline.o readn.o readable_timeo.o rtt.o signal.o signal_intr.o sock_bind_wild.o sock_cmp_addr.o sock_cmp_port.o sock_ntop.o sock_ntop_host.o sock_get_port.o sock_set_addr.o sock_set_port.o sock_set_wild.o sockfd_to_family.o str_cli.o str_echo.o tcp_connect.o tcp_listen.o tv_sub.o udp_client.o udp_connect.o udp_server.o wraplib.o wrapsock.o wrapstdio.o wrappthread.o wrapunix.o write_fd.o writen.o writable_timeo.o
# Following are all the object files to create in the libfree/ directory.
LIBFREE_OBJS = in_cksum.o inet_ntop.o inet_pton.o
# Following are all the object files to create in the libgai/ directory.
LIBGAI_OBJS =
# Following are all the object files to create in the libroute/ directory.
LIBROUTE_OBJS = get_rtaddrs.o if_indextoname.o if_nameindex.o if_nametoindex.o net_rt_iflist.o net_rt_dump.o sock_masktop.o
# Following are all the object files to create in the libxti/ directory.
LIBXTI_OBJS = wrapxti.o xti_accept.o xti_flags_str.o xti_getopt.o xti_ntop.o xti_ntop_host.o xti_rdwr.o xti_setopt.o xti_str_opts.o xti_tlook_str.o
CLEANFILES = core core.* *.core *.o temp.* *.out typescript* \
*.lc *.lh *.bsdi *.sparc *.uw
----------------------------------------------------------------------------------------------------------------------------------------
将所有makefile文件都用到的变量放在顶层目录的makefile文件中,各级子目录的makefile文件均包含顶层的makefile文件。
ar rv 库文件名 .o文件列表
r参数将后面的.o文件列表打包成库文件,若库文件存在,则将 .o文件添加进去,一般添加到末尾,并覆盖库中原来存在的同名的.o文件。
root@lhw-laptop:/home/lhw/unpv13e/lib# make
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o connect_nonb.o connect_nonb.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o connect_timeo.o connect_timeo.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o daemon_inetd.o daemon_inetd.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o daemon_init.o daemon_init.c
daemon_init.c: 在函数‘daemon_init’中:
daemon_init.c:34: 警告: 忽略声明有 warn_unused_result 属性的‘chdir’的返回值
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o dg_cli.o dg_cli.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o dg_echo.o dg_echo.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o error.o error.c
error.c: 在函数‘err_doit’中:
error.c:102: 警告: 格式字符串不是一个字面字符串而且没有待格式化的实参
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o get_ifi_info.o get_ifi_info.c
get_ifi_info.c: 在函数‘get_ifi_info’中:
get_ifi_info.c:115: 警告: 此函数中的‘haddr’在使用前可能未初始化
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o gf_time.o gf_time.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o host_serv.o host_serv.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o family_to_level.o family_to_level.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o mcast_leave.o mcast_leave.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o mcast_join.o mcast_join.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o mcast_get_if.o mcast_get_if.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o mcast_get_loop.o mcast_get_loop.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o mcast_get_ttl.o mcast_get_ttl.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o mcast_set_if.o mcast_set_if.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o mcast_set_loop.o mcast_set_loop.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o mcast_set_ttl.o mcast_set_ttl.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o my_addrs.o my_addrs.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o read_fd.o read_fd.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o readline.o readline.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o readn.o readn.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o readable_timeo.o readable_timeo.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o rtt.o rtt.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o signal.o signal.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o signal_intr.o signal_intr.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o sock_bind_wild.o sock_bind_wild.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o sock_cmp_addr.o sock_cmp_addr.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o sock_cmp_port.o sock_cmp_port.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o sock_ntop.o sock_ntop.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o sock_ntop_host.o sock_ntop_host.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o sock_get_port.o sock_get_port.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o sock_set_addr.o sock_set_addr.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o sock_set_port.o sock_set_port.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o sock_set_wild.o sock_set_wild.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o sockfd_to_family.o sockfd_to_family.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o str_cli.o str_cli.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o str_echo.o str_echo.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o tcp_connect.o tcp_connect.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o tcp_listen.o tcp_listen.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o tv_sub.o tv_sub.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o udp_client.o udp_client.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o udp_connect.o udp_connect.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o udp_server.o udp_server.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o wraplib.o wraplib.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o wrapsock.o wrapsock.c
wrapsock.c: 在函数‘Inet6_rth_space’中:
wrapsock.c:81: 警告: 隐式声明函数‘inet6_rth_space’
wrapsock.c: 在函数‘Inet6_rth_init’中:
wrapsock.c:93: 警告: 隐式声明函数‘inet6_rth_init’
wrapsock.c:93: 警告: 赋值时将整数赋给指针,未作类型转换
wrapsock.c: 在函数‘Inet6_rth_add’中:
wrapsock.c:103: 警告: 隐式声明函数‘inet6_rth_add’
wrapsock.c: 在函数‘Inet6_rth_reverse’中:
wrapsock.c:110: 警告: 隐式声明函数‘inet6_rth_reverse’
wrapsock.c: 在函数‘Inet6_rth_segments’中:
wrapsock.c:119: 警告: 隐式声明函数‘inet6_rth_segments’
wrapsock.c: 在函数‘Inet6_rth_getaddr’中:
wrapsock.c:131: 警告: 隐式声明函数‘inet6_rth_getaddr’
wrapsock.c:131: 警告: 赋值时将整数赋给指针,未作类型转换
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o wrapstdio.o wrapstdio.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o wrappthread.o wrappthread.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o wrapunix.o wrapunix.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o write_fd.o write_fd.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o writen.o writen.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o writable_timeo.o writable_timeo.c
ar rv ../libunp.a connect_nonb.o connect_timeo.o daemon_inetd.o daemon_init.o dg_cli.o dg_echo.o error.o get_ifi_info.o gf_time.o host_serv.o family_to_level.o mcast_leave.o mcast_join.o mcast_get_if.o mcast_get_loop.o mcast_get_ttl.o mcast_set_if.o mcast_set_loop.o mcast_set_ttl.o my_addrs.o read_fd.o readline.o readn.o readable_timeo.o rtt.o signal.o signal_intr.o sock_bind_wild.o sock_cmp_addr.o sock_cmp_port.o sock_ntop.o sock_ntop_host.o sock_get_port.o sock_set_addr.o sock_set_port.o sock_set_wild.o sockfd_to_family.o str_cli.o str_echo.o tcp_connect.o tcp_listen.o tv_sub.o udp_client.o udp_connect.o udp_server.o wraplib.o wrapsock.o wrapstdio.o wrappthread.o wrapunix.o write_fd.o writen.o writable_timeo.o
ar: creating ../libunp.a
a - connect_nonb.o
a - connect_timeo.o
a - daemon_inetd.o
a - daemon_init.o
a - dg_cli.o
a - dg_echo.o
a - error.o
a - get_ifi_info.o
a - gf_time.o
a - host_serv.o
a - family_to_level.o
a - mcast_leave.o
a - mcast_join.o
a - mcast_get_if.o
a - mcast_get_loop.o
a - mcast_get_ttl.o
a - mcast_set_if.o
a - mcast_set_loop.o
a - mcast_set_ttl.o
a - my_addrs.o
a - read_fd.o
a - readline.o
a - readn.o
a - readable_timeo.o
a - rtt.o
a - signal.o
a - signal_intr.o
a - sock_bind_wild.o
a - sock_cmp_addr.o
a - sock_cmp_port.o
a - sock_ntop.o
a - sock_ntop_host.o
a - sock_get_port.o
a - sock_set_addr.o
a - sock_set_port.o
a - sock_set_wild.o
a - sockfd_to_family.o
a - str_cli.o
a - str_echo.o
a - tcp_connect.o
a - tcp_listen.o
a - tv_sub.o
a - udp_client.o
a - udp_connect.o
a - udp_server.o
a - wraplib.o
a - wrapsock.o
a - wrapstdio.o
a - wrappthread.o
a - wrapunix.o
a - write_fd.o
a - writen.o
a - writable_timeo.o
ranlib ../libunp.a
t参数查看库文件的内容
root@lhw-laptop:/home/lhw/unpv13e/lib# ar t ../libunp.a
connect_nonb.o
connect_timeo.o
daemon_inetd.o
daemon_init.o
dg_cli.o
dg_echo.o
error.o
get_ifi_info.o
gf_time.o
host_serv.o
family_to_level.o
mcast_leave.o
mcast_join.o
mcast_get_if.o
mcast_get_loop.o
mcast_get_ttl.o
mcast_set_if.o
mcast_set_loop.o
mcast_set_ttl.o
my_addrs.o
read_fd.o
readline.o
readn.o
readable_timeo.o
rtt.o
signal.o
signal_intr.o
sock_bind_wild.o
sock_cmp_addr.o
sock_cmp_port.o
sock_ntop.o
sock_ntop_host.o
sock_get_port.o
sock_set_addr.o
sock_set_port.o
sock_set_wild.o
sockfd_to_family.o
str_cli.o
str_echo.o
tcp_connect.o
tcp_listen.o
tv_sub.o
udp_client.o
udp_connect.o
udp_server.o
wraplib.o
wrapsock.o
wrapstdio.o
wrappthread.o
wrapunix.o
write_fd.o
writen.o
writable_timeo.o
root@lhw-laptop:/home/lhw/unpv13e/libfree# make
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o in_cksum.o in_cksum.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o inet_ntop.o inet_ntop.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o inet_pton.o inet_pton.c
ar rv ../libunp.a in_cksum.o inet_ntop.o inet_pton.o
a - in_cksum.o
a - inet_ntop.o
a - inet_pton.o
ranlib ../libunp.a
root@lhw-laptop:/home/lhw/unpv13e/libfree# ar t ../libunp.a
connect_nonb.o
connect_timeo.o
daemon_inetd.o
daemon_init.o
dg_cli.o
dg_echo.o
error.o
get_ifi_info.o
gf_time.o
host_serv.o
family_to_level.o
mcast_leave.o
mcast_join.o
mcast_get_if.o
mcast_get_loop.o
mcast_get_ttl.o
mcast_set_if.o
mcast_set_loop.o
mcast_set_ttl.o
my_addrs.o
read_fd.o
readline.o
readn.o
readable_timeo.o
rtt.o
signal.o
signal_intr.o
sock_bind_wild.o
sock_cmp_addr.o
sock_cmp_port.o
sock_ntop.o
sock_ntop_host.o
sock_get_port.o
sock_set_addr.o
sock_set_port.o
sock_set_wild.o
sockfd_to_family.o
str_cli.o
str_echo.o
tcp_connect.o
tcp_listen.o
tv_sub.o
udp_client.o
udp_connect.o
udp_server.o
wraplib.o
wrapsock.o
wrapstdio.o
wrappthread.o
wrapunix.o
write_fd.o
writen.o
writable_timeo.o
in_cksum.o
inet_ntop.o
inet_pton.o
可见三个.o文件添加到了lipunp.a尾端
ar qv 库文件名 .o文件列表
q参数也添加.o文件到库文件中,但若库中存在同名文件,并不覆盖。
root@lhw-laptop:/home/lhw/unpv13e/libfree# ar qv ../libunp.a in_cksum.o inet_ntop.o inet_pton.o
a - in_cksum.o
a - inet_ntop.o
a - inet_pton.o
root@lhw-laptop:/home/lhw/unpv13e/libfree# ar t ../libunp.a connect_nonb.o
connect_timeo.o
daemon_inetd.o
daemon_init.o
dg_cli.o
dg_echo.o
error.o
get_ifi_info.o
gf_time.o
host_serv.o
family_to_level.o
mcast_leave.o
mcast_join.o
mcast_get_if.o
mcast_get_loop.o
mcast_get_ttl.o
mcast_set_if.o
mcast_set_loop.o
mcast_set_ttl.o
my_addrs.o
read_fd.o
readline.o
readn.o
readable_timeo.o
rtt.o
signal.o
signal_intr.o
sock_bind_wild.o
sock_cmp_addr.o
sock_cmp_port.o
sock_ntop.o
sock_ntop_host.o
sock_get_port.o
sock_set_addr.o
sock_set_port.o
sock_set_wild.o
sockfd_to_family.o
str_cli.o
str_echo.o
tcp_connect.o
tcp_listen.o
tv_sub.o
udp_client.o
udp_connect.o
udp_server.o
wraplib.o
wrapsock.o
wrapstdio.o
wrappthread.o
wrapunix.o
write_fd.o
writen.o
writable_timeo.o
in_cksum.o
inet_ntop.o
inet_pton.o
in_cksum.o
inet_ntop.o
inet_pton.o