makefile写法
Makefile文件语法
Makefile⽂件语法概述本⽂将介绍Makefile种注释、回显、通配符、变量、循环判断、函数注释Makefile中只有单⾏注释,没有多⾏注释,注释以 # 开头。
以下Makefile注释⽚段节选⾃的Makefile# Makefile for installing Lua# See doc/readme.html for installation and customization instructions.# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT =======================# Your platform. See PLATS for possible values.PLAT= noneechoing(回显)通常,make在执⾏命令⾏之前会把要执⾏的命令⾏进⾏输出。
我们称之为“回显”,就好像我们输⼊命令执⾏⼀样。
@如果要执⾏的命令⾏以字符“@”开始,则make在执⾏时这个命令就不会被回显。
典型的⽤法是我们在使⽤“echo”命令输出⼀些信息时。
如:@echo 开始编译XXX模块......当make执⾏时,将输出“开始编译XXX模块......”这个信息。
如果在命令⾏之前没有字符“@”,那么,make的输出就是:echo编译XXX模块......编译XXX模块......“-n”或“--just-print”如果使⽤make的命令⾏参数“-n”或“--just-print”,那么make执⾏时只显⽰所要执⾏的命令,但不会真正的去执⾏这些命令。
只有在这种情况下make才会打印出所有make需要执⾏的命令,其中也包括了使⽤“@”字符开始的命令。
这个选项对于我们调试Makefile⾮常有⽤,使⽤这个选项我们可以按执⾏顺序打印出Makefile中所有需要执⾏的命令。
“-s”或“--slient”make参数“-s”或“--slient”则是禁⽌所有执⾏命令的显⽰,就好像所有的命令⾏均使⽤“@”开始⼀样。
交叉编译makefile编写
交叉编译makefile编写交叉编译Makefile编写在软件开发中,我们通常会遇到需要在不同平台上编译程序的情况。
当我们需要在一台主机上编译运行另一种架构的程序时,就需要进行交叉编译。
而Makefile作为一种构建工具,可以帮助我们自动化编译过程,提高开发效率。
本文将介绍如何编写适用于交叉编译的Makefile,以实现在不同平台上的程序构建。
一、了解交叉编译概念交叉编译是指在一台主机上编译生成另一种架构的可执行文件。
通常情况下,我们在本机上编写并编译程序,然后在本机上运行。
但是,当我们需要在不同的平台上运行程序时,由于不同平台的指令集、库文件等差异,我们就需要使用交叉编译来生成适用于目标平台的可执行文件。
二、Makefile的基本结构Makefile是一种用于描述程序构建过程的文件,它包含了一系列规则(rules),每个规则由一个或多个目标(target)和依赖项(dependencies)组成。
当某个目标的依赖项发生变化时,Make工具会根据规则自动更新目标文件。
一个基本的Makefile结构如下所示:```target: dependenciescommand```其中,target表示目标文件,dependencies表示目标文件的依赖项,command表示生成目标文件的命令。
三、交叉编译的Makefile编写在编写交叉编译的Makefile之前,我们需要了解目标平台的相关信息,如架构、编译器、库文件等。
以ARM架构为例,我们可以使用arm-linux-gnueabi-gcc作为交叉编译器。
我们需要定义一些变量,用于指定交叉编译工具链和相关参数:```CC = arm-linux-gnueabi-gccCFLAGS = -Wall -O2```其中,CC表示编译器,CFLAGS表示编译参数。
接下来,我们可以定义目标文件和依赖项:```TARGET = myprogramSRCS = main.c foo.c bar.cOBJS = $(SRCS:.c=.o)```其中,TARGET表示目标文件,SRCS表示源文件列表,OBJS表示目标文件列表。
makefile编写规则
makefile编写规则⼀、makefile 规则:⼀般开头都是 Tab ,不能空格, include 前⾯不能是 Tab; 1、如果没编译过,将所有的(.c)⽂件编译并且链接; 2、如果有其中的(.c)⽂件改变,编译并链接改变的⽂件; 3、如果(.h)⽂件被修改,编译引⽤相应的(.c)⽂件, 链接; 4、在随意修改时间的情况下,会导致编译过程中⽣成的(.o 中间⽂件)与可执⾏⽂件时间不⼀致,此时会编译相应的⽂件,并链接,最终编译成可执⾏⽂件;⼆、第⼀版 makefile: 例如有2个 .h ⽂件(utils.h, player.h, actor.h)和 3个 .c ⽂件( main.c, player.c, actor.c)需要编译链接:/*****main.c*********/#include "utils.h"#include "player.h"void main() {// do something}/*******player.c**********/#include "utils.h"#include "actor.h"bool create_player() {// do something}/****actor.c************/#include "utils.h"bool create_actor() {// do something}/********* makefile *****************/test : main.o actor.occ -o test main.o actor.omain.o : main.c utils.h player.h actor.hcc -c main.cpalyer.o: player.c player.h actor.h utils.hcc -c player.cactor.o: actor.h utils.hcc -c actor.cclean:rm test ain.o player.o actor.o 优点:可毒性很强,思路清晰明了; 缺点:⿇烦,重复的依赖过多,当需要编译⼤量⽂件时容易出错;第⼆版:利⽤ makefile 的变量;/********* makefile *****************/OBJ = main.o actor.o // 跟第⼀版⽐较,唯⼀的区别在这test : $(OBJ) // 这⼉cc -o test $(OBJ) // 这⼉main.o : main.c utils.h player.h actor.hcc -c main.cpalyer.o: player.c player.h actor.h utils.hcc -c player.cactor.o: actor.h utils.hcc -c actor.c .PHONY : clean // 伪⽬标,避免:如果当前⽬录下存在 clean rm 指令不执⾏clean:-rm test $(OBJ) // 前⾯的(-)表⽰,执⾏过程中不 care 出错;第三版:利⽤ GUN make 的⾃动推导规则 当 make 看到(.o )⽂件,他会⾃动把(.c)⽂件加上依赖关系,包括执⾏的语句(cc -c xx.c);/********* makefile *****************/OBJ = main.o actor.o // 跟第⼀版⽐较,唯⼀的区别在这test : $(OBJ) // 这⼉cc -o test $(OBJ) // 这⼉main.o : utils.h player.h actor.hpalyer.o: player.h actor.h utils.hactor.o: actor.h utils.h .PHONY : clean // 伪⽬标,避免:如果当前⽬录下存在 clean rm 指令不执⾏clean:-rm test $(OBJ)第四版:对第三版的整理(有⼀些重复的 .h) 公共的⼀起依赖,单独的单独依赖/********* makefile *****************/OBJ = main.o actor.o // 跟第⼀版⽐较,唯⼀的区别在这test : $(OBJ) // 这⼉cc -o test $(OBJ) // 这⼉$(OBJ) : utils.h actor.omain.o player.o .PHONY : clean // 伪⽬标,避免:如果当前⽬录下存在 clean rm 指令不执⾏clean:-rm test $(OBJ)优点:简洁缺点:不好理解以上的makefike⽂件的基本写法;或许你也发现了,如果有⼏百个源⽂件咋整呢,光是⽬录就要晕死,下⾯就是针对这种情况来说⼀下⼤型⼯程 makefile 的编写设计⼆、⼤型项⽬makefile编写: Makefile 同样也有像 c / c++ 类似的include功能; 例如我们有⼀堆 a.mk , b.mk以及 foo.make和⼀个变量 $(bar),其包含了 e.mk,f.mk, 那么 include foo.make *.mk $(bar) ------- 等价-------》 include foo.make a.mk b.mk e.mk f.mk。
linux makefile中路径写法
linux makefile中路径写法================Makefile在Linux系统中被广泛用于编译和构建项目,它能够自动化地完成许多重复的任务,大大提高了开发效率。
在Makefile中,路径的书写是一个重要的组成部分。
下面我们将详细讨论在Linux Makefile中如何正确地书写路径。
一、绝对路径与相对路径-----------在Makefile中,路径的书写主要有两种方式:绝对路径和相对路径。
1. **绝对路径**:从文件系统的根目录开始的路径。
例如`/home/user/myfile.txt`就是一个绝对路径。
在Makefile中,绝对路径通常是从构建系统的根目录开始的。
2. **相对路径**:相对于当前工作目录的路径。
在Makefile 中,通常使用`./`表示当前目录,`../`表示上级目录。
选择使用绝对路径还是相对路径取决于你的项目结构和开发者的偏好。
一般来说,推荐使用相对路径,因为它们更灵活,可以适应不同的项目目录结构。
二、路径书写规范--------在Makefile中书写路径时,有一些规范和最佳实践需要遵循:1. **文件名**:文件名应该简洁明了,不要使用空格或其他特殊字符。
避免使用长文件名或难以理解的文件名。
2. **目录分隔符**:在Linux系统中,路径的分隔符是反斜杠(`\`)。
当路径包含多个目录时,需要使用两个反斜杠(`\\` 或`/`)。
在Makefile中,推荐使用正斜杠(`/`),因为它在所有平台上都是通用的。
3. **自动更新**:在Makefile中,可以使用`$(wildcard)`函数来匹配目录中的文件。
例如,`$(wildcard source/*.c)`将匹配source目录下的所有C源文件。
4. **构建系统根目录**:在Makefile中,通常使用构建系统的根目录作为路径的起点。
这可以通过变量来实现,例如`ROOT :=/path/to/build`。
makefile make install 用法举例
makefile make install 用法举例Makefile是一种用于自动化编译和构建软件的工具,它可以根据不同的构建目标(如编译、安装等)自动生成相应的构建指令。
在Makefile中,可以使用make命令来执行构建任务,其中make install是一种常用的构建指令,用于安装软件包。
一、Makefile的创建在创建Makefile之前,需要了解项目的基本结构和依赖关系,并根据需求定义不同的构建目标。
Makefile通常包含多个规则,每个规则定义了一个特定的构建目标及其对应的构建指令。
以下是一个简单的Makefile示例,用于编译一个C语言程序:```makefileCC=gccCFLAGS=-Wall -gSRC=main.c utils.cOBJ=$(SRC:.c=.o)all: $(SRC) Makefile $(OBJ)$(CC) $(CFLAGS) $(OBJ) -o program%.o: %.c$(CC) $(CFLAGS) -c $< -o $@clean:rm -f $(OBJ) $(EXE) *.o core* *~ .depend```在这个示例中,我们定义了两个规则:all规则和%.o规则。
all规则用于定义编译和链接指令,而%.o规则用于定义编译指令。
在执行make命令时,Makefile会根据当前目录下的Makefile和源文件自动生成相应的构建指令。
二、make install的使用make install是Makefile中常用的一种构建指令,用于将软件包安装到目标系统中。
使用make install命令时,需要指定安装的目标目录和安装选项。
下面是一个简单的示例:假设我们有一个名为myapp的软件包,将其安装到/usr/local/目录下:```bashmake install prefix=/usr/local/```在这个示例中,我们使用make install命令将myapp软件包安装到/usr/local/目录下。
sv中 makefile文件的写法
很高兴接到您的指示,让我来帮助您撰写关于sv中makefile文件的文章。
让我们来深入了解一下makefile文件的概念和作用。
1. 什么是makefile文件?在SV(SystemVerilog)编程中,makefile文件是用来组织和管理编译工程中的各个源文件和依赖关系的文件。
它定义了编译规则和指令,用于自动化编译和构建整个项目。
2. makefile文件的基本结构在编写makefile文件时,通常会包含以下基本元素:- 变量定义:定义编译器、编译选项、源文件列表等变量。
- 规则定义:定义编译规则,包括目标文件、依赖文件和编译指令。
- 依赖关系:明确指出各个源文件之间的依赖关系,以便make工具能够正确地进行编译。
3. sv中makefile文件的写法在SV项目中,编写makefile文件需要特别关注以下几点:- 定义变量:可以通过定义变量来指定编译器、编译选项、原文件列表等信息,使得makefile文件更加灵活和可维护。
- 设置规则:需要设置好编译规则,包括目标文件、依赖文件和编译指令。
这些规则应该准确反映出SV项目的结构和依赖关系。
- 定义依赖:在makefile文件中,需要清晰地定义各个源文件之间的依赖关系,以确保make工具能够正确地进行增量编译,提高编译效率。
4. 个人观点和理解在我看来,编写高质量的makefile文件对于SV项目的管理和维护至关重要。
一个良好的makefile文件可以提高项目的编译效率,简化编译过程,并且便于团队协作和代码管理。
在编写makefile文件时,应该注重规范和细节,以确保项目的可维护性和稳定性。
总结回顾通过编写这篇文章,我深入了解了sv中makefile文件的写法,并且通过我的个人观点和理解对这个主题进行了探讨。
在文章中多次提及了主题文字,并采用了从简到繁、由浅入深的方式来探讨主题,以便您能更深入地理解。
希望这篇文章能够对您有所帮助。
以上是我为您准备的关于sv中makefile文件的文章,希望能够满足您的要求。
大型工程多个目录下的Makefile写法
⼤型⼯程多个⽬录下的Makefile写法1、前⾔2、简单测试 测试程序在同⼀个⽂件中,共有func.h、func.c、main.c三个⽂件,Makefile写法如下所⽰:1 CC = gcc2 CFLAGS = -g -Wall34 main:main.o func.o5 $(CC) main.o func.o -o main6 main.o:main.c7 $(CC) $(CFLAGS) -c main.c -o main.o8 func.o:func.c9 $(CC) $(CFLAGS) -c func.c -o func.o10 clean:11 rm -rf *.o执⾏过程如下图所⽰:3、通⽤模板 实际当中程序⽂件⽐较⼤,这时候对⽂件进⾏分类,分为头⽂件、源⽂件、⽬标⽂件、可执⾏⽂件。
也就是说通常将⽂件按照⽂件类型放在不同的⽬录当中,这个时候的Makefile需要统⼀管理这些⽂件,将⽣产的⽬标⽂件放在⽬标⽬录下,可执⾏⽂件放到可执⾏⽬录下。
测试程序如下图所⽰:完整的Makefile如下所⽰:1 DIR_INC = ./include2 DIR_SRC = ./src3 DIR_OBJ = ./obj4 DIR_BIN = ./bin56 SRC = $(wildcard ${DIR_SRC}/*.c)7 OBJ = $(patsubst %.c,${DIR_OBJ}/%.o,$(notdir ${SRC}))89 TARGET = main1011 BIN_TARGET = ${DIR_BIN}/${TARGET}1213 CC = gcc14 CFLAGS = -g -Wall -I${DIR_INC}1516 ${BIN_TARGET}:${OBJ}17 $(CC) $(OBJ) -o $@1819 ${DIR_OBJ}/%.o:${DIR_SRC}/%.c20 $(CC) $(CFLAGS) -c $< -o $@21 .PHONY:clean22 clean:23 find ${DIR_OBJ} -name *.o -exec rm -rf {}解释如下:(1)Makefile中的符号@, ^, < 的意思: @ 表⽰⽬标⽂件 ^ 表⽰所有的依赖⽂件 < 表⽰第⼀个依赖⽂件 $? 表⽰⽐⽬标还要新的依赖⽂件列表(2)wildcard、notdir、patsubst的意思: wildcard : 扩展通配符 notdir :去除路径 patsubst :替换通配符例如下图例⼦所⽰:输出结果如下所⽰:SRC = $(wildcard *.c)等于指定编译当前⽬录下所有.c⽂件,如果还有⼦⽬录,⽐如⼦⽬录为inc,则再增加⼀个wildcard函数,象这样:SRC = (wildcard *.c) (wildcard inc/*.c)(3)gcc -I -L -l的区别:gcc -o hello hello.c -I /home/hello/include -L /home/hello/lib -lworld上⾯这句表⽰在编译hello.c时-I /home/hello/include表⽰将/home/hello/include⽬录作为第⼀个寻找头⽂件的⽬录, 寻找的顺序是:/home/hello/include-->/usr/include-->/usr/local/include -L /home/hello/lib表⽰将/home/hello/lib⽬录作为第⼀个寻找库⽂件的⽬录, 寻找的顺序是:/home/hello/lib-->/lib-->/usr/lib-->/usr/local/lib-lworld表⽰在上⾯的lib的路径中寻找libworld.so动态库⽂件(如果gcc编译选项中加⼊了“-static”表⽰寻找libworld.a静态库⽂件)参考:Processing math: 0%。
手把手教你如何写Makefile
手把手教你如何写Makefile陈皓 2005.04.01一、Makefile的规则在讲述这个Makefile之前,还是让我们先来粗略地看一看Makefile的规则。
target ... : prerequisites ...commandtarget也就是一个目标文件,可以是Object File,也可以是执行文件。
还可以是一个标签(Label),对于标签这种特性,在后续的“伪目标”章节中会有叙述。
prerequisites就是,要生成那个target所需要的文件或是目标。
command也就是make需要执行的命令。
(任意的Shell命令)这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites 中的文件,其生成规则定义在command中。
说白一点就是说,prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行。
这就是Makefile的规则。
也就是Makefile中最核心的内容。
说到底,Makefile的东西就是这样一点,好像我的这篇文档也该结束了。
呵呵。
还不尽然,这是Makefile的主线和核心,但要写好一个Makefile还不够,我会以后面一点一点地结合我的工作经验给你慢慢到来。
内容还多着呢。
:)二、一个示例正如前面所说的,如果一个工程有3个头文件,和8个C文件,我们为了完成前面所述的那三个规则,我们的Makefile应该是下面的这个样子的。
edit : main.o kbd.o command.o display.o \insert.o search.o files.o utils.occ -o edit main.o kbd.o command.o display.o \insert.o search.o files.o utils.omain.o : main.c defs.hcc -c main.ckbd.o : kbd.c defs.h command.hcc -c kbd.ccommand.o : command.c defs.h command.hcc -c command.cdisplay.o : display.c defs.h buffer.hcc -c display.cinsert.o : insert.c defs.h buffer.hcc -c insert.csearch.o : search.c defs.h buffer.hcc -c search.cfiles.o : files.c defs.h buffer.h command.hcc -c files.cutils.o : utils.c defs.hcc -c utils.cclean :rm edit main.o kbd.o command.o display.o \insert.o search.o files.o utils.o反斜杠(\)是换行符的意思。
makefile编译流程
makefile编译流程Makefile是一种用于自动化编译的工具,它可以根据源代码文件的依赖关系自动编译出目标文件。
Makefile的编写需要遵循一定的规则和语法,下面将介绍Makefile的编译流程。
1. 编写Makefile文件Makefile文件是一个文本文件,其中包含了编译的规则和依赖关系。
在编写Makefile文件时,需要遵循一定的语法规则,如使用TAB键缩进、使用变量和函数等。
2. 执行make命令在Makefile文件所在的目录下执行make命令,make会自动读取Makefile文件,并根据其中的规则和依赖关系进行编译。
如果Makefile文件中没有指定目标,则默认编译第一个目标。
3. 分析依赖关系在执行make命令时,make会先分析Makefile文件中的依赖关系,确定哪些文件需要重新编译。
如果某个源文件被修改了,那么与之相关的目标文件也需要重新编译。
4. 编译源文件在确定需要重新编译的文件后,make会依次编译每个源文件,生成对应的目标文件。
编译过程中,make会根据Makefile文件中的规则和命令进行编译。
5. 链接目标文件在所有的源文件都编译完成后,make会将所有的目标文件链接起来,生成最终的可执行文件。
链接过程中,make会根据Makefile文件中的规则和命令进行链接。
6. 完成编译当所有的源文件都编译完成并链接成功后,make会输出编译成功的信息,并生成最终的可执行文件。
如果编译过程中出现错误,make会输出错误信息并停止编译。
总之,Makefile编译流程是一个自动化的过程,它可以大大提高编译的效率和准确性。
在编写Makefile文件时,需要注意语法规则和依赖关系,以确保编译过程的正确性。
makefile中if then写法
makefile中if then写法如何在Makefile 中使用if-then 写法Makefile 是一种软件构建工具,广泛用于管理和构建软件项目。
它使用一系列规则和命令来指导构建过程。
其中,条件语句if-then 是Makefile 中常用的控制语句之一。
在本文中,我们将逐步介绍如何在Makefile 中使用if-then 写法,以及它的用途和常见示例。
一、if-then 写法的基本语法在Makefile 中,if-then 语句的基本语法如下所示:ifeq (条件, 值)#条件为真时执行的命令else#条件为假时执行的命令endif在上述语法中,ifeq 是条件语句的关键字,用于判断一个条件是否为真。
条件是通过与指定的值进行比较来确定的。
若条件为真,则执行ifeq 和else 之间的命令块;若条件为假,则执行else 和endif 之间的命令块。
二、if-then 语句的使用场景if-then 语句在Makefile 中具有广泛的应用场景。
它可以用于实现以下功能:1. 根据不同的条件选择性地执行命令。
2. 根据环境变量的值选择性地执行命令。
3. 根据文件存在与否选择性地执行命令。
4. 根据命令执行结果选择性地执行不同的命令。
下面让我们逐步来看每个使用场景的示例。
三、根据不同的条件选择性地执行命令首先,我们来看一个根据不同的条件选择性地执行命令的示例。
假设我们有一个变量MODE,它的值可以是release 或debug。
根据MODE 的不同,我们可以选择性地执行不同的命令。
makefileMODE := releaseifeq ((MODE), release)# release 模式下执行的命令(info Building release version...)gcc -O3 -o myprogram main.celse# debug 模式下执行的命令(info Building debug version...)gcc -g -o myprogram main.cendif在上述示例中,(info ...) 是一个内置函数,用于在Makefile 执行过程中打印文本消息。
makefile基本使用方法
makefile基本使用方法makefile是一种用来管理和自动化构建程序的工具。
它可以根据源代码文件的依赖关系和编译规则来自动构建目标文件和可执行文件。
makefile的基本使用方法如下:1. 创建makefile文件:在项目的根目录下创建一个名为makefile 的文件。
2. 定义变量:在makefile中,可以使用变量来存储一些常用的参数和路径,以便于后续的使用。
例如,可以定义一个名为CC的变量来指定编译器的名称,如:CC=gcc。
3. 编写规则:在makefile中,可以使用规则来指定如何编译源代码文件和生成目标文件。
一个规则由两部分组成:目标和依赖。
目标是要生成的文件,依赖是生成目标文件所需要的源代码文件。
例如,可以编写以下规则:```target: dependency1 dependency2command1command2```其中,target是目标文件,dependency1和dependency2是依赖的源代码文件,command1和command2是生成目标文件所需要执行的命令。
4. 编写默认规则:在makefile中,可以使用一个默认规则来指定如何生成最终的可执行文件。
默认规则的目标通常是可执行文件,依赖是所有的源代码文件。
例如,可以编写以下默认规则:```all: target1 target2```其中,target1和target2是生成的目标文件。
5. 编写clean规则:在makefile中,可以使用clean规则来清理生成的目标文件和可执行文件。
例如,可以编写以下clean规则: ```clean:rm -f target1 target2```其中,target1和target2是要清理的目标文件。
6. 运行make命令:在命令行中,使用make命令来执行makefile 文件。
make命令会自动根据规则和依赖关系来编译源代码文件和生成目标文件。
例如,可以运行以下命令:``````make命令会根据makefile文件中的规则和依赖关系来编译源代码文件并生成目标文件和可执行文件。
makefile 链接动态库的写法
makefile 链接动态库的写法在Makefile 中链接动态库时,你需要使用`-l` 标志指定要链接的库的名称。
同时,还需要使用`-L` 标志指定库文件的搜索路径(如果库文件不在标准路径中)。
以下是一个简单的Makefile 示例,演示如何链接动态库:```make# Makefile 示例# 编译器CC = gcc# 编译选项CFLAGS = -Wall -O2# 目标文件TARGET = my_program# 源文件SOURCE = main.c# 动态库名称LIBRARY = my_library# 动态库搜索路径LIBRARY_PATH = /path/to/library# 目标文件生成规则$(TARGET): $(SOURCE)$(CC) $(CFLAGS) -o $(TARGET) $(SOURCE) -L$(LIBRARY_PATH) -l$(LIBRARY)# 清理规则clean:rm -f $(TARGET)```在这个示例中:- `CC` 定义了编译器为`gcc`。
- `CFLAGS` 定义了编译选项,你可以根据需要进行调整。
- `TARGET` 定义了目标文件的名称。
- `SOURCE` 定义了源文件的名称。
- `LIBRARY` 定义了要链接的动态库的名称(不包括前缀`lib` 和后缀)。
- `LIBRARY_PATH` 定义了动态库的搜索路径。
在目标文件生成规则中,使用了`-L` 标志指定了库文件的搜索路径,使用`-l` 标志指定了要链接的库的名称。
请确保在实际路径中替换`LIBRARY_PATH` 和`LIBRARY` 的值,并根据需要修改其他参数。
使用`make` 命令执行这个Makefile,将会编译`main.c` 并链接到动态库,生成`my_program` 可执行文件。
简述Makefile文件的格式
简述Makefile文件的格式Makefile文件是一种常见的文本文件,用于描述一个项目中各个文件之间的依赖关系和编译规则。
Makefile文件通常由一系列规则组成,每个规则由一个目标、依赖关系和命令组成。
Makefile文件的格式如下:1. 目标(Target)目标是指需要生成的文件或者执行的操作。
在Makefile中,目标通常是一个可执行程序或者一个库文件。
目标的格式为:target: dependenciescommand其中,target表示目标名称,dependencies表示该目标所依赖的其他文件或者操作,command表示生成该目标所需要执行的命令。
2. 依赖关系(Dependencies)依赖关系指该目标所依赖的其他文件或者操作。
在Makefile中,可以通过在目标后面加上冒号(:)来定义该目标所依赖的其他文件或者操作。
多个依赖关系之间可以使用空格或者Tab键来进行分隔。
3. 命令(Command)命令是指生成该目标所需要执行的具体操作。
在Makefile中,可以通过在每个规则后面添加一行以Tab键开头的命令来定义具体操作。
4. 变量(Variables)变量是指用于存储各种编译参数和路径等信息的变量。
在Makefile中,可以通过使用$()符号来引用变量,并使用=符号来进行赋值操作。
例如:CFLAGS = -Wall -O2CC = gcctarget: dependencies$(CC) $(CFLAGS) -o target dependencies5. 注释(Comments)注释是指用于对Makefile中各个规则进行解释说明的文本。
在Makefile中,可以使用#符号来进行注释,#符号后面的内容将被忽略。
总之,Makefile文件是一个非常重要的工具,在项目开发过程中起到了至关重要的作用。
掌握Makefile文件的格式和编写方法,可以帮助我们更加高效地管理和组织项目代码,并提高项目开发效率。
简单制作Makefile方法
1.在当前目录下创建一个名为hello的子目录。hello这个目录用于存放hello.c这个程序及相关文件。新建一个源程序文件hello.c
#include <stdio.h>
int main(int argc, char** argv)
{
printf("Welcome to use autoconf and automake\n");
通过以上步骤,在源代码所在目录下自动生成了Makefile文件。
configure.in文件
autoconf提用来产生"configure"文件的工具。"configure"是一个Shell脚本,它可以自动设定一些编译参数使程序能够在不同平台上进行编译。autoconf读取configure.in文件然后产生,"configure"这个Shell脚本。
如何使用产生的Makefile文件
执行configure脚本文件所产生的Makefile文件有几个预定的选项可供使用。
l make all:产生设定的目标,即生成所有的可执行文件。使用make也可以达到此目的。
l make clean:删除之前编译时生成的可执行文件及目标文件(形如*.o的中间文件)。
configure.in文件的内容是一系列GNU m4的宏,这些宏经autoconf理后会变成检查系统特性的Shell脚本。configure.in文件中宏的顺序并没有特别的规定,但是每一个configure.in文件必须以宏AC_INIT开头,以宏AC_OUTPUT结束。一般可先用autoscan这个工具扫描原始文件以产生一个configure.scan文件,再对configure.scan作些修改,从而生成configure.in文件
Makefile使用总结
Makefile使⽤总结1. Makefile 简介Makefile 是和 make 命令⼀起配合使⽤的.很多⼤型项⽬的编译都是通过 Makefile 来组织的, 如果没有 Makefile, 那很多项⽬中各种库和代码之间的依赖关系不知会多复杂. Makefile的组织流程的能⼒如此之强, 不仅可以⽤来编译项⽬, 还可以⽤来组织我们平时的⼀些⽇常操作. 这个需要⼤家发挥⾃⼰的想象⼒.本篇博客是基于⽽整理的, 有些删减, 追加了⼀些⽰例.⾮常感谢 gunguymadman_cu 提供如此详尽的Makefile介绍, 这正是我⼀直寻找的Makefile中⽂⽂档.1.1 Makefile 主要的 5个部分 (显⽰规则, 隐晦规则, 变量定义, ⽂件指⽰, 注释)Makefile基本格式如下:target ... : prerequisites ...command......其中,target - ⽬标⽂件, 可以是 Object File, 也可以是可执⾏⽂件prerequisites - ⽣成 target 所需要的⽂件或者⽬标command - make需要执⾏的命令 (任意的shell命令), Makefile中的命令必须以 [tab] 开头1. 显⽰规则 :: 说明如何⽣成⼀个或多个⽬标⽂件(包括⽣成的⽂件, ⽂件的依赖⽂件, ⽣成的命令)2. 隐晦规则 :: make的⾃动推导功能所执⾏的规则3. 变量定义 :: Makefile中定义的变量4. ⽂件指⽰ :: Makefile中引⽤其他Makefile; 指定Makefile中有效部分; 定义⼀个多⾏命令5. 注释 :: Makefile只有⾏注释 "#", 如果要使⽤或者输出"#"字符, 需要进⾏转义, "\#"1.2 GNU make 的⼯作⽅式1. 读⼊主Makefile (主Makefile中可以引⽤其他Makefile)2. 读⼊被include的其他Makefile3. 初始化⽂件中的变量4. 推导隐晦规则, 并分析所有规则5. 为所有的⽬标⽂件创建依赖关系链6. 根据依赖关系, 决定哪些⽬标要重新⽣成7. 执⾏⽣成命令2. Makefile 初级语法2.1 Makefile 规则2.1.1 规则语法规则主要有2部分: 依赖关系和⽣成⽬标的⽅法.语法有以下2种:target ... : prerequisites ...command...或者target ... : prerequisites ; commandcommand...*注* command太长, 可以⽤ "\" 作为换⾏符2.1.2 规则中的通配符* :: 表⽰任意⼀个或多个字符:: 表⽰任意⼀个字符[...] :: ex. [abcd] 表⽰a,b,c,d中任意⼀个字符, [^abcd]表⽰除a,b,c,d以外的字符, [0-9]表⽰ 0~9中任意⼀个数字~ :: 表⽰⽤户的home⽬录2.1.3 路径搜索当⼀个Makefile中涉及到⼤量源⽂件时(这些源⽂件和Makefile极有可能不在同⼀个⽬录中),这时, 最好将源⽂件的路径明确在Makefile中, 便于编译时查找. Makefile中有个特殊的变量VPATH就是完成这个功能的.指定了VPATH之后, 如果当前⽬录中没有找到相应⽂件或依赖的⽂件, Makefile 回到VPATH指定的路径中再去查找.. VPATH使⽤⽅法:vpath <directories> :: 当前⽬录中找不到⽂件时, 就从<directories>中搜索vpath <pattern> <directories> :: 符合<pattern>格式的⽂件, 就从<directories>中搜索vpath <pattern> :: 清除符合<pattern>格式的⽂件搜索路径vpath :: 清除所有已经设置好的⽂件路径# ⽰例1 - 当前⽬录中找不到⽂件时, 按顺序从 src⽬录 ../parent-dir⽬录中查找⽂件VPATH src:../parent-dir# ⽰例2 - .h结尾的⽂件都从 ./header ⽬录中查找VPATH %.h ./header# ⽰例3 - 清除⽰例2中设置的规则VPATH %.h# ⽰例4 - 清除所有VPATH的设置VPATH2.2 Makefile 中的变量2.2.1 变量定义 ( = or := )OBJS = programA.o programB.oOBJS-ADD = $(OBJS) programC.o# 或者OBJS := programA.o programB.oOBJS-ADD := $(OBJS) programC.o其中 = 和 := 的区别在于, := 只能使⽤前⾯定义好的变量, = 可以使⽤后⾯定义的变量测试 =# Makefile内容OBJS2 = $(OBJS1) programC.oOBJS1 = programA.o programB.oall:@echo $(OBJS2)# bash中执⾏make, 可以看出虽然 OBJS1 是在 OBJS2 之后定义的, 但在 OBJS2中可以提前使⽤$ makeprogramA.o programB.o programC.o测试 :=# Makefile内容OBJS2 := $(OBJS1) programC.oOBJS1 := programA.o programB.oall:@echo $(OBJS2)# bash中执⾏make, 可以看出 OBJS2 中的 $(OBJS1) 为空$ makeprogramC.o2.2.2 变量替换# Makefile内容SRCS := programA.c programB.c programC.cOBJS := $(SRCS:%.c=%.o)all:@echo "SRCS: " $(SRCS)@echo "OBJS: " $(OBJS)# bash中运⾏make$ makeSRCS: programA.c programB.c programC.cOBJS: programA.o programB.o programC.o2.2.3 变量追加值 +=# Makefile内容SRCS := programA.c programB.c programC.cSRCS += programD.call:@echo "SRCS: " $(SRCS)# bash中运⾏make$ makeSRCS: programA.c programB.c programC.c programD.c2.2.4 变量覆盖 override作⽤是使 Makefile中定义的变量能够覆盖 make 命令参数中指定的变量语法:override <variable> = <value>override <variable> := <value>override <variable> += <value>下⾯通过⼀个例⼦体会 override 的作⽤:# Makefile内容 (没有⽤override)SRCS := programA.c programB.c programC.call:@echo "SRCS: " $(SRCS)# bash中运⾏make$ make SRCS=nothingSRCS: nothing################################################## Makefile内容 (⽤override)override SRCS := programA.c programB.c programC.call:@echo "SRCS: " $(SRCS)# bash中运⾏make$ make SRCS=nothingSRCS: programA.c programB.c programC.c2.2.5 ⽬标变量作⽤是使变量的作⽤域仅限于这个⽬标(target), ⽽不像之前例⼦中定义的变量, 对整个Makefile都有效.语法:<target ...> :: <variable-assignment><target ...> :: override <variable-assignment> (override作⽤参见变量覆盖的介绍)⽰例:# Makefile 内容SRCS := programA.c programB.c programC.ctarget1: TARGET1-SRCS := programD.ctarget1:@echo "SRCS: " $(SRCS)@echo "SRCS: " $(TARGET1-SRCS)target2:@echo "SRCS: " $(SRCS)@echo "SRCS: " $(TARGET1-SRCS)# bash中执⾏make$ make target1SRCS: programA.c programB.c programC.cSRCS: programD.c$ make target2 <-- target2中显⽰不了 $(TARGET1-SRCS)SRCS: programA.c programB.c programC.cSRCS:2.3 Makefile 命令前缀Makefile 中书写shell命令时可以加2种前缀 @ 和 -, 或者不⽤前缀.3种格式的shell命令区别如下:不⽤前缀 :: 输出执⾏的命令以及命令执⾏的结果, 出错的话停⽌执⾏前缀 @ :: 只输出命令执⾏的结果, 出错的话停⽌执⾏前缀 - :: 命令执⾏有错的话, 忽略错误, 继续执⾏⽰例:# Makefile 内容 (不⽤前缀)all:echo"没有前缀"cat this_file_not_existecho"错误之后的命令" <-- 这条命令不会被执⾏# bash中执⾏make$ makeecho"没有前缀" <-- 命令本⾝显⽰出来没有前缀 <-- 命令执⾏结果显⽰出来cat this_file_not_existcat: this_file_not_exist: No such file or directorymake: *** [all] Error 1############################################################ Makefile 内容 (前缀 @)all:@echo "没有前缀"@cat this_file_not_exist@echo "错误之后的命令" <-- 这条命令不会被执⾏# bash中执⾏make$ make没有前缀 <-- 只有命令执⾏的结果, 不显⽰命令本⾝cat: this_file_not_exist: No such file or directorymake: *** [all] Error 1############################################################ Makefile 内容 (前缀 -)all:-echo"没有前缀"-cat this_file_not_exist-echo"错误之后的命令" <-- 这条命令会被执⾏# bash中执⾏make$ makeecho"没有前缀" <-- 命令本⾝显⽰出来没有前缀 <-- 命令执⾏结果显⽰出来cat this_file_not_existcat: this_file_not_exist: No such file or directorymake: [all] Error 1 (ignored)echo"错误之后的命令" <-- 出错之后的命令也会显⽰错误之后的命令 <-- 出错之后的命令也会执⾏2.4 伪⽬标伪⽬标并不是⼀个"⽬标(target)", 不像真正的⽬标那样会⽣成⼀个⽬标⽂件.典型的伪⽬标是 Makefile 中⽤来清理编译过程中中间⽂件的 clean 伪⽬标, ⼀般格式如下: .PHONY: clean <-- 这句没有也⾏, 但是最好加上clean:-rm -f *.o2.5 引⽤其他的 Makefile语法: include <filename> (filename 可以包含通配符和路径)⽰例:# Makefile 内容all:@echo "主 Makefile begin"@make other-all@echo "主 Makefile end"include ./other/Makefile# ./other/Makefile 内容other-all:@echo "other makefile begin"@echo "other makefile end"# bash中执⾏make$ lltotal 20K-rw-r--r-- 1 wangyubin wangyubin 125 Sep 2316:13 Makefile-rw-r--r-- 1 wangyubin wangyubin 11K Sep 2316:15 <-- 这个⽂件不⽤管drwxr-xr-x 2 wangyubin wangyubin 4.0K Sep 2316:11 other$ ll other/total 4.0K-rw-r--r-- 1 wangyubin wangyubin 71 Sep 2316:11 Makefile$ make主 Makefile beginmake[1]: Entering directory `/path/to/test/makefile'other makefile beginother makefile endmake[1]: Leaving directory `/path/to/test/makefile'主 Makefile end2.6 查看C⽂件的依赖关系写 Makefile 的时候, 需要确定每个⽬标的依赖关系.GNU提供⼀个机制可以查看C代码⽂件依赖那些⽂件, 这样我们在写 Makefile ⽬标的时候就不⽤打开C源码来看其依赖那些⽂件了.⽐如, 下⾯命令显⽰内核源码中 virt/kvm/kvm_main.c 中的依赖关系$ cd virt/kvm/$ gcc -MM kvm_main.ckvm_main.o: kvm_main.c iodev.h coalesced_mmio.h async_pf.h <-- 这句就可以加到 Makefile 中作为编译 kvm_main.o 的依赖关系2.7 make 退出码Makefile的退出码有以下3种:0 :: 表⽰成功执⾏1 :: 表⽰make命令出现了错误2 :: 使⽤了 "-q" 选项, 并且make使得⼀些⽬标不需要更新2.8 指定 Makefile,指定特定⽬标默认执⾏ make 命令时, GNU make在当前⽬录下依次搜索下⾯3个⽂件 "GNUmakefile", "makefile", "Makefile",找到对应⽂件之后, 就开始执⾏此⽂件中的第⼀个⽬标(target). 如果找不到这3个⽂件就报错.⾮默认情况下, 可以在 make 命令中指定特定的 Makefile 和特定的⽬标.⽰例:# Makefile⽂件名改为 MyMake, 内容target1:@echo "target [1] begin"@echo "target [1] end"target2:@echo "target [2] begin"@echo "target [2] end"# bash 中执⾏make$ lsMakefile$ mv Makefile MyMake$ lsMyMake$ make <-- 找不到默认的 Makefilemake: *** No targets specified and no makefile found. Stop.$ make -f MyMake <-- 指定特定的Makefiletarget [1] begintarget [1] end$ make -f MyMake target2 <-- 指定特定的⽬标(target)target [2] begintarget [2] end2.9 make 参数介绍make 的参数有很多, 可以通过 make -h 去查看, 下⾯只介绍⼏个我认为⽐较有⽤的.参数含义--debug[=<options>]输出make的调试信息, options 可以是 a, b, v-j --jobs同时运⾏的命令的个数, 也就是多线程执⾏ Makefile-r --no-builtin-rules禁⽌使⽤任何隐含规则-R --no-builtin-variabes禁⽌使⽤任何作⽤于变量上的隐含规则-B --always-make假设所有⽬标都有更新, 即强制重编译2.10 Makefile 隐含规则这⾥只列⼀个和编译C相关的.编译C时,<n>.o 的⽬标会⾃动推导为 <n>.c# Makefile 中main : main.ogcc -o main main.o#会⾃动变为:main : main.ogcc -o main main.omain.o: main.c <-- main.o 这个⽬标是隐含⽣成的gcc -c main.c2.11 隐含规则中的命令变量和命令参数变量2.11.1 命令变量, 书写Makefile可以直接写 shell时⽤这些变量.下⾯只列出⼀些C相关的变量名含义RM rm -fAR arCC ccCXX g++⽰例:# Makefile 内容all:@echo $(RM)@echo $(AR)@echo $(CC)@echo $(CXX)# bash 中执⾏make, 显⽰各个变量的值$ makerm -farccg++2.11.2 命令参数变量变量名含义ARFLAGS AR命令的参数CFLAGS C语⾔编译器的参数CXXFLAGS C++语⾔编译器的参数⽰例: 下⾯以 CFLAGS 为例演⽰# test.c 内容#include <stdio.h>int main(int argc, char *argv[]){printf ("Hello Makefile\n");return 0;}# Makefile 内容test: test.o$(CC) -o test test.o# bash 中⽤make来测试$ lltotal 24K-rw-r--r-- 1 wangyubin wangyubin 69 Sep 2317:31 Makefile-rw-r--r-- 1 wangyubin wangyubin 14K Sep 2319:51 <-- 请忽略这个⽂件-rw-r--r-- 1 wangyubin wangyubin 392 Sep 2317:31 test.c$ makecc -c -o test.o test.ccc -o test test.o <-- 这个是⾃动推导的$ rm -f test test.o$ make CFLAGS=-Wall <-- 命令中加的编译器参数⾃动追加⼊下⾯的编译中了cc -Wall -c -o test.o test.ccc -o test test.o2.12 ⾃动变量Makefile 中很多时候通过⾃动变量来简化书写, 各个⾃动变量的含义如下:⾃动变量含义$@⽬标集合$%当⽬标是函数库⽂件时, 表⽰其中的⽬标⽂件名$<第⼀个依赖⽬标. 如果依赖⽬标是多个, 逐个表⽰依赖⽬标$?⽐⽬标新的依赖⽬标的集合$^所有依赖⽬标的集合, 会去除重复的依赖⽬标$+所有依赖⽬标的集合, 不会去除重复的依赖⽬标$*这个是GNU make特有的, 其它的make不⼀定⽀持3. Makefile ⾼级语法3.1 嵌套Makefile在 Makefile 初级语法中已经提到过引⽤其它 Makefile的⽅法. 这⾥有另⼀种写法, 并且可以向引⽤的其它 Makefile 传递参数.⽰例: (不传递参数, 只是调⽤⼦⽂件夹 other 中的Makefile)# Makefile 内容all:@echo "主 Makefile begin"@cd ./other && make@echo "主 Makefile end"# ./other/Makefile 内容other-all:@echo "other makefile begin"@echo "other makefile end"# bash中执⾏make$ lltotal 28K-rw-r--r-- 1 wangyubin wangyubin 104 Sep 2320:43 Makefile-rw-r--r-- 1 wangyubin wangyubin 17K Sep 2320:44 <-- 这个⽂件不⽤管drwxr-xr-x 2 wangyubin wangyubin 4.0K Sep 2320:42 other$ ll other/total 4.0K-rw-r--r-- 1 wangyubin wangyubin 71 Sep 2316:11 Makefile$ make主 Makefile beginmake[1]: Entering directory `/path/to/test/makefile/other'other makefile beginother makefile endmake[1]: Leaving directory `/path/to/test/makefile/other'主 Makefile end⽰例: (⽤export传递参数)# Makefile 内容export VALUE1 := export.c <-- ⽤了 export, 此变量能够传递到 ./other/Makefile 中VALUE2 := no-export.c <-- 此变量不能传递到 ./other/Makefile 中all:@echo "主 Makefile begin"@cd ./other && make@echo "主 Makefile end"# ./other/Makefile 内容other-all:@echo "other makefile begin"@echo "VALUE1: " $(VALUE1)@echo "VALUE2: " $(VALUE2)@echo "other makefile end"# bash中执⾏make$ make主 Makefile beginmake[1]: Entering directory `/path/to/test/makefile/other'other makefile beginVALUE1: export.c <-- VALUE1 传递成功VALUE2: <-- VALUE2 传递失败other makefile endmake[1]: Leaving directory `/path/to/test/makefile/other'主 Makefile end*补充* export 语法格式如下:export variable = valueexport variable := valueexport variable += value3.2 定义命令包命令包有点像是个函数, 将连续的相同的命令合成⼀条, 减少 Makefile 中的代码量, 便于以后维护.语法:define <command-name>command...endef⽰例:# Makefile 内容define run-hello-makefile@echo -n "Hello"@echo " Makefile!"@echo "这⾥可以执⾏多条 Shell 命令!"endefall:$(run-hello-makefile)# bash 中运⾏make$ makeHello Makefile!这⾥可以执⾏多条 Shell 命令!3.3 条件判断条件判断的关键字主要有 ifeq ifneq ifdef ifndef语法:<conditional-directive><text-if-true>endif# 或者<conditional-directive><text-if-true>else<text-if-false>endif⽰例: ifeq的例⼦, ifneq和ifeq的使⽤⽅法类似, 就是取反# Makefile 内容all:ifeq ("aa", "bb")@echo "equal"else@echo "not equal"endif# bash 中执⾏make$ makenot equal⽰例: ifdef的例⼦, ifndef和ifdef的使⽤⽅法类似, 就是取反# Makefile 内容SRCS := program.call:ifdef SRCS@echo $(SRCS)else@echo "no SRCS"# bash 中执⾏make$ makeprogram.c3.4 Makefile 中的函数Makefile 中⾃带了⼀些函数, 利⽤这些函数可以简化 Makefile 的编写.函数调⽤语法如下:$(<function> <arguments>)# 或者${<function> <arguments>}<function> 是函数名<arguments> 是函数参数3.4.1 字符串函数字符串替换函数: $(subst <from>,<to>,<text>)功能: 把字符串<text> 中的 <from> 替换为 <to>返回: 替换过的字符串# Makefile 内容all:@echo $(subst t,e,maktfilt) <-- 将t替换为e# bash 中执⾏make$ makemakefile模式字符串替换函数: $(patsubst <pattern>,<replacement>,<text>)功能: 查找<text>中的单词(单词以"空格", "tab", "换⾏"来分割) 是否符合 <pattern>, 符合的话, ⽤ <replacement> 替代.返回: 替换过的字符串# Makefile 内容all:@echo $(patsubst %.c,%.o,programA.c programB.c)# bash 中执⾏make$ makeprogramA.o programB.o去空格函数: $(strip <string>)功能: 去掉 <string> 字符串中开头和结尾的空字符返回: 被去掉空格的字符串值# Makefile 内容VAL := " aa bb cc "all:@echo "去除空格前: " $(VAL)@echo "去除空格后: " $(strip $(VAL))# bash 中执⾏make去除空格前: aa bb cc去除空格后: aa bb cc查找字符串函数: $(findstring <find>,<in>)功能: 在字符串 <in> 中查找 <find> 字符串返回: 如果找到, 返回 <find> 字符串, 否则返回空字符串# Makefile 内容VAL := " aa bb cc "all:@echo $(findstring aa,$(VAL))@echo $(findstring ab,$(VAL))# bash 中执⾏make$ makeaa过滤函数: $(filter <pattern...>,<text>)功能: 以 <pattern> 模式过滤字符串 <text>, *保留* 符合模式 <pattern> 的单词, 可以有多个模式返回: 符合模式 <pattern> 的字符串# Makefile 内容all:@echo $(filter %.o %.a,program.c program.o program.a)# bash 中执⾏make$ makeprogram.o program.a反过滤函数: $(filter-out <pattern...>,<text>)功能: 以 <pattern> 模式过滤字符串 <text>, *去除* 符合模式 <pattern> 的单词, 可以有多个模式返回: 不符合模式 <pattern> 的字符串# Makefile 内容all:@echo $(filter-out %.o %.a,program.c program.o program.a)# bash 中执⾏make$ makeprogram.c排序函数: $(sort <list>)功能: 给字符串 <list> 中的单词排序 (升序)返回: 排序后的字符串# Makefile 内容all:@echo $(sort bac abc acb cab)# bash 中执⾏make$ makeabc acb bac cab取单词函数: $(word <n>,<text>)功能: 取字符串 <text> 中的第<n>个单词 (n从1开始)返回: <text> 中的第<n>个单词, 如果<n> ⽐ <text> 中单词个数要⼤, 则返回空字符串# Makefile 内容all:@echo $(word 1,aa bb cc dd)@echo $(word 5,aa bb cc dd)@echo $(word 4,aa bb cc dd)# bash 中执⾏make$ makeaadd取单词串函数: $(wordlist <s>,<e>,<text>)功能: 从字符串<text>中取从<s>开始到<e>的单词串. <s>和<e>是⼀个数字.返回: 从<s>到<e>的字符串# Makefile 内容all:@echo $(wordlist 1,3,aa bb cc dd)@echo $(word 5,6,aa bb cc dd)@echo $(word 2,5,aa bb cc dd)# bash 中执⾏make$ makeaa bb ccbb单词个数统计函数: $(words <text>)功能: 统计字符串 <text> 中单词的个数返回: 单词个数# Makefile 内容all:@echo $(words aa bb cc dd)@echo $(words aabbccdd)@echo $(words )# bash 中执⾏make$ make41⾸单词函数: $(firstword <text>)功能: 取字符串 <text> 中的第⼀个单词返回: 字符串 <text> 中的第⼀个单词# Makefile 内容all:@echo $(firstword aa bb cc dd)@echo $(firstword aabbccdd)@echo $(firstword )# bash 中执⾏make$ makeaaaabbccdd3.4.2 ⽂件名函数取⽬录函数: $(dir <names...>)功能: 从⽂件名序列 <names> 中取出⽬录部分返回: ⽂件名序列 <names> 中的⽬录部分# Makefile 内容all:@echo $(dir /home/a.c ./bb.c ../c.c d.c)# bash 中执⾏make$ make/home/ ./ ../ ./取⽂件函数: $(notdir <names...>)功能: 从⽂件名序列 <names> 中取出⾮⽬录部分返回: ⽂件名序列 <names> 中的⾮⽬录部分# Makefile 内容all:@echo $(notdir /home/a.c ./bb.c ../c.c d.c)# bash 中执⾏make$ makea.c bb.cc.cd.c取后缀函数: $(suffix <names...>)功能: 从⽂件名序列 <names> 中取出各个⽂件名的后缀返回: ⽂件名序列 <names> 中各个⽂件名的后缀, 没有后缀则返回空字符串# Makefile 内容all:@echo $(suffix /home/a.c ./b.o ../c.a d)# bash 中执⾏make$ make.c .o .a取前缀函数: $(basename <names...>)功能: 从⽂件名序列 <names> 中取出各个⽂件名的前缀返回: ⽂件名序列 <names> 中各个⽂件名的前缀, 没有前缀则返回空字符串# Makefile 内容all:@echo $(basename /home/a.c ./b.o ../c.a /home/.d .e)# bash 中执⾏make$ make/home/a ./b ../c /home/加后缀函数: $(addsuffix <suffix>,<names...>)功能: 把后缀 <suffix> 加到 <names> 中的每个单词后⾯返回: 加过后缀的⽂件名序列# Makefile 内容all:@echo $(addsuffix .c,/home/a b ./c.o ../d.c)# bash 中执⾏make$ make/home/a.c b.c ./c.o.c ../d.c.c加前缀函数: $(addprefix <prefix>,<names...>)功能: 把前缀 <prefix> 加到 <names> 中的每个单词前⾯返回: 加过前缀的⽂件名序列# Makefile 内容all:@echo $(addprefix test_,/home/a.c b.c ./d.c)# bash 中执⾏make$ maketest_/home/a.c test_b.c test_./d.c连接函数: $(join <list1>,<list2>)功能: <list2> 中对应的单词加到 <list1> 后⾯返回: 连接后的字符串# Makefile 内容all:@echo $(join a b c d,1234)@echo $(join a b c d,12345)@echo $(join a b c d e,1234)# bash 中执⾏make$ makea1 b2 c3 d4a1 b2 c3 d4 5a1 b2 c3 d4 e3.4.3 foreach语法:$(foreach <var>,<list>,<text>)⽰例:# Makefile 内容targets := a b c dobjects := $(foreach i,$(targets),$(i).o)all:@echo $(targets)@echo $(objects)# bash 中执⾏make$ makea b c da.ob.oc.od.o3.4.4 if这⾥的if是个函数, 和前⾯的条件判断不⼀样, 前⾯的条件判断属于Makefile的关键字语法:$(if <condition>,<then-part>)$(if <condition>,<then-part>,<else-part>)⽰例:# Makefile 内容val := aobjects := $(if $(val),$(val).o,nothing)no-objects := $(if $(no-val),$(val).o,nothing)all:@echo $(objects)@echo $(no-objects)# bash 中执⾏make$ makea.onothing3.4.5 call - 创建新的参数化函数语法:$(call <expression>,<parm1>,<parm2>,<parm3>...)⽰例:# Makefile 内容log = "====debug====" $(1) "====end===="all:@echo $(call log,"正在 Make")# bash 中执⾏make$ make====debug==== 正在 Make ====end====3.4.6 origin - 判断变量的来源语法:$(origin <variable>)返回值有如下类型:类型含义undefined<variable> 没有定义过default<variable> 是个默认的定义, ⽐如 CC 变量environment<variable> 是个环境变量, 并且 make时没有使⽤ -e 参数file<variable> 定义在Makefile中command line<variable> 定义在命令⾏中override<variable> 被 override 重新定义过automatic<variable> 是⾃动化变量⽰例:# Makefile 内容val-in-file := test-fileoverride val-override := test-overrideall:@echo $(origin not-define) # not-define 没有定义@echo $(origin CC) # CC 是Makefile默认定义的变量@echo $(origin PATH) # PATH 是 bash 环境变量@echo $(origin val-in-file) # 此Makefile中定义的变量@echo $(origin val-in-cmd) # 这个变量会加在make的参数中@echo $(origin val-override) # 此Makefile中定义的override变量@echo $(origin @) # ⾃动变量, 具体前⾯的介绍# bash 中执⾏make$ make val-in-cmd=val-cmdundefineddefaultenvironmentfilecommand lineoverrideautomatic3.4.7 shell语法:$(shell <shell command>)它的作⽤就是执⾏⼀个shell命令, 并将shell命令的结果作为函数的返回.作⽤和 `<shell command>` ⼀样, ` 是反引号3.4.8 make 控制函数产⽣⼀个致命错误: $(error <text ...>)功能: 输出错误信息, 停⽌Makefile的运⾏# Makefile 内容all:$(error there is an error!)@echo "这⾥不会执⾏!"# bash 中执⾏make$ makeMakefile:2: *** there is an error!. Stop.输出警告: $(warning <text ...>)功能: 输出警告信息, Makefile继续运⾏# Makefile 内容all:$(warning there is an warning!)@echo "这⾥会执⾏!"# bash 中执⾏make$ makeMakefile:2: there is an warning!这⾥会执⾏!3.5 Makefile中⼀些GNU约定俗成的伪⽬标如果有过在Linux上, 从源码安装软件的经历的话, 就会对 make clean, make install ⽐较熟悉.像 clean, install 这些伪⽬标, ⼴为⼈知, 不⽤解释就⼤家知道是什么意思了.下⾯列举⼀些常⽤的伪⽬标, 如果在⾃⼰项⽬的Makefile合理使⽤这些伪⽬标的话, 可以让我们⾃⼰的Makefile看起来更专业, 呵呵 :)伪⽬标含义all所有⽬标的⽬标,其功能⼀般是编译所有的⽬标clean删除所有被make创建的⽂件install安装已编译好的程序,其实就是把⽬标可执⾏⽂件拷贝到指定的⽬录中去print列出改变过的源⽂件tar把源程序打包备份. 也就是⼀个tar⽂件dist创建⼀个压缩⽂件, ⼀般是把tar⽂件压成Z⽂件. 或是gz⽂件TAGS更新所有的⽬标, 以备完整地重编译使⽤check 或 test⼀般⽤来测试makefile的流程。
sv 中的makefile 写法
SV(SystemVerilog)是一种硬件描述语言,用于设计和验证数字电路。
在进行SV代码编写的过程中,makefile是一种非常有用的工具,可以帮助组织和管理SV项目中的代码文件。
本文将介绍SV中makefile的写法,希望能为SV开发者提供一些参考和帮助。
1. 为什么需要makefile在SV项目中,通常会涉及到多个源文件、库文件、测试文件等。
使用makefile可以帮助我们轻松地组织和管理这些文件,实现自动化编译、信息和运行测试的功能。
makefile还可以帮助我们避免重复编译文件,提高开发效率。
2. makefile的基本结构makefile由一系列规则组成,每个规则由一个目标、依赖列表和命令组成。
一个基本的makefile看起来像这样:```makefiletarget: dependenciesmand```其中,target表示规则的目标文件,dependencies表示该目标文件的依赖文件mand表示需要执行的命令。
3. 使用变量在makefile中,我们可以使用变量来定义一些常量,方便我们在后续的规则中使用。
例如:```makefileSV_SRC = file1.sv file2.sv file3.sv```这样,我们就可以在后续的规则中使用$(SV_SRC)来表示这些文件,而不需要重复地写出它们的文件名。
4. 基本规则在SV项目中,常见的makefile规则包括编译规则、信息规则和运行测试规则。
以下是一个简单的例子:```makefileall: $(SV_SRC)vlog $(SV_SRC)sim: allvsim top_module```在这个例子中,我们定义了两个规则,分别是all和sim。
all规则依赖于$(SV_SRC)中的文件,使用vlog命令对这些文件进行编译。
sim规则依赖于all规则,使用vsim命令来运行测试。
5. 使用通配符在makefile中,我们还可以使用通配符来表示一类文件。
makefile参数
makefile参数Makefile是一种文本文件,用于描述构建源代码的规则和依赖关系,以及如何将源代码编译成可执行文件或库。
Makefile通常由一个名为"make"的工具来解析和执行,该工具会根据规则自动检测源码的更改,并根据需要重新编译相关文件。
Makefile的参数可以用于修改make工具的行为,并指导其对源代码进行编译和构建。
以下是一些常用的Makefile参数:1. -f <filename>或--file=<filename>: 指定Makefile的文件名。
默认情况下,make工具会在当前目录下寻找名为"Makefile"或"makefile"的文件作为Makefile文件。
使用该参数可以指定不同的Makefile文件。
2. -j <n>或--jobs=<n>: 指定make工具并行处理的任务数。
该参数可以加快构建过程的速度,尤其适用于大型项目。
通常推荐的取值范围是CPU核数的两倍。
3. -C <dir>或--directory=<dir>: 指定make工具的工作目录。
默认情况下,make工具会在当前目录下查找Makefile文件并进行构建。
使用该参数可以指定其他目录,从而在其中查找Makefile文件并在该目录下进行构建。
4. --dry-run: 执行模拟运行,不实际构建任何文件。
该参数可以用于检查Makefile的正确性,以及在构建之前查看将要执行的命令。
5. --silent或--quiet: 取消make工具的输出信息。
使用该参数可以让构建过程更加清晰,只显示构建过程的关键信息。
6. --no-print-directory: 取消make工具的目录切换信息的输出。
默认情况下,make工具会在进入每个目录之前打印当前切换的目录路径。
使用该参数可以减少输出信息的大小。
makefile 冒号的用法
Makefile 冒号的用法
在Makefile中,冒号(:)主要有两种用法:
规则中的冒号:在Makefile的规则中,冒号用于分隔目标文件和依赖项。
规则的格式为“目标文件:依赖项1 依赖项2 ... 命令”。
其中,目标文件是规则要生成的文件,依赖项是目标文件所依赖的其他文件,命令是用于生成目标文件的命令。
例如,下面的规则表示当目标文件“foo.o”发生变化时,执行命令“gcc -c foo.c”来重新生成它:
makefile
foo.o: foo.c
gcc -c foo.c
双冒号规则中的冒号:在Makefile中,双冒号规则是一种特殊的规则,用于指定当多个文件具有相同的依赖项时,如何执行不同的命令来生成目标文件。
双冒号规则的格式为“目标文件:: 依赖项1 依赖项2 ... 命令”。
例如,下面的规则表示当“foo.c”或“bar.c”发生变化时,分别执行不同的命令来重新生成“Newprog”目标文件:
makefile
Newprog :: foo.c $(CC) $(CFLAGS) $< -o $@
Newprog :: bar.c $(CC) $(CFLAGS) $< -o $@
在双冒号规则中,当同一个目标出现在多个规则中时,会按照规则的书写顺序执行。
因此,在上面的例子中,如果“foo.c”发生变化,将执行第一个规则重新生成“Newprog”,然后执行第二个规则重新生成“Newprog”,因为“bar.c”没有被修改。
总结起来,冒号在Makefile中有两种主要用法:一种是用于分隔目标文件
和依赖项的普通规则中的冒号,另一种是用于指定多个规则中如何执行不同命令的双冒号规则中的冒号。
make file的if fi写法
一、make file的概念及作用make file是一种用来描述文件之间的依赖关系,以及如何通过执行特定命令来生成目标文件的工具。
它的作用在于帮助程序员自动化编译、信息和部署程序,提高开发效率和代码质量。
二、make file的语法及基本结构1. make file以一组规则的形式存在,每个规则包含了目标、依赖以及命令三部分。
2. 目标指定了规则要生成的文件名,可以是可执行文件、中间文件或者其他类型的文件。
3. 依赖指定了生成目标文件所需要依赖的文件或者其他目标文件。
4. 命令指定了生成目标文件的具体操作,可以是编译、信息、复制等操作。
三、make file的if/then/fi写法1. if/then/fi是make file中用来判断条件并执行相应操作的语法结构,类似于C语言中的if语句。
2. if后面跟着条件表达式,根据条件的真假来决定执行then后面的命令还是fi后面的命令。
3. then后面跟着要执行的命令,可以是单个命令,也可以是多个命令使用分号分隔。
4. fi表示if语句的结束,标志着条件判断部分的结束。
四、if/then/fi的使用场景1. if/then/fi结构可以用来根据特定条件执行不同的命令,比如根据评台的不同选择不同的编译选项。
2. 可以在make file中根据文件的存在与否来判断是否执行特定操作,比如判断依赖文件是否存在,如果不存在则生成。
3. 可以根据变量的取值来选择不同的操作,比如根据DEBUG变量的取值来选择是否生成调试信息。
五、if/then/fi的注意事项1. 在make file中使用if/then/fi时需要注意语法的正确性,要保证if、then和fi的配对和嵌套关系正确。
2. 条件表达式要保证逻辑上的正确性,避免出现歧义和错误。
3. 命令部分的书写要符合make file的语法规范,保证可以正确执行。
4. 对于复杂的条件判断,可以考虑使用shell脚本来处理,然后在make file中调用对应的shell脚本。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Makefile
Zheda Innovation Technology CO.LTD
2009-7-22
目录
1概述 (3)
2作用 (3)
3规则 (3)
3.1M AKEFILE规则 (3)
3.2简单例子 (4)
4MAKE工作方式 (4)
Revision History
1概述
makefile关系到了整个工程的编译规则。
一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。
makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make 命令,整个工程完全自动编译,极大的提高了软件开发的效率。
2作用
Makefile的作用,简单说来,就是制定编译(compile)和链接(link)规则,告诉make命令如何编译和链接程序。
Makefile来告诉make命令如何编译和链接这几个文件。
规则是:
1)如果这个工程没有编译过,那么我们的所有C文件都要编译并被链接。
2)如果这个工程的某几个C文件被修改,那么我们只编译被修改的C文件,并链接目标程序。
3)如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的C文件,并链接目标程序。
3规则
3.1 Makefile规则
在讲述这个Makefile之前,还是让我们先来粗略地看一看Makefile的规则。
target ... : prerequisites ...
command
...
...
target也就是一个目标文件,可以是Object File,也可以是执行文件。
还可以是一个标签(Label)。
prerequisites就是,要生成那个target所需要的文件或是目标。
command也就是make需要执行的命令。
(任意的Shell命令)
这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中。
说白一点就是说,prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行。
这就是Makefile的规则。
也就是Makefile中最核心的内容。
3.2 简单例子
objects = hello.o //定义变量,方便以后维护
hello : $(objects)
cc -o hello $(objects) //链接完成编译的中间代码文件*.o hello.o : //根据make的隐晦规则,编译器会自动推导所依赖的源文件或*.h文件
.PHONY : clean
clean :
-rm hello $(objects) //clean命令
4Make工作方式
1、读入所有的Makefile。
2、读入被include的其它Makefile。
3、初始化文件中的变量。
4、推导隐晦规则,并分析所有规则。
5、为所有的目标文件创建依赖关系链。
6、根据依赖关系,决定哪些目标要重新生成。
7、执行生成命令。