GNU Make / Makefile 学习资料

GNU Make学习总结(一)
GNU Make学习总结(二)
这篇学习总结,从一个简单的小例子开始,逐步加深,来讲解Makefile的用法。
最后用上面总结过的知识,给出了一个通用的C/C++ Makefile
文中提到《GNU 项目管理》一书,有280页。我觉得初学没必要看这么厚的书。豆瓣上对其评价也是不太实用。等以后有更深层次的需求时,再去看。
另外还有:
阮一峰-Make命令教程
这篇写的很简单,不过其中提到了一点很重要:每一行"命令"是独立的Shell。第二篇《使用Make构建网站》不需要看,是针对node.js的。
陈皓-跟我一起写Makefile
这本读起来很轻松,同时也比较全面。
徐海兵翻译-GNU make手册
官方文档通常是深入浅出的,非常推荐。就是比较罗嗦,也很厚,放最后看好了。 作者:Hexus
链接:https://www.jianshu.com/p/d63aff959d3d
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

  

今天学习了makefile的基本语法,特此总结一下。

主要的学习网站:https://www.jianshu.com/p/d63aff959d3d
原文:

GNU Make / Makefile 学习资料

GNU Make学习总结(一)
GNU Make学习总结(二)
这篇学习总结,从一个简单的小例子开始,逐步加深,来讲解Makefile的用法。
最后用上面总结过的知识,给出了一个通用的C/C++ Makefile
文中提到《GNU 项目管理》一书,有280页。我觉得初学没必要看这么厚的书。豆瓣上对其评价也是不太实用。等以后有更深层次的需求时,再去看。
另外还有:
阮一峰-Make命令教程
这篇写的很简单,不过其中提到了一点很重要:每一行"命令"是独立的Shell。第二篇《使用Make构建网站》不需要看,是针对node.js的。
陈皓-跟我一起写Makefile
这本读起来很轻松,同时也比较全面。
徐海兵翻译-GNU make手册
官方文档通常是深入浅出的,非常推荐。就是比较罗嗦,也很厚,放最后看好了。 作者:Hexus
链接:https://www.jianshu.com/p/d63aff959d3d
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

引用阮一峰的话:

代码变成可执行文件,叫做编译(compile);先编译这个,还是先编译那个(即编译的安排),叫做构建(build)。

Make是最常用的构建工具,诞生于1977年,主要用于C语言的项目。但是实际上 ,任何只要某个文件有变化,就要重新构建的项目,都可以用Make构建。

入门
简介
Make是一种将源代码转换成可执行文件的自动化工具,通过Make语言,描述了源文件、中间文件、可执行文件之间的关系。与此同时,Make工具可以对编译过程进行优化,在重新编译时会根据时间戳来决定哪些文件需要重新生成,在编译大型工程时,这会省下不少时间(每次第一次编内核都是输完Make后先睡一觉再说...)。Make有多种变种,其中GNU Make使用相对广泛,在大多Linux/UNIX系统都对其提供支持。

Make一般将细节放在Makefile中,make命令会自动在当前文件夹下找到Makefile并执行,而Makefile的核心内容就是规则,它是Makefile的主要组成。每项规则可以由三部分组成:目标(target),必要条件(prerequisite),命令(command)。书写格式如下所示,目标和条件之间由冒号隔开,命令写在下一行,并以TAB开头,每条规则中可以有多个目标,多个条件以及多条命令。

target1 target2: prereq1 prereq2
command1
command2

tab开头请别忘记!!

