博客首页 注册 建议与交流 排行榜 加入友情链接
推荐 投诉 搜索: 帮助

jiaxiyingying

加喜英英的家 注:文章多为转载,作为学习所用 QQ:122827420
  jiaxi.cublog.cn

关于作者
姓名:jiaxi
职业:计算机
年龄:
位置:武汉
个性介绍:
|| << >> ||
我的分类


makefile 生成 .la
  如果你了解LINUX库的生成过程,你会发现根本就与那个叫做“libtool”的工具没有任何关系,那

这个软件为什么会多出来一个libtool呢?其实只要看看它的源代码,就知道原来他是讲所有库的生成过

程封装在这个libtool里面,然后只要运用简单的规则就可以实现库的生成了,这有点类似于Makefile的

过程,只不过区别是make软件不用我们自己去设计,它是LINUX自带的。而libtool是根据自己设计的软

件结构而编写的用来生成自己的库的软件。难怪它的库名都叫做.la文件呢!(一般都是.so)。

    但究竟它是怎样生成库的呢?我只有首先从生成共享库的基本知识去了解。

    比如现在我定义了一个很简单的函数 int myadd(int x,int y)并将它放在myadd.h文件中:
----------------------
/*  myadd.h
            */
#include<stdio.h>
#include<math.h>


int myadd(int x,int y);
-----------------------
    这只是定义了一个函数的雏形,接下来对函数进行具体定义,并将它存在myadd.c中:
----------------------
/*  myadd.c
            */
#include<stdio.h>
#include<math.h>
#include<myadd.h>            //必须包含对应的头文件


int myadd(int x,int y)
{
 int x,y,z;
 z=x+y;
 return(z);
}
----------------------
    现在已经定义了一个完整的函数,现在如果有一个程序需要调用这个函数,为了实现让所有程序都

能够调用这个函数,将它添加到库中是必要且方便的。下面就需要通过以上两个文件来生成库文件,方

法如下:
    要进行LINUX下的C编程,要学会使用SHELL命令,但在调试过程中需要输入大量的命令,未免有些烦

琐。还好我们有Makefile,通过编写Makefile可以对程序的编译进行控制,当所有的任务全部设定好以

后,只要在SHELL中敲make 就可以了。所以我们就来编写Makefile,让它来帮我们形成自己的共享库文

件(libmylib.la)这里要指出,LINUX不以文件后缀来区分文件,所以库的后缀是.so也可以(即

libmyalib.so,  注:一般情况下共享库的后缀都是.so,但这里为了和本文所讨论的内容相一致而用.la

).
Makefile文件如下:
-----------------------
##     Makefile  for  generating libmyadd.la
#
#---
SHELL = /bin/sh
CC = /usr/bin/gcc

all:libmylib.la                //所要生成的库文件名

libmylib.la:myadd.o
${CC} -shared -o libmylib.la myadd.o    //通过myadd.o生成共享库libmylib.la

myadd.o:myadd.c myadd.h              
${CC} -c -g -w myadd.c                //通过对myadd.c的编译生成目标文件myadd.o

clean:
rm -rf myadd.o libmylib.la            //卸载时所需的模块
--------------------------------------------
    现在myadd.c ,myadd.h ,Makefile三个文件均放在同一个目录里,且所有程序已经确认无误后,将

SHELL转入该目录下,输入make(回车),即可看到系统对其进行编译,且最终在该目录中生成了

libmylib.la和myadd.o文件。接下来用一个叫做mytest的例程来调用libmylib.la库,设该例程放在以上

目录的一个子目录test中。mytest.c内容如下:
-----------------------------
#include<stdio.h>\
#include<math.h>
#include<myadd.h>

main()
{
  int a,b,c;
  a=3;
  b=4;
  c=myadd(a,b);
  printf("the result is%d\n", c);
  return;
 }
-------------------------
    同样在test目录中编写一个Makefile:
--------------------
/test/Makefile
-------
#用mytest.c程序来调用libmylib.la中的myadd()函数
#-----------------------------
#Makefile程序 :
#---------------------------
CC = /usr/bin/gcc
INCPATH = -I../                       //代表上层目录
COMPILE = ${CC} $(INCPATH) -c -g -Wall -W    

all: mytest.o
${CC} -o mytest mytest.o -L.. -lmylib    //指明库的位置,引用时将libmylib改为lmylib

mytest.o:mytest.c
${COMPILE} mytest.c                 //对mytest.c进行编译生成mytest.o

clean:
rm -rf mytest.o
-------------------------------
在/test目录下,输入make (回车),即可看到如下结果:
# the result is 7
这证明调用库已经成功。

    最后,基于以上内容,我们设想是否能在CVODES所生成的库中添加以上myadd()函数,然后用该软件
本身的规则来调用这个库。为了这一想法,笔者通过分析软件中的各个Makefile,并按照其规则将以上

提到的myadd.h,myadd.c,以及mytest.c添加到软件中去。最后调试mytest.c看看能否得到正确的结果,

如果结果正确,证明myadd()函数已经添加到库中。下面是具体的添加过程:
 
    1.选择SHARED模块,将myadd.h复制到该模块的include目录下,前面已经说过,该目录只是存放函 

   数的雏形;
    2.同样复制myadd.c到该模块的source目录下,该目录里面的文件是对应函数的具体定义;
    3.复制mytest.c到CVODES模块里面的examples_ser目录下;

    以上只是将所要添加的文件简单的分配给各模块,但软件本身不会感觉到这些文件的存在,所以还

必须对相应模块的Makefile进行改写。以下是具体的改写过程:

    1.首先用文本编辑器打开SHARED模块中source目录下的Makefile文件进行编辑:
       1).找到变量 SHARED_LIB_FILES 以及OBJECT_FILES,并在其后分别添加myadd.lo和myadd.o;
       2).在其中install部分的后面,对照其他.h文件的规则,添加myadd.h;
       3).在Makefile底部同样对照.lo文件的生成规则,添加myadd.lo项;
    2.然后同样用文本编辑器编辑CVODES模块中examples_ser目录下的Makefile:
       1).找到变量EXEC_FILES,并在其后添加mytest;
       2).在其中的all部分的最后,同样对照软件本身的规则添加mytest项:即:

    mytest: $(srcdir)/mytest.c
(TAB) $(COMPILER_PREFIX) $(CC) $(CPPFLAGS) -I$(SUNDIALS_INC_DIR) $(CFLAGS) -c

$(srcdir)/mytest.c
(TAB) $(LINKER_PREFIX) $(CC) -o $(builddir)/mytest $(builddir)/mytest.o $(LDFLAGS)

$(LIBS) -L$(SUNDIALS_LIB_DIR) $(SUNDIALS_LIBS)
    这样,软件在统一编译时就会连同我们添加的文件一起编译,最终将在libsundials_shared.la库中

包含我们所定义的myadd()函数(因为我们将函数添加进了SHARED模块),同时在安装软件的最后一步会对

我们的mytest.c进行编译并且连接,形成mytest可执行文件,当运行./mytest 后,会看到我们所希望的

结果----the result is 7.

    最后,通过这些努力,可以看到以下结论:我们不仅可以调用软件本身提供的函数库,而且可以自

己定义函数来修正这些库(如libsundials_shared.la),我们甚至还可以形成一些与该软件本身没有任

何关系的库文件(如libmylib.la)。

 原文地址 http://aendey.bokee.com/1913577.html
发表于: 2008-01-17,修改于: 2008-01-17 13:26,已浏览1823次,有评论0条 推荐 投诉


网友评论
 发表评论