Linux下make与makefile
make 用来解析 makefile 文件
make 的选项:
-d 显示调试信息
-f 文件 默认是从 makefile 或 Makefile 中读取依赖信息,用该选项可更改文件
-h 显示所有 makefile 的 help 信息
-n 显示 makefile 执行命令的顺序,但不执行
-s 运行时不显示任何信息
makefile 格式:
目标:依赖列表
<Tab>命令列表
目标通常是指要生成的文件的名称,可以使可执行文件或obj文件,也可以是一个执行的动作名称,如clean
。依赖是用来 产生目标 的材料,比如源文件,一个目标经常有多个依赖
命令是生成目标时执行的动作,一个规则可以含有几个命令,每个命令占一行
执行make clean时,由于clean没有依赖,所以它的命令将被强制执行
make clean中的 clean 是一个虚目标,一般用来删除 make 产生的文件
makefile 语法:
# 注释
\ 连接符,前后不要有空格
?,* 通配符
例1. hello.c文件内容:
#include<stdio.h>
int main(void)
{
printf("Hello Linux!\n");
return ;
}
关于hello.c的 makefile 文件内容为:
hello:hello.o
gcc -o hello hello.o 或 gcc hello.o -o hello
hello.o:hello.c
gcc -c -o hello.o hello.c 或 gcc -c hello.c -o hello.o clean:
rm -f *.o
多文件时 makefile 编写:
例2.假如源文件 a.c 和 b.c 可生成可执行文件 test。其 makefile 文件内容为:
test:a.o b.o
gcc -o test a.o b.o 或 gcc a.o b.o -o test
a.o:a.c
gcc -c -o a.o a.c 或 gcc -c a.c -o a.o
b.o:b.c
gcc -c -o b.o b.c 或 gcc -c b.c -o b.o clean:
rm -f *.o
make 只有在依赖比目标新的时候才会执行其后命令。可通过 touch 命令修改某文件时间。
makefile 中变量的 定义 方式为: 变量 := 值
makefile 给变量 增加 一个值为: 变量 += 值
makefile 中变量的 引用 方式为: $(变量名) 或 ${变量名}、$单字符变量
makefile 几种赋值及区别:
:= 简单的赋值,如果变量已经有值,会覆盖旧值
?= 条件赋值,如果变量未定义,则赋值,如果变量已定义,无论其值空与否,均不赋值。
+= 给已经赋值的变量后面添加一个值,原值依然包含在新值中。
例如:
C=gcc
$C
CC=gcc
$(CC) 或 ${CC}
例3:
用此方式,修改 例1 的 makefile 文件为:
CC := gcc
Objects := test.o
Sources := test.c
test:$(Objects)
$(CC) -o test $(Objects)
$(Objects):$(Sources)
$(CC) -c -o $(Objects) $(Sources) clean:
rm -f *.o
makefile 中还可添加如下命令来进行打包:
tar:
tar -cvf pack.tar makefile *.c *.h
执行 make tar 就可以将文件夹中所有 .c .h 还有 makefile 文件打包
makefile 中的内置变量:
$@ 当前目标的名称
$^ 所有依赖
$< 比当前目标更新的依赖。第一个依赖
$? 比当前目标更新的依赖 列表 。表示所有已修改的依赖文件
利用内置变量,修改 例3 的 makefile 文件为:
CC := gcc
Objects := test.o
Sources := test.c
test:$(Objects)
$(CC) -o $@ $^
$(Objects):$(Sources)
$(CC) -c -o $@ $^ clean:
rm -f *.o
注意:内置变量指代的内容是不固定的,是随上下文变化的。例如:
abc:bcd
里面的目标为 abc ,依赖为 bcd。而
hello:hello.c
里面的目标为 hello,依赖为 hello.c
还可以利用 makefile 默认的识别方式,用 %.c 表示所有 .c 文件,%.o 表示所有 .o 文件:
例如:改写 例2:
test:a.o b.o
gcc -o $@ $^ 或 gcc $^ -o $@
%.o:%.c
gcc -c -o $@ $^ 或 gcc -c $^ -o $@ clean:
rm -f *.o
makefile 如果省略文件名,会默认将目标与依赖同名。此时,可省略依赖和命令。
例如:再次简化上例:
test:a.o b.o
gcc -o $@ $^ 或 gcc $^ -o $@
a.o:
b.o: clean:
rm -f *.o
上面的
a.o:
b.o:
两行可以简写成一行:
%.o:
虚目标:
makefile 中有一些目标,它们是一些不存在的文件,而且也无需创建他们,这些目标称虚目标。
虚目标允许你强制执行某些事件,而这些事件在正常规则中不会发生。
虚目标总是使与之有关的命令被执行。
常见虚目标列表:
all 生成工程中所有可执行者,通常是 makefile 的第一个生成目标
clean 删除 make all 生成的所有文件
install 在系统目录中安装工程项目生成的可执行文件和文档
uninstall 删除 make install 安装的所有文件
例如,某安装包的 makefile 文件如下:
InstallDir := /usr/local/bin/
install:a b
cp -f $^ $(InstallDir)
cd $(InstallDir); chmod $^
rm -f *.o $^
uninstall:
cd $(InstallDir); rm a b
a:a.o
gcc -o a a.o
a.o:a.c
gcc -c -o a.o a.c
clean:
rm -f *.o
执行 make install 即可安装。
有时候,为了防止 makefile 中的虚目标与实际文件重名,例如:实际路径中存在一个 install 文件,如果执行 make install ,则会报错。为了防止这种情况,可在虚目标前面加上修饰符,如下:
clean:
rm -f *.o
.PHONY:clean
加上之后,即使有同名文件,也不会报错。
.PHONY 后可加多个虚目标,例如:
.PHONY: module module_install clean
下例执行 make all 可以生成所有目标:
all:test hello
test:test.o
.....
hello:hello.o
....
makefile 常见错误:
1.制表符用空格代替。解决办法:cat -t makefile可查看makefile中的制表符:^I
2.连接符'\'和换行符之间插入了空格。解决办法:cat -e makefile。会将换行符用 $ 显示
Linux下make与makefile的更多相关文章
- Linux下GCC和Makefile实例(从GCC的编译到Makefile的引入)
一.确认已经装好了GCC和Make的软件包 可以使用whereis命令查看: 如果whereis gcc和whereis make命令有结果,说明安装了这两个软件,可以继续往下做. 二.使用GCC ...
- Linux下GCC和Makefile实例(从GCC的编译到Makefile的引入) 转
http://www.crazyant.net/2011/10/29/linux%E4%B8%8Bgcc%E5%92%8Cmakefile%E5%AE%9E%E4%BE%8B%EF%BC%88%E4% ...
- linux下如何调试Makefile?
答:make --debug=all (输出所有的调试信息)
- linux 下如何 makefile
本文目的: 尝试着把makefile讲解清楚.非原创,仅仅是学习笔记和备忘录之用. makefile 的目的和好处: 一个工程中的源文件不计数,其按类型.功能.模块分别放在若干个目录中,makefil ...
- Linux下MakeFile初探
make是linux下的编译命令,用于编译和生成Linux下的可执行文件.这个命令处理的对象是Makefile,makefile等.由于make的强大解析能力,makefile文件的编写也变得极为简单 ...
- [转]Linux下的Makefile
Makefile 介绍——————— make命令执行时,需要一个 Makefile 文件,以告诉make命令需要怎么样的去编译和链接程序. 首先,我们用一个示例来说明Makefile的书写规则.以便 ...
- 【转载】Linux下makefile详解--跟我一起写 Makefile
概述 —— 什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一个好的和professional的程序员,makef ...
- Linux下C/C++程序开发管理(makefile)
一.引言 从我们刚开始编写一个简单的C/C++ "Hello,World!",到将其编译.运行处结果—这部分工作IDE(集成开发环境)帮我们做了,包括语法错误检查 ...
- linux 下C语言编程库文件处理与Makefile编写
做开发快3年了,在linux下编译安装软件算是家常便饭了.就拿gcc来说,都有不下10次了,可基本每次都会碰到些奇奇怪怪的问题.看来还是像vs.codeblocks这样的ide把人弄蠢了.便下定决心一 ...
随机推荐
- Windows OS上安装运行Apache Kafka教程
Windows OS上安装运行Apache Kafka教程 下面是分步指南,教你如何在Windows OS上安装运行Apache Zookeeper和Apache Kafka. 简介 本文讲述了如何在 ...
- scrapy爬虫笔记(二)------交互式爬取
开始网页爬取:(1)交互式爬取 首先,我们使用scrapy建立起爬虫的框架.在命令行中输入 scrapy shell “url” 如:scrapy shell “http://www.baidu.co ...
- Daily Scrum02 12.06
由于一些原因,我们的会议没有在昨天如期举行.今天,我们首先将到目前为止的进度进行了总结. 我们第二轮迭代的主要目标是优化算法,美化界面,增加单词软件的趣味性. 我们准备将软件做的更亲民,界面更友好,我 ...
- SQL查询到的数据放到DataSet中
public DataTable GetTable(string Id) { StringBuilder strSql = new StringBuilder(); DataSet ds = new ...
- WPF中UserControl和DataTemplate
最新更新: http://denghejun.github.io 前言 前言总是留给我说一些无关主题的言论,WPF作为全新Microsoft桌面或web应用程序显示技术框架, 从08年开始,一直到现在 ...
- php进程占用大量cpu优化
使用TOP 命令发现php进程占用大量的cpu,达到100%,需要优化. 1 ll /proc/6264/fd 查看进程正在使用的资源 2 strace -p 6264 追踪进程正在做的事情 引用 h ...
- Java 005 枚举
枚举概述:就是有有限值的集合或类.是指将变量的值一一列出来, 变量的值只限于列举出来的值得范围. 举例: 一周7天, 一年12个月等.回想单列设计模式: 单例类是一个类只有一个实例.那么多例类就是一个 ...
- 自动化小应用系列----利用selenium启动多个独立的浏览器
在我们测试的时候对于同一个系统,我们往往需要登陆多个不同的账号,由于cookie的原因,我们只能退出一个账号在登陆另外一颗账号,非常麻烦.我们可以使用selenium来启动浏览器,这样每个浏览器的属性 ...
- Scala的函数,高阶函数,隐式转换
1.介绍 2.函数值复制给变量 3.案例 在前面的博客中,可以看到这个案例,关于函数的讲解的位置,缺省. 4.简单的匿名函数 5.将函数做为参数传递给另一个函数 6.函数作为输出值 7.类型推断 8. ...
- 源码网站(msdn.itellyou.cn) good
verysource 100万源码http://www.verysource.com/category/delphi-vcl/ MSDN DOWNLOADhttp://msdn.itellyou.cn ...