自己写的案例:

 #include "integrate.h"

 float collect(float s,float t,int n,float (*p)(float x))
{
int i;
float f,h,x,y1,y2,area;
f=0.0;
h=(t-s)/n;
x=s;
y1=(*p)(x); for(i=;i<=n;i++)
{
x=x+h;
y2=(*p)(x);
area=(y1+y2)*h/;
y1=y2;
f=f+area;
}
return (f);
}
float fun1(float x)
{
float fx;
fx=x*x-2.0*x+2.0;
return(fx);
}
float fun2(float x)
{
float fx;
fx=x*x*x+3.0*x*x-x+2.0;
return(fx);
}
float fun3 (float x)
{
float fx;
fx=x*sqrt(+cos(*x));
return(fx);
}
float fun4(float x)
{
float fx;
fx=/(1.0+x*x);
return(fx);
} #include <stdio.h>
#include <math.h>
#include "integrate.h" int main()
{
int n,flag;
float a,b,v=0.0; printf("Input the count range(from A to B)and the number of sections.\n");
scanf("%f%f%d",&a,&b,&n);
printf("Enter your choice: '1' for fun1,'2' for fun2,'3' for fun3,'4' for fun4==>");
scanf("%d",&flag); if(flag==)
v=collect(a,b,n,fun1);
else if(flag==)
v=collect(a,b,n,fun2);
else if(flag==)
v=collect(a,b,n,fun3);
else
v=collect(a,b,n,fun4);
printf("v=%f\n",v);
return ;
} //------------integrate.h------------
#ifndef _INTEGRATE_H_
#define _INTEGRATE_H_ #include <stdio.h>
#include <math.h> float collect( float s, float t, int m, float (*p)(float x) );
float fun1(float x);
float fun2(float x);
float fun3(float x);
float fun4(float x); #endif

首先;三个文件都在一个目录下
两个C文件,一个h文件。
最简单的makefile

main: main.o integrate.o
gcc integrate.o main.o -o main main.o: main.c integrate.h
gcc -c main.c integrate.o: integrate.c integrate.h
gcc -c integrate.c

#为了避免这种情况,可以明确声明clean是"伪目标",写法如下。声明clean是"伪目标"之后,make就不会去检查是否存在一个叫做clean的文件,而是每次运行都执行对应的命令。像.PHONY这样的内置目标名还有不少,
.PHONY: clean
clean:
rm *.o *.exe
点击make后,显示如下命令:

gcc -c main.c
gcc -c integrate.c
gcc integrate.o main.o -o main

这个比较简单。

复杂一点:

#这一章主要对生成规则进行了详细介绍,主要分为具体规则、模式规则、静态模式规则、隐含规则、后缀规则等等。在了解这些规则之前,首先了解一些其它的前提知识。

#变量及自动变量
#在Makefile中,使用x,$(xx)。关于变量的使用会在下一章详细介绍,这里主要说一下自动变量。自动变量一般用在命令中,会根据目标和条件自动替换成对应的内容。以下是几个常用的自动变量: #$@ 目标文件名
#$% 档案文件成员,是指以a.o(b.o)这种形式作为目标时,括号中的内容
#$< 第一个必要条件文件名
#$? 时间戳在目标文件之后的所有必要条件文件名,空格隔开
#$^ 所有必要条件的文件名,空格隔开,这份列表删除了重复的文件名
#$+ 和$^一样,只是未删除重复的文件名
#$* 目标的主文件名(即不包括后缀)
#以上变量都有两个变体,加D表示文件的目录部分,加F表示文件的文件名部分,注意要加括号,如($F)等。
#我们可以使用自动变量来修改之前的Makefile,简化命令部分的书写 main: main.o integrate.o
gcc $^ -o $@ main.o: main.c integrate.h
gcc -c $< integrate.o: integrate.c integrate.h
gcc -c $< .PHONY: clean all
all:main
clean:
rm *.o *.exe

  

$<,$@是自动变量,解释看上面的说明,
all:main可以在命令行中,等同于make,即make all等同于make。

显示结果:

gcc -c main.c
gcc -c integrate.c
gcc main.o integrate.o -o main

 版本三,更加难一点

CC=gcc
CFLAGS=-I.
DEPS = integrate.h
OBJ = integrate.o main.o %.o: %.c $(DEPS)
$(CC) $(CFLAGS) -c $< -o $@ main: $(OBJ)
$(CC) $(CFLAGS) $^ -o $@ .PHONY: clean
all:main
clean:
rm *.o *.exe

参考自:http://www.cs.colby.edu/maxwell/courses/tutorials/maketutor/

Makefile 4

CC=gcc
CFLAGS=-I.
DEPS = hellomake.h
OBJ = hellomake.o hellofunc.o %.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS) hellomake: $(OBJ)
$(CC) -o $@ $^ $(CFLAGS)

  

