Unix网络编程第三版源码编译

时间:2020-12-17 22:12:03
环境:
$ cat /etc/issue
Ubuntu 12.04.1 LTS \n \l

$ cat /proc/version
Linux version 3.2.0-48-generic (buildd@komainu) (gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) ) #74-Ubuntu SMP Thu Jun 6 19:43:26 UTC 2013

$ uname -a
Linux ubuntu-server 3.2.0-48-generic #74-Ubuntu SMP Thu Jun 6 19:43:26 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux


下载:
$ git clone https://github.com/maxliaops/Unix-Network-Programming.git

配置:
$ cd Unix-Network-Programming/
$ chmod 755 configure
$ ./configure
主要的工作是检查系统是否有源码编译所依赖的各种资源(系统版本是否匹配、编译器、库文件、头文件以及结构体定义等等)
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking for gcc... gcc
checking for C compiler default output... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables...
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ANSI C... none needed
checking for ranlib... ranlib
checking for pthread_create in -lpthread... yes
checking for t_open in -lnsl... no
checking for library containing socket... none required
checking for /usr/local/bind/lib/libbind.a... no
checking for /home/liaops/libbind.a... no
checking for /home/liaops/libresolv.a... no
checking for res_init in -lresolv... no
checking for t_open in -lxti... no
checking for /home/liaops/libunp.a... no
checking for /home/liaops/libunpxti.a... no
checking how to run the C preprocessor... gcc -E
checking for egrep... grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/socket.h... yes
checking for sys/time.h... yes
checking for time.h... yes
checking for netinet/in.h... yes
checking for arpa/inet.h... yes
checking for errno.h... yes
checking for fcntl.h... yes
checking for netdb.h... yes
checking for signal.h... yes
checking for stdio.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for sys/stat.h... yes
checking for sys/uio.h... yes
checking for unistd.h... yes
checking for sys/wait.h... yes
checking for sys/un.h... yes
checking for sys/param.h... yes
checking for sys/select.h... yes
checking for sys/sysctl.h... yes
checking for poll.h... yes
checking for sys/event.h... no
checking for strings.h... yes
checking for sys/ioctl.h... yes
checking for sys/filio.h... no
checking for sys/sockio.h... no
checking for pthread.h... yes
checking for net/if_dl.h... no
checking for xti.h... no
checking for xti_inet.h... no
checking for netconfig.h... no
checking for netdir.h... no
checking for stropts.h... yes
checking whether time.h and sys/time.h may both be included... yes
checking if uint8_t defined... yes
checking if int16_t defined... yes
checking if uint16_t defined... yes
checking if int32_t defined... yes
checking if uint32_t defined... yes
checking if size_t defined... yes
checking if ssize_t defined... yes
checking if socklen_t defined... yes
checking if sa_family_t defined... yes
checking if t_scalar_t defined... no
checking if t_uscalar_t defined... yes
checking for struct sockaddr.sa_len... no
checking for struct sockaddr_storage... yes
checking for struct sockaddr_storage.ss_family... yes
checking for struct msghdr.msg_control... yes
checking for struct ifreq.ifr_mtu... yes
checking for getaddrinfo function prototype in netdb.h... yes
checking for getnameinfo function prototype in netdb.h... yes
checking for gethostname function prototype in unistd.h... yes
checking for getrusage function prototype in sys/resource.h... yes
checking for hstrerror function prototype in netdb.h... yes
checking for if_nametoindex function prototype in net/if.h... yes
checking for inet_aton function prototype in arpa/inet.h... yes
checking for inet_pton function prototype in arpa/inet.h... yes
checking for pselect function prototype in sys/select.h... yes
checking for snprintf function prototype in stdio.h... yes
checking for sockatmark function prototype in sys/socket.h... yes
checking for struct addrinfo... yes
checking for struct if_nameindex... yes
checking for struct sockaddr_dl... no
checking for struct timespec... yes
checking for /dev/tcp... no
checking for /dev/xti/tcp... no
checking for /dev/streams/xtiso/tcp... no
checking for bzero... yes
checking for getaddrinfo... yes
checking for gethostname... yes
checking for gethostbyname2... yes
checking for gethostbyname_r... yes
checking for getnameinfo... yes
checking for hstrerror... yes
checking for if_nametoindex... yes
checking for inet_aton... yes
checking for inet_pton... yes
checking for inet6_rth_init... yes
checking for kqueue... no
checking for kevent... no
checking for mkstemp... yes
checking for poll... yes
checking for pselect... yes
checking for snprintf... yes
checking for sockatmark... yes
checking for vsnprintf... yes
checking for IPv4 support... yes
checking for IPv6 support... yes
checking for Unix domain sockets... yes
checking for multicast support... yes
checking for -I/home/liaops/doc/unp2ev1/src/include... no
configure: creating ./config.status
config.status: creating Makefile
config.status: creating Make.defines
config.status: creating config.h



