首先创建一个工程project:
Project目录如下:
project
| ——src
| ——common
| ——comhead.h
| ——include
——streamutils.h
| ——utils
| ——streamutils.cc
| ——testautomake.cc
comhead.h内容为:
#ifndef __COMHEAD_H
#define __COMHEAD_H
#include <iostream>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
using namespace std;
const int INIT_BLK_SIZE = 100;//bytes
#endif
Streamutils.h的内容为:
#ifndef __STREAMUTILS_H
#define __STREAMUTILS_H
class StreamUtils{
public:
static int8_t readInt8(int fd);
static int16_t readInt16(int fd);
static int32_t readInt32(int fd);
static int64_t readInt64(int fd);
static u_int32_t readByLength(int fd,int length,char *);
static u_int32_t writeInt8(int fd,int8_t value);
static u_int32_t writeInt16(int fd,int16_t value);
static u_int32_t writeInt32(int fd,int32_t value);
static u_int32_t writeInt64(int fd,int64_t value);
static u_int32_t writeByLength(int fd,int length,char *);
};
#endif
Streamutils.cc的内容为:
#include "comhead.h"
#include "streamutils.h"
/*
* @return :0 ,error
**/
int8_t StreamUtils::readInt8(int fd){
int8_t byte;
ssize_t len = read(fd,&byte,1);
if(len <= 0){
return len;
}
return byte;
}
/*
* @return : 0,error
*/
int16_t StreamUtils::readInt16(int fd){
int16_t tint16 ;
ssize_t len = read(fd,&tint16,2);
if(len < 0){
return len;
}
return tint16;
}
/*
* @return : 0,error
*/
int32_t StreamUtils::readInt32(int fd){
int32_t tint32 ;
ssize_t len = read(fd,&tint32,4);
if(len < 0){
return len;
}
return tint32;
}
/*
*@return : o,error
*/
int64_t StreamUtils::readInt64(int fd){
int64_t tint64;
ssize_t len = read(fd,&tint64,8);
if(len < 0){
return len;
}
return tint64;
}
/*
* @return : 0,error;
*/
u_int32_t StreamUtils::readByLength(int fd,int length,char * buffer){
u_int32_t len = read(fd,buffer,length);
return len;
}
u_int32_t StreamUtils::writeInt8(int fd,int8_t value){
u_int32_t len = write(fd,&value,1);
return len;
}
/*
* @return : 0,error
*/
u_int32_t StreamUtils::writeInt16(int fd,int16_t value){
u_int32_t len = write(fd,&value,2);
return len;
}
/*
* @return : 0,error
*/
u_int32_t StreamUtils::writeInt32(int fd,int32_t value){
u_int32_t len = write(fd,&value,4);
return len;
}
/*
*@return : o,error
*/
u_int32_t StreamUtils::writeInt64(int fd,int64_t value){
u_int32_t len = write(fd,&value,8);
return len;
}
/*
* @return : 0,error;
*/
u_int32_t StreamUtils::writeByLength(int fd,int length,char * buffer){
u_int32_t len = write(fd,buffer,length);
return len;
}
Testautomake.cc的内容为:
#include "comhead.h"
#include "streamutils.h"
int main(){
int fd = open("/dev/urandom",O_RDONLY);
u_int32_t data;
data = StreamUtils::readInt32(fd);
close(fd);
cout<<"data :"<<data<<endl;
}
下面是用autoconf和automake制作makefile的过程:
一、在project目录下,运行autoscan,生成configure.scan文件,修改configure.scan的内容为如下:
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.63)
AC_INIT(testautomake, 1.0, iechyu@163.com)
AM_INIT_AUTOMAKE(testautomake,1.0)//automake命令必须的宏
AC_CONFIG_SRCDIR([src/testautomake.cc])
AC_CONFIG_HEADERS(config.h)
# Checks for programs.
AC_PROG_CXX
AC_PROG_CC
# Checks for libraries.
# Checks for header files.
AC_CHECK_HEADERS([arpa/inet.h fcntl.h netinet/in.h stdlib.h string.h sys/socket.h unistd.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_TYPE_INT16_T
AC_TYPE_INT32_T
AC_TYPE_INT64_T
AC_TYPE_INT8_T
AC_TYPE_SSIZE_T
AC_PROG_RANLIB //生成静态库必须的宏
# Checks for library functions.
AC_SUBST([DOLLAR_SIGN],[$])//定义DOLLAR_SIGN代表“$”,在makefile.am中不能直接使用“$”,否则的会出错。
//下面是配置生成的Makefile的位置。我们在3个目录(包含需要编译的文件的目录)中生成Makefile文件
AC_OUTPUT([Makefile
src/Makefile
src/utils/Makefile])
修改configure.scan文件后,将其改名为:configure.ac
一、运行aclocal命令,生成用户定义的宏。
二、运行autoconf,生成configure文件
三、运行autoheader。生成config.h.in文件
四、编写Makefile.am
在configure.ac的AC_OUTPUT宏中指定的目录中分别编写Makefile.am文件,在project目录中的Makefile.am内容为:
SUBDIRS= src/utils src //配置,在处理当前目录前需要一次处理的目录,目录的顺序很重要
CURRENTPATH= @DOLLAR_SIGN@(shell pwd)//利用了configure.ac中定义的宏代表“$”
INCLUDES=-I$(CURRENTPATH)/src/include -I$(CURRENTPATH)/src/common//定义头文件包含的目录
#CPFLAG:=$(DEFS)
export INCLUDES
Src/Makefile.am的内容为:
bin_PROGRAMS=testautomake //指定生成的可执行文件的名称,可以包含路径。
testautomake_SOURCES=testautomake.cc
testautomake_LDADD=$(top_srcdir)/src/utils/libstreamutils.a //指定需要链接的目标文件或静态库
testautomake_LDFLAGS=-D_GNU_SOURCE //编译选项,比如需要使用的动态库-lpthread
DEFS+=-D_GNU_SOURCE
export INCLUDES
Src/utils/Makefile.am的内容为:
//通常用noinst_LIBRARIES来生成静态库来代表目标文件,因为automake中没有用于生成目标文件的宏,还有一种方法是使用noinst_PROGRAMS来生成目标文件,但是需要更改automake生成的makefile.in文件,注释掉生成可执行文件的链接目标文件的过程,比较麻烦。
noinst_LIBRARIES=libstreamutils.a //生成的静态库文件,可以包含路径,如果要生成动态库,要用到libtool ,相应为noinst_LTLIBRARIES
libstreamutils_a_SOURCES=streamutils.cc
INCLUDES=-I$(top_srcdir)/src/include -I$(top_srcdir)/src/common//头文件的目录路径,如果在project目录中的Makefile.am文件中指定了INCLUDE,则在这里不必再指定。
一、Makefile.am文件编写完成后,执行automake --add-missing --copy(可不要),在各包含Makefile.am的目录生成Makefile.in文件。
二、运行./configure即可生成Makefile,然后使用make编译即可。