Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1520524
  • 博文数量: 230
  • 博客积分: 474
  • 博客等级: 下士
  • 技术积分: 1955
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-19 18:40
文章分类

全部博文(230)

文章存档

2020年(3)

2019年(3)

2018年(12)

2017年(13)

2016年(11)

2015年(55)

2014年(74)

2013年(39)

2012年(2)

2011年(18)

我的朋友

分类: LINUX

2011-06-08 16:57:00

一直都是自己写Makefile,主要因为以前的开发中自己开发的都是系统定制的程序,而且已经习惯了拿别人的比较完美的Makefile程序来改成自己的,今天尝试了一下自己用automake来生成Makefile,不知道以后对自己有多大用处,但是作为开发人员,了解还是必须的。
其实,在学习中,我一直坚持的是,首先找到一个最简单的实例来完成一次,然后去看官方文档,这里就是一个简单的实例
1、创建目录和文件,我们最常用的helloworld
    helloworld.c

    #include "helloworld.h"
    int main()
    {
            printf("HELLO WORLD!\n");
    }

    helloworld.h

    #include
      #include
2、autoscan
   生成configure.scan,自己改名为configure.in
    mv configure.scan configure.in
    修改configure.in
    #                                               -*- Autoconf -*-
    # Process this file with autoconf to produce a configure script.

    #AC_PREREQ([2.67])
    #AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
    AC_INIT(helloworld.c)
    AM_INIT_AUTOMAKE(helloworld, 1.0)
    AC_CONFIG_SRCDIR([helloworld.h])
    #AC_CONFIG_HEADERS([config.h])

    # Checks for programs.
    AC_PROG_CC

    # Checks for libraries.

    # Checks for header files.
    AC_CHECK_HEADERS([stdlib.h])

    # Checks for typedefs, structures, and compiler characteristics.

    # Checks for library functions.

    AC_OUTPUT(Makefile)
3、执行aclocal和autoconf
4、创建Makefile.am
    AUTOMAKE_OPTIONS=foreign
    bin_PROGRAMS=helloworld
    helloworld_SOURCES=helloworld.c
5、automake
    automake --add-missing
完成了configure,然后就可以 configure并make,你的HelloWORLD出来了。


分类: LINUX


关于automake的实践
今天弄了很久的automake,自动生成Makefile,这样写程序时就会方便很多。之前也花时间看过一次,但当时只是对着一个hello.c的例子试了一遍就过去了,印象并不深刻,过后就忘记了。最近在学minigui时,考贝过来的程序每次都用一个笨办法来编译:直接考到mg-sample文件夹里面的src里,再在Makefile.am里加入所要编译的文件。由于对automake不了解,经常在./configure时出错,又不知道怎么去改,费时费力。这个问题托了好久,终于决心要把它搞定。
要实现的功能:
1.编写的程序用automake 能够成功生成Makefile文件。
2.用automake生成交叉编译的Makefile.

仔细看下这篇文章,有关于这个知识点的详细介绍:http://www.ibm.com/developerworks/cn/linux/l-makefile/

按照文中的步骤进行:注意如图的各文件的依赖关系。

这里举个例子是minigui里的mg-samples-1.3.1/src/helloworld.c
1.建立test目录,将helloworld.c copy进来,然后:

[root@localhost mg-samples-1.3.1]# cd test/   *进入目录
[root@localhost test]# ls                     *可以看到这时只有源文件
helloworld.c
[root@localhost test]# autoscan   
[root@localhost test]# ls   *查看,生成了configure.scan
autoscan.log configure.scan helloworld.c
[root@localhost test]# mv configure.scan configure.in *重命名一下
[root@localhost test]# ls
autoscan.log configure.in helloworld.c
[root@localhost test]# vim configure.in *编辑configure.in

*******************生成的文件内容如下:

# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.63])
AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
AC_CONFIG_SRCDIR([helloworld.c])
AC_CONFIG_HEADERS([config.h])

# Checks for programs.
AC_PROG_CC

# Checks for libraries.

# Checks for header files.

# Checks for typedefs, structures, and compiler characteristics.

# Checks for library functions.

AC_OUTPUT

******************************修改如下:
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.63])
AC_INIT(helloworld.c,1.0)
AM_INIT_AUTOMAKE(helloworld, 1.0) 重点要加上这一句,最后的输出文件名及版本
AC_CONFIG_SRCDIR([helloworld.c]) 如果有多个源文件,按其默认或只写文件中的任意一个就好了,只是测试
AC_CONFIG_HEADERS([config.h])

# Checks for programs.
AC_PROG_CC

# Checks for libraries.

# Checks for header files.

# Checks for typedefs, structures, and compiler characteristics.

# Checks for library functions.

AC_OUTPUT(Makefile)  这时是最生要输出的文件名,要输出的是Makefile


*****************然后回到终端里:
[root@localhost test]# aclocal
[root@localhost test]# ls    产生aclocal.m4
aclocal.m4 autoscan.log configure.in~
autom4te.cache configure.in helloworld.c
[root@localhost test]# autoconf
[root@localhost test]# ls
aclocal.m4 autoscan.log configure.in helloworld.c
autom4te.cache configure configure.in~
看到生成了configure,这个就是最后要./configure的文件了.但是现在要执行这个命令生成Makefile还需要一个文件:Makefile.am
需要手动编辑

[root@localhost test]# vim Makefile.am

输入如下:
bin_PROGRAMS=helloworld    最生输出的可执行文件名,输出多个则用空格隔开即可
helloworld_SOURCES=helloworld.c 依赖的源文件,有多个源文件用空格隔开,有头文件也写出来。
helloworld_LDADD=-lminigui -lpthread 链接时要的额外函数库名