编译库:

编译所有例程都需要用到的基础库
$ cd lib
$ make

得到静态库文件:libudp.a

查看符号表 (主要是想看一下这个库的各个源文件调用了哪些Linux系统调用)
$ nm -g libunp.a

从中可以发现以下几个文件比较重要,主要是对常用的API进行了一层包装。
wrapsock.o:     对套接字socket的包装
    accept
    bind
    connect
    err_quit
    err_sys
    getenv
    getpeername
    getsockname
    getsockopt
    inet6_rth_add
    inet6_rth_getaddr
    inet6_rth_init
    inet6_rth_reverse
    inet6_rth_segments
    inet6_rth_space
    listen
    poll
    recv
    recvfrom
    recvmsg
    select
    send
    sendmsg
    sendto
    setsockopt
    shutdown
    sockatmark
    socket
    socketpair
    strtol
wrapstdio.o:    对标准IO库中文件相关函数的包装
    fclose
    fdopen
    ferror
    fgets
    fopen
    fputs
wrappthread.o:  对线程库pthread的包装
    pthread_cond_broadcast
    pthread_cond_signal
    pthread_cond_timedwait
    pthread_cond_wait
    pthread_create
    pthread_detach
    pthread_join
    pthread_key_create
    pthread_kill
    pthread_mutex_init
    pthread_mutex_lock
    pthread_mutex_unlock
    pthread_mutexattr_init
    pthread_mutexattr_setpshared
    pthread_once
    pthread_setspecific
wrapunix.o:     对其他常用Linux/Unix系统调用的包装
    __strdup
    calloc
    close
    dup2
    err_quit
    err_sys
    fcntl
    fork
    gettimeofday
    ioctl
    malloc
    mkstemp
    mmap
    open
    pipe
    read
    sigaddset
    sigdelset
    sigemptyset
    sigfillset
    sigismember
    sigpending
    sigprocmask
    sysconf
    sysctl
    unlink
    wait
    waitpid
    write

问题:为什么要对这些API接口进行包装,是否多此一举?




继续编译基本库
$ cd ../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
inet_ntop.c: In function ‘inet_ntop’:
inet_ntop.c:61: error: argument ‘size’ doesn’t match prototype
/usr/include/arpa/inet.h:65: error: prototype declaration
make: *** [inet_ntop.o] Error 1

出现错误!

Fix:
inet_ntop.c第61行 size_t size ->改成 socklen_t size)

再次编译
$ make
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

貌似这次编译的内容并到了libunp.a中,没有生成新的库文件。


$ cd ../libgai
$ make
ar rv ../libunp.a
ranlib ../libunp.a


拷贝生成的库文件到系统库目录
$ cd ..
$ sudo cp libunp.a /usr/lib
$ sudo cp libunp.a /usr/lib32

以后编译代码的时候加上-lunp链接我们的库。

修改unp.h并将其和config.h拷贝到/usr/include中




编译并测试一个基本的客户端例程

$ cd intro/
$ make daytimetcpcli
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o daytimetcpcli.o daytimetcpcli.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -o daytimetcpcli daytimetcpcli.o ../libunp.a -lpthread

编译成功后,在当前目录会生成可执行镜像daytimetcpcli

运行daytimetcpcli
$ ./daytimetcpcli
usage: a.out <IPaddress>

$ ./daytimetcpcli 127.0.0.1
connect error: Connection refused

Fix:
开启daytime服务

$ make daytimetcpsrv
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o daytimetcpsrv.o daytimetcpsrv.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -o daytimetcpsrv daytimetcpsrv.o ../libunp.a -lpthread

sudo ./daytimetcpsrv &

再次运行daytimetcpcli
$ ./daytimetcpcli 127.0.0.1
Mon Mar 3 22:47:35 2014