https://cloud.tencent.com/developer/article/2142074
一、概述
利用 GNU Autoconf 及 Automake 这两套工具来协助我们自动产生 Makefile文件,并且让开发出来的软件可以像大多数源码包那样,只需"./configure", “make”,“make install” 就可以把程序安装到系统中。
目前automake支持三种目录层次:flat、shallow和deep:
-
flat指的是所有文件都位于同一个目录中。
就是所有源文件、头文件以及其他库文件都位于当前目录中,且没有子目录。Termutils就是这一类。
-
shallow指的是主要的源代码都储存在顶层目录,其他各个部分则储存在子目录中。
就是主要源文件在当前目录中,而其它一些实现各部分功能的源文件位于各自不同的目录。automake本身就是这一类。
-
deep指的是所有源代码都被储存在子目录中;顶层目录主要包含配置信息。
就是所有源文件及自己写的头文件位于当前目录的一个子目录中,而当前目录里没有任何源文件。
二、安装
三、基本使用
1graph TB;
2source[源码root];
3configure.scan;
4configure.in;
5aclocal.m4;
6configure;
7Makefile.am;
8Makefile.in;
9Makefile;
10start(开始)
11start2(开始)
12
13start2 --编程-->source;
14source --autoscan--> configure.scan;
15configure.scan --手动编辑--> configure.in;
16configure.in --aclocal--> aclocal.m4;
17configure.in --autoconf--> configure;
18aclocal.m4 --autoconf--> configure;
19start --手动创建--> Makefile.am
20Makefile.am --automake--> Makefile.in;
21configure.in --> Makefile.in;
22Makefile.in --> Makefile
23configure --> Makefile;
1.编写C代码文件
1vim app.c
1#include <stdio.h>
2#include <stdlib.h>
3
4int main(int argc, char **argv){
5 int i;
6 for(i=0; i<argc; i++){
7 printf("argv[%d]=%s\n", i, argv[i]);
8 }
9 return 0;
10}
2.执行autoscan命令生成configure.scan文件
生成configure.scan文件之后,将文件修改成configure.ac文件,如果没有这个.ac文件,执行aclocal命令的时候会报错。
1autoscan
2ls
3mv configure.scan configure.ac
3.修改configure.ac文件参数
初始生成的configure.ac:
1# -*- Autoconf -*-
2# Process this file with autoconf to produce a configure script.
3
4AC_PREREQ([2.71])
5AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
6AC_CONFIG_SRCDIR([app.c])
7AC_CONFIG_HEADERS([config.h])
8
9# Checks for programs.
10AC_PROG_CC
11
12# Checks for libraries.
13
14# Checks for header files.
15
16# Checks for typedefs, structures, and compiler characteristics.
17
18# Checks for library functions.
19
20AC_OUTPUT
每个configure.ac文件都是以AC_INIT开头,以AC_OUTPUT结束。
AC_PROG_RANLIB如果是多线程的程序的话要加入这句话,要不运行automake命令时会出错
AC_INIT 测试程序 测试函数库 测试头文件 测试类型定义 测试结构 测试编译器特性 测试库函数 测试系统调用 AC_OUTPUT
文件解释:
-
AC_PREREQ宏声明本文件要求的autoconf版本,本例使用的版本为2.71。
-
AC_INIT()中分别的是: 软件包的名字,版本,作者的联系方式(一般是Email)
AC_INIT宏用来定义软件的名称和版本等信息,”FULL-PACKAGE-NAME”为软件包名称,”VERSION”为软件版本号,”BUG-REPORT-ADDRESS”为BUG报告地址(一般为软件作者邮件地址)。
1AC_INIT([app], [1.1.2], [[email protected]])
-
在下面再自己添加一行AM_INIT_AUTOMAKE(),里面填入: 程序名字,版本号。
1AM_INIT_AUTOMAKE(app,1.1.2)
-
AC_CONFIG_SRCDIR宏用来侦测所指定的源码文件是否存在,来确定源码目录的有效性。此处为当前目录下的app.c。
-
AC_CONFIG_HEADER宏用于生成config.h文件,以便autoheader使用。
-
AC_PROG_CC用来指定编译器,如果不指定,选用默认gcc。 比如: AC_PROG_CC(gcc)
-
AC_OUTPUT用来设定 configure 所要产生的文件,如果是makefile,configure会把它检查出来的结果带入makefile.in文件产生合适的makefile。使用Automake时,还需要一些其他的参数,这些额外的宏用aclocal工具产生。(如上流程图)
最后AC_OUTPUT()填写生成的文件名称。
1AC_OUTPUT(Makefile)
修改之后的configure.ac:
1# -*- Autoconf -*-
2# Process this file with autoconf to produce a configure script.
3
4AC_PREREQ([2.71])
5AC_INIT([app], [1.1.2], [[email protected]])
6AM_INIT_AUTOMAKE(app,1.1.2)
7AC_CONFIG_SRCDIR([app.c])
8AC_CONFIG_HEADERS([config.h])
9
10# Checks for programs.
11AC_PROG_CC
12
13# Checks for libraries.
14
15# Checks for header files.
16
17# Checks for typedefs, structures, and compiler characteristics.
18
19# Checks for library functions.
20
21AC_OUTPUT(Makefile)
4.执行aclocal命令生成aclocal.m4文件
1aclocal
2ls
5.使用autoconf工具生成configure文件
1autoconf
2ls
6.使用autoheader生成config.h.in文件
1autoheader
7.手工编辑Makefile.am文件
Makefile.am是一种比Makefile更高层次的规则。只需指定要生成什么目标,它由什么源文件生成,要安装到什么目录等构成。
Automake工具会根据config.in中的参量把Makefile.am转换成Makefile.in文件。在使用Automake之前,要先手动建立Makefile.am文件。
文件创建之后,需要写三项代码:
-
第一项:软件规范,有三个候选项:foreign(国外),gnu(GNU),gnits
如果使用foreign等级,它只检测必须的文件
-
第二项:生成的可执行文件名
-
第三项:生成可执行文件所需的原始文件,有多个文件时用空格隔开。
1touch Makefile.am
2vim Makefile.am
1AUTOMAKE_OPTIONS=foreign
2bin_PROGRAMS=app
3app_SOURCES=app.c
8.使用automake命令生成Makefile.in文件
添加选项–add-missing 可以让automake工具自动添加必要的脚本文件
注意: 不能在共享目录下执行,因为共享目录下是windows文件系统(FA32/NTFS),不支持link操作。
1automake
9.运行configure配置生成最终的Makefile文件
configure脚本为了让一个程序能够在各种不同类型的机器上运行而设计的。在使用make编译源代码之前,configure会根据自己所依赖的库而在目标机器上进行匹配。
约定俗成的,所有的configure脚本都把脚本文件名起为configure,一般来讲都是shell脚本,根据所在的系统环境生成makefile文件。
configure脚本运行时扫描当前环境,生成一个名为config.status的子脚本。子脚本将Makefile.in文件转换为适应于当前系统环境的Makefile文件。
1$./configure
2checking for a BSD-compatible install... /usr/bin/install -c
3checking whether build environment is sane... yes
4checking for a race-free mkdir -p... /usr/bin/mkdir -p
5checking for gawk... gawk
6checking whether make sets $(MAKE)... yes
7checking whether make supports nested variables... yes
8checking for gcc... gcc
9checking whether the C compiler works... yes
10checking for C compiler default output file name... a.out
11checking for suffix of executables...
12checking whether we are cross compiling... no
13checking for suffix of object files... o
14checking whether the compiler supports GNU C... yes
15checking whether gcc accepts -g... yes
16checking for gcc option to enable C11 features... none needed
17checking whether gcc understands -c and -o together... yes
18checking whether make supports the include directive... yes (GNU style)
19checking dependency style of gcc... gcc3
20checking that generated files are newer than configure... done
21configure: creating ./config.status
22config.status: creating Makefile
23config.status: creating config.h
24config.status: executing depfiles commands
10.使用Makefile编译,运行程序
1$make
2make all-am
3make[1]: 进入目录“/home/zhaoxiaoqi/code/c/test-automake”
4gcc -DHAVE_CONFIG_H -I. -g -O2 -MT app.o -MD -MP -MF .deps/app.Tpo -c -o app.o app.c
5mv -f .deps/app.Tpo .deps/app.Po
6gcc -g -O2 -o app app.o
7make[1]: 离开目录“/home/zhaoxiaoqi/code/c/test-automake”
8
9$./app 1 2 3
10argv[0]=./app
11argv[1]=1
12argv[2]=2
13argv[3]=3
11.Make支持的其他命令
1#清除目标文件
2make clean
3#将源文件打包
4make dist
5#编译源文件生成目标文件
6make
7#将目标文件拷贝到指定目录下
8make install
四、configure文件详解
五、多个文件生成Makefile示例(同级目录)
现在目录下有main.c, print.c, sum.c三个c文件,config.h,sum.h两个头文件
修改Makefile.am内容:
1AUTOMAKE_OPTIONS=foreign
2bin_PROGRAMS=app
3app_SOURCES=main.c print.c sum.c
六、Makefile.am格式详解
Makefile.am中可用的全局变量
变量 | 含义 |
---|---|
INCLUDES | 链接所需要的头文件 |
LDADD | 链接所需要的库文件 |
LDFLAGS | 链接所需要的库文件选项标志 |
EXTRA_DIST | 配置打包时需要打包的其他文件 |
SUBDIRS | 设置处理本目录之前需要递归处理的子目录 |
例:
1SUBDIRS=src/lib src/ModuleA/apple/shell src/ModuleA/apple/core
2CURRENTPATH=$(shell /bin/pwd)
3INCLUDES=-I $(CURRENTPATH)/src/include -I $(CURRENTPATH)/src/ModuleA/apple/include
4export INCLUDES
Makefile.am中可用的路径变量
在Makefile.am中尽量使用相对路径,系统预定义了两个基本路径:
路径变量 | 含义 |
---|---|
$(top_srcdir) | 工程最顶层目录,用于引用源程序 |
$(top_builddir) | 定义了生成目标文件最上层目录,用于引用.o 等一些编译出来的目标文件 |
$(prefix) | 定义了软件的安装的路径 |
-
automake标准安装路径
默认安装路径为:$(prefix) = /usr/local,可以通过./configure –prefix=<new_path>的方法来覆盖。
其它的预定义目录还包括:bindir = (prefix)/bin,libdir=(prefix)/lib, datadir = (prefix)/share,sysconfdir=(prefix)/etc等等。
-
定义一个新的安装路径
比如test, 可定义
testdir = (prefix)/test
,然后test_DATA=test1 test2
,则test1,test2会作为数据文件安装到(prefix)/ /test目录下。
例:
1devicedir = ${prefix}/dev
2device_DATA = package
3#package文件会作为数据文件安装到dev目录之下,这相当于定义了一种安装类型:devicedir,所以想怎么安装就怎么安装,后面的XXXXXdir,dir是固定不变的
Makefile.am一般格式
PROGRAMS。表示可执行文件
LIBRARIES。表示静态库文件
LTLIBRARIES。表示动态库文件,前面的LT表示libtool。
HEADERS。头文件。
SCRIPTS。脚本文件,这个可以被用于执行。如:example_SCRIPTS,如果用这样的话,需要我们自己定义安装目录下的example目录
DATA。数据文件,不能执行。
文件类型 | 书写格式 | 示例 |
---|---|---|
软件规范 | AUTOMAKE_OPTIONS=foreign | 有三个候选项: foreign(国外),gnu(GNU),gnits 如果使用foreign等级,它只检测必须的文 |
可执行文件 | bin_PROGRAMS=foo foo_SOURCES=xxx.c foo_LDADD= foo_LDFLAGS= foo_DEPENDENCIES= |
bin_PROGRAMS=foo (设置可执行文件的名称) 如果可执行文件的名称为foo,后面的代码前缀,都需要填foo |
静态库 | lib_LIBRARIES=libfoo.a foo_a_SOURCES= foo_a_LDADD= foo_a_LIBADD= foo_a_LDFLAGS= |
如果程序里使用了静态库编译,需要在configure.ac文件里增加以下宏定义代码 AC_PROG_RANLIB |
动态库 | lib_LTLIBRARIES=libfoo.la foo_la_SOURCES= foo_la_LDADD= foo_la_LIBADD= foo_la_LDFLAGS= |
如果程序里使用了动态库编译,需要在configure.ac文件里增加以下宏定义代码 AC_PROG_LIBTOOL 表示利用libtool 来自动生成动态库 编译共享库前,需要运行以下命令: libtoolize -f -c |
头文件 | include_HEADERS=xx.h xx.h xx.h | 软件发布时需要的头文件 make install之后,会将头文件放到安装目录下的include目录里。 |
数据文件 | data_DATA=data1 xxx2 xxx3 |
对于可执行文件和静态库类型,如果只想编译,不想安装到系统中,可以用noinst_PROGRAMS代替bin_PROGRAMS,noinst_LIBRARIES代替lib_LIBRARIES。
如果有帮助文档,不需要编译,但是需要随着软件发布一起发布,可以按下面格式进行定义:
1EXTRA_DIST=led/led.h key/key.h
七、auotomake多级目录生成Makefile(不发布静态库)
多级目录结构的软件,一般是单个程序、库文件或模块放在各自的目录中。automake要求每个目录都有自己的Makefile.am文件来编译各自目录 下的代码。在顶级的目录中,有一个Makefile.am文件,该文件通过SUBDIRS指明了这个目录下有多少个直接下级目录的代码需要编译。下级目录的Makefile.am也指明自己需要编译的下级目录。通过这样的层层递归i,从而完成多级目录结构的编译。
1.创建待编译的源码(模拟真实项目环境)
1$tree -C
2.
3├── main
4│ └── main.c
5├── print
6│ ├── print.c
7│ └── print.h
8└── sum
9 ├── sum.c
10 └── sum.h
顶层目录是project,在project目录下分别是main\print\sum目录。 main目录里的main.c是包含main函数的主程序,分别调用了sum和print目录下.c文件里的函数。
2.project顶层目录下的操作过程
-
执行autoscan命令生成configure.scan文件
1autoscan
-
将configure.scan改名成configure.in (早期in, 现在常用.ac)
1mv configure.scan configure.in
-
修改configure.in
1[wbyq@wbyq project]$ cat configure.in 2# -*- Autoconf -*- 3# Process this file with autoconf to produce a configure script. 4 5AC_PREREQ([2.63]) 6AC_INIT([app], [1.2.3], [[email protected]]) 7AC_CONFIG_SRCDIR([main/main.c]) 8AC_CONFIG_HEADERS([config.h]) 9AM_INIT_AUTOMAKE(app,1.2.3) 10AC_PROG_RANLIB #使用了静态库编译,需要此宏定义 11 12# Checks for programs. AC_PROG_CC 13 14# Checks for libraries. 15 16# Checks for header files. 17 18# Checks for typedefs, structures, and compiler characteristics. 19 20# Checks for library functions. 21 22 23AC_OUTPUT(Makefile 24 main/Makefile 25 sum/Makefile 26 print/Makefile)
-
分别执行aclocal、autoconf、autoheader命令
1ls 2aclocal 3ls 4autoconf 5ls
-
创建Makefile.am文件
1touch Makefile.am
1AUTOMAKE_OPTIONS=foreign 2SUBDIRS= print sum main #表示本目录的直接下级目录需要编译 #注意:顺序不能反,按照调用顺序来写。
如果有帮助文档,不需要编译,但是需要随着软件发布一起发布,可以按下面格式进行定义:
1EXTRA_DIST=doc/help.txt
doc/help.txt不需要编译,但要发布该文件。如果有多个文件,则用空格分开。
3.main目录下创建Makefile.am文件
在main目录下建立Makefile.am文件。
1AUTOMAKE_OPTIONS=foreign
2bin_PROGRAMS=app #本目录的文件编译成可执行文件app
3app_SOURCES=main.c
4app_LDADD=$(top_srcdir)/sum/libsum.a $(top_srcdir)/print/libprint.a
5INCLUDES=-I$(top_srcdir)/print/ -I$(top_srcdir)/sum
app_LDADD 指定需要的库文件
INCLUDES 指定需要的头文件
4.print目录下创建Makefile.am文件
1[wbyq@wbyq project]$ cat print/Makefile.am
2AUTOMAKE_OPTIONS=foreign
3noinst_LIBRARIES=libprint.a
4libprint_a_SOURCES=print.h print.c
5INCLUDES=-I$(top_srcdir)/sum
5.sum目录下创建Makefile.am文件
1[wbyq@wbyq project]$ cat sum/Makefile.am
2AUTOMAKE_OPTIONS=foreign
3noinst_LIBRARIES=libsum.a
4libsum_a_SOURCES=sum.h sum.c
6.编译
1[wbyq@wbyq project]$ automake --add-missing
2[wbyq@wbyq project]$./configure --prefix=$PWD/_install
3[wbyq@wbyq project]$ make
4[wbyq@wbyq project]$ make install
八、auotomake多级目录生成Makefile(发布静态库)
目录结构
在main.里调用了led.c和key.c里的函数。
1$tree -C
2.
3├── key
4│ ├── key.c
5│ ├── key.h
6│ └── Makefile.am
7├── led
8│ ├── led.c
9│ ├── led.h
10│ └── Makefile.am
11├── Makefile.am
12└── user
13 ├── main.c
14 └── Makefile.am
main.c:
1#include <stdio.h>
2#include "key.h"
3#include "led.h"
4
5int main(char argc,char **argv) {
6 led_init(); key_init();
7 return 0;
8}
led.c:
1 #include "led.h"
2
3 void led_init(void) {
4 printf("led_init\n");
5 }
led.h:
1#ifndef LED_H
2#define LED_H
3
4#include <stdio.h>
5void led_init(void);
6
7#endif
key.c:
1#include "key.h"
2#include "led.h"
3
4void key_init(void) {
5 led_init();
6 printf("key_init\n");
7}
key.h:
1#ifndef KEY_H
2#define KEY_H
3#include <stdio.h>
4void key_init(void);
5#endif
调用关系图:
1graph LR;
2main.c --> led.c & key.c;
3key.c --> led.c;
4
顶层Makefile.am文件代码(自己创建)
1AUTOMAKE_OPTIONS=foreign #软件规范
2SUBDIRS=led key user #执行本目录前,需要递归执行make的目录
user/Makefile.am文件代码(自己创建)
1AUTOMAKE_OPTIONS=foreign #软件规范
2bin_PROGRAMS=app #可执行文件名称
3app_SOURCES=main.c #可执行需要的源文件
4app_LDADD=$(top_srcdir)/led/libled.a $(top_srcdir)/key/libkey.a #可执行文件需要的库文件
5INCLUDES=-I$(top_srcdir)/led -I$(top_srcdir)/key #编译需要的头文件 EXTRA_DIST=$(top_srcdir)/led/led.h $(top_srcdir)/key/key.h #打包时需要额外添加的文件
6#make dist打包命令
key/Makefile.am文件代码(自己创建)
1AUTOMAKE_OPTIONS=foreign #软件规范
2lib_LIBRARIES=libkey.a #生成的静态库文件
3libkey_a_SOURCES=key.c key.h #生成静态库需要的源文件。 格式:libkey_a_SOURCES --将原来的.换成_
4key_a_LDADD=$(top_srcdir)/led/libled.a
5INCLUDES=-I$(top_srcdir)/led
led/Makefile.am文件代码(自己创建)
1AUTOMAKE_OPTIONS=foreign #软件规范
2lib_LIBRARIES=libled.a #生成的静态库文件(lib开头表示执行make installs时会一起发布,加noinst就不会一起发布)
3libled_a_SOURCES=led.c led.h #生成静态库需要的源文件。 格式:libkey_a_SOURCES --将原来的.换成_
顶层目录下的configure.ac 文件代码
-
执行autoscan 命令生成configure.scan 文件
-
修改configure.scan 文件后缀为.ac或者.in
-
修改configure.ac 文件参数
-
configure.ac文件代码如下:
1# -*- Autoconf -*- 2# Process this file with autoconf to produce a configure script. 3 4AC_PREREQ([2.63]) 5AC_INIT([app], [1.2.3], [[email protected]]) 6AC_CONFIG_SRCDIR([user/main.c]) 7AC_CONFIG_HEADERS([config.h]) 8AM_INIT_AUTOMAKE(app,1.2.3) 9AC_PROG_RANLIB #表示使用静态库 10# Checks for programs. 11AC_PROG_CC 12# Checks for library functions. 13AC_OUTPUT(Makefile user/Makefile led/Makefile key/Makefile)
-
aclocal
-
autoconf
-
autoheader
-
automake –add-missing
-
./configure –prefix=$PWD/_install
-
make && make install
-
tree _install/ -C
1_install/ 2├── bin 3│ └── app 4└── lib 5 ├── libkey.a 6 └── libled.a 7 83 directories, 3 files
九、auotomake多级目录生成Makefile(发布动态库+静态库)
目录结构
与八的一模一样。
顶层Makefile.am文件代码(自己创建)
1AUTOMAKE_OPTIONS=foreign #软件规范
2SUBDIRS=led key user #执行本目录前,需要递归执行make的目录
user/Makefile.am文件代码(自己创建)
和八对比文件名有所变化。从.a变成了.la。
1AUTOMAKE_OPTIONS=foreign #软件规范
2bin_PROGRAMS=app #可执行文件名称
3app_SOURCES=main.c #可执行需要的源文件
4app_LDADD=$(top_srcdir)/led/libled.la $(top_srcdir)/key/libkey.la #可执行文件需要的动态库文件 INCLUDES=-I$(top_srcdir)/led -I$(top_srcdir)/key #编译需要的头文件 EXTRA_DIST=$(top_srcdir)/led/led.h $(top_srcdir)/key/key.h #打包时需要额外添加的文件 make dist打包命令
key/Makefile.am文件代码(自己创建)
1AUTOMAKE_OPTIONS=foreign #软件规范
2lib_LTLIBRARIES=libkey.la #生成的动态库文件
3libkey_la_SOURCES =key.c key.h #生成静态库需要的源文件。 格式:libkey_la_SOURCES --将原来的.换成_
4key_a_LDADD=$(top_srcdir)/led/libled.la
5INCLUDES=-I$(top_srcdir)/led
led/Makefile.am文件代码(自己创建)
1AUTOMAKE_OPTIONS=foreign #软件规范
2lib_ LTLIBRARIES =libled.la #生成的动态库文件(lib开头表示执行make installs时会一起发布,加noinst就不会一起发布)
3libled_la_SOURCES=led.c led.h #生成静态库需要的源文件。 格式:libkey_la_SOURCES --将原来的.换成_
顶层目录下的configure.ac 文件代码
-
autoscan
-
mv configure.scan configure.ac
-
vim configure.ac
八使用的是AC_PROG_RANLIB #表示使用静态库
1# -*- Autoconf -*- 2# Process this file with autoconf to produce a configure script. 3AC_PREREQ([2.63]) 4AC_INIT([app], [1.2.3], [[email protected]]) 5AC_CONFIG_SRCDIR([user/main.c]) 6AC_CONFIG_HEADERS([config.h]) 7AM_INIT_AUTOMAKE(app,1.2.3) 8AC_PROG_LIBTOOL#使用动态库 9 10# Checks for programs. 11AC_PROG_CC 12# Checks for library functions. 13AC_OUTPUT(Makefile user/Makefile led/Makefile key/Makefile)
-
aclocal\autoconf\autoheader
-
libtoolize -f -c #共享库必须要执行
-
automake –add-missing
-
./configure –prefix=$PWD/_install
-
make && make install
-
tree -C
1
十、自定义安装目录示例(make install)
1wbyqdir=$(prefix)/wbyq_666
2wbyq_DATA=$(top_srcdir)/666.c $(top_srcdir)/888.c
wbyq:表示是新的路径类型。
wbyq_666:表示在安装路径下创建的目录名称。
666.c、888.c :是执行make install 拷贝到wbyq_666目录下的文件。
十一、多级目录与函数的嵌套调用生成Makefile
C文件及调用关系图
main/main.c:
1#include <stdio.h>
2#include "print.h"
3
4int main() {
5 int a=123;
6 int b=456;
7 print(a,b);
8}
sum/sum.h:
1#ifndef _SUM_H
2#define _SUM_H
3int sum(int,int);
4#endif
sum/sum.c:
1#include "sum.h"
2
3int sum(int a,int b) {
4 int c;
5 c=a+b;
6 return c;
7}
print/print.h:
1#ifndef _PRINT_H
2#define _PRINT_H
3#include "sum.h"
4#include <stdio.h>
5void print(int,int);
6#endif
print/print.c:
1#include "print.h"
2
3void print(int a,int b) {
4 int c;
5 c=sum(a,b);
6 printf("%d\n",c);
7}
1graph LR;
2 main.c --> print.c;
3 print.c --> sum.c;
automake操作
-
autoscan
-
mv configure.scan configure.ac
-
vim configure.ac
-
cat configure.ac
1AC_PREREQ([2.63]) 2AC_INIT([app], [1.2.3], [[email protected]]) 3AC_CONFIG_SRCDIR([main/main.c]) 4AC_CONFIG_HEADERS([config.h]) 5AM_INIT_AUTOMAKE(app,1.2.3) 6AC_PROG_RANLIB #使用了静态库编译,需要此宏定义 7AC_PROG_CC AC_OUTPUT(Makefile 8 main/Makefile 9 print/Makefile 10 sum/Makefile)
-
aclocal
-
autoconf
-
autoheader
-
vim Makefile.am
-
cat Makefile.am
1AUTOMAKE_OPTIONS=foreign 2SUBDIRS= sum print main #顺序
-
vim main/Makefile.am
-
cat main/Makefile.am
1AUTOMAKE_OPTIONS=foreign 2bin_PROGRAMS=app 3app_SOURCES=main.c 4app_LDADD=$(top_srcdir)/print/libprint.a $(top_srcdir)/sum/libsum.a #顺序很重要 5INCLUDES=-I$(top_srcdir)/print/ -I$(top_srcdir)/sum/
-
vim sum/Makefile.am
-
cat sum/Makefile.am
1AUTOMAKE_OPTIONS=foreign 2lib_LIBRARIES=libsum.a 3libsum_a_SOURCES=sum.h sum.c
-
vim print/Makefile.am
-
cat print/Makefile.am
1AUTOMAKE_OPTIONS=foreign 2noinst_LIBRARIES=libprint.a 3libprint_a_SOURCES=print.h print.c 4#重要 5print_a_LDADD=$(top_srcdir)/sum/libsum.a 6INCLUDES=-I$(top_srcdir)/sum
-
automake –add-misiing
-
./configure –prefix=$PWD/_install
-
make && make install
-
tree _install
1├── bin │ 2 └── app 3└── lib 4 ├── libprint.a 5 └── libsum.a