打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Autoconf的使用例子
userphoto

2007.09.30

关注

Autoconf的使用例子

 

Autoconf的使用例子
 
作者:wanbin1980

  现在有环境 t/,下面有4个源码目录分别是client/ lib/ daemon/ module/,要达到的目标是
  
  将lib/ module/ daemon/ 一起编译,编成可执行文件 mydaemon
  
  将 lib/ client/ 一起编译,编成动态库libmylib.so
  
  将 lib/ client/ 一起编译,与目标2不同的是,在编译client/下的源文件时要带上预编译-D__DEBUG_MAIN__选项,最后编译成test1、test2、test3、test4,这个功能常用来生成一个测试的程序或工具。
  
  make all要求把以上3个目标都编译出来,make install的时候只安装mydaemon和libmylib.so
  
  除了常见make all和make install以外,增加make newiled make libnewfile.so make 以及make install-newfiled make install-libnewfile 。
  
  步骤如下:
  
  确保机器上安装以下软件 aclocal autoconf libtoolize automake 。编写一个脚本init.sh,把以下程序的加进去,如下:
  
  touch NEWS
  
  touch README
  
  touch AUTHORS
  
  touch ChangeLog
  
  aclocal
  
  autoconf
  
  libtoolize --force --automake --copy
  
  automake --copy --add-missing --gnu
  
  通过autoscan生成configure.ac,然后将它改名configure.in,然后作如下几处修改。
  
  AC_INIT(mysoft,1.0,xxx@163.com)
  
  AC_INIT_AUTOMAKE(mysoft,1.0)
  
  AC_PREFIX_DEFAULT(/usr/local/mysoft) 这里添上安装文件的路径,比如/usr/local/mysoft/
  
  增加LIBTOOL=”$LIBTOOL --silent”
  
  AC_OUTPUT(Makefile lib/Makefile client/Makefile module/Makefile daemon/Makefile) 这里列出你要生成的全部的Makefile。
  
  这步是关键,为每个目录添加一个叫Makfile.am的文件,具体如下:
  
  在t/目录下,由于这个目录下本身没有源文件(源文件都在它的子目录里面),所以这个目录下的Makefile..am很简单,只要写下面一句
  
  SUBDIRS lib module client daemon
  
  注意编译时的先后次序。
  
  在lib/目录下,由于这个目录下的源文件是为其它目录的源文件服务的,所以在lib目录下,我们编译出一下.a文件,以供别的目录使用。在Makefile.am中写如下内容:
  
  noinst_LIBRARIES = libcompat.a
  
  libcompat_a_SOURCES = a.c b.c c.c d.c
  
  libcompat_a_CFLAGS = -I../include  -I/usr/local
  
  noinst_LIBRARIES的意思是生成的库是不会被make install 所安装的。库的名字可以随便取。
  
  libcompat_a_CFLAGS是编译时要带的一些选项
  
  module/目录和功能和lib/的功能相似,因此Makefile.am也相似,如下
  
  noinst_LIBRARIES = libmodule.a
  
  libmodule_a_SOURCES = a.c b.c c.c d.c
  
  libmodule_a_CFLAGS = -I../daemon  -I.../include
  
  client目录的Makefile.am较复杂,因为1:它要完成目标2,编译出一个动态库。2:它又要完成目标3,编译出一些可执行文件出来。
  
  LDADD = ../lib/libcompat.a
  
  AM_CFLAGS = -D__DEBUG_MAIN__  -I../include  -I../usr/local/include
  
  AM_LDFLAGS = -lpthread –lssl –L/usr/local/lib
  
  (LDADD指的是编译这个目录的时候,会用到这个.a。AM_CFLAGS是全局的选项,当某个程序prog有prog_CFLAGS时,AM_CFLAGS会被替换掉。)
  
  noinst_PROGRAMS = test1 test2 test3 test4
  
  (因为在目标4中要求make install的时候不安装这些程序,所以是noinst。
  
  这里没有指明编译这些程序的源文件,所以默认会去找test1.c test2.c test3.c test4.c
  
  这里没有指明编译选项,所以在编译这些程序时,会使用AM_CFLAGS。)
  
  lib_LTLIBRARIES = libmylib.la
  
  libmylib_la_SOURCE = a.c b.c c.c d.c
  
  libmylib_la_LDFLAGS = -lpthread
  
  libnewfile_la_CFLAGS = -I../include
  
  include_HEADERS = ../include/mylib.h
  
  (lib_LTLIBRARIES是说明要生成的动态库名称,因为是使用libtool,所以这里用的是la,生成动态库的过程由libtool去自动完成。libmylib_la_LDFLAGS说明的是要连接的时候用到的一些库,libnewfile_la_CFLAGS是在编译libmylib.la时用到的选项。include_HEADERS是指在安装libmylib时,要把这个头文件也安装到include里面)
  
  daemon/目录。将如下内容写到Makefile.am中
  
  LDADD = ../module/libmodule.a ../lib/libcompat.a
  
  libexec_PROGRAMS = mydaemon
  
  mydaemon_SOURCES = a.c b.c c.c d.c e.c
  
  mydaemon_CFLAGS = -I../include
  
  mydaemon_LDFLAGS = -lpthread –L/usr/local/lib

  (libexec_PROGRRAMS,指的是要生成的程序名,并且暗示程序安装的路径,这里用的是libexec_ 原因是mydaemon是一个daemon,按照freebsd上的通用做会是把daemon放在libexec/下。同理,如果你写成bin_PROGRRAMS,程序会被安装到bin/)。
  
  到目前为止,init.sh应该可以远行了,然后./configure 然后make all make install。但还没有完成我们全部的任务,因为还有最后一个目标5,为了增加make的target,我们的作法是直接在最顶部目录t/Makefile.am中按照Makefile的写法,手工增加target。之所以可以这样做有两个原因,第一、是因为automake自动会把Makefile.am的内容原封不动地拷到新生成的Makefile中,所以在Makefile.am中增加target也就相当于在新生成的Makefile中增加。第二、在默认情况下,Makefile.am中的每个要生成的程序都可以在相应目录中单独去make,也就是说automake会为每个要生成的程序写一个target。比如在client目录中,我们可以make test1 make libmylib,这些都可以成功执行。
  
  知道了上述两个原因,我们就可以开始修改t/Makefile.am,增加下列内容:
  
  mydaemon: lib/*.c module/*.c daemon/*.c
  
  $(MAKE) –C lib
  
  $(MAKE) –C module
  
  $(MAKE) mydaemon –C daemon
  
  libmylib: lib/*.c client/*.c
  
  $(MAKE) –C lib
  
  $(MAKE) libmylib.la –C client
  
  test: lib/*.c client/*.c
  
  $(MAKE) –C lib
  
  $(MAKE) test1 –C lib
  
  $(MAKE) test2 –C lib
  
  $(MAKE) test3 –C lib
  
  $(MAKE) test4 –C lib
  
  install-libmylib: client/libmylib.la
  
  $(mkinstalldirs) $(libdir)
  
  $(LIBTOOL) --mode=install /usr/local/install  -c client/libmylib.la $(libdir)/libnewfile.la
  
  install-test: client/*.c
  
  $(mkinstalldirs) $(bindir)
  
  $(LIBTOOL)  --mode=install /usr/local/install –c client/test1  $(bindir)/test1
  
  $(LIBTOOL)  --mode=install /usr/local/install –c client/test2  $(bindir)/test2
  
  $(LIBTOOL)  --mode=install /usr/local/install –c client/test3  $(bindir)/test3
  
  $(LIBTOOL)  --mode=install /usr/local/install –c client/test4  $(bindir)/test4
  
  install-mydaemon:daemon/mydaemon
  
  $(mkinstalldirs) $(DESTDIR)$(libexecdir)
  
  $(LIBTOOL) --mode=install /usr/bin/install –c daemon/mydaemon $(libexecdir)/mydaemon
  
  ($(mkinstalldirs) $(libexecdir)的作用是看看有没有这个目录,如果没有的话新建。$(libexecdir)就是/usr/local/mysoft/libexec/。)
  
  到此为止,任务完成了。运行./init.sh ,运行./configure,它会根据Makefile.am生成Makefile,然后就可以make 以及make install了。
  
  总结一下:
  
  两个很有用的选项 prog_CFLAGS prog_LDCFLAGS 可以满足我们增加编译选项和连接选项的功。对应的全局变量是AM_CFLAGS AM_LDFLAGS
  
  如果是两个或两个以上目录的源文件需要合在一起编译,可以采用每个目录编译编译成一个.a,然后能过LDADD把它们放在一起连接。
  
  我们可以直接在Makefile.am中写Makefile的内容。
  
  我在做的过程序中疑惑的问题
  
  当bin_PROGRAMS=hello hello_SOURCE=test1.c test2.c时,AutoMake生成的中间文件会是hello-test1.o hello-test2.o,看起来有点别扭。
  
  有时明明是我只修改了Makefile.am,按理说,我只要执行./configure,就可重新生成Makfile。但有时并不能如我所愿,而我重新执行./init.sh问题就解决了。我的经验是当你修改了Makefile.am后发现没什么变化的时候,运行一下./init.sh或许就好了。
  
  在使用过程中觉得make好像有什么记忆之类的机制,有时,我改了Makfile.am,重新生成了Makefile后,运行make,它还是上次运行失败的结果,再运行一次就好了。很奇怪。
  
  我在编辑Makefile.am时,往Makefile.am里面增加command的,我在command 前面明明是用了/t,可是最终被Automake拷到新的Makefile后,却变成了4个空格。很郁闷,最后用了一个笨方法,把Makefile.am改名成Makefile,用vi打开看一下,确保是/t,然后再把名字改回去。这样就可以了,可能是我vim的配置问题。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
linux下.a/.so/.la目标库区别
耕耘Linux : Linux下静态库生成指南
静态库&动态库
ARM开发板上USB 摄像头图像采集实现
linux静态库的生成与使用
用configure建立工具的学习
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服