码迷,mamicode.com
首页 > 其他好文 > 详细

使用autotools

时间:2015-06-13 12:51:28      阅读:109      评论:0      收藏:0      [点我收藏+]

标签:autool   autoconf   automake   

autotools (autoconf, automake)能自动创建用来编译代码的各种文件(configure, makefile). 有了它,我们就不需要手动写makefile了,也不用在环境变化的时候,手动的去调整makefile. 这一切autotools可以完成。

下面以一个例子来说说明。

1. C代码。下面是一个EFL的简单程序,需要先安装好 EFL的各种库。

#include <Elementary.h>
static void
on_done(void *data, Evas_Object *obj, void *event_info)
{
   // quit the mainloop (elm_run function will return)
   elm_exit();
}
EAPI_MAIN int
elm_main(int argc, char **argv)
{
   Evas_Object *win, *box, *lab, *btn;
   // new window - do the usual and give it a name (hello) and title (Hello)
   win = elm_win_util_standard_add("hello", "Hello");
   // when the user clicks "close" on a window there is a request to delete
   evas_object_smart_callback_add(win, "delete,request", on_done, NULL);
   // add a box object - default is vertical. a box holds children in a row,
   // either horizontally or vertically. nothing more.
   box = elm_box_add(win);
   // make the box horizontal
   elm_box_horizontal_set(box, EINA_TRUE);
   // add object as a resize object for the window (controls window minimum
   // size as well as gets resized if window is resized)
   elm_win_resize_object_add(win, box);
   evas_object_show(box);
   // add a label widget, set the text and put it in the pad frame
   lab = elm_label_add(win);
   // set default text of the label
   elm_object_text_set(lab, "Hello out there world!");
   // pack the label at the end of the box
   elm_box_pack_end(box, lab);
   evas_object_show(lab);
   // add an ok button
   btn = elm_button_add(win);
   // set default text of button to "OK"
   elm_object_text_set(btn, "OK");
   // pack the button at the end of the box
   elm_box_pack_end(box, btn);
   evas_object_show(btn);
   // call on_done when button is clicked
   evas_object_smart_callback_add(btn, "clicked", on_done, NULL);
   // now we are done, show the window
   evas_object_show(win);
   // run the mainloop and process events and callbacks
   elm_run();
   return 0;
}
ELM_MAIN()

2. configure.ac 

这是 autoconf 输入文件,因此有人也写为 configure.in(一推荐不要这样命名,因为 make dist-clean 的时候,会执行 rm -rf *.in,导致被误删).

这个文件里面通常做一些测试,比如,检查某些函数或者文件是否存在。比如,如果要检查函数 gettimeofday() 是否存在,可以用:

AC_CHECK_FUNCS(gettimeofday)。

下面是这个例子的文件内容:

AC_INIT(myapp, 0.0.0, myname@mydomain.com)
AC_PREREQ(2.52)
AC_CONFIG_SRCDIR(configure.ac)
AM_CONFIG_HEADER(config.h)
AC_PROG_CCsuo
AM_INIT_AUTOMAKE(1.6 dist-bzip2)
PKG_CHECK_MODULES([ELEMENTARY], elementary)
AC_OUTPUT(Makefile)

解释如下:

AC_INIT: autoconf 的一个宏, 三个参数分别为:包的名字, 版本,和联系邮件

AC_PREREQ: 确保 autoconf的版本至少为 version. 如果不满足条件,就报错

AC_CONFIG_SRCDIR: 这个宏用来检查参数表示的文件确实在代码目录下存在

AM_CONFIG_HEADER: 这个宏定义了一个头文件(config.h),里面通常是一些预编译的宏。

这个文件的输入文件是 config.h.in。因此,有时候也这样写:

AM_CONFIG_HEADER(config.h:config.in)
AC_PROG_CC: 定义C编译器。如果CC还没定义,就查找gcc, cc, 然后是其它的编译器,然后把CC 环境变量定义为找到的那个编译器。
AM_INIT_AUTOMAKE: 后面可以跟很多参数。在这里, 1.6表示automake版本至少要是1.6, dist-bzip2表示创建一个bzip2压缩格式的目标文件。
如果执行 make dist,就会生成这样的包。
PKG_CHECK_MODULES: 完整的格式如下:
PKG_CHECK_MODULES(prefix, list-of-modules, action-if-found, action-if-not-found)
prefix是用来作为那些保存有编译选项和库信息的变量的前缀。比如,就这个例子,ELEMENTART_CFLAGS, ELEMENTARY_LIBS
第二个参数为要检查是否存在的模块。

后面两个参数一般不需要写。

AC_OUTPUT:每个 autoconf 脚本都要以 这个宏结束。它创建一个config.status并且运行它。这个宏后面跟的参数也是要被创建的文件。


3. Makefile.am

