使用autotools

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, [email protected])
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 = @[email protected]
myapp_CFLAGS = @[email protected]

解释如下:

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 "[email protected]"

执行 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

时间: 2024-10-22 16:07:53

使用autotools的相关文章

Makefile文件编写和autotools的使用

在Linux或Unix环境下,对于只含有几个源代码文件的小程序(如hello.c)的编译,可以手工键入gcc命令对源代码文件逐个进行编译:然而在大型的项目开发中,可能涉及几十到几百个源文件,采用手工键入的方式进行编译,则非常不方便,而且一旦修改了源代码,尤其头文件发生了的修改,采用手工方式进行编译和维护的工作量相当大,而且容易出错.所以在Linux或Unix环境下,人们通常利用GNU make工具来自动完成应用程序的维护和编译工作.实际上,GNU make工具通过一个称为Makefile的文件来

Linux江湖23:使用Eclipse和Gnu Autotools管理C/C++项目

在我该系列的之前的所有随笔中,都是采用 Linux 发行版自带的包管理工具(如 apt-get.yum 等)进行软件的安装和卸载,从来没有向大家展示使用源代码自行编译安装软件的方法.但是长期混迹于 Unix/Linux 世界的童鞋们都知道,从源代码自行编译安装软件并不是那么的难,一般都是这样三个步骤: configure make make install 之所以能够把源代码的构建管理得如此简单,这得益于 Gnu 的 Autotools 工具链.在上面的三个命令中,configure 是一个脚本

Autotools Mythbuster

Preface Diego Elio?"Flameeyes"?Pettenò Author and Publisher?<[email protected]> SRC=https://autotools.io/index.html David J.?"user99"?Cozatt Miscellaneous Editing?<[email protected]> Copyright ? 2009-2013 Diego Elio Pettenò

Autotools发展史

在linux下面撸过代码.做过开发的,想必都听说过Makefile. 对,是Makefile,不是make love.如果你看成了后者,只能说:同志,你的三观有问题,需要格式化你的硬盘~ 在linux开发程序,没有集成开发环境IDE(integrated development environment),没有VC++6.0, 只有Makefile和冰冷黑漆漆的shell窗口,寒冷的夜,考验着每一个工程师疲惫的心 Makefile语法复杂.难以维护.对于一个小项目还好,对于大型的项目和开源项目,现

Autotools使用流程【转】

本文转载自:http://blog.csdn.net/scucj/article/details/6079052 手工写Makefile是一件很有趣的事情,对于比较大型的项目,如果有工具可以代劳,自然是一件好事.在Linux系统开发环境中,GNU Autotools 无疑就充当了这个重要角色.(在Windows系统的开发环境中,IDE工具,诸如Visual Studio,来管理项目也很方便.) 本文以一个简单项目为例子,来讲述GNU Autotools的一列工具及其命令的用法. autotool

GNU Autotools的使用方法

手工写Makefile是一件很有趣的事情,对于比较大型的项目,如果有工具可以代劳,自然是一件好事.在Linux系统开发环境中,GNU Autotools 无疑就充当了这个重要角色.(在Windows系统的开发环境中,IDE工具,诸如Visual Studio,来管理项目也很方便.) 本文以一个简单项目为例子,来讲述GNU Autotools的一列工具及其命令的用法. autotools是系列工具, 它主要由autoconf.automake.perl语言环境和m4等组成:所包含的命令有五个:  

Basics on GNU autotools developing environment

GNU Autotools will be considered as the ideal tool to manage Fortran project after creating a basic program structure by using Eclipse IDE. Eclipse IDE is quite convenient for developing a simple project, however, only one target binary can be genera

Mac下安装MacProt,并GNU autotools的安装和使用 autoconf,automake

1 MacPort的下载:http://www.macports.org/install.php, 需要安装xCode支持macport 2 安装MacPorts 与其他Mac的软件的安装方式相同,挂载dmg后,打开pkg,按照引导一步步next,然后没有drag到Application的动作. (注:这一步骤非常慢.有的网友说是断了网就好了,如果这样的话,或许是在更新一些多余信息.) 3 然后将/opt/local/bin和/opt/local/sbin添加到$PATH搜索路径中  编辑/et

Makefile自动生成(autotools工具的使用)

autotools是个系列工具,首先确认你的Ubuntu系统是否安装了以下工具(可以通过which命令查看): aclocal autoscan autoconf autoheader automake --------------------------------------------------------------------------------- 安装方法: [email protected]:~$ sudo apt-get install autoconf 装完后,用whic

使用autotools系列工具自动部署源代码编译安装

在Linux系统下开发一个较大的项目,完全手动建立Makefile是一件费力而又容易出错的工作.autotools系列工具只需用户输入简单的目标文件.依赖文件.文件目录等就可以比较轻松地生成Makefile了. 这极大地简化了Makefile的编写和维护,作者也是刚体验到其威力,所以将其过程记录下来. 本文以一个简单的hello.c文件进行验证. 准备工作 首先需要安装autotools系列工具,包括aclocal.autoscan.automake.autoheader.autoconf等.