http://blog.csdn.net/hongfuhaocomon/article/details/51523394

http://blog.csdn.net/lanmanck/article/details/8462088

一.库

什么是库,简单的可以说是可执行代码的二进制形式,能够被操作系统载入内存执行。操作系统的不同,二者的库也是不兼容的,如windows与linux.

库又分为静态库和动态库,动态库又称为共享库。linux下静态库(.a)文件,动态库(.so)文件。主要存放函数库的路径有:/lib , /usr/lib.

二.静态库与动态库

1.静态库

这类库的名字一般是libname.a.利用静态库编写的文件比较大,原因是整个函数库中的数据都被整合进目标代码文件中去。它的优点是,编译后的执行程序不需要外部的函数库支持,因为所有使用的函数都已经被编译进可执行文件了。同样它的不足,如果静态函数库改变了,那么你的程序必须重新编译,而且体积也较大。

2.动态库

名字一般是libname.so.相对于静态函数库,动态函数库在编译的时候并没有被编译进目标代码中,你的程序执行到相关函数是菜调用函数库里的函数,因此动态函数库所产生的可执行文件比较小。由于函数库没有被整合进你的程序,而是程序运行时动态申请并调用,所以程序的运行环境中必须提供相应的库。动态函数库的改变并不影响你的程序,所以动态函数库的升级比较方便。而且如果多个应用程序都要使用同一函数库,动态库就非常适合,可以减少应用程序的体积。

三.库的创建

静态库的创建

gcc -c filen.c

ar -cr libname.a file1.o file2.o 。。

ar:静态函数库创建的命令
-c :create的意思
-r :replace的意思,表示当前插入的模块名已经在库中存在,则替换同名的模块。如果若干模块中有一个模块在库中不存在,ar显示一个错误信息,并不替换其他同名的模块。默认的情况下,新的成员增加在库德结尾处。

动态库的创建

gcc -shard -fpic -o libname.so test1.c test2.c ....

-fpic:产生代码位置无关代码

-shared 生成一个共享库

四.实际操作

1.编写三个简单函数ADD.c SUB.c MUL.c如下

ADD.c

#include <stdio.h>
 int ADD(int a, int b)
  {
      return a+b;
  }

SUB.c

#include <stdio.h>
  int SUB(int a ,int b)
  {
      return a-b;
  }

MUL.c

#include <stdio.h>
  int MUL(int a , int b)
  
  {
      return a*b;
  }
 和一个头文件 fun.h

#ifdef __FUN_H_
#define __FUN_H_
  extern ADD(int a , int b);
  extern SUB(int a , int b);
  extern MUL(int a , int b);
#endif
以及一个main函数main.c

main.c

#include <stdio.h>

#include <fun.h>
 int main (void)
{
     int a=5;
     int b=10;
     printf("a=5,b=10\n");
     printf("a+b=%d\n",ADD(a,b));
     printf("a-b=%d\n",SUB(a,b));
     printf("a*b=%d\n",MUL(a,b));
     return 0;
 }
 其中main.c 放在~/app下 fun.h ADD.c SUB.c MUL.c放在~/src下

2.生成静态库

[hongfuhao@localhost src]$ ls
ADD.c  fun.h  makefile  MUL.c  SUB.c
[hongfuhao@localhost src]$ gcc -c *.c
[hongfuhao@localhost src]$ ls
ADD.c  ADD.o  fun.h  makefile  MUL.c  MUL.o  SUB.c  SUB.o
[hongfuhao@localhost src]$ ar -cr libfun.a *.o
[hongfuhao@localhost src]$ ls
ADD.c  ADD.o  fun.h  libfun.a  makefile  MUL.c  MUL.o  SUB.c  SUB.o

上中libfun.a即是一个静态库

生成动态库

[hongfuhao@localhost src]$ ls
ADD.c  ADD.o  fun.h  libfun.a  makefile  MUL.c  MUL.o  SUB.c  SUB.o
[hongfuhao@localhost src]$ gcc -shared -fpic -o libfun.so  *.c  
[hongfuhao@localhost src]$ ls
ADD.c  ADD.o  fun.h  libfun.a  libfun.so  makefile  MUL.c  MUL.o  SUB.c  SUB.o

上中libfun.so 就是一个动态库

3.静态库与动态库的使用

对main.c进行编译

[hongfuhao@localhost app]$ ls
main.c  makefile
[hongfuhao@localhost app]$ gcc main.c
main.c:14:17: 错误:fun.h:没有那个文件或目录

