以下是APUE第二版和第一版源码的编绎和执行过程:
1. Advanced Programming in the UNIX® Environment: Second Edition (APUE第二版)
a. 进入APUE网站下载Source code: src.tar.tar。
b. 当前压缩包路径/APUEDIR/,解压并进入源码目录apue.2e。
$ ls src.tar.tar $ tar -zxvf src.tar.tar ... $ ls apue.2e src.tar.tar $ cd apue.2e/
c. 了解并获取当前系统支持的Makefile类型:Make.defines.freebsd,Make.defines.linux,Make.defines.macos,Make.defines.solaris其中之一。
$ sh systype.sh (查看系统类型) linux $ vi Make.defines.linux (编辑相应的Makefile文件,设置当前工作目录) #WKDIR=/home/sar/apue.2e WKDIR=/APUEDIR/apue.2e #更改为当前源码目录 (保存退出)
d. 编绎
d.1. 若想一次编绎所有文件
$ cd /APUEDIR/apue.2e/ $ make (编绎出错,找不到nawk命令) ... nawk -f makeconf.awk >conf.c /bin/sh: line 1: nawk: command not found make[2]: *** [conf.c] Error 127 ... $ 修改std/linux.mk,将nawk更改为awk或gawk,或执行ln -s /bin/gawk $HOME/bin/nawk,生成一个nawk $ make clean (消除之前的编绎过程记录) $ make (重新编绎) (会出现一些warning信息,无妨)
d.2. 若只想单独测试某个程序,如advio/mcopy.c,此程序用于拷贝文件,并生成文件副本:
$ cd /APUEDIR/apue.2e/advio/ $ cp linux.mk Makefile (建立当前工作目录下的Makefile文件,作者已在所有目录下放置了四个.mk文件,分别对应四个系统) $ make clean (清除当前工作目录下已经编绎过的可执行文件及目标文件) $ make mcopy (编绎指定的单个程序,无后缀) gcc -DLINUX -ansi -I/APUEDIR/apue.2e/include -Wall -D_GNU_SOURCE -L../lib mcopy.c ../lib/libapue.a -o mcopy $ ./mcopy (非法执行,无参数) usage: ./mcopy $ ./mcopy linux.mk linux.mk.bak (正确执行,拷贝linux.mk,生成文件副本linux.mk.bak) $ ls Makefile catgetmsg.c devzero.c freebsd.mk linux.mk linux.mk.bak macos.mk mcopy mcopy.c nonblockw.c pendlock.c solaris.mk
2. Advanced Programming in the Unix Environment (APUE第一版)
a. 主站似乎已经无法匿名登录。
b. 当前压缩包路径/APUEDIR/,解压并进入源码目录/APUEDIR/apue/。
$ ls stevens.advprog.tar.Z $ tar -zxvf stevens.advprog.tar.Z $ ls apue stevens.advprog.tar.Z $ cd apue/
c. 了解并获取当前系统支持的Makefile类型:Make.def.44,Make.def.sun,Make.def.svr4其中之一。
$ cd lib.sun/ 或 $ cd lib.44/ 或 $ cd lib.svr4/,进入任一目录,这些目录其中之一即系统编绎目录,也是生成库文件libmisc.a的目录 $ sh systype.sh (查看最接近的当前系统类型,作者似乎对三个目录的systype.sh文件作了硬连接,修改其中任何一个,都会使其它目录的这个文件也作相应变化) svr4 $ cd .. (进入上层目录,即apue/) $ cp Make.def.svr4 Make.defines $ vi Make.defines (设置库文件libmisc.a地址) ... #LDFLAGS=/home/stevens/libmisc.a LDFLAGS=/APUEDIR/apue/libmisc.a ... #LIB = /home/stevens/libmisc.a LIB = /APUEDIR/apue/libmisc.a ... (保存退出) $ cd lib.svr4/ (进入主编绎目录,即apue/lib.svr4/) $ vi Makefile #make `systype.sh` make `/bin/bash systype.sh` (添加执行路径,否则程序无反应导致make失败) (保存退出)
d. 编绎
$ cd /APUEDIR/apue/lib.svr4/ (进入主编绎目录) $ make (make失败,重复定义) ... strerror.c:3: conflicting types for 'sys_errlist' /usr/include/bits/sys_errlist.h:28: previous declaration of 'sys_errlist' make[2]: *** [strerror.o] Error 1 ... $ vi strerror.c (修改当前目录下的错误处理文件) //extern char *sys_errlist[]; //extern int sys_nerr; (将这两行注释掉,/usr/include/bits/sys_errlist.h中已有声明,如今这个文件已不推荐使用,但仍然被包含在/usr/include/stdio.h文件中) (保存退出)
e. 生成后期程序编绎需要依赖的库文件libmisc.a
$ cd /APUEDIR/apue/lib.svr4/ $ make clean (清除已编绎记录) rm -f *.o a.out core temp.* $ make (重新编绎) $ cd .. (编绎完成,返回上层目录,即apue/) $ ls (已生成一个库文件libmisc.a,所有的程序都需要依赖这个文件进行编绎) ... libmisc.a ...
f. 开始测试某个程序,如advio/mcopy.c,此程序用于拷贝文件,并生成文件副本:
$ cd /APUEDIR/apue/advio/ $ make clean (清除当前工作目录下已经编绎过的可执行文件及目标文件) $ make mcopy (编绎指定的单个程序,无后缀) cc /home/zhangfeng/apue/oldapue/apue/libmisc.a mcopy.c /home/zhangfeng/apue/oldapue/apue/libmisc.a -o mcopy /home/zhangfeng/apue/oldapue/apue/libmisc.a(strerror.o): In function 'strerror': strerror.o(.text+0x18): 'sys_errlist' is deprecated; use 'strerror' or 'strerror_r' instead strerror.o(.text+0xf): 'sys_nerr' is deprecated; use 'strerror' or 'strerror_r' instead (暂时忽略警告信息) $ ./mcopy (非法执行,无参数) usage: a.out $ ./mcopy Makefile Makefile.bak (正确执行,拷贝Makefile,生成文件副本Makefile.bak) $ ls Makefile Makefile.bak catgetmsg.c devzero.c mcopy mcopy.c nonblockw.c ourhdr.h pollpipe.c selectpipe.c