CentOS 7.6 进行编译
使用cat /etc/redhat-release
看到操作系统是CentOS Linux release 7.6.1810 (Core)
,使用uname -r
看到内核是3.10.0-957.el7.x86_64
,gcc --version
可以看到gcc版本是4.8.5
。
wget http://www.apuebook.com/src.3e.tar.gz
下载《Unix环境高级编程》第三版里边提供的源代码。
tar -xf src.3e.tar.gz
进行解压,cd apue.3e/
进入到解压的源代码目录里边。
执行make
。
报错如下:
/tmp/ccMz5Ijf.o: In function `thr_fn':
barrier.c:(.text+0x80): undefined reference to `heapsort'
collect2: error: ld returned 1 exit status
make[1]: *** [barrier] Error 1
make[1]: Leaving directory `/code/clanguagecode/apue.3e/threads'
make: *** [all] Error 1
yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
。
yum install -y libbsd libbsd-devel
安装。
成功截图如下:
make
再次执行。
执行成功如下:
Ubuntu 20.04 进行编译
lsb_release -a
看到操作系统的版本是Ubuntu 20.04.4
,uname -r
看到操作系统内核的版本是5.4.0-100-generic
,gcc --version
看到gcc的版本是9.3.0
。
sudo wget http://www.apuebook.com/src.3e.tar.gz
下载源代码。
sudo tar xf src.3e.tar.gz
进行解压,cd apue.3e/
进入到解压的源代码目录里边。
sudo make
进行编译。
报错如下:
/usr/bin/ld: /tmp/cc4I3NHz.o: in function `main':
devrdev.c:(.text+0xc5): undefined reference to `minor'
/usr/bin/ld: devrdev.c:(.text+0xdb): undefined reference to `major'
/usr/bin/ld: devrdev.c:(.text+0x128): undefined reference to `minor'
/usr/bin/ld: devrdev.c:(.text+0x13e): undefined reference to `major'
collect2: error: ld returned 1 exit status
make[1]: *** [Makefile:18: devrdev] Error 1
make[1]: Leaving directory '/code/clanguagecode/apue.3e/filedir'
make: *** [Makefile:6: all] Error 1
参考博文:Ubuntu20.04 编译运行apue.3e 避坑指南
Unix 环境高级编程书(第三版)源码编译(apue.3e)
Unix环境高级编程(第3版)环境搭建
sudo cat -n ./filedir/devrdev.c | grep "#endif"
看到./filedir/devrdev.c
里边只有第4行中有#endif
这个字符串,sudo cat -n ./filedir/devrdev.c | grep "#include <sys/sysmacros.h>"
可以看到./filedir/devrdev.c
文件里边没有#include <sys/sysmacros.h>
这个头文件。
sudo sed -i 's:#endif:#endif\n#include <sys/sysmacros.h>:g' ./filedir/devrdev.c
文件里边的字符串#endif
下添加#include <sys/sysmacros.h>
一行头文件,sudo cat -n ./filedir/devrdev.c | grep "#include <sys/sysmacros.h>"
可以看到#include <sys/sysmacros.h>
添加到./filedir/devrdev.c
第5行了。
sudo make
执行。
发现报错如下:
gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE buf.c -o buf -L../lib -lapue
buf.c: In function ‘is_unbuffered’:
buf.c:90:15: error: ‘FILE’ {aka ‘struct _IO_FILE’} has no member named ‘__pad’; did you mean ‘__pad5’?
90 | #define _flag __pad[4]
| ^~~~~
buf.c:98:13: note: in expansion of macro ‘_flag’
98 | return(fp->_flag & _IONBF);
| ^~~~~
buf.c: In function ‘is_linebuffered’:
buf.c:90:15: error: ‘FILE’ {aka ‘struct _IO_FILE’} has no member named ‘__pad’; did you mean ‘__pad5’?
90 | #define _flag __pad[4]
| ^~~~~
buf.c:104:13: note: in expansion of macro ‘_flag’
104 | return(fp->_flag & _IOLBF);
| ^~~~~
buf.c: In function ‘buffer_size’:
buf.c:92:15: error: ‘FILE’ {aka ‘struct _IO_FILE’} has no member named ‘__pad’; did you mean ‘__pad5’?
92 | #define _base __pad[2]
| ^~~~~
buf.c:111:13: note: in expansion of macro ‘_base’
111 | return(fp->_base - fp->_ptr);
| ^~~~~
buf.c:91:14: error: ‘FILE’ {aka ‘struct _IO_FILE’} has no member named ‘__pad’; did you mean ‘__pad5’?
91 | #define _ptr __pad[1]
| ^~~~~
buf.c:111:25: note: in expansion of macro ‘_ptr’
111 | return(fp->_base - fp->_ptr);
| ^~~~
buf.c: In function ‘is_unbuffered’:
buf.c:99:1: warning: control reaches end of non-void function [-Wreturn-type]
99 | }
| ^
buf.c: In function ‘is_linebuffered’:
buf.c:105:1: warning: control reaches end of non-void function [-Wreturn-type]
105 | }
| ^
buf.c: In function ‘buffer_size’:
buf.c:115:1: warning: control reaches end of non-void function [-Wreturn-type]
115 | }
| ^
make[1]: *** [Makefile:16: buf] Error 1
make[1]: Leaving directory '/code/clanguagecode/apue.3e/stdio'
make: *** [Makefile:6: all] Error 1
需要把下边的内容删除:
#ifdef _LP64
#define _flag __pad[4]
#define _ptr __pad[1]
#define _base __pad[2]
#endif
可以直接使用vim
找到上边的内容,然后进行删除。但是我这里采取sed
的删除方法,接下来的操作就是为了删除上边的内容,sudo sed -n '89,+4p' ./stdio/buf.c
可以看到上边的内容是在89~93行。
sudo sed '89,93d' ./stdio/buf.c > ./stdio/buf_bak.c
可以把89~93行删除之后的内容保存到./stdio/buf_bak.c
。
sudo rm -rf ./stdio/buf.c
把./stdio/buf.c
文件删除,sudo cp ./stdio/buf_bak.c ./stdio/buf.c
把buf_bak.c
更名为buf.c
,sudo sed -n '89,+4p' ./stdio/buf.c
可以看到89~93行内容已经更改了。
sudo cat -n ./stdio/buf.c | grep "_flag"
看一下_flag
在./stdio/buf.c
中的位置。
sudo sed -i 's:return(fp->_flag \& _IONBF);:return(fp->_flags \& _IONBF);:g' ./stdio/buf.c
将return(fp->_flag \& _IONBF);
替换为return(fp->_flags \& _IONBF);
,将fp->_flag
后加个s
。
sudo sed -i 's:return(fp->_flag \& _IOLBF);:return(fp->_flags \& _IOLBF);:g' ./stdio/buf.c
将return(fp->_flag \& _IOLBF);
替换为return(fp->_flags \& _IOLBF);
,将fp->_flag
后加个s
。
sudo make clean && sudo make
执行。
发现报错如下:
buf.c: In function ‘buffer_size’:
buf.c:106:11: error: ‘FILE’ {aka ‘struct _IO_FILE’} has no member named ‘_base’
106 | return(fp->_base - fp->_ptr);
| ^~
buf.c:106:23: error: ‘FILE’ {aka ‘struct _IO_FILE’} has no member named ‘_ptr’
106 | return(fp->_base - fp->_ptr);
| ^~
buf.c:110:1: warning: control reaches end of non-void function [-Wreturn-type]
110 | }
| ^
make[1]: *** [Makefile:16: buf] Error 1
make[1]: Leaving directory '/code/clanguagecode/apue.3e/stdio'
make: *** [Makefile:6: all] Error 1
sudo sed -i 's:return(fp->_base - fp->_ptr);:return(fp->_IO_buf_end - fp->_IO_buf_base);:g' ./stdio/buf.c
将return(fp->_base - fp->_ptr);
替换为return(fp->_IO_buf_end - fp->_IO_buf_base);
。
sudo make clean && sudo make
执行。
发现报错
/usr/bin/ld: cannot find -lbsd
collect2: error: ld returned 1 exit status
make[1]: *** [Makefile:31: badexit2] Error 1
make[1]: Leaving directory '/code/clanguagecode/apue.3e/threads'
make: *** [Makefile:6: all] Error 1
sudo apt-get install -y libbsd-dev
安装libbsd-dev
。
sudo make clean && sudo make
执行。
完成如下:
执行示例代码
在apue.3e/figlinks
目录下有书本代码图片编号对应示例代码的软连接,可以更快找到对应源码。