前四行是内置变量,应该不难理解。
模式规则
在gcc编译器中一般使用后缀表示文件类型,gcc会将x.c文件认为是C源文件,并翻译成对应的x.o,这种文件名的对应关系是模式规则的基础,使得Makefile对于目标x.o会自动去寻找对应的x.c文件,因此对于很多规则,我们都可以简化。
在一个规则中,如果主文件名中包含了%就表示这是一个模式规则。所谓模式规则,是指对符合这个模式的目标都采用这个规则,注意%和通配符的不同,在Makefile中是可以使用通配符的,*.c表示的是所有以c结尾的文件的集合,而%.c表示所有以c结尾的文件都匹配这条规则,一定要注意区分。
所有的内置规则都是模式规则,使用make -p可以看到这些内置规则,用其中生成%.o的这一条作为例子

%.o: %.c
#commands to execute (built-in): 这个是注释
$(COMPILE.c) $(OUTPUT_OPTION) $<

所有c文件结合h文件都要编译成相应的.o文件
%.o: %.c $(DEPS)
$(CC) $(CFLAGS) -c $< -o $@

版本四:多文件夹管理编译
将h文件放在include下,将.c文件放在src下,Makefile文件与两个文件同级,如下所示:

|-- integrate
\-- include
|-- integrate.h
\-- src
|-- integrate.c
|-- main.c
Makefile

#这时候再在InputSpeed目录下执行make就会报找不到文件的错误,解决的方法之一是通过VPATH = src include将源文件加入到Make的搜索路径中,但这样并不是最好的方法,因为不同的文件夹下可能有同名的文件,VPATH只会返回第一个找到的文件,并不一定是我们想要的文件,我们可以使用vpath pattern directory的形式来指定在哪个目录下搜索哪个文件,具体用法可以看下面给出的Makefile,其中%类似于通配符,告诉Make在src下找.c文件,在include下找.h文件。现在make已经可以找到所有的文件了,但还不行,因为gcc命令找不到函数的原型,我们通过-I命令把头文件的位置告诉GCC。修改后的Makefile文件如下所示

#VAPTH src include
vpath %.c src
vpath %.h include
CFLAGS = -I include main: main.o integrate.o
gcc $^ -o $@ main.o: main.c integrate.h
gcc $(CFLAGS) -c $< -o $@ integrate.o: integrate.c integrate.h
gcc $(CFLAGS) -c $< -o $@ .PHONY: clean all
all:main
clean:
rm *.o *.exe

  

版本五:隐含规则
就是make自带的内置规则,不是模式规则就是后缀规则。在我们没有为规则编写命令时,make会自动去内置规则中找是否有对应的规则,上面模式规则中举的例子就是一个隐含规则,利用该隐含规则,我们可以进一步简化我们的Makefile,

vpath %.c src
vpath %.h include
CFLAGS = -I include
CC=gcc main: main.o integrate.o
main.o: integrate.h
integrate.o: integrate.h .PHONY: clean all
all:main
clean:
rm *.o *.exe

隐含规则的出现,使我们的Makefile一句命令都没有用就完成了编译,也简洁了很多,实在是十分强大。这个makefile格式真是比较厉害的。

gcc -I include   -c -o main.o src/main.c
gcc -I include -c -o integrate.o src/integrate.c
gcc main.o integrate.o -o main

  

