liuchuanwu的个人博客分享 http://blog.sciencenet.cn/u/liuchuanwu

博文

Makefile语法——以gcc为例

已有 4997 次阅读 2014-3-11 16:47 |个人分类:Linux|系统分类:科研笔记| 编译, makefile, 链接

一、编译和链接

编译是用编译程序把源代码文件代码译成目标代码(ObjectFile文件)的过程。链接是用链接程序把目标文件合成执行文件的过程。在编译是,编译器只检测程序语法,和函数、变量是否被声明。如果函数未被声明,编译器会给出一个警告,但可以生成目标文件。而在链接时,链接器会在所有的目标文件中找寻函数的实现,如果找不到,就会链接错误码。


二、命令行编译

例如我利用4个文件main.c:

#include<stdio.h>
int main()
{  int sum;
   sum = add(1, 2);
   show(sum);
   return 0;
}


f_add.c:

int add(int a, int b)
{
   return a + b;
}


f_show.c:

void show(int value)
{
   printf("sum = %dn", value);
   stamp();
}


和f_stamp.c:

void stamp()
{
  printf("This is a stamp!n");
}

可直接生成可执行文件a.out

gcc main.c f_add.c f_show.c f_stamp.c

如果想生成可执行文件calc,可以有如下过程:

首先生成目标文件*.o

$ gcc -c main.c f_add.c f_show.c f_stamp.c

如果没有其它多余文件,可以使用通配符(gcc -c *.c)。再链接成为可执行文件

$ gcc -o calc main.o f_add.o f_show.o f_stamp.o -lm

现在我们就可以通过./calc运行calc文件了。



三、Makefile规则

target: prerequisites...

<tab>command

其中target就是一个(或多个)目标文件。可以是ObjectFile,也可以是执行文件,还可以是一个标(Label)。prerequisites是生成那个target所需要的文件。Command是生成target时,make要执行的命令(任意的shell命令)。如果prerequisites中有一个以上的文件target文件要新的话,command所定义的命令就会被执行。这是Makefile的核心内容。


因此我们可以写出如下的Makefile

calc: main.o f_add.o f_show.o f_stamp.o
       gcc -o calc main.o f_add.o f_show.o f_stamp.o -lm

main.o: main.c f_add.c f_show.c
       gcc -c main.c f_add.c f_show.c
f_add.o: f_add.c
       gcc -c f_add.c
f_show.o: f_show.c f_stamp.c
       gcc -c f_show.c f_stamp.c
f_info: f_info.c
       gcc -c f_stamp.c
clean:
       rm calc main.o f_add.o f_show.o \
            f_stamp.o

注意每行需要执行的命令要以<tab>开头。反斜杠\是换行符。可以用#开头进行注释。clean不是一个文件,只是一个动作。


我们输入make命令后,系统会:

a、读入Makefile或makefile文件

b、读入被include的其他Makefile

c、初始化文件中的变量

d、推到隐晦规则,并分析所有规则

e、为所有目标文件(包括target)创建依赖关系链

f、决定那些目标要重新生成。即当目标文件不存在或其依赖文件的修改时间比目标文件的更新。

g、执行生成命令

这就是make的分层次文件依赖性。如果我们修改了一个源文件如f_stamp.c,那么f_stamp.o将被重新编译,进而clac也会被重新链接生成。在Makefile中向clean这种没被target直接或间接关联的,其后所定义的命令将不被自动执行。但可以通过make clean来执行。



四、自动推导

make会把每一个目标文件file.o文件就会把其对应的file.c文件加入到file.o的依赖文件中。


五、Makefile中使用变量

可以用变量来简化Makefile,如在前例可简化为

Objects = main.o f_add.o f_show.o f_stamp.o


calc: $(Objects)

gcc -o calc $(objects)


clean:
       rm calc $(Objects)


未完待续。


2014年3月11日

参考:

陈皓. 《跟我一起写Makefile》



https://wap.sciencenet.cn/blog-1005104-775065.html

上一篇:C语言中变量的存储方式和生存期
下一篇:C Pointers and Arrays Notes

0

该博文允许注册用户评论 请点击登录 评论 (0 个评论)

数据加载中...

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2021-5-7 18:11

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部