编译器报错 找不到头文件  需要指定头文件的位置

-I选项 指定头文件的路径

[hongfuhao@localhost app]$ gcc -I../src main.c
/tmp/ccZw9v3Q.o: In function `main':
main.c:(.text+0x30): undefined reference to `ADD'
main.c:(.text+0x5a): undefined reference to `SUB'
main.c:(.text+0x84): undefined reference to `MUL'
collect2: ld 返回 1

链接器再一次报错  未能找库

-L选项来指定库的路径

-l选项来指定库的名字 (去掉lib和.a .so)剩下的部分  即-lfun

[hongfuhao@localhost app]$ gcc -I../src main.c -L../src -lfun -o app
[hongfuhao@localhost app]$ ls
app  main.c  makefile

生成一个可执行文件 app

[hongfuhao@localhost app]$ ./app
./app: error while loading shared libraries: libfun.so: cannot open shared object file: No such file or directory

执行时出错  找不到动态库

[hongfuhao@localhost app]$ file app
app: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped

这时我们可以发现 系统编译时默认使用的是动态链接  执行时我们需要指定动态库的位置

两种方法:

1:将函数库移动到/lib 或者/usr/lib下 (需要root权限)

2:修改一个环境变量 LD_LIBRARY_PATH

在这里我采用第二种方法

[hongfuhao@localhost app]$ ./app
./app: error while loading shared libraries: libfun.so: cannot open shared object file: No such file or directory
[hongfuhao@localhost app]$ file app
app: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped
[hongfuhao@localhost app]$ cd ../src
[hongfuhao@localhost src]$ ls
ADD.c  ADD.o  fun.h  libfun.a  libfun.so  makefile  MUL.c  MUL.o  SUB.c  SUB.o
[hongfuhao@localhost src]$ pwd
/home/hongfuhao/src
[hongfuhao@localhost src]$ cd ../app
[hongfuhao@localhost app]$ ls
app  main.c  makefile
[hongfuhao@localhost app]$ export LD_LIBRARY_PATH='/home/hongfuhao/src'
[hongfuhao@localhost app]$ ./app
a=5,b=10
a+b=15
a-b=-5
a*b=50

可以看到程序成功执行

如果想采用静态链接方式  需要-static关键字

[hongfuhao@localhost app]$ ls
main.c  makefile
[hongfuhao@localhost app]$ gcc -static -I../src main.c -o bpp -L../src -lfun
[hongfuhao@localhost app]$ ls
bpp  main.c  makefile
[hongfuhao@localhost app]$ ./bpp
a=5,b=10
a+b=15
a-b=-5
a*b=50

这时再看bpp文件

[hongfuhao@localhost app]$ file bpp
bpp: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.18, not stripped

采用的静态链接执行时不需要指定库的路径

两个文件app与bpp的大小 使用du命令

[hongfuhao@localhost app]$ du app
8       app
[hongfuhao@localhost app]$ du bpp
744     bpp

看一个文件执行依赖的动态库

[hongfuhao@localhost app]$ ldd app
        linux-vdso.so.1 =>  (0x00007ffe7a3bf000)
        libfun.so => /home/hongfuhao/src/libfun.so (0x00007f775018f000)
        libc.so.6 => /lib64/libc.so.6 (0x00000030cee00000)
        /lib64/ld-linux-x86-64.so.2 (0x00000030ce600000)

以上为app依赖的动态库文件
[hongfuhao@localhost app]$ ldd bpp
        不是动态可执行文件

bpp不是动态链接所以不显示

上述就完成一个静态库和动态库的创建和使用

五.makefile

1.概述

Linux 环境下的程序员如果不会使用GNU make来构建和管理自己的工程,应该不能算是一个合格的专业程序员,至少不能称得上是 Unix程序员。在 Linux(unix )环境下使用GNU 的make工具能够比较容易的构建一个属于你自己的工程,整个工程的编译只需要一个命令就可以完成编译、连接以至于最后的执行。不过这需要投入一些时间去完成一个或者多个称之为Makefile 文件的编写。