这是 automake的输入文件。它和makefile的语法是一样的。automake会把 makefile.am 转换成 makefile.in.

AUTOMAKE_OPTIONS = 1.4 foreign
MAINTAINERCLEANFILES = Makefile.in aclocal.m4 config.h.in configure depcomp install-sh missing
INCLUDES = -I$(top_srcdir)
bin_PROGRAMS = myapp
myapp_SOURCES = main.c
myapp_LDADD = @ELEMENTARY_LIBS@
myapp_CFLAGS = @ELEMENTARY_CFLAGS@
解释如下:

AUTOMAKE_OPTIONS: automake的选项。 1.4表示版本至少要为1.4, foreign表示这个 package不遵循GNU的标准。标准GNU包会发布一些

额外的文件,比如,ChangeLog, AUTHORS。选择了foreign之后,即使没有这些文件,automake也不会警告。

MAINTAINERCLEANFILES
是一个make承认的变量,它保存了可以被删除的一些中间文件。比如,执行下面的命令

make maintainer-clean

这个变量指示的文件就被删除。

top_srcdir:用在#include里面,表示项目所在的最顶端目录(top-most directory).

automake会把#include 展开到makefile.in里面。

bin_PROGRAMS: _PROGRAMS表示后面的文件是makefile要编译连接出来的。bin表示编出的文件要安装在 bindir目录下

myapp_LDADD和 myapp_CFLAGS表示用到的库和头文件。也可以这样写:

myapp_LDADD = $(ELEMENTARY_LIBS)
myapp_CFLAGS = $(ELEMENTARY_CFLAGS)

4. autogen.sh

#!/bin/sh
 echo "Running aclocal..." ; aclocal $ACLOCAL_FLAGS || exit 1
 echo "Running autoheader..." ; autoheader || exit 1
 echo "Running autoconf..." ; autoconf || exit 1
 echo "Running automake..." ; automake --add-missing --copy --gnu || exit 1
 ./configure "$@"

执行 aclocal 会生成 aclocal.m4  aclocal 是需要执行的,它会收集automake需要用到一些 autoconf的宏(根据当前的configure.ac).

aclocal会扫描 *.m4文件,然后是 configure.ac文件,把所有用到宏(包括间接依赖用到的)放到 aclocal.m4文件里面。

autoheader是为了把编译配置过程中产生的宏定义都放到一个文件里面(AC_CONFIG_HEADER定义的那个对应的输入文件,config.h.in)

autoheader产生 cponfig.h.in, 然后 configure 根据 config.h.in 生成 config.h.

autoconf 根据 configure.ac生成 configure.

automake 根据 makefile.am生成 makefile.in


现在,就可以开始配置和编译了。

首先,确保上面的几个文件已经准备好:

$ ls
autogen.sh  configure.ac  main.c  Makefile.am
然后,执行 autogen.sh:

$ ./autogen.sh 
Running aclocal...
Running autoheader...
Running autoconf...
Running automake...
configure.ac:5: installing './compile'
configure.ac:6: installing './install-sh'
configure.ac:6: installing './missing'
Makefile.am:3: warning: 'INCLUDES' is the old name for 'AM_CPPFLAGS' (or '*_CPPFLAGS')
Makefile.am: installing './depcomp'
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables... 
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking whether gcc understands -c and -o together... yes
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
/bin/bash: /home/charles/missing: No such file or directory
configure: WARNING: 'missing' script is too old or missing
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for style of include used by make... GNU
checking whether make supports nested variables... yes
checking dependency style of gcc... gcc3
checking for pkg-config... /usr/bin/pkg-config
checking pkg-config is at least version 0.9.0... yes
checking for ELEMENTARY... yes
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: creating config.h
config.status: executing depfiles commands
可以看到,此时,生成了很多文件:

p$ ls
aclocal.m4      config.h       configure     main.c       missing
autogen.sh      config.h.in    configure.ac  Makefile     stamp-h1
autom4te.cache  config.log     depcomp       Makefile.am
compile         config.status  install-sh    Makefile.in

执行configure:

$ ./configure 
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables... 
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking whether gcc understands -c and -o together... yes
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
/bin/bash: /home/charles/missing: No such file or directory
configure: WARNING: 'missing' script is too old or missing
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for style of include used by make... GNU
checking whether make supports nested variables... yes
checking dependency style of gcc... gcc3
checking for pkg-config... /usr/bin/pkg-config
checking pkg-config is at least version 0.9.0... yes
checking for ELEMENTARY... yes
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: creating config.h
config.status: config.h is unchanged
config.status: executing depfiles commands

执行 make:

