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就可以编译程序
























0 0
原创粉丝点击