所要完成的Makefile 文件描述了整个工程的编译、连接等规则。其中包括:工程中的哪些源文件需要编译以及如何编译、需要创建那些库文件以及如何创建这些库文件、如何最后产生想要得可执行文件。尽管看起来可能是很复杂的事情,但是为工程编写Makefile 的好处是能够使用一行命令来完成“自动化编译”,一旦提供一个(通常对于一个工程来说会是多个)正确的 Makefile。编译整个工程你所要做的唯一的一件事就是在shell 提示符下输入make命令。整个工程完全自动编译,极大提高了效率。

make是一个命令工具,它解释Makefile 中的指令(应该说是规则)。在Makefile文件中描述了整个工程所有文件的编译顺序、编译规则。Makefile 有自己的书写格式、关键字、函数。像C 语言有自己的格式、关键字和函数一样。而且在Makefile 中可以使用系统shell所提供的任何命令来完成想要的工作。Makefile(在其它的系统上可能是另外的文件名)在绝大多数的IDE 开发环境中都在使用,已经成为一种工程的编译方法

2.makefile 小结即规范

Make  执行总目标

Make clean 执行makefile 中的clean目标

Make -C directory 到directory中执行make

Make clean -C directory  同上两命令

Make -f common_makefile 通过-f 指定一个makefile文件

Make var=value   给makefie传一个参数其值为value

# 注释

VAR=XXX    定义变量VAR,强制赋值

VAR+=XXX 追加

VAR?=XXX   之前定义这用之前  没有定义 则定义

Target: depend1 depend2 . .          #依赖可以是文件(目录)或其他目标

(tab)  action1 action2            #动作那一行必须以TAB键打头

Depend1:

@(tab)Action1 action2    #@j键表示不打印该行动作信息

2.实际操作

编写自己的makefile

使用之前静态库与动态库的案例

创建一个makefile

1 LIB_NAME?=fun
  2 
  3 all:static_library shared_library
  4 
  5 static_library:
  6     gcc -c *.c;
  7     ar  -cr lib${LIB_NAME}.a *.o;
  8 
  9 shared_library:
 10     gcc -shared -fpic -o lib${LIB_NAME}.so *.c;
 11 
 12 clean:
 13     rm -rf *.o
 14     rm -rf *.a *.so

[hongfuhao@localhost src]$ ls
ADD.c  fun.h  makefile  MUL.c  SUB.c

makefile已经创建完成

make命令可以完成之前的操作

[hongfuhao@localhost src]$ ls
ADD.c  fun.h  makefile  MUL.c  SUB.c
[hongfuhao@localhost src]$ make
gcc -c *.c;
ar  -cr libfun.a *.o;
gcc -shared -fpic -o libfun.so *.c;
[hongfuhao@localhost src]$ ls
ADD.c  ADD.o  fun.h  libfun.a  libfun.so  makefile  MUL.c  MUL.o  SUB.c  SUB.o

完成了静态库和动态库的创建  只需要make一下

对main.c进行makefile的编写

makefile                                                                                                                           
  1 APP_NAME?=APP
  2 
  3 all:lib_make
  4     gcc -static -I../src main.c -L../src -lfun -o ${APP_NAME};
  5 
  6 lib_make:
  7     make -C ../src;
  8 
  9 clean:
 10     rm -rf ${APP_NAME}

[hongfuhao@localhost app]$ ls
main.c  makefile
[hongfuhao@localhost app]$ ls
main.c  makefile

只需要make一下 就可以完成main.c编译

[hongfuhao@localhost app]$ make
make -C ../src;
make[1]: Entering directory `/home/hongfuhao/src'
gcc -c *.c;
ar  -cr libfun.a *.o;
gcc -shared -fpic -o libfun.so *.c;
make[1]: Leaving directory `/home/hongfuhao/src'
gcc -static -I../src main.c -L../src -lfun -o APP;
[hongfuhao@localhost app]$ ls
APP  main.c  makefile

生成一个APP的可执行文件makefile中执行的是静态链接

可以直接执行APP

[hongfuhao@localhost app]$ ./APP
a=5,b=10
a+b=15
a-b=-5
a*b=50

程序成功执行

即完成了一个简单的makefile的编写

