1.关于程序的编译和链接

一般来说,无论是C、C++首先要把源文件编译成中间目标文件即 Object File(windows为.obj文件,unix为.o文件),这个动作叫做编译(compile)。然后再把大量的Object File合成执行文件,这个动作叫作链接(link)。

1.1编译

编译时编译器只检查语法是否正确,函数与变量的声明是否正确。如果函数未被声明,编译器会给出一个警告,但可以生成Object File。一般来说,每个源文件都应该对应于一个中间目标文件(O文件或是OBJ文件)。

cc -c foobar.c         ==>将源文件编译但不链接,成目标文件foobar.o
cc foobar.c -o foobar ==>将源文件编译并链接,生成可执行文件foobar

1.2链接

链接时主要是链接函数和全局变量。链接器会在所有的Object File中找寻函数的实现,如果找不到,那到就会报链接错误码(Linker Error)。

cc -o foobar foobar.c  ==>链接生成可执行文件foobar

1.3自定义函数库(打包中间目标文件)ar命令

如果需要链接中间目标文件太多,链接时需要明显地指出所有中间目标文件名,十分不便。可以给中间目标文件打个包,在Windows下这种包叫“库文件”(Library File),也就是 .lib 文件,在UNIX下,是Archive File,也就是 .a 文件静态库。

PS:我们可以使用中间目标文件(O文件或是OBJ文件)或静态库文件来链接我们的应用程序。

ar crv libtest.a *.o  ==>将该目录下的所有目标文件打包生成了libtest.a文件静态库

2.make命令

make是一个命令工具,是一个解释Makefile中指令的命令工具。在命令行输入make命令后,会查找当前目录下的Makefile文件来执行,根据Makefile文件编译源代码生成中间目标文件、链接后生成可执行文件。

一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。使用示例(其中all、install和clean均为Makefile文件中定义的伪目标):

make          ==>默认找到Makefile中第一个目标,进行编译链接
make all
make clean

3.Makefile文件

make命令执行时,需要一个 Makefile 文件,告诉make命令需要怎么样的去编译和链接程序。Makefile带来的好处就是“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。

Makefile中除了编译链接目标外,还可以使用伪目标。通常情况下,为了规范和统一,会参考Linux源码的Makefile规则来书写我们的Makefile中的伪目标,这些伪目标都是GNU开源软件定义和采用的。

“all”—— 这个伪目标是所有目标的目标,其功能一般是编译所有的目标。
“clean” —— 这个伪目标功能是删除所有被make创建的文件。
“install” —— 这个伪目标功能是安装已编译好的程序,其实就是把目标执行文件拷贝到指定的目标中去。
“print” —— 这个伪目标的功能是例出改变过的源文件。
“tar” —— 这个伪目标功能是把源程序打包备份。也就是一个tar文件。
“dist” —— 这个伪目标功能是创建一个压缩文件,一般是把tar文件压成Z文件,或是gz文件。
“TAGS” —— 这个伪目标功能是更新所有的目标,以备完整地重编译使用。
“check”和“test” —— 这两个伪目标一般用来测试makefile的流程。

3.1 Makefile规则

target... : prerequisites ...
command
...

target:是一个目标,可以是目标文件Object File,也可以是执行文件,还可以是一个标签(伪目标)。

prerequisites:是要生成那个target所需要的文件或目标。

command:也就是make需要执行的命令(任意的Shell命令,一定要以Tab键开头)。

3.2 Makefile规则示例

仅做编译:main.o是我们的第一个目标,main.c和defs.h是目标所依赖的源文件,而执行命令为“cc -c main.c”

编译链接:main是我们的第二个目标,main.c和defs.h是目标所依赖的源文件,而执行命令为“cc  main.c -o main”

main.o : main.c defs.h
cc -c -o main.o main.c
main: main.c defs.h
cc main.c -o main

3.3 Makefile规则示例(自动推导)

GNU的make很强大,它可以自动推导依赖c文件以及编译命令。以main.c为例

仅做编译:make看到一个[main.o]目标,它会自动的把[main.c]文件加在依赖关系中,并自动推导出cc -c -o  main.o main.c

编译链接:make看到一个[main]目标,它会自动把[main.c]文件加在依赖关系中,并自动推导出cc  main.c -o main

Makefile中如下定义

main.o: defs.h
main: defs.h

等同于

main.o : main.c defs.h
cc -c -o main.o main.c
main: main.c defs.h
cc main.c -o main

3.4 清空目标文件规则示例

每个Makefile中都应该写一个清空目标文件(执行文件和.o目标文件)的规则,这不仅便于重编译,也很利于保持文件的清洁。规矩:使用clean伪目标,且永远放在Makefile文件的最后。

目标:清理可执行文件main和目标文件mian.o

一般常用写法:

clean :
rm main main.o

更健壮写法:

.PHONY : clean
clean :
-rm main main.o

.PHONY表示clean是一个“伪目标”。在rm命令前面加了一个小减号,标识忽略文件出现的问题,继续执行。

3.5 Makefile变量定义示例

目标:生成可执行文件main,引用多个目标文件

objects = main.o kbd.o \
insert.o search.o files.o utils.o
main: $(objects)
cc -o main $(objects)

定义变量objects后,引用变量使用$(objects) 。.反斜杠(\)是换行符的意思,这样比较便于Makefile的易读。

3.6 Makefile经典示例

目标:一个工程包含有3个头文件和8个C文件,需要编译链接成可执行文件edit。

objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
.PHONY : all
all: $(objects)
cc -o edit $(objects) main.o : defs.h
kbd.o : defs.h command.h
command.o : defs.h command.h
display.o : defs.h buffer.h
insert.o : defs.h buffer.h
search.o : defs.h buffer.h
files.o : defs.h buffer.h command.h
utils.o : defs.h .PHONY : clean
clean :
-rm edit $(objects)