makefile学习(1)的更多相关文章

  1. [转]Windows平台下Makefile学习笔记

    Windows平台下Makefile学习笔记(一) 作者:朱金灿 来源:http://blog.csdn.net/clever101 决心学习Makefile,一方面是为了解决编译开源代码时需要跨编译 ...

  2. makefile 学习归纳

    makefile 学习归纳 一直希望 好好整理下 makefile的写法,这在linux编程界是必备技能.下面就好好的说道说道. 可以参考的大神总结 整理 makefile是供make命令执行的 脚本 ...

  3. <转>Windows平台下Makefile学习笔记(二)

    本文转自:http://blog.csdn.net/clever101/article/details/8286066 上次我们学习了怎么用Makefile编译一个控制台工程.这次我们学习一下如何使用 ...

  4. (二)我的Makefile学习冲动&&编译过程概述

    前言 一 年轻的冲动 二 学习曲线 1 Makefile基本语法 2 bash基础 3 world 三 编译过程概述 1 主机预装工具 2 编译host工具 3 编译交叉工具链 4 编译内核模块 5 ...

  5. Makefile学习笔记

    ls -l 查看文件详细信息 1.gcc -E test.c -o test.i//预编译gedit test.i //查看:高级C 2.gcc -Wall -S test.i -o test.s// ...

  6. makefile学习笔记(多目录嵌套调用、变量使用)

    http://blog.csdn.net/leexiang_han/article/details/9274229   学习了几天的makefile的嵌套调用编写也有一些心得,先声明,我也是初学者写文 ...

  7. Makefile学习(一)变量

    鉴于之前有一些了解,还有自己的学习习惯,我一上来就看Makefile的变量这一章.主要脉络是根据GNU make中文手册. 第六章:Makefile中的变量 6使用变量 定义:变量是一个名字,代表一个 ...

  8. makefile 学习一

    近期在学习nginx,由于实在linux下,一些代码须要用makefile文件来编译,比較节省时间. 由于在nginx中加入一个新的模块假设用./configure方法来加入,特别是当你的代码有错时, ...

  9. Makefile学习总结

    Makefile用法分析     在linux开发中,应用程序的编译基本都采用GNU的make工具,而make搭配Makefile来实现工程代码的编译,在越是大型复杂的项目中,make的强悍之处越是明 ...

随机推荐

  1. 机器学习框架ML.NET学习笔记【1】基本概念与系列文章目录

    一.序言 微软的机器学习框架于2018年5月出了0.1版本,2019年5月发布1.0版本.期间各版本之间差异(包括命名空间.方法等)还是比较大的,随着1.0版发布,应该是趋于稳定了.之前在园子里也看到 ...

  2. elasticsearch远程代码执行漏洞告警

    es版本:1.7.2 最近在做es项目的时候出现,启动es一段时间系统就会报警,结果查询了一下,原来是es的漏洞: 官网描述: 大致意思就是: 漏洞出现在脚本查询模块,默认搜索引擎支持使用脚本代码(M ...

  3. ElasticSearch java API 按照某个字段排序

    searchRequestBuilder.addSort("publish_time", SortOrder.DESC); 按照某个字段排序的话,hit.getScore()将会失 ...

  4. uvm_svcmd_dpi——DPI在UVM中的实现(二)

    UVM中有需要从cmmand line 输入参数的需求,所有uvm_svcmd_dpi.svh和uvm_svcmd_dpi.cc 文件就是实现功能. uvm_svcmd_dpi.svh的源代码如下,我 ...

  5. kubernetes发布解释型语言应用的最佳实践

    说明 k8s在发布编译型语言的应用时,几乎不用多考虑,就会选择将编译好jar/war包(java语言)或者二进制文件(golang/c++)直接打到镜像当中,生成新的应用镜像,然后将镜像推到镜像仓库, ...

  6. 常用工具使用(sublimeText)

    1.sublime Text  (插件的安装,删除,更新) 1.1 使用 ctrl+`快捷键(Esc下面的波浪线按钮) 或者 菜单项View > Show Console 来调出命令界面,下面代 ...

  7. GetIPAddress——获得本地IP地址信息

    1.gethostname()需要初始化套接字库 加载#pragma comment(lib,"ws2_32.lib"),和WSAStartup(MAKEWORD(2,2),&am ...

  8. 谈谈bootstrap在实践中的应用

    bootstrap官网是http://www.bootcss.com/ bootstrap的CDN的网址是http://www.bootcdn.cn/ 在平时写的时候尽量用CDN,这样对于网站的运行效 ...

  9. Project Euler 第一题效率分析

    Project Euler: 欧拉计划是一系列挑战数学或者计算机编程问题,解决这些问题需要的不仅仅是数学功底. 启动这一项目的目的在于,为乐于探索的人提供一个钻研其他领域并且学习新知识的平台,将这一平 ...

  10. iOS开发学习之大牛们的博客

    http://blog.csdn.net/iosbird/article/details/51981023 唐巧:http://blog.devtang.com/blog/archives/ 王巍:h ...