$ make
make  all-am
make[1]: Entering directory `/home/charles/code/EFL/test/tmp'
gcc -DHAVE_CONFIG_H -I. -I.   -pthread -D_REENTRANT -I/usr/local/include/elementary-1 -I/usr/local/include/elocation-1 -I/usr/local/include/efl-1 -I/usr/local/include/ecore-x-1 -I/usr/local/include/eina-1 -I/usr/local/include/eina-1/eina -I/usr/local/include/eet-1 -I/usr/local/include/evas-1 -I/usr/local/include/ecore-1 -I/usr/local/include/ecore-evas-1 -I/usr/local/include/ecore-file-1 -I/usr/local/include/ecore-input-1 -I/usr/local/include/edje-1 -I/usr/local/include/eo-1 -I/usr/local/include/ethumb-client-1 -I/usr/local/include/emotion-1 -I/usr/local/include/ecore-imf-1 -I/usr/local/include/ecore-con-1 -I/usr/local/include/eio-1 -I/usr/local/include/eldbus-1 -I/usr/local/include/efreet-1 -I/usr/local/include/emile-1 -I/usr/local/include/ector-1 -I/usr/local/include/ecore-input-evas-1 -I/usr/local/include/ecore-audio-1 -I/usr/local/include/ephysics-1 -I/usr/local/include/embryo-1 -I/usr/local/include/ecore-imf-evas-1 -I/usr/local/include/ethumb-1 -I/usr/local/include/eeze-1 -I/usr/include/glib-2.0 -I/usr/lib/i386-linux-gnu/glib-2.0/include -I/usr/include/libpng12 -I/usr/include/fribidi -I/usr/include/freetype2 -I/usr//include/luajit-2.0 -I/usr/include/bullet -I/usr/include/dbus-1.0 -I/usr/lib/i386-linux-gnu/dbus-1.0/include -I/usr/include/libmount -I/usr/include/blkid -I/usr/include/uuid   -g -O2 -MT myapp-main.o -MD -MP -MF .deps/myapp-main.Tpo -c -o myapp-main.o `test -f 'main.c' || echo './'`main.c
mv -f .deps/myapp-main.Tpo .deps/myapp-main.Po
gcc -pthread -D_REENTRANT -I/usr/local/include/elementary-1 -I/usr/local/include/elocation-1 -I/usr/local/include/efl-1 -I/usr/local/include/ecore-x-1 -I/usr/local/include/eina-1 -I/usr/local/include/eina-1/eina -I/usr/local/include/eet-1 -I/usr/local/include/evas-1 -I/usr/local/include/ecore-1 -I/usr/local/include/ecore-evas-1 -I/usr/local/include/ecore-file-1 -I/usr/local/include/ecore-input-1 -I/usr/local/include/edje-1 -I/usr/local/include/eo-1 -I/usr/local/include/ethumb-client-1 -I/usr/local/include/emotion-1 -I/usr/local/include/ecore-imf-1 -I/usr/local/include/ecore-con-1 -I/usr/local/include/eio-1 -I/usr/local/include/eldbus-1 -I/usr/local/include/efreet-1 -I/usr/local/include/emile-1 -I/usr/local/include/ector-1 -I/usr/local/include/ecore-input-evas-1 -I/usr/local/include/ecore-audio-1 -I/usr/local/include/ephysics-1 -I/usr/local/include/embryo-1 -I/usr/local/include/ecore-imf-evas-1 -I/usr/local/include/ethumb-1 -I/usr/local/include/eeze-1 -I/usr/include/glib-2.0 -I/usr/lib/i386-linux-gnu/glib-2.0/include -I/usr/include/libpng12 -I/usr/include/fribidi -I/usr/include/freetype2 -I/usr//include/luajit-2.0 -I/usr/include/bullet -I/usr/include/dbus-1.0 -I/usr/lib/i386-linux-gnu/dbus-1.0/include -I/usr/include/libmount -I/usr/include/blkid -I/usr/include/uuid   -g -O2   -o myapp myapp-main.o -L/usr/local/lib -lelementary -lefl -leina -lpthread -leet -levas -lecore -lecore_evas -lecore_file -lecore_input -ledje -leo -lethumb_client -lemotion -lecore_imf -lecore_con -leldbus -lefreet -lefreet_mime -lefreet_trash -leio -ldl -lm   
make[1]: Leaving directory `/home/charles/code/EFL/test/tmp'


References:

1. http://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/html_node/Input.html

2.https://autotools.io/pkgconfig/pkg_check_modules.html

3. http://www.gnu.org/software/autoconf/manual/automake.html

4.https://www.sourceware.org/autobook/autobook/autobook_36.html

5. https://docs.enlightenment.org/stable/elementary/group__Start.html

6.http://www.delorie.com/gnu/docs/automake/automake_17.html

7. http://mij.oltrelinux.com/devel/autoconf-automake/

8. http://www.seul.org/docs/autotut/

9. http://inti.sourceforge.net/tutorial/libinti/autotoolsproject.html

使用autotools

标签:autool   autoconf   automake   

原文地址:http://blog.csdn.net/caspiansea/article/details/46481473

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!