使用Automake生成Makefile及动态库和静态库的创建.doc
《使用Automake生成Makefile及动态库和静态库的创建.doc》由会员分享,可在线阅读,更多相关《使用Automake生成Makefile及动态库和静态库的创建.doc(9页珍藏版)》请在冰点文库上搜索。
使用Automake生成Makefile及动态库和静态库的创建
使用Automake创建和使用静态库
1.目录结构如下:
[c-sharp] viewplaincopy
1.example
2.|——src 目录(存放源代码文件)
3. |——hello.c
4.|——lib 目录(存放用来生成库的文件)
5. |——test.c 用来生成静态库libhello.a
6.|——include 目录(存放程序中使用的头文件)
7. |——hello.h
2.编写的各个目录下的源文件
[c-sharp] viewplaincopy
1.hello.h 文件
2.extern void print(char *);
3.test.c 文件
4.#include
5.void print(char *msg)
6.{
7.print(“%s/n”, msg);
8.}
9.hello.c 文件
10.#include “hello.h”
11.int main()
12.{
13.print(“Hello static library!
”);//这里用到的是静态库中的函数
14.return 0;
15.}
3.编写lib/Makefile.am文件
[c-sharp] viewplaincopy
1.noinst_LIBRARIES=libhello.a
2.libhello_a_SOURCES=test.c
3.AUTOMAKE_OPTIONS=foreign
第一行noinst表示生成的是静态库,不需要makeinstall,直接制定它的位置和名字就
可以使用。
第二行表示用来生成静态库的源文件。
如果要把静态库生成到其他地方,可以在=后面
加上路径(建议用绝对路径,并将所要用到的静态库生成在同一个文件夹下,如lib)。
第三行AUTOMAKE_OPTIONS是Automake的选项。
Automake主要是帮助开发GNU软
件的人员来维护软件,所以在执行Automake时,会检查目录下是否存在标准GNU软件中
应具备的文件,例如'NEWS'、'AUTHOR'、'ChangeLog'等文件。
设置为foreign时,Automake
会改用一般软件的标准来检查。
如果不加这句的话,需要在autoconf之前,先执行touchNEWS
READMEAUTHORSChangeLog来生成'NEWS'、'AUTHOR'、'ChangeLog'等文件
4.编写src/Makefile.am文件
[c-sharp] viewplaincopy
1.AUTOMAKE_OPTIONS=foreign
2.INCLUDES= -I../include
3.bin_PROGRAMS=hello
4.hello_SOURCES=hello.c
5.hello_LDADD=../lib/libhello.a
第二行指定头文件的位置,-I是idirafter的缩写。
../include指定头文件的位置,..是上
一级目录,也就是这里的example目录。
第三行指定生成可执行文件名hello,在这里可执行文件生成在src下,建议将可执行文
件生成到一个特定的文件夹下,让它和源代码分开,如/root/test目录下。
写法为:
[c-sharp] viewplaincopy
1.bin_PROGRAMS=/root/test/hello,后面的第四、五行也相对应地变为:
2._root_test_hello_SOURCES=hello.c
3._root_test_hello_LDADD=../lib/libhello.a
第四行指定生成可执行文件hello的源代码文件,如果hello.c在其他目录下,需要加上
完整的路径。
第五行指定需要使用静态库的位置。
5.生成静态库文件lib/libhello.a。
执行autoscan生成configure.scan文件,将它重命名为configure.in并修改其内容。
[c-sharp] viewplaincopy
1.#configure.in
2.# Process this file with autoconf to produce a configure script.
3.AC_PREREQ(2.59)
4.AC_INIT(libhello.a,1.1,[])
5.AM_INIT_AUTOMAKE
6.# Checks for programs.
7.AC_PROG_CC
8.# Checks for libraries.
9.AC_PROG_RANLIB//需要加入的内容,因为使用了静态库
10.# Checks for header files.
11.# Checks for typedefs, structures, and compiler characteristics.
12.# Checks for library functions.
13.AC_OUTPUT([Makefile])
14.AC_INIT(FILE)
该宏用来检查源代码所在路径,autoscan会自动产生,一般无须修改它。
AM_INIT_AUTOMAKE(PACKAGE,VERSION)
这个是使用Automake所必备的宏,PACKAGE是所要产生软件的名称,VERSION是版
本编号。
也可以把包和版本号等信息放在AC_INIT(FILE)宏里。
AC_PROG_CC
检查系统可用的C编译器,若源代码是用C写的就需要这个宏。
AC_OUTPUT(FILE)
设置configure所要产生的文件,若是Makefile,configure便会把它检查出来的结果
填充到Makefile.in文件后产生合适的Makefile。
后面的FILE是一个Makefile的输出列表,
你可以选着将要输出的Makefile的位置和个数。
建议只在src中输出Makefile。
在lib目录下依次执行aclocal、autoconf、automake--add-missing、./configure、make,
此时在该目录下就可以看到生成的静态库文件libhello.a
6.在src目录下,执行autoscan生成configure.scan文件,将它重命名为configure.in并修
改其内容。
[c-sharp] viewplaincopy
1.#configure.in
2.# Process this file with autoconf to produce a configure script.
3.AC_PREREQ(2.59)
4.AC_INIT(hello,1.1,[])
5.AM_INIT_AUTOMAKE
6.AC_CONFIG_SRCDIR([hello.c])
7.# Checks for programs.
8.AC_PROG_CC
9.# Checks for libraries.
10.# Checks for header files.
11.# Checks for typedefs, structures, and compiler characteristics.
12.# Checks for library functions.
13.AC_OUTPUT([Makefile])
7.在src目录下依次执行aclocal、autoconf、automake--add-missing、./configure、make,
生成可执行文件hello
8.执行makeinstall进行安装,最后输入hello来运行程序,查看效果:
Hellostaticlibrary!
执行成功!
使用gcc创建和使用静态库
1.编写mylib.h文件
[c-sharp] viewplaincopy
1.#ifndef _mylib_h_
2.#define _mylib_h_
3.void welcome();
4.void outstring(const char * str);
5.#endif
2.编写mylib.c文件,用来生成静态库。
[c-sharp] viewplaincopy
1.#include
2.void welcome()
3.{
4.printf(“welcome to libmylib/n”);
5.}
6.void outstring(const char * str)
7.{
8.if(str!
=NULL)
9.printf(“%s”,str);
10.}
3.编译源文件,产生目标代码
gcc–omylib.o–cmylib.c
4.将上面产生的目标文件加入到静态库中,并把静态库拷贝到系统默认的路径
[c-sharp] viewplaincopy
1.ar rcs libmylib.a mylib.o
2.cp libmylib.a /usr/lib/
5.编写测试程序来使用刚才创建的静态库libmylib.a
[c-sharp] viewplaincopy
1.#include “mylib.h”
2.#include
3.Int main()
4.{
5.printf(“create and use library:
/n”);
6.welcome();
7.outstring(“It’s a successful/n”);
8.}
6.编译使用库函数的程序
[c-sharp] viewplaincopy
1.gcc –o test test.c -lmylib
运行./test查看结果。
使用Automake创建和使用动态库
动态库与静态库的差别在于:
动态库是在程序执行的时候加载到内存,供调用函数使用。
1.目录结构如下:
[c-sharp] viewplaincopy
1.example
2.|——src 目录(存放源代码文件)
3.|——hello.c
4.|——lib 目录(存放用来生成库的文件)
5.|——test.c 用来生成动态库libhello.la
6.|——include 目录(存放程序中使用的头文件)
7.|——hello.h
2.编写各个目录下的源文件如下:
[c-sharp] viewplaincopy
1.hello.h 文件
2.extern void print(char *);
3.test.c 文件
4.#include
5.void print(char *msg)
6.{
7.print(“%s/n”, msg);
8.}
9.hello.c 文件
10.#include “hello.h”
11.int main()
12.{
13.print(“Hello static library!
”);//这里用到的是动态库中的函数
14.return 0;
15.}
3.在lib目录下编译需要生成动态库的文件,生成动态库,并安装到系统的标准库中,供
程序调用。
具体步骤如下:
(1)编写Makefile.am文件
[c-sharp] viewplaincopy
1.AUTOMAKE_OPTIONS=foreign
2.lib_LTLIBRARIES=libhello.la
3.libhello_la_SOURCES=test.c
这里lib_LTLIBRARIES的意思是生成的动态库,然后指定动态库依赖的源文件
test.c,若有多个源文件用空格隔开。
(2)在lib目录下,用命令autoscan产生configure.scan文件,并改名为configure.in。
这
里需加上宏AC_PROG_LIBTOOL,表示利用libtool来自动生成动态库
[c-sharp] viewplaincopy
1.#configure.in
2.# Process this file with autoconf to produce a configure script.
3.AC_PREREQ(2.59)
4.AC_INIT(hello,1.0, [miaoquan@])
5.AM_INIT_AUTOMAKE
6.AC_CONFIG_SRCDIR([test.c])
7.#AC_CONFIG_HEADER([config.h])
8.# Checks for programs.
9.AC_PROG_CC
10.# Checks for header files.
11.# Checks for typedefs, structures, and compiler characteristics.
12.# Checks for library functions.
13.AC_PROG_LIBTOOL
14.AC_CONFIG_FILES([Makefile])
15.AC_OUTPUT
(3)执行命令aclocal、libtoolize-f-c、autoconf、automake--add-missing、./configure、
make、makeinstall将动态库安装到系统的标准库中,以供调用(一般为/usr/local/lib)。
注:
libtoolize提供了一种标准的方式来将libtool支持加入一个软件包,而GNUlibtool是
一个通用库支持脚本,将使用动态库的复杂性隐藏在统一、可移植的接口中。
4.生成src目录下的hello可执行文件
(1)编写src/Makefile.am文件
[c-sharp] viewplaincopy
1.AUTOMAKE_OPTIONS=foreign
2.INCLUDES= -I../include
3.bin_PROGRAMS=hello
4.hello_SOURCES=hello.c
5.hello_LDADD=-lhello
-ldir指定编译时搜索库的路径。
与静态库不同的是,创建动态库时不用指定库路
径,编译器自动在标准库中查找libhello.so文件。
(2)执行autoscan生成configure.scan文件,将它重命名为configure.in并修改其内容。
[c-sharp] viewplaincopy
1.# configure.in
2.# Process this file with autoconf to produce a configure script.
3.AC_PREREQ(2.59)
4.AC_INIT(hello,1.0, [miaoquan@])
5.AM_INIT_AUTOMAKE
6.AC_CONFIG_SRCDIR([hello.c])
7.#AC_CONFIG_HEADER([config.h])
8.# Checks for programs.
9.AC_PROG_CC
10.# Checks for header files.
11.# Checks for typedefs, structures, and compiler characteristics.
12.# Checks for library functions.
13.AC_CONFIG_FILES([Makefile])
14.AC_OUTPUT
(3)在src目录下编译并生成目标文件,执行命令aclocal、libtoolize-f-c、autoconf、
automake--add-missing、./configure、make,此时你一定会觉得,成功近在咫尺了。
再
执行目标文件./hello,结果却在你的意料之外:
./hello:
errorwhileloadingsharedlibraries:
libhello.so.0:
cannotopensharedobjectfile:
Nosuchfileordirectory
在执行目标文件的时候,Shell找不到共享库的位置,需要我们手工载入库路径。
5.shell搜索动态库路径位置的两种方法
(1)使用命令导入动态库的路径,命令如下:
exportLD_LIBRARY_PATH=dir(如/usr/local/lib)
(2)修改/etc/ld.so.conf文件,加入搜索路径,修改后用ldconfig命令载入修改。
将自己可能存放库文件的路径都加入到/etc/ld.so.conf中是明智的选择^_^。
添加
方法也极其简单,将库文件的绝对路径直接写进去就OK了,一行一个。
例如:
/usr/local/lib
/usr/lib
/lib
需要注意的是:
这种搜索路径的设置方式对于程序连接时的库(包括共享库和静态
库)的定位已经足够了,但是对于使用了共享库的程序的执行还是不够的。
这是因为
为了加快程序执行时对共享库的定位速度,避免使用搜索路径查找共享库的低效率,所
以是直接读取库列表文件/etc/ld.so.cache从中进行搜索的。
/etc/ld.so.cache是一个非
文本的数据文件,不能直接编辑,它是根据/etc/ld.so.conf中设置的搜索路径由
/sbin/ldconfig命令将这些搜索路径下的共享库文件集中在一起而生成的(ldconfig命令
要以root权限执行)。
因此,为了保证程序执行时对库的定位,在/etc/ld.so.conf中
进行了库搜索路径的设置之后,还必须要运行/sbin/ldconfig命令更新/etc/ld.so.cache
文件之后才可以。
ldconfig,简单的说,它的作用就是将/etc/ld.so.conf列出的路径下的库
文件缓存到/etc/ld.so.cache以供使用。
因此当安装完一些库文件,(例如刚安装好glib),
或者修改ld.so.conf增加新的库路径后,需要运行一下/sbin/ldconfig使所有的库文件都
被缓存到ld.so.cache中,如果没做,即使库文件明明就在/usr/lib下的,也是不会被使
用的,结果编译过程中报错,缺少xxx库,去查看发现明明就在那放着,搞的想大骂
computer蠢猪一个^_^。
极力推荐使用这种方法!
利用gcc创建和使用动态库
1.用下面的命令将mylib.c程序创建成一个动态库:
gcc–fPIC–omylib.o–cmylib.c
gcc–shared–olibtt.somylib.o
-fPIC作用于编译阶段,告诉编译器产生与位置无关代码(Position-IndependentCode),
则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的
任意位置,都可以正确的执行。
这正是共享库所要求的,共享库被加载时,在内存的位置不
是固定的。
-shared作用于链接阶段,实际传递给链接器ld,让其添加作为共享库所需要的额外描
述信息,去除共享库所不需的信息。
也可以直接使用下面一条命令:
gcc–fPIC–shared–olibtt.somylib.c
2.将动态库拷贝到linux的标准库中,usr/local/lib或者/usr/lib或者/lib:
cplibttt.so/usr/local/lib
3.编译src目录下的源程序时,指定动态库文件的目录,调用动态库中的函数
gcc–otesttest.c/usr/lib/libttt.so
4.设置shell动态库搜索路径,运行生成的可执行文件