makefile 转载的更多相关文章

  1. Configure,Makefile.am, Makefile.in, Makefile文件

    一 软件安装关于 makefile文件问题 如果拿到的工程文件中,没有Makefile文件,而只有configure.in和Makefile.am文件,我们是不能够直接进行编译的,必须根据config ...

  2. 转载-------makefile 使用总结

    转载自:http://www.cnblogs.com/wang_yb/p/3990952.html 1. Makefile 简介 Makefile 是和 make 命令一起配合使用的. 很多大型项目的 ...

  3. 【转载】makefile经典教程

    该篇文章为转载,是对原作者系列文章的总汇加上标注. 支持原创,请移步陈浩大神博客: http://blog.csdn.net/haoel/article/details/2886 makefile很重 ...

  4. 转载一篇makefile,说的很详细

    March 3, 2015 8:19 PM 原文见:https://www.cnblogs.com/OpenShiFt/p/4313351.html Makefile 文件的编写 学习前的准备 需要准 ...

  5. makefile 使用【转载】

    该篇文章为转载,是对原作者系列文章的总汇加上标注. 支持原创,请移步陈浩大神博客: http://blog.csdn.net/haoel/article/details/2886 makefile很重 ...

  6. 深入浅出Android makefile(1)--初探(转载)

    转载:http://nfer-zhuang.iteye.com/blog/1752368 一.说明 android build system是一个非常庞大的系统,要编译Android工程.修改或新增A ...

  7. make命令与Makefile(转载)

    概述博客内容包含linux下make命令的使用与makefile的书写规则等,希望通过本文档使读者对make命令makefile文件有进一步了解,由于鄙人经验学识有限文档中会有描述不准确以及理解偏差, ...

  8. 使用automake等命令自动生成Makefile文件 (转载)

    使用automake等命令自动生成Makefile文件   Linux下编程时,为了方便编译,往往使用Makefile文件自动完成编译,但是Makefile文件本身的书写十分复杂,规则很多.好在Lin ...

  9. Makefile <网络转载>

    陈皓 (CSDN)概述——什 么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一个好的和 professional的 ...

随机推荐

  1. 第十二课 CSS基本选择器 css学习2

    基础选择器一.标签选择器(元素选择器)标签选择器是指用HTML标签名称作为选择器,按标签名称分类语法:标签名{属性1:属性值1;属性2:属性值2;属性3:属性值3;} 二.类选择器1.类选择器使用&q ...

  2. [总结]CSS/CSS3常用样式与web移动端资源

    CSS/CSS3常用样式与知识点 IE条件注释 条件注释简介 IE中的条件注释(Conditional comments)对IE的版本和IE非IE有优秀的区分能力,是WEB设计中常用的hack方法.条 ...

  3. java基础(一):谈谈java内存管理与垃圾回收机制

    看了很多java内存管理的文章或者博客,写的要么笼统,要么划分的不正确,且很多文章都千篇一律.例如部分地方将jvm笼统的分为堆.栈.程序计数器,这么分太过于笼统,无法清晰的阐述java的内存管理模型: ...

  4. arcgis api 3.x for js 入门开发系列十五台风轨迹

    前言 关于本篇功能实现用到的 api 涉及类看不懂的,请参照 esri 官网的 arcgis api 3.x for js:esri 官网 api,里面详细的介绍 arcgis api 3.x 各个类 ...

  5. @Resource 与 @Service注解的区别

    pring中什么时候用@Resource,什么时候用@service当你需要定义某个类为一个bean,则在这个类的类名前一行使用@Service("XXX"),就相当于讲这个类定义 ...

  6. 数据文件实时同步(rsync + sersync2)

    因近期项目需求,需要同步云端服务器的数据给**方做大数据分析. 思路: 起初只要数据同步,准备开放数据采集接口.但实时性较差,会有延迟. 故而寻觅各种解决方案,最终确定使用 rsync 进行文件同步, ...

  7. Windows中通过命令行启动打开Service 管理工具

    经常需要打开Services 管理工具操控Service 的启动,停止. 通过控制面板 --> 管理工具 -->Service  太慢. 学到一个快捷方式. windows + R  启动 ...

  8. June 28th. 2018, Week 26th. Thursday

    You cannot change the circumstances but you can change yourself. 既然改变不了环境,那就改变自己. From Jim Rohn. Rec ...

  9. Angular CLI 升级 6.0 之后遇到的问题

    Angular CLI 1.7.4 在使用 ng build --prod 会构建失败,而 ng build 是正常的.比较好的解决办法是使用 ng build --prod --extract-li ...

  10. [Alpha阶段]无人转会申请

    Alpha阶段无人转会申请 大家好,我们是Water_T团队.我们团队在Alpha阶段较好完成了预期目标,团队成员合作愉快,氛围良好,配合默契,且完成的产品在alpha阶段中是用户可互动.可使用的功能 ...