导读
在学习Unix高级环境编程与Unix网络编程的时候,按照作者的提示操作即可成功的编译运行这两本书提供的源代码,但是如果自己想想在自己的环境里按照书籍学习,也就是在自己的环境里调用作者封装的api该怎么办呢?很直接的想法是将作者提供的api编译成Linux下的库,然后将需要的头文件和可文件拷贝到系统存放头文件和库文件的位置就可以了,查阅资料之后,成功的在Ubuntu16.04上搭建好了这两本书的运行环境。
软件环境
- Ubuntu16.04
- make
- cmake
- gcc-5.4.0
- CLion
搭建apue.3e开发环境
- 从官网下载apue.3e源代码到本地
- 解压源文件
tar -xvf apue.3e.tar.gz
- 安装依赖
libbsd-dev
sudo apt-get install libbsd-dev
- 进入在apue.3e目录下执行
make
命令,会在lib目录下生成libapue.a的库文件 - 用管理权限将相应的头文件和库文件拷贝到系统目录
cp ./include/apue.h /usr/include
cp ./lib/libapue.a /usr/lib
cp ./lib/error.c /usr/include
- 测试
#include <apue.h>
int
main(int argc, char *argv[]) {
printf("process id : %d", getpid());
exit(0);
}
- 编译运行
g++ -0 apue_test main.cpp
到此为止,apue.3e的开发环境就搭建好啦,下面我们继续搭建《Unix网络编程》这本书的开发环境!
搭建unp开发环境
- 从官网下载unpv13e的源代码
- 解压源代码
tar -xvf unpv13e.tar.gz
- 在目录unpe13v下依次执行以下命令编译源代码
./configure
cd lib
make
cd ../libfree
make
cd ../libroute
make // 这一步可能会出错,是因为你的系统不支持4.4BSD,并不影响本书的学习
cd ../libgai
make
cd ..
- 将生成的libunp.a拷贝至系统库目录
sudo cp libunp.a /usr/lib
- 将修改
lib/unp.h
中#include "../config.h"
为#include "config.h"
- 将
lib/unp.h
以及config.h
拷贝至系统头文件目录
sudo cp ./lib/unp.h /usr/include
sudo cp config.h /usr/include
- 在CLion中创建一个CPP项目测试
intro/daytimesrv.c
#include "unp.h"
#include <time.h>
int
main(int argc, char **argv)
{
int listenfd, connfd;
struct sockaddr_in servaddr;
char buff[MAXLINE];
time_t ticks;
listenfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(8080); /* daytime server */
Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
for ( ; ; ) {
connfd = Accept(listenfd, (SA *) NULL, NULL);
ticks = time(NULL);
snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
Write(connfd, buff, strlen(buff));
Close(connfd);
}
}
- 编译
daytimetcpsrv.c
gcc -o daytimetcpsrv daytimetcpsrv.c
-lunp 运行
./daytimetcpsrv
问题
如果用g++编译运行还是会出错,至今未解决,希望有人解决了可以告知,谢谢啦!
g++ -o daytimesrv daytimetcpsrv.cpp -lunp
/tmp/cc4nI2AN.o: In function `main':
daytimetcpsrv.c:(.text+0x37): undefined reference to `Socket(int, int, int)'
daytimetcpsrv.c:(.text+0x97): undefined reference to `Bind(int, sockaddr const*, unsigned int)'
daytimetcpsrv.c:(.text+0xa9): undefined reference to `Listen(int, int)'
daytimetcpsrv.c:(.text+0xc0): undefined reference to `Accept(int, sockaddr*, unsigned int*)'
daytimetcpsrv.c:(.text+0x133): undefined reference to `Write(int, void*, unsigned long)'
daytimetcpsrv.c:(.text+0x140): undefined reference to `Close(int)'
collect2: error: ld returned 1 exit status