makefile 转载
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 。。
动态库的创建
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 转载的更多相关文章
- Configure,Makefile.am, Makefile.in, Makefile文件
一 软件安装关于 makefile文件问题 如果拿到的工程文件中,没有Makefile文件,而只有configure.in和Makefile.am文件,我们是不能够直接进行编译的,必须根据config ...
- 转载-------makefile 使用总结
转载自:http://www.cnblogs.com/wang_yb/p/3990952.html 1. Makefile 简介 Makefile 是和 make 命令一起配合使用的. 很多大型项目的 ...
- 【转载】makefile经典教程
该篇文章为转载,是对原作者系列文章的总汇加上标注. 支持原创,请移步陈浩大神博客: http://blog.csdn.net/haoel/article/details/2886 makefile很重 ...
- 转载一篇makefile,说的很详细
March 3, 2015 8:19 PM 原文见:https://www.cnblogs.com/OpenShiFt/p/4313351.html Makefile 文件的编写 学习前的准备 需要准 ...
- makefile 使用【转载】
该篇文章为转载,是对原作者系列文章的总汇加上标注. 支持原创,请移步陈浩大神博客: http://blog.csdn.net/haoel/article/details/2886 makefile很重 ...
- 深入浅出Android makefile(1)--初探(转载)
转载:http://nfer-zhuang.iteye.com/blog/1752368 一.说明 android build system是一个非常庞大的系统,要编译Android工程.修改或新增A ...
- make命令与Makefile(转载)
概述博客内容包含linux下make命令的使用与makefile的书写规则等,希望通过本文档使读者对make命令makefile文件有进一步了解,由于鄙人经验学识有限文档中会有描述不准确以及理解偏差, ...
- 使用automake等命令自动生成Makefile文件 (转载)
使用automake等命令自动生成Makefile文件 Linux下编程时,为了方便编译,往往使用Makefile文件自动完成编译,但是Makefile文件本身的书写十分复杂,规则很多.好在Lin ...
- Makefile <网络转载>
陈皓 (CSDN)概述——什 么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一个好的和 professional的 ...
随机推荐
- loj#6073. 「2017 山东一轮集训 Day5」距离(树链剖分 主席树)
题意 题目链接 Sol 首先对询问差分一下,我们就只需要统计\(u, v, lca(u, v), fa[lca(u, v)]\)到根的路径的贡献. 再把每个点与\(k\)的lca的距离差分一下,则只需 ...
- Android视频录制从不入门到入门系列教程(一)————简介
一.WHY Android SDK提供了MediaRecorder帮助开发者进行视频的录制,不过这个类很鸡肋,实际项目中应该很少用到它,最大的原因我觉得莫过于其输出的视频分辨率太有限了,满足不了项目的 ...
- WPF软件开发系统之五——展会展厅触摸屏企业产品宣传展示系统
本系统开发背景:上海展会多点触摸大屏(60寸以上)上互动展示. 功能包括:企业背景.产品.合作伙伴.所获荣誉等以图片.文字.视频多媒体的方式呈块状显示,亮点功能为支持多点操作去旋转.缩放.拖拽呈现各种 ...
- Django 日志配置
Django日志处理 settings配置 ########### # LOGGING # ########### BASE_LOG_DIR = os.path.join(os.path.dirnam ...
- [认证授权] 2.OAuth2授权(续) & JWT(JSON Web Token)
1 RFC6749还有哪些可以完善的? 1.1 撤销Token 在上篇[认证授权] 1.OAuth2授权中介绍到了OAuth2可以帮我们解决第三方Client访问受保护资源的问题,但是只提供了如何获得 ...
- MyIsam与InnoDB存储引擎主要区别
MyIsam与InnoDB主要有以下4点大的区别,缓存机制,事务支持,锁定实现,数据物理存储方式(包括索引和数据). 1.缓存机制 myisam 仅仅缓存索引,不会缓存实际数据信息,他会将这一工作交给 ...
- marathon传参一
今天试了下marathon传参,新建一个job,增加一个参数,然后用cmd方式,echo出来 定义的json: { "id": "test1", "l ...
- 类System
System类简介: 在 System 类中提供了大量的静态方法,有标准输入.标准输出和错误输出流:对外部定义的属性和环境变量的访问:加载文件和库的方法:还有快速复制数组的一部分的实用方法. 常用方法 ...
- day10(函数定义,使用)
一:函数 # ***** # 函数:完成 特定 功能的代码块,作为一个整体,对其进行特定的命名,该名字就代表函数 # -- 现实中:很多问题要通过一些工具进行处理 => 可以将工具提前生产出来并 ...
- HTTP的一些基本概念
HTTP协议:HTTP(超文本传输协议)协议就是计算机在网络中进行通信所必须共同遵守的规则,它允许将超文本标记语言(HTML)文档从Web服务器传送到客户端的浏览器,我们目前使用的是HTTP/1.1 ...