上周说的使用autotools生成makefile文件入门,只是最简单的入门例子,没有多大的实际用处。而本文则采用常用项目的代码结构,用autotools生成makefile文件,轻而易举的理顺各个源文件之间纷繁复杂的相互关系。
项目代码目录如下:
project
|-- AUTHORS
|-- ChangeLog
|-- NEWS
|-- README
|-- include
| |-- funca.h
| `-- funcb.h
|-- src
| |-- funca.c
| `-- funcb.c
`-- test
`-- test.c
其中AUTHORS, ChangeLog, NEWS, README四个文件是手工新建的空文件,里面啥都没有,真实项目写入相应信息即可。
下面是五个程序文件的内容:
//funca.h #ifndef __FUNCA__H__ #define __FUNCA__H__ void funca(); #endif |
//funcb.h #ifndef __FUNCB__H__ #define __FUNCB__H__ void funcb(); #endif |
//funca.c #include <stdio.h> void funca() { printf("HELLO im function a\n"); return; } |
//funcb.c #include <stdio.h> void funcb() { printf("HELLO im function b\n"); return ; } |
//test.c #include <stdio.h> #include "funca.h" #include "funcb.h" int main() { printf("This is main function!\n"); funca(); funcb(); return 0; } |
在project主目录,src目录和test分别建立Makefile.am文件,内容如下:
project目录的Makefile.am(注意,库文件要在主文件前面,涉及到makefile的依赖问题,以后讲makefile了再介绍):
SUBDIRS = src test
src目录的Makefile.am:
lib_LTLIBRARIES = libtest.la libtest_la_SOURCES = funca.c \ funcb.c |
test目录的Makefile.am:
INCLUDES= -I$(top_srcdir)/include bin_PROGRAMS = test test_SOURCES = test.c test_LDADD = $(top_builddir)/src/libtest.la |
运行命令$ autoscan 生成文件configure.scan,修改configure.scan,修改后文件内容如下(红色修改,蓝色添加):
# -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) AC_INIT(test, 1.0) AC_CONFIG_SRCDIR([test/test.c]) AM_CONFIG_HEADER([config.h]) AM_INIT_AUTOMAKE(test, 1.0) # Checks for programs. AC_PROG_CC AM_PROG_LIBTOOL # Checks for libraries. # Checks for header files. # Checks for typedefs, structures, and compiler characteristics. # Checks for library functions. AC_CONFIG_FILES([Makefile src/Makefile test/Makefile]) AC_OUTPUT |
修改文件完毕后,为文件改名 $ mv configure.scan configure.in
为了偷懒省事,学习网上前辈们的方法,在project目录下新建autogen.sh脚本,内容如下:
#! /bin/sh libtoolize --force --automake rm -f config.cache rm -f config.log aclocal autoheader autoconf automake -a |
给脚本执行权限 $chmod a+x autogen.sh 后就可以运行脚本 $./autogen.sh生成configure文件了。
生成configure文件后就是 ./configure && make && make install 三步曲(测试的话没有必要make install)。
是不是想知道src目录下文件编译生成的库文件在哪里阿?别急,运行$ ls -a 命令是不是看到有隐藏文件 .libs阿?目录下面的.o文件,动态库和静态库都在里面,甚至连动态库版本号的软链接都给你弄好了,强大的autotools。
相应的,在test目录下的.libs隐藏目录包含有test.c文件调用动态库和静态库的两个二进制文件:lt-test test,而在test目录下有个test脚本文件就是调用链接好动态库的test二进制文件。 看看那个test脚本文件,就实现一个简单的功能都这么复杂,有一百多行,看得人眼花缭乱,autotools真是太强大了!