makefile的前世今生---by 香蕉麦乐迪
来源:互联网 发布:史学方法导论知乎 编辑:程序博客网 时间:2024/04/28 16:23
一:基本原理
1、file命令可以查看文件的类型:
比如file 111.jpg
111.jpg: JPGE image data, JFIF standard 1.02
2、编译的过程
以c语言为例,以文本文件编写的源代码,会被gcc编译成2进制的可执行文件;中间有一步,先会生成.o文件(目标文件),然后将.o文件与我们调用的函数库链接,最后生成可执行文件;
3、函数库:动态函数库和静态函数库
动态函数库的执行过程:
从外部动态函数库的执行过程可以发现,动态函数库的优点是源程序生成的可执行文件会小很多,而且函数库升级方便;
在linux中静态函数库后缀.a,动态函数库后缀.so;
存放的路径一般都在/lib /usr/lib中;
使用ldconfig命令可以将指定的函数库加载到内存中,这样可以加快常用的动态函数库的速度;
ldconfig的语法如下:
ldconfig [-f conf_file] [-C cache]
ldconfig [-p]
简单解释读者就会明白:我们直接执行ldconfig,ldconfig会查看/etc/ld.so.conf文件,该文件中可以添加目录比如/usr/local/lib 这样ldconfig命令会将该目录下的.so文件加载到内存中,而当前加载的动态函数库的信息会存储在/etc/ld.so.cache文件中;
上面的[-f conf_file] [-C cache]参数就是指定非默认的conf和cache文件;ldconfig [-p] 是显示当前所有已经加载的函数库和路径,也就是ld.so.cache文件中的内容
ldd [-vdr] [filename] :查看某个文件使用了哪些动态函数库
4、make与configure
有了前面的编译过程的了解,我们来看看linux下编译时,make命令是如何操作的 ;
为什么需要make:我们需要对主程序和每个子程序写一个编译命令,还要写最终的链接命令,对于源文件数量成千上万的的时候,这样做就太麻烦了,所以我们借助make这个工具简化编译过程;
执行make,会发生什么:执行make时,make会在当前目录下寻找makefile文件,makefile文件中记录了应该如何编译和链接,同时make会判断源文件是否发生了改动而只更新改动后的目标文件(提高了效率),make后就产生了可执行文件;
5、如何产生makefile文件呢
make需要makefile文件,可是如何得到makefile文件,有两种办法
1:自己动手写makefile,指定你的编译,链接方式;(针对自己的电脑,自己写程序的时候方便使用)
2:使用configure或config文件(软件开发商发行,通用性强),congfigure文件会检测当前电脑的运行环境,检测完毕后根据环境建立makefile文件
主要是做以下检测:
检测是否有符合要求的编译器
检测是否有依赖的函数库
检测是否有依赖的头文件
检测linux内核版本是否符合要求
6、软件的安装
软件安装可以直接将软件下载下来,编译安装或者使用RPM软件管理机制与yum在线更新模式(Debian使用的是dpkg软件管理机制与apt在线更新模式);
直接下载下来安装,我们称之为tarball软件:也就是先用tar打包,然后使用gzip或bzip2或其他压缩的 软件源代码,下载后解压缩,然后使用make编译好,配置好相应的文件,该软件就可以使用了;
可以使用MD5或SHA1方式计算文件的指纹码,以此判断文件是否经过修改;有些下载的源程序可能有错误或者被黑客修改过,以此可以确保源文件的正确和安全;
二:简单范例
1、gcc的简易用法(编译、参数、链接)
假如有这样一个案例:
main.c:让用户输入数据->调用sin_value计算三角函数值->输出数据;
sin_value.c:计算sin值;
sin_value.h:函数的头文件
main.c:
#include<stdio.h>
#include<sin_value.h>int main(void){float angle=0;float sin_angle=0;printf("please input angle:\n");scanf("%f",&angle);sin_angle=sin_value(angle);printf("sin_angle is:%f\n",sin_angle);}
sin_value.c:
#include<stdio.h>
#include<math.h>float sin_value(float angle){return sin(3.1415*angle/180);}
sin_value.h:
void sin_value(float value);
方法一:在shell中输入下列两行命令
gcc -c main.c sin_value.c //编译产生目标文件,-c是参数,后面接所有要编译的源文件
gcc -o main main.o sin_value.o -lm -L/lib -L/usr/lib //利用目标文件以及库,生成二进制可执行文件;-o是参数,main是生成的可执行文件名,后面接所有需要的目标文件;-lm是链接的库文件,l表示lib,m指的是libm.so这个库文件,省去开头的lib和后缀名,;-L以及后面的路径指明库函数的路径,这里可以省略,因为-L/lib -L/usr/lib是默认路径;
这里还要注意,默认头文件是在当前路径和/usr/include中的,如果不在这些路径里,需要显式的指明:
gcc -c main.c sin_value.c -I/usr/include //用 -I/path 说明
gcc还有很多其他的参数,比如-O 表示根据当前环境,优化执行速度:
gcc -c -O main.c sin_value.c
-Wall显示警告信息,编译过程会更加严谨:
gcc -c -Wall main.c sin_value.c
方法二:使用makefile
如果每次编译都要输入上面的命令,未免太繁琐,所以我们可以将上面的命令写在makefile中:
makefile:
main: main.o sin_value.ogcc -o main main.o sin_value.o -lm
简要说明上面的语法:
目标<target>:目标文件1 目标文件2
<tab> gcc -o 欲建立的可执行文件 目标文件1 目标文件2
即:命令以tab键开头,目标信息说明的那一行,make命令会自动寻找同名的源文件,比如对于main.o文件,会自动寻找main.c文件;
建立好makefile文件后,执行:make
就可以完成程序的编译;使用make的好处 :简化了命令的输入;make只会编译修改过的源文件,所以对于大型工程,编译速度会快很多;
下面我们在makefile中加入新的规则:
main: main.o sin_value.ogcc -o main main.o sin_value.o -lmclean:rm -f main main.o sin_value.o
使用make clean就可以清楚之前生成的文件,使用make main就可以编译程序
- makefile的前世今生---by 香蕉麦乐迪
- makefile的前世今生
- 产品管理的前世今生-今生篇--Posted by ucpm
- 前世今生的缘
- 互联网的前世今生
- 救世主的前世今生
- 3G的前世今生
- Gentoo的前世今生
- Mozilla的前世今生
- Java的“前世今生”
- unix的前世今生
- 浏览器的前世今生
- JAVA的前世今生
- bug的前世今生
- CKO的前世今生
- BIM的前世今生
- XVID的前世今生
- ActionScript的前世今生
- pkg-config使用方法
- Android——终极版上拉刷新下拉加载(兼容ScrlooView、ListView、GridView以及各类布局)
- 检查数字签名(交叉签名)
- SpringMVC的各种参数绑定方式
- android全屏去掉title栏的多种实现方法
- makefile的前世今生---by 香蕉麦乐迪
- 未能从程序集“System.ServiceModel”中加载类型“System.ServiceModel.Activation.HttpModule”。
- PgSQL · 特性分析 · full page write 机制
- HADOOP Unable to load native-hadoop library for your platform解决办法
- Androd 错误解决--webview.destroy() called while still attached
- Java中Cloneable接口
- ceilometer的数据采集机制
- 多管齐下,靠谱娱乐走上泛娱乐之路
- 微信支付授权申请及接入流程