24小时热门版块排行榜    

CyRhmU.jpeg
查看: 2658  |  回复: 11
【奖励】 本帖被评价9次,作者dxf_dxf_dxf增加金币 6.6
当前只显示满足指定条件的回帖,点击这里查看本话题的所有回帖

dxf_dxf_dxf

银虫 (小有名气)


[资源] [VASP编译]一 什么是.so文件、.a文件?

要想自己编译VASP,就需要修改Makefile。本文介绍makefile工作原理的基础:库文件的工作原理。本系列包括三篇。第一篇将.so文件、.a文件。明白了本文,你就可以对vasp所需的库文件随意移动、改名,所谓心中明了而游刃有余。
    第二篇讲makefile的工作原理,第三篇则是实战测试不同编译器和数学库对vasp计算速度的影响。
【先上例子再说】[cite 1]
CODE:
/*
** tools.h
*/
#include "stdio.h"
#include "stdlib.h"
void draw();
void write();
void sign();
void show();

/*
**tools.c
*/
#include "tools.h"
void draw()
{
printf("draw some graphics./n");
}
void write()
{
printf("write some characters./n");
}
void sign()
{
printf("sign your name./n");
}
void show()
{
printf("A picture by xufeng./n");
draw();
write();
printf("A picture is finished./n");
}

按照如下编译:
CODE:
g++ -fPIC -shared -o libmytools.so tools.c

执行生成一个libmytools.so文件,按照Linux标准对象的命名惯例,应该在库名称之前加上"lib"前缀, 尽管不是必须的。编译开关-fPIC代表函数符号可以重定向[更多介绍请参考 cite 7 结尾部分],-shared代表编译结果是一个标准对象。

不同于Win32DLL,Linux标准对象中的所有函数都是直接导出的,都可以被调用程序 所访问。下面我们编写调用程序:
CODE:
/*
** test.c
*/
#include "tools.h"
main()
{
show();
printf("success!/n");
}

按照如下gcc编译:
CODE:
g++ -o test test.c ./libmytools.so

或者 :
CODE:
g++ -o test test.c -L./ -lmytools

-L选项表示用户指定的库函数的搜索位置,-lmytools表示加载libmytools.so这个共享库[cite 5,6]。

【工作原理说明】

1 为什么要使用库?

我们用C/C++语言编译、链接生成可执行文件,有一些常用的函数(例如:打印到屏幕printf,开根号sqrt,求幂pow),我们不想每次写程序的时候都把这些函数自己重写一遍,而是利用别人现成的结果[cite 3]。

2 库的工作原理是怎样的?

库分成两种[cite 4]:静态库和共享库。

静态库文件名为 如果你使用静态库,那么你所使用到的库会被整合到你生成的可执行文件中。使用静态库的好处是,即使你所使用的库升级了、或者被误删除了,你生成的这个可执行文件仍然可以使用。缺点是,这样生成的可执行文件比较大,而且占用更多的内存[cite 4]。

如果你的可执行文件使用共享库,它会包含一个叫做import directory的表,该表包含可执行文件所使用的所有库的名字。根据表中记录,操作系统在硬盘上——[lab File_Place] 默认位置(\lib,\usr\lib等)、LD_LIBRARY_PATH[cite 2,3]、可执行文件所在的目录(本人测试结论)——搜索需要的库,然后将它们加载到内存中,之后将它们在内存中的地址更新到可执行程序中。可执行程序根据库在内存中的地址调用库中的函数或引用库中的数据[cite 4]。可以使用ldd [filename]来查看[filename]所对应的文件所用到的库的名称、操作系统在磁盘上哪里找到了这些库文件、它们在内存中对应什么地址[cite 3]。这样做的好处是,多个可执行文件、多个进程可以共享一个库,不论是磁盘还是内存上都节约了空间。缺点是,库文件升级以后可能会导致错误;如果没有安装相应的库,某些应用程序无法使用(找不到库文件)[cite 4]。

【实际操作】

1 如何生成我们自己的库?

按照编写一般C语言的方法去写一个源程序,唯一不同的是不需要main函数。

a. 生成静态库

略 有精力再看吧。

提示:

创建一个静态库是相当简单的。通常使用 ar 程序把一些目标文件(.o)组合在一起,
成为一个单独的库,然后运行 ranlib,以给库加入一些索引信息。

[cite 3 search "ar"]

b. 生成动态库

假设你编写的源文件为[sourcename].c和[sourcename].h

g++ -fPIC -shared -o lib[libname].so [sourcename].c ([sourcename]表示你用来生成库的源文件的文件名,[libname]表示你希望声称的库的文件名)

2 如何使用我们创建的、别人创建的库?

要做到以下三点[cite 6]:

a 在我们的源程序中include相应的头文件(#include "[sourcename].h" )

b 编译时指定[sourcename].h的位置(如果在当前目录下可以不指定) -I目录位置(如-I./) 注意没有空格

c 编译时指定lib[libname].so的位置(如果在当前目录下可以不指定) -L目录位置(如-L./) 注意没有空格

d 编译时加载lib[libname].so -l[libname] (如-lm,加载libm.so) 注意没有空格

e 运行时保证所需要的so文件在指定位置(见上文 [cite File_Place])



转载时请注明原始链接: http://blog.renren.com/blog/bp/Q7sbEoWez5

参考文献

[1][转]在linux下编写动态链接库的步骤 httpp://blog.csdn.net/dfman1978/article/details/5921166

[2]学习 linux下如何编写动态链接库 http://blog.sina.com.cn/s/blog_67eb1f2f0100mgnd.html

[3]静态、共享和动态库的使用 http://ruikai.blog.hexun.com/3498786_d.html

[4]wiki 库 http://zh.wikipedia.org/wiki/%E5 ... %E7%AE%97%E6%9C%BA)

[5]《嵌入式Linux应用程序开发详解》3.4.2 Gcc编译选项分析

[6]gcc中的-I -L -l选项http://blog.sina.com.cn/s/blog_68b1a51b01012j13.html

[7]gcc编译流程及编译选项分析 http://blog.sina.com.cn/s/blog_498a6eeb0100tyx4.html

[8]百度百科LD_LIBRARY_PATH http://baike.baidu.com/view/1270749.htm

[ Last edited by zzy870720z on 2012-4-5 at 08:28 ]
回复此楼

» 收录本帖的淘帖专辑推荐

第一性原理和电化学 VASP资料 VASP

» 猜你喜欢

» 本主题相关价值贴推荐,对您同样有帮助:

已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

nonsense2012

新虫 (初入文坛)


★★★★★ 五星级,优秀推荐

重要的计算机基础知识的介绍!!拜读中
9楼2012-04-10 05:24:56
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖
查看全部 12 个回答

lihb734

铁杆木虫 (职业作家)


★★★★★ 五星级,优秀推荐

感谢分享,辛苦了
2楼2012-04-05 08:00:26
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

qzhost

木虫 (小有名气)


★ 一星级,一般

dxf_dxf_dxf: 取消置顶 2012-04-05 10:44:29
对楼主的专业知识表示膜拜
虽然多学点知识是不错
但这些知识对编译VASP来说感觉没什么具体的用处。。
因为只要按教程走一般都问题不大
实用性稍欠缺了些
路过支持一下
3楼2012-04-05 08:06:57
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

dxf_dxf_dxf

银虫 (小有名气)


dxf_dxf_dxf: 取消置顶 2012-04-05 10:56:00
引用回帖:
3楼: Originally posted by qzhost at 2012-04-05 08:06:57:
对楼主的专业知识表示膜拜
虽然多学点知识是不错
但这些知识对编译VASP来说感觉没什么具体的用处。。
因为只要按教程走一般都问题不大
实用性稍欠缺了些
路过支持一下

其实我是想说明.so文件和.a文件可以随便挪,并且对于netlib blas+lapack和Libgoto BLAS+vasp lapack来说,编译vasp只需要编译它们时得到的.so文件和.a文件,并且可以大胆的对.so文件、.a文件改名、移动。

如果你不懂原理,你就不敢随便改,出了问题也不知道怎么解决。
4楼2012-04-05 10:44:08
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖
☆ 无星级 ★ 一星级 ★★★ 三星级 ★★★★★ 五星级
普通表情 高级回复(可上传附件)
信息提示
请填处理意见