使用autoconf生成Makefile并编译工程的步骤
前言
在Linux下,编译和链接需要用Makefile,而写好一个Makefile可不容易,写出一个规范的Makefile更是麻烦。我们可以利用autoconf来生成一个Makefile,尤其在大型工程里,能省去很多麻烦。
这里我会用一个工程来说明怎么做,有一些步骤不是必须的,但是如果你看不出来哪些步骤不是必须的,最好跟着一步步走,因为某些步骤省略了,代码也需要做出相应修改(如修改路径等)。
步骤
首先安装autoconf
sudo apt-get install autoconf
新建一个项目文件夹(例如:joy)
mkdir joy
cd joy
在里面新建两个文件夹 lib 和 src ,用于放工程的库文件和源文件。
mkdir lib
mkdir src
如下图所示:
进入lib文件夹,新建一个头文件,如:haha.h,随便声明个函数吧。
cd lib
gedit haha.h
//haha.h
#include <stdio.h>
void printhaha();
进入src文件夹,新建一个C文件,如:haha.c,实现头文件的函数;新建一个C文件,如:main_code.c,编写主函数。
cd ../src
gedit haha.c
//haha.c
#include "../lib/haha.h"
void printhaha()
{
printf("hahan");
}
//main_code.c
#include "../lib/haha.h"
void main()
{
printhaha();
}
回到joy文件夹下,我们的工程文件都已经写好了
cd ..
运行autoscan生成configure.scan
autoscan
编辑configure.scan
gedit configure.scan
编辑之前的文件是这样的
#编辑之前的原始文件
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.69])
AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
AC_CONFIG_SRCDIR([src/haha.c])
AC_CONFIG_HEADERS([config.h])
# Checks for programs.
AC_PROG_CC
# Checks for libraries.
# Checks for header files.
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_OUTPUT
前缀AC指的是 AutoConf AC_PREREQ不用管 AC_INIT里面填【包名】【版本】【BUG提交地址 也就是你的邮箱】 AC_CONFIG_SRCDIR里填源文件路径下的任意一个文件名,autoconf通过检测这个文件是否存在,判断这个路径是否正确,一般不用管 AC_CONFIG_HEADERS不用管 插入下面这句,automake阶段需要,否则会报错 AM_INIT_AUTOMAKE 前缀AM指的是 AutoMake 最后的AC_OUTPUT,改为AC_OUTPUT(Makefile) 修改完之后的文件如下所示:
#修改后的文件
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.69])
AC_INIT(hhh, 1.0, idontknow@666.com)
AC_CONFIG_SRCDIR([src/haha.c])
AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE
# Checks for programs.
AC_PROG_CC
# Checks for libraries.
# Checks for header files.
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_OUTPUT(Makefile)
保存,并将configure.scan重命名为configure.ac
新建Makefile.am
gedit Makefile.am
输入以下代码
AUTOMAKE_OPTIONS=
foreign
subdir-objects
bin_PROGRAMS=test_prj
test_prj_SOURCES=
lib/haha.h
src/haha.c
src/main_code.c
AUTOMAKE_OPTIONS后面是automake的执行选项,用空格隔开; foreign指的是只检测必须的文件; subdir-objects指的是编译生成的.o文件可以放在子路径(跟源文件放一起),没有这个选项的话,所有.o文件都会放在工程根目录下; bin_PROGRAMS 后面的名字是 生成的可执行二进制文件名 可以有多个 bin_PROGRAMS ,但每个 bin_PROGRAMS 都需要有相对应的 xxx_SOURCES ; xxx_SOURCES 是 可执行文件xxx的依赖项,包括头文件,源文件等
用aclocal生成aclocal.m4文件
aclocal
用autoconf生成configure文件
autoconf
用autoheader生成config.h.in
autoheader
用automake生成Makefile.in,需要加上 –add-missing使其自动加上缺省文件
automake --add-missing
然后我们这个软件就做好了,可以整个包拿去上传github或者开源论坛了。
别人下载了我们的源码包之后怎么编译链接可执行文件呢?或者说我们怎么编译链接我们的可执行文件呢?
以下是源码安装的一般步骤,也是我们编译链接的步骤
首先生成Makefile
./configure
然后make
make
现在我们可以看见,可执行文件 test_prj 已经被生成出来了
运行一下,结果如下:
结果是正确的。
进入src目录下,我们发现多了两个文件
这就是AUTOMAKE_OPTIONS里subdir-objects的作用,少了这句话,这两个.o文件就会出现在你的根目录下。如果很不幸你的工程比较大,有同名文件的话,那就可能出现很严重的后果了,所以这句话建议加上。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对ZaLou.Cn的支持。如果你想了解更多相关内容请查看下面相关链接
- 使用jQuery封装实用函数
- scala 学习笔记(05) OOP(中)灵活的trait
- Web Fundamentsals学习1-Multiple-Screen-Site
- Vagrant使用
- java 中的异步回调
- 澳大利亚域名管理机构多年敲竹杠?
- ASP.NET中使用HttpWebRequest调用WCF
- scala 学习笔记(06) OOP(下)多重继承 及 AOP
- Angular企业级开发(4)-ngResource和REST介绍
- CSS魔法堂:"那不是bug,是你不懂我!" by inline-block
- scala 学习笔记(03) 参数缺省值、不定个数参数、类的属性(Property)、泛型初步
- Cmd Markdown编辑器简明语法手册
- 如何让spring mvc web应用启动时就执行特定处理
- CSS魔法堂:小结一下Box Model与Positioning Scheme
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- OpenGL ES 绘制纹理
- Win10+Unlocker3+VMware15.5+MacOS10.14+xcode+QT for ios+虚拟机苹果系统 自用 实践笔记
- OpenGL ES 纹理过滤模式-glTexParameteri
- Jenkins时间修改为北京时间
- OpenGL ES for Android 绘制一个点
- OpenGL ES for Android 绘制线
- Jenkins自定义主题
- OpenGL ES for Android 绘制三角形
- Centos7 安装 Tomcat8 的正确姿势 并设置开机自启 实践笔记
- ASP.NET Core 使用 Google 验证码(reCAPTCHA v3)代替传统验证码
- Centos7 安装 Tomcat8 伪集群 的正确姿势 并设置开机自启 实践笔记
- 问题合集,持续更新
- ASP.NET Core Swagger接入使用IdentityServer4 的 WebApi
- 基于IdentityServer4的OIDC实现单点登录(SSO)原理简析
- OpenGL ES 变量、结构体、语句、函数、精度