makefile 无法工作

如果要在更新某些文件时运行或更新任务,则可以使用make实用程序。 make实用程序需要一个文件Makefile (或makefile ),该makefile定义了要执行的任务集。 您可能已使用make从源代码编译程序。 大多数开源项目使用make来编译最终的可执行二进制文件,然后可以使用make install

在本文中,我们将使用基本和高级示例探索makeMakefile 。 在开始之前,请确保已在系统中安装了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

让我们添加更多伪造目标: generateclean 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_hellogenerate

$ 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,它如何工作?相关推荐

  1. 为什么我的cpld需要重新上电才能工作_正压型防爆配电箱的调试工作

    防爆配电箱的调试工作是防爆箱生产流程中最为关键的一步,也就是我们常说的出厂检验,生配电箱都要配好对应的出厂检验报告才算是合格的.下面介绍下正压型防爆配电箱的调试流程: 一.正压型防爆配电箱调试前准备工 ...

  2. sap运维要做哪些工作_社会工作师可以做哪些工作?考试难不难?

    导语 什么是社会工作师?社会工作师考试难不难?社会工作师可以做哪些工作?一起来了解一下! 一听说社会工作师前景比较好,遂有很多人想要报考社会工作师考试,但是什么是社会工作师呢?社会工作师考试难不难呢? ...

  3. 离线处理需要做哪些工作_游戏配音需要做哪些工作?

    游戏配音的工作可以细分为三个阶段:录制准备阶段.录制阶段和后期处理阶段,下面小编将根据这三个方面做详细的介绍. 第一阶段--录制准备阶段 游戏配音员在拿到游戏角色的资料之后,先要对这个资料进行一次完整 ...

  4. 学习python可以从事哪些工作_学习Python可以从事哪些工作呢?

    相比其他编程语言,Python虽然起步较晚,但随着人工智能时代的到来以及国家政策的支持得到迅猛发展.很多的知名企业都或多或少的使用Python进行开发,对于Python开发人才的需求也一直居高不下.为 ...

  5. 35去一线城市找工作_空间计算如何改变一线工作的现状

    35去一线城市找工作 Mixed reality enhances our ability to create, learn, and collaborate in the workplace. Am ...

  6. 大专自学python找工作_大专生自学Python到找到工作的经历

    先做个自我介绍,我13年考上一所很烂专科民办的学校,学的是生物专业,具体的学校名称我就不说出来献丑了.13年我就辍学了,我在那样的学校,一年学费要1万多,但是根本没有人学习,我实在看不到希望,我就退学 ...

  7. makefile传字符串给c语言,makefile终极奥义

    什么是makefile? 或许很多 的程序员都不知道这个东西,因为那些 的 都为你做了这个工作,但是一个好的和 的程序员, 还是要懂.这就好像现在有这么多的 的编辑器,但如果你想成为一个专业人士,你还 ...

  8. Makefile编写及一个简单的Makefile架构实现

    Makefile编写及一个简单的Makefile架构实现 Makefile常用命令 GCC/G++常用编译参数 简单Makefile框架实现 使用CMake构建项目 Makefile常用命令 make ...

  9. linux内核makefile详解,linux kernel编译Makefile和Kconfig,make menuconfig详解

    Sam需要看看2.6 kernel中USB Mouse的代码.顺便谈谈Kernel中Makefile和Kconfig文件的关系以及配合使用. 背景知识: 背景知识一:Kconfig介绍: 在#make ...

最新文章

  1. Windows Phone SDK update for Windows Phone 7.8
  2. vue启动时报错,node-modules下xxx缺失
  3. 产品网络推广方案之网站SEO优化如何“讨好”用户,降低网站跳出率?
  4. 软考-信息系统项目管理师-信息文档管理与配置管理
  5. html5 拖拽上传文件时,屏蔽浏览器默认打开文件
  6. 子进程会继承父进程的哪些内容_【学习教程】Node.js创建子进程方法
  7. 去除狂人采集器添加在帖子中的广告信息
  8. 通用sqlserver分页存储过程
  9. rabbitmq windows 连接 linux,在Centos7中,从主机 Windows 上无法远程访问 Linux 上rabbitmq的解决方法...
  10. C语言 — 转义字符
  11. DupeString 与 StringOfChar 的区别 - 回复 鹰@长空
  12. 利用PCA降维的手工计算实例
  13. 中柏平板电脑刷linux,中柏平板电脑系统下载与安装教程
  14. ArcGIS Pro与ArcGis区别
  15. 设计模式之旅(三)--观察者模式
  16. Java DateUtil 时间工具类
  17. 计算机工作表中按升序排列,计算机文化基础上机指导
  18. C++泛型编程——模板学习
  19. Long类型数据比较
  20. 目前主流游戏引擎的分析报告

热门文章

  1. 同步工具之Semaphore信号量
  2. JAVA中获得前一天的时间
  3. Oracle10gR5GridControl InstallOnLinux
  4. Codeforces 847H - Load Testing
  5. shareSDK 提示#warning:尚未配置[新浪微博]URL Scheme:sinaweibosso.或wb
  6. 不允许创建临时变量交换两个变量的内容
  7. 【原创】开源Math.NET基础数学类库使用(05)C#解析Delimited Formats数据格式
  8. Java5、Java6、Java7的新特性
  9. Jedis 1.0.0 版 源码分析系列3:JedisPool.java
  10. 2010上半年网络工程师上午试题分析与解答