用autoconf和automake自动生成makefile

本文介绍了一个具体的项目构建实例,展示了如何利用Autoconf和Automake来生成Makefile,实现项目的自动化编译。从目录结构搭建开始,详细解释了配置文件的编写过程,并通过具体代码文件说明了其工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先创建一个工程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;
}

下面是用autoconfautomake制作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.acAC_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编译即可。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值