这里举个例子是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下的二进制执行文件了。
一个晚上,也就弄了这么多。一个问题,多动手实践,有时候可能一时没有查找具体例子,自己动手试几下也就出来了。
|