还有其他参数,参照上面的那篇文章。

[root@localhost test]# automake --add-missing
configure.in:6: installing `./install-sh'
configure.in:6: installing `./missing'

Makefile.am: installing `./INSTALL'
Makefile.am: required file `./NEWS'
 not found
Makefile.am: required file `./README' not found
Makefile.am: required file `./AUTHORS'
 not found
Makefile.am: required file `./ChangeLog' not found
Makefile.am: installing `./COPYING'

configure.in:8: required file `config.h.in' not found
Makefile.am: installing `./depcomp'


这里直接用automake --add-missing会提示错误,需要这几个文件,可以动touch建立,
[root@localhost test]# touch NEWS README AUTHORS ChangeLog

如果不建立这些文件,则在Makefile的第一行加上Automake_OPTIONS=foreign,如下:


AUTOMAKE_OPTIONS=foreign
bin_PROGRAMS=helloworld
helloworld_SOURCES=helloworld.c
helloworld_LDADD=-lminigui -lpthread
上面还有一个错误为:configure.in:8: required file `config.h.in' not found

是因为在automake之前没有建立config.h.in,运行如下命令即可
[root@localhost test]# autoheader


接着,再次运行automake --add-missing,可以看到生成了Makefile.in文件
[root@localhost test]# automake --add-missing
[root@localhost test]# ls
aclocal.m4 config.h.in configure.in~ helloworld.c Makefile.am
autom4te.cache configure COPYING INSTALL Makefile.in
autoscan.log configure.in depcomp install-sh missing


然后执行,./configure,即可生成Makefile
[root@localhost test]# ./configure 
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for gcc... gcc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables... 
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 for style of include used by make... GNU
checking dependency style of gcc... gcc3
configure: creating ./config.status
config.status: creating Makefile
config.status: creating config.h
config.status: executing depfiles commands
[root@localhost test]# ls
aclocal.m4 config.h.in configure.in helloworld.c Makefile.am
autom4te.cache config.log configure.in~ INSTALL Makefile.in
autoscan.log config.status COPYING install-sh missing
config.h configure depcomp Makefile stamp-h1
[root@localhost test]# make
make all-am
make[1]: Entering directory `/home/minigui/mg-samples-1.3.1/test'
gcc -g -O2 -o helloworld helloworld.o -lminigui -lpthread 
make[1]: Leaving directory `/home/minigui/mg-samples-1.3.1/test'

[root@localhost test]# ls
aclocal.m4 config.log COPYING INSTALL missing
autom4te.cache config.status depcomp install-sh stamp-h1
autoscan.log configure helloworld Makefile
config.h configure.in helloworld.c Makefile.am
config.h.in configure.in~ helloworld.o Makefile.in

可以看到make之后生成了helloworld 


这里主要是将最后要链接的两个库名加入进去。同时在Makefile.am中也可以用LDFLAGS加入库的路径,不过上面的例子没有用到,因为按系统默认库就可以生成在PC机上运行的MINIGUI程序。


但是如果要交叉编译,直接用./configure生成Makefile可以运行在arm上的话,还需要指定头文件和库文件。关于c语言的头文件和库文件,最近总算理解了一点,但还是很模糊。我的理解是这样的:

1.头文件,即include中,只是一些函数的声明。

2.c语言的编译是按单个文件进行的,单个文件编译生成“.o”格式的文件,如果a函数要调用b函数的话,那么b函数的定义必须在a的前面。否则,在a函数之前就需要对b函数进行声明。

3.不同文件中。若引用函数库中的b函数,则此时a和b肯定是在不同的文件内的,这样,在a之前需要对b函数进行声明,而对于库函数的声明都全部写在了头文件里,所以a所在的文件中,只需在文件的开始把头文件include进来。比如最常用的#include ,其实就是把stdio.h里的所有内容都复制到a文件的开头,这样,在函数a之前就一定有对b函数的声明了。

4.编译器将各个文件编译成“.o“格式的文件,然后用链接器将所有的.o文件,包括含数库一起,最后链接成目标文件。如上例中的helloworld。

在我的机子上,对于交叉编译,

编译器位于/usr/local/arm/2.95.2/bin,即其中的armv4l-unknown-linux-gcc

链接器是/usr/local/arm/2.95.2/bin/armv4l-unknown-linux-ld

交叉编译好的minigui头文件位于/usr/local/arm/2.95.2/armv4l-unknown-linux/include/,(注意,名为minigui的头文件文件夹位于这个目录下,文件夹下有如window.h等多个minigui头文件在minigui文件夹内)

库函数位于/usr/local/arm/2.95.2/armv4l-unknown-linux/lib/ 内


交叉编译时用如下命令:(交叉编译器的环境变量已经添加,如果没有添加则需要绝对路径)

./configure --build=i686-linux --host=arm --target=arm CC=armv4l-unknown-linux-gcc LD=arm-unknown-linux-ld CFLAGS=-I/usr/local/arm/2.95.2/armv4l-unknown-linux/include/ LDFLAGS=-L/usr/local/arm/2.95.2/armv4l-unknown-linux/lib  

这样生成了Makefile,以后直接make就可以生成arm下的二进制执行文件了。


一个晚上,也就弄了这么多。一个问题,多动手实践,有时候可能一时没有查找具体例子,自己动手试几下也就出来了。

阅读(846) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

mingfei102011-06-08 16:58:58

写完了,发现了一个有用的链接,别人写的,比自己写的好多了,
http://www.cppblog.com/liu1061/articles/54543.html