makefile 无法工作_什么是Makefile,它如何工作?
makefile 无法工作
如果要在更新某些文件时运行或更新任务,则可以使用make
实用程序。 make
实用程序需要一个文件Makefile
(或makefile
),该makefile
定义了要执行的任务集。 您可能已使用make
从源代码编译程序。 大多数开源项目使用make
来编译最终的可执行二进制文件,然后可以使用make install
。
在本文中,我们将使用基本和高级示例探索make
和Makefile
。 在开始之前,请确保已在系统中安装了make
。
基本例子
让我们从在终端上打印经典的“ Hello World”开始。 创建一个空目录myproject
其中包含具有以下内容的文件Makefile
:
say_hello:
echo "Hello World"
现在,通过在目录
myproject键入make
运行文件。 输出将是:
$ make
echo "Hello World"
Hello World
在上面的示例中,在任何编程语言中,
say_hello
行为都类似于函数名。 这称为目标 。 先决条件或依赖项遵循目标。 为了简单起见,在此示例中我们没有定义任何先决条件。 命令echo "Hello World"
称为配方 。 配方使用先决条件作为目标 。 目标,先决条件和配方共同构成了规则 。
总而言之,以下是典型规则的语法:
target: prerequisites
< TAB > recipe
例如,目标可能是取决于先决条件的二进制文件(源文件)。 另一方面,前提条件也可以是依赖于其他依赖项的目标:
final_target: sub_target final_target.c
Recipe_to_create_final_target
sub_target: sub_target.c
Recipe_to_create_sub_target
目标不必是文件; 就像我们的示例一样,它可能只是配方的名称。 我们称这些为“虚假目标”。
回到上面的示例,执行
make时,将显示整个命令echo "Hello World"
,然后显示实际命令输出。 我们通常不想要那个。 要禁止回显实际命令,我们需要使用@
开头echo
:
say_hello:
@ echo "Hello World"
现在尝试再次运行
make 。 输出应仅显示以下内容:
$ make
Hello World
让我们添加更多伪造目标:
generate
并clean
Makefile
:
say_hello:
@ echo "Hello World"
generate:
@ echo "Creating empty text files..."
touch file- { 1 .. 10 } .txt
clean:
@ echo "Cleaning up..."
rm * .txt
如果我们尝试在更改后运行
make ,则仅执行目标say_hello
。 这是因为makefile中只有第一个目标是默认目标。 通常被称为默认目标 ,这就是为什么您会在大多数项目中将all
视为第一个目标的原因。 召集其他目标是all
的责任。 我们可以使用称为.DEFAULT_GOAL
的特殊伪造目标来覆盖此行为。
让我们在makefile的开头包含它:
.DEFAULT_GOAL := generate
这将默认运行目标generate
:
$ make
Creating empty text files...
touch file- { 1 .. 10 } .txt
顾名思义,虚假目标
.DEFAULT_GOAL一次只能运行一个目标。 这就是为什么大多数makefile将all
文件都包含为目标,并可以根据需要调用任意多个目标的原因。
让我们将all
虚假目标包括在内,并删除.DEFAULT_GOAL
:
all: say_hello generate
say_hello:
@ echo "Hello World"
generate:
@ echo "Creating empty text files..."
touch file- { 1 .. 10 } .txt
clean:
@ echo "Cleaning up..."
rm * .txt
在运行
make之前,让我们包括另一个特殊的伪音目标.PHONY
,在其中定义不是文件的所有目标。 make
将运行其配方,而不管该名称的文件是否存在或其最后修改时间是什么。 这是完整的makefile:
.PHONY: all say_hello generate clean
all: say_hello generate
say_hello:
@ echo "Hello World"
generate:
@ echo "Creating empty text files..."
touch file- { 1 .. 10 } .txt
clean:
@ echo "Cleaning up..."
rm * .txt
make
应该调用say_hello
并generate
:
$ make
Hello World
Creating empty text files...
touch file- { 1 .. 10 } .txt
这是一个很好的做法不叫
clean的all
或把它作为第一目标。 clean
应首先手动调用clean
来作为make
的第一个参数:
$ make clean
Cleaning up...
rm * .txt
现在您已经了解了基本Makefile的工作方式以及如何编写简单的Makefile,让我们看一些更高级的示例。
进阶范例
变数
在makefile中定义变量的最简单方法是使用
=运算符。 例如,将命令gcc
分配给变量CC
:
CC = gcc
这也称为递归扩展变量 ,它在规则中使用,如下所示:
hello: hello.c
${CC} hello.c -o hello
您可能已经猜到了,配方在传递到终端时会如下扩展:
gcc hello.c -o hello
${CC}
和$(CC)
都是调用gcc
有效引用。 但是,如果尝试将变量重新分配给自己,则会导致无限循环。 让我们验证一下:
CC = gcc
CC = ${CC}
all:
@ echo ${CC}
运行
make将导致:
$ make
Makefile: 8 : *** Recursive variable 'CC' references itself ( eventually ) . Stop.
为了避免这种情况,我们可以使用
:=运算符(也称为简单扩展变量 )。 运行下面的makefile文件应该没有问题:
CC := gcc
CC := ${CC}
all:
@ echo ${CC}
模式和功能
以下makefile可以使用变量,模式和函数来编译所有C程序。 让我们逐行探索它:
# Usage:
# make # compile all binary
# make clean # remove ALL binaries and objects
.PHONY = all clean
CC = gcc # compiler to use
LINKERFLAG = -lm
SRCS := $(wildcard *.c)
BINS := $(SRCS:%.c=%)
all: ${BINS}
%: %.o
@echo "Checking.."
${CC} ${LINKERFLAG} $< -o $@
%.o: %.c
@echo "Creating object.."
${CC} -c $<
clean:
@echo "Cleaning up..."
rm -rvf *.o ${BINS}
以
#开头的行是注释。行
.PHONY = all clean
定义all
虚假目标且clean
。变量
LINKERFLAG
定义在配方中与gcc
一起使用的标志。SRCS := $(wildcard *.c)
:$(wildcard pattern)
是filenames的功能之一 。 在这种情况下,所有扩展名为.c
文件都将存储在变量SRCS
。BINS := $(SRCS:%.c=%)
:这称为替代引用 。 在这种情况下,如果SRCS
具有价值'foo.c bar.c'
,BINS
将有'foo bar'
。all: ${BINS}
:假目标将${BINS}
all
呼叫值作为单个目标。规则:
% : % .o
@ echo "Checking.."
${CC} ${LINKERFLAG} $ & lt; -o $ @让我们看一个例子来理解这个规则。 假设
foo是${BINS}
中的值之一。 然后,%
将匹配foo
(%
可以匹配任何目标名称)。 以下是展开形式的规则:foo: foo.o
@ echo "Checking.."
gcc -lm foo.o -o foo如图所示,
%
被foo
代替。$<
被foo.o
替换。$<
被图案化以匹配先决条件,而$@
匹配目标。${BINS}
每个值都将调用此规则规则:
% .o: % .c
@ echo "Creating object.."
${CC} -c $ & lt;上一条规则中的每个前提条件都被视为该规则的目标。 以下是展开形式的规则:
foo.o: foo.c
@ echo "Creating object.."
gcc -c foo.c最后,我们删除target
clean
中的所有二进制文件和目标文件。
下面是上述makefile的重写,假设它位于具有单个文件foo.c:
的目录中foo.c:
# Usage:
# make # compile all binary
# make clean # remove ALL binaries and objects
.PHONY = all clean
CC = gcc # compiler to use
LINKERFLAG = -lm
SRCS := foo.c
BINS := foo
all: foo
foo: foo.o
@echo "Checking.."
gcc -lm foo.o -o foo
foo.o: foo.c
@echo "Creating object.."
gcc -c foo.c
clean:
@echo "Cleaning up..."
rm -rvf foo.o foo
有关makefile的更多信息,请参考GNU Make手册 ,其中提供了完整的参考资料和示例。
您还可以阅读我们的GNU Autotools简介,以了解如何自动为您的编码项目生成makefile。
翻译自: https://opensource.com/article/18/8/what-how-makefile
makefile 无法工作
makefile 无法工作_什么是Makefile,它如何工作?相关推荐
- 为什么我的cpld需要重新上电才能工作_正压型防爆配电箱的调试工作
防爆配电箱的调试工作是防爆箱生产流程中最为关键的一步,也就是我们常说的出厂检验,生配电箱都要配好对应的出厂检验报告才算是合格的.下面介绍下正压型防爆配电箱的调试流程: 一.正压型防爆配电箱调试前准备工 ...
- sap运维要做哪些工作_社会工作师可以做哪些工作?考试难不难?
导语 什么是社会工作师?社会工作师考试难不难?社会工作师可以做哪些工作?一起来了解一下! 一听说社会工作师前景比较好,遂有很多人想要报考社会工作师考试,但是什么是社会工作师呢?社会工作师考试难不难呢? ...
- 离线处理需要做哪些工作_游戏配音需要做哪些工作?
游戏配音的工作可以细分为三个阶段:录制准备阶段.录制阶段和后期处理阶段,下面小编将根据这三个方面做详细的介绍. 第一阶段--录制准备阶段 游戏配音员在拿到游戏角色的资料之后,先要对这个资料进行一次完整 ...
- 学习python可以从事哪些工作_学习Python可以从事哪些工作呢?
相比其他编程语言,Python虽然起步较晚,但随着人工智能时代的到来以及国家政策的支持得到迅猛发展.很多的知名企业都或多或少的使用Python进行开发,对于Python开发人才的需求也一直居高不下.为 ...
- 35去一线城市找工作_空间计算如何改变一线工作的现状
35去一线城市找工作 Mixed reality enhances our ability to create, learn, and collaborate in the workplace. Am ...
- 大专自学python找工作_大专生自学Python到找到工作的经历
先做个自我介绍,我13年考上一所很烂专科民办的学校,学的是生物专业,具体的学校名称我就不说出来献丑了.13年我就辍学了,我在那样的学校,一年学费要1万多,但是根本没有人学习,我实在看不到希望,我就退学 ...
- makefile传字符串给c语言,makefile终极奥义
什么是makefile? 或许很多 的程序员都不知道这个东西,因为那些 的 都为你做了这个工作,但是一个好的和 的程序员, 还是要懂.这就好像现在有这么多的 的编辑器,但如果你想成为一个专业人士,你还 ...
- Makefile编写及一个简单的Makefile架构实现
Makefile编写及一个简单的Makefile架构实现 Makefile常用命令 GCC/G++常用编译参数 简单Makefile框架实现 使用CMake构建项目 Makefile常用命令 make ...
- linux内核makefile详解,linux kernel编译Makefile和Kconfig,make menuconfig详解
Sam需要看看2.6 kernel中USB Mouse的代码.顺便谈谈Kernel中Makefile和Kconfig文件的关系以及配合使用. 背景知识: 背景知识一:Kconfig介绍: 在#make ...
最新文章
- Windows Phone SDK update for Windows Phone 7.8
- vue启动时报错,node-modules下xxx缺失
- 产品网络推广方案之网站SEO优化如何“讨好”用户,降低网站跳出率?
- 软考-信息系统项目管理师-信息文档管理与配置管理
- html5 拖拽上传文件时,屏蔽浏览器默认打开文件
- 子进程会继承父进程的哪些内容_【学习教程】Node.js创建子进程方法
- 去除狂人采集器添加在帖子中的广告信息
- 通用sqlserver分页存储过程
- rabbitmq windows 连接 linux,在Centos7中,从主机 Windows 上无法远程访问 Linux 上rabbitmq的解决方法...
- C语言 — 转义字符
- DupeString 与 StringOfChar 的区别 - 回复 鹰@长空
- 利用PCA降维的手工计算实例
- 中柏平板电脑刷linux,中柏平板电脑系统下载与安装教程
- ArcGIS Pro与ArcGis区别
- 设计模式之旅(三)--观察者模式
- Java DateUtil 时间工具类
- 计算机工作表中按升序排列,计算机文化基础上机指导
- C++泛型编程——模板学习
- Long类型数据比较
- 目前主流游戏引擎的分析报告
热门文章
- 同步工具之Semaphore信号量
- JAVA中获得前一天的时间
- Oracle10gR5GridControl InstallOnLinux
- Codeforces 847H - Load Testing
- shareSDK 提示#warning:尚未配置[新浪微博]URL Scheme:sinaweibosso.或wb
- 不允许创建临时变量交换两个变量的内容
- 【原创】开源Math.NET基础数学类库使用(05)C#解析Delimited Formats数据格式
- Java5、Java6、Java7的新特性
- Jedis 1.0.0 版 源码分析系列3:JedisPool.java
- 2010上半年网络工程师上午试题分析与解答