3.7 测试使用源文件main.c

#include <stdio.h>
int main(void)
{
printf("Hello world/n");
return ;
}

参考文档:

make all、make clean、make install 等命令的来源

Makefile经典教程

Linux 如何使用GCC编译器将一个文件夹下的100个.o文件打包成一个静态库文件(.a)

cc,gcc命令解释

gcc的使用简介与命令行参数说明

【C编程基础】make命令和makefile文件的更多相关文章

  1. Shell脚本——make命令和Makefile文件【转】

    https://blog.csdn.net/twc829/article/details/72729799 make命令是一个常用的编译命令,尤其在C/C++开发中,make命令通过makefile文 ...

  2. 简介make命令和makefile文件

    一.为什么要用到 make 命令和 makefile 文件 在 Linux 下编写一个程序,每次编译都需要在命令行一行一行的敲命令.如果是一个很小的程序还好说,命令不怎的复杂,编译速度也挺快,但是对于 ...

  3. make命令和makefile文件

    make命令和makefile文件的结合提供了一个在项目管理领域十分强大的工具,它不仅常被用于控制源代码的编译,而且还用于手册页的编写以及将应用程序安装到目标目录. makefile文件由一组依赖关系 ...

  4. 【 MAKEFILE 编程基础之二】MAKEFILE 书写规划以及语法规则!

    本站文章均为 李华明Himi 原创,转载务必在明显处注明: 转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/gcc-makefile/768.html   ...

  5. gcc命令以及makefile文件

    (一)makefile里涉及到的gcc命令 gcc -I./inc:指定头文件寻找目录 将按照 ./inc --> /usr/include --> /usr/local/include的 ...

  6. make命令以及makefile

    make命令以及makefile使用RCS与CVS进行源代码控制编写手册页使用patch与tar发布软件开发环境 多源代码的问题 当我们编写小程序时,许多人都是简单的在编辑后通过重新编译所有的文件重新 ...

  7. 单文件夹下的C程序如何编写Makefile文件

    通过学习已经学会了GCC的一些基础的命令,以及如何将C语言源代码编译成可执行文件. 我们已经知道在linux环境下编译源码时,常会有以下三个步骤: ./configure make make clea ...

  8. 利用 autoconf 和 automake 生成 Makefile 文件

    一.相关概念的介绍 什么是 Makefile?怎么书写 Makefile?竟然有工具可以自动生成 Makefile?怎么生成啊?开始的时候,我有这么多疑问,所以,必须得先把基本的概念搞个清楚. 1.M ...

  9. MakeFile 文件详解

    GNU的make工作时的执行步骤入下:(想来其它的make也是类似)      1.读入所有的Makefile.      2.读入被include的其它Makefile.      3.初始化文件中 ...

随机推荐

  1. eclipse下SpringMVC+Maven+Mybatis+MySQL项目搭建

    这篇文章主要讲解使用eclipse对Spirng+SpringMVC+Maven+Mybatis+MySQL项目搭建过程,包括里面步骤和里面的配置文件如何配置等等都会详细说明. 接下来马上进入项目搭建 ...

  2. 买or不买?如何测试博彩公司赔率是否合理?

    世界杯期间,烧烤店.酒吧都热闹起来了,柔柔我的朋友圈也热闹起来了,有酱紫的: 还有酱紫的: 然后还有酱紫的: 酱紫的: 当然天台也是一如既然的热闹: 似乎人人都在输钱,那真正的赢家在哪里呢?博彩业的真 ...

  3. SQL优化一(SQL使用技巧)

    1.行列转换: decode(条件,值1,返回值1,值2,返回值2,...值n,返回值n,缺省值); select decode(sign(变量1-变量2),-1,变量1,变量2) from dual ...

  4. Ubuntu创建新用户的正确姿势

    作者按:因为教程所示图片使用的是 github 仓库图片,网速过慢的朋友请移步<Ubuntu 创建新用户的正确姿势>原文地址.更欢迎来我的小站看更多原创内容:godbmw.com,进行&q ...

  5. 你所不知道的JSON.stringify

    译者按: 老司机们,你知道JSON.stringify还有第二个和第三个可选参数吗?它们是什么呢? 原文: What you didn’t know about JSON.Stringify 译者: ...

  6. 小tips:Hbuilder编辑器开启less自动编译为css的方法

    1.首先,依次打开菜单栏->工具->预编译器设置,打开后是这样的: 2.然后点击新建. 3.文件后缀为.less触发命令地址就是lessc.cmd所在的地址,先用npm全局安装less, ...

  7. 【读书笔记】iOS-更改编辑器键的绑定

    一,Xcode-->Preferences--->Key Bindings. 参考资料:<Xcode实战开发>

  8. Salesforce 数据备份和恢复小知识

    数据备份的类型 在Salesforce中可以使用多种API进行数据备份,它们是: REST API SOAP API Buik API Metadata API 数据备份有三种选择: 完全备份(Ful ...

  9. Python_记一次网站数据定向爬取实现

    记一次网站数据定向爬取实现 by:授客 QQ:1033553122 测试环境: Python版本:Python 3.4 Win7 请勿用于商业及非法用途,仅供学习研究用,否则后果自负 数据爬取场景 如 ...

  10. Android RecycleView多种布局实现(工厂模式)

    RecycleView是个很常用的控件,很多APP中都可以看到它的身影,同时它也是个很难用的控件,主要就难在多种布局的实现. 在<第一行代码—Android>这本书里边有个RecycleV ...