Linux Makefile实验
- 格式:pdf
- 大小:260.17 KB
- 文档页数:9
linux makefile编写规则(原创实用版)目录一、Makefile 简介二、Makefile 的规则1.目标文件2.依赖文件3.命令三、Makefile 中的变量1.通用变量2.局部变量四、Makefile 中的路径1.源文件路径2.目标文件路径3.库文件路径五、Makefile 编写实例六、总结正文一、Makefile 简介Makefile 是一个用于自动化构建和编译软件的脚本文件,通常在Linux 系统中使用。
它可以帮助开发者管理源代码,以及确定哪些文件需要编译,如何编译,以及编译后的文件如何链接。
通过编写 Makefile,开发者可以轻松地构建和维护复杂的软件项目。
Makefile 主要包括三类规则:目标文件、依赖文件和命令。
1.目标文件目标文件是 Makefile 中要生成的文件,可以是对象文件、库文件或执行文件。
在 Makefile 中,目标文件通常以“target”关键字开头,后面跟要生成的文件名。
例如:“target = main.o”。
2.依赖文件依赖文件是 Makefile 中要生成目标文件所需要的其他文件,通常是源代码文件。
在 Makefile 中,依赖文件通常以“prerequisites”关键字开头,后面跟要依赖的文件名。
例如:“prerequisites = a.c b.c”。
3.命令命令是用来生成目标文件的命令,通常是编译器或链接器。
在Makefile 中,命令通常以“command”关键字开头,后面跟要执行的命令。
例如:“command = gcc -o main.o a.c b.c”。
三、Makefile 中的变量Makefile 中的变量可以用于存储常量值,以便在 Makefile 中多次使用。
变量分为通用变量和局部变量。
1.通用变量通用变量是在整个 Makefile 中都可以使用的变量。
通用变量通常在Makefile 的开头定义,使用“define”关键字。
通用makefile文件(windows,linux)makefile的缺省目录结构如图所示,用户可以修改黄色部分的目录名,这是用户手动建立的。
注意图中黄色的makefile文件不能修改。
蓝色部分是make按照makefile文件自动生成的。
用户可以通过make命令修改最后产生的执行文件名称一般描述:首先手动创建根目录,此处创建的目录是d:\make-file,用户可以创建任意目录名称,根目录创建完成后,将makefile文件放于该文件夹内。
在根目录下手动创建inc和src两个文件夹,分别用于存放.h头文件和.c源文件,并将要编译的头文件和源文件放于这两个文件夹下。
缺省情况下,即运行命令make会编译链接inc和src文件夹下的源程序,将自动创建obj,dep和bin三个文件夹,其中obj文件夹下存放.o文件,dep文件夹下存放.d依赖文件,bin文件夹下存放生成的exe文件,缺省文件名为default.exe。
命令格式:Make [I_PATH= .h file directory] [C_PATH=.c file directory] [EXE = output .exe filename]命令描述:[]表示可选参数;I_PATH参数指定头文件路径,若不带I_PATH参数,make会到inc目录下查找头文件;C_PATH参数指定c文件路径,若不带C_PATH参数,make会编译src下的c文件;EXE参数指定输出可执行文件名,若不带EXE参数,会在bin目录下生成名字为default.exe 的可执行程序。
使用举例:make编译链接inc下的头文件和src下的源程序,在bin文件夹下生成名字为default.exe的可执行文件。
make EXE=tan.exe编译链接inc下的头文件和src下的源程序,在bin文件夹下生成名字为tan.exe的可执行文件。
make I_PATH=head编译链接head下的头文件和src文件夹下的源程序,在bin文件夹下生成名字为default.exe 的可执行文件。
实例详解Linux下的Make命令前⾔⽆论是在linux 还是在Unix环境中,make都是⼀个⾮常重要的编译命令。
不管是⾃⼰进⾏项⽬开发还是安装应⽤软件,我们都经常要⽤到make或make install。
利⽤make⼯具,我们可以将⼤型的开发项⽬分解成为多个更易于管理的模块,对于⼀个包括⼏百个源⽂件的应⽤程序,使⽤make和 makefile⼯具就可以简洁明快地理顺各个源⽂件之间纷繁复杂的相互关系。
⽽且如此多的源⽂件,如果每次都要键⼊gcc命令进⾏编译的话,那对程序员来说简直就是⼀场灾难。
⽽make⼯具则可⾃动完成编译⼯作,并且可以只对程序员在上次编译后修改过的部分进⾏编译。
因此,有效的利⽤make和 makefile⼯具可以⼤⼤提⾼项⽬开发的效率。
Make 如何⼯作的对于不知道背后机理的⼈来说,make 命令像命令⾏参数⼀样接收⽬标。
这些⽬标通常存放在以 “Makefile” 来命名的特殊⽂件中,同时⽂件也包含与⽬标相对应的操作。
更多信息,阅读关于 Makefiles 如何⼯作的系列⽂章。
当 make 命令第⼀次执⾏时,它扫描 Makefile 找到⽬标以及其依赖。
如果这些依赖⾃⾝也是⽬标,继续为这些依赖扫描Makefile 建⽴其依赖关系,然后编译它们。
⼀旦主依赖编译之后,然后就编译主⽬标(这是通过 make 命令传⼊的)。
现在,假设你对某个源⽂件进⾏了修改,你再次执⾏ make 命令,它将只编译与该源⽂件相关的⽬标⽂件,因此,编译完最终的可执⾏⽂件节省了⼤量的时间。
Make 命令实例下⾯是本⽂所使⽤的测试环境:OS —— Ubunut 13.04Shell —— Bash 4.2.45Application —— GNU Make 3.81下⾯是⼯程的内容:$ lsanotherTest.c Makefile test.c test.h下⾯是 Makefile 的内容:all: testtest: test.o anotherTest.ogcc -Wall test.o anotherTest.o -o testtest.o: test.cgcc -c -Wall test.canotherTest.o: anotherTest.cgcc -c -Wall anotherTest.cclean:rm -rf *.o test现在我们来看 Linux 下⼀些 make 命令应⽤的实例:1. ⼀个简单的例⼦为了编译整个⼯程,你可以简单的使⽤ make 或者在 make 命令后带上⽬标 all。
实验二M akefile实验【实验目的】1、了解makefile的概念和构成。
2、会使用GNU make编译一个或者多个文件。
3、掌握Makefile文件的编写。
【实验条件】1、VMware虚拟机。
2、Redhat Linux平台。
【实验内容与步骤】1、使用命令编译程序在这里通过vi编译器来创建两个文件hello.c和makefile。
[hello.c]* test make file* Emdoor*#include "stdio.h"main(){printf( "wellcom emdoor!\n");}[makefile]# test for makefileCC = gccCFLAGS =all : hellohello: hello.o$(CC) $(CFLAGS) hello.o -o hellohello.o: hello.c$(CC) $(CFLAGS) -c hello.c -o hello.o clean:在将上述Makefile文件与源文件hello.c保存到同一目录之后,就可以在命令行中输入“make”命令来编译整个项目了。
make在执行过程中,首先会查找到Makefile文件第一条规则中的目标,即上述文件中的all。
根据设定好的规则,该目标需要依赖于hello。
由于all并不是一个已经存在的文件,所以每次在make被调用的时候,显然都需要先检查hello。
继续往下不难发现,hello目标是依赖于hello.o。
当make处理到目标hello.o时,会先查看其对应的依赖对象,这个以来对象是hello.c,此时就会对hello.c进行编译,得到目标文件hello.o,然后是目标文件hello.o被连接,得到可执行文件hello。
先后执行如下命令:可以看到输出结果:在Makefile中,并不是所有的目标都对应于磁盘上的文件。
有的目标存在只是为了形成一条规则,从而完成特定的工作,并不生成新的目标文件,这样的目标称为伪目标。
linux vscode makefile语法在Linux 系统中,如果您想使用VSCode 编写Makefile 相关的项目,可以参考以下步骤进行安装和配置:1. 首先,确保已经正确安装了Visual Studio Code。
如果尚未安装,可以参考[1] 中的教程进行安装。
2. 安装Makefile 插件。
打开VSCode,转到“扩展”选项卡(快捷键:Ctrl+Shift+X),搜索“Makefile”,找到名为“Makefile Support”的插件,点击“安装”。
3. 创建一个新的Makefile 项目。
在VSCode 中,创建一个新的文件夹,然后在该文件夹中打开终端(快捷键:Ctrl+`)。
4. 编写Makefile 语法。
在项目根目录下创建一个名为“Makefile”的文件,然后编写相应的Makefile 语法。
以下是一个简单的示例:```make# 设置变量MY_PROJECT_NAME = MyProjectMY_PROJECT_VERSION = 1.0# 设置目标all: build# 构建目标build:echo "Building $MY_PROJECT_NAME $MY_PROJECT_VERSION"# 在这里添加您的构建命令,例如:cmake、make等# 清理目标clean:echo "Cleaning $MY_PROJECT_NAME"# 在这里添加您的清理命令,例如:rm -rf build/# 默认执行构建目标default: build```5. 保存Makefile 文件并按F5 键运行项目。
VSCode 将会自动使用内置的终端执行Makefile 中的命令。
6. 如果需要使用GPU 加速构建,可以在Makefile 中添加相应的NVIDIA CUDA 或者AMD OpenCL 命令。
例如,如果您使用的是NVIDIA GPU,可以添加以下命令:```makebuild_gpu:echo "Building $MY_PROJECT_NAME $MY_PROJECT_VERSION using GPU"# 在这里添加您的GPU 构建命令,例如:nvcc、cuda编译器等```7. 按照项目需求修改Makefile 中的命令和目标。
计算机科学系实验报告
课程名称Linux系统班级11软件2班实验名称grep、make命令及shell编程指导教师XXX
姓名123 学号123456 日期
一、实验目的
1.学习grep工具的使用, 能熟练使用grep进行文本搜索。
学习简单的正则表达式, 能在grep中使用正则表达式进行文本搜索。
二、学习make命令的使用, 能编写简单的Makefile文件。
三、 4. 学习shell编程,掌握的shell语法,能编写简单的shell脚本。
四、实验环境
Win7下vm虚拟机, Linux操作系统
五、实验内容
1.grep的使用
make命令的使用
shell编程
六、实验心得
对于这些命令, 一开始我很迷茫, 直到后面一个同学说直接在百度搜了linux命令大全, 我就去查, 没想到查起来这么方便, 很快就做好了。
实验二、嵌入式Linux多线程编程实验一、实验目的1. 熟悉线程的定义、创建及应用方法,掌握编译源代码时引入线程库的方法。
2. 掌握如何利用信号量完成线程间的同步与互斥。
3. 熟悉Makefile工作原理,掌握编写Makefile的编写方法。
二、实验基本要求1. 掌握熟悉线程的定义及操作方法。
2. 利用信号量的PV操作完成完成以下单个生产者和单个消费者模型的代码。
3. 编写在Ubuntu中编译执行的makefile文件,然后在Ubuntu中执行。
4. 编写在实验箱中编译执行的makefile文件,然后在实验箱中执行。
注意Makefile编写规范缩进应使用制表键即Tab键。
三、实验原理1.Linux线程的定义线程(thread)是在共享内存空间中并发的多道执行路径,它们共享一个进程的资源,如文件描述和信号处理。
在两个普通进程(非线程)间进行切换时,内核准备从一个进程的上下文切换到另一个进程的上下文要花费很大的开销。
这里上下文切换的主要任务是保存老进程CPU状态并加载新进程的保存状态,用新进程的内存映像替换进程的内存映像。
线程允许你的进程在几个正在运行的任务之间进行切换,而不必执行前面提到的完整的上下文。
另外本文介绍的线程是针对POSIX线程,也就是pthread。
也因为Linux对它的支持最好。
相对进程而言,线程是一个更加接近于执行体的概念,它可以与同进程中的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。
在串行程序基础上引入线程和进程是为了提高程序的并发度,从而提高程序运行效率和响应时间。
也可以将线程和轻量级进程(LWP)视为等同的,但其实在不同的系统/实现中有不同的解释,LWP更恰当的解释为一个虚拟CPU或内核的线程。
它可以帮助用户态线程实现一些特殊的功能。
Pthread是一种标准化模型,它用来把一个程序分成一组能够同时执行的任务。
2. 什么场合会使用Pthread即线程(1) 在返回前阻塞的I/O任务能够使用一个线程处理I/O,同时继续执行其他处理任务。
Makefile两个实验实验⼗四Makefile⼯程管理器14.1 编写包含多⽂件的Makefile【实验内容】编写⼀个包含多⽂件的Makefile。
【实验⽬的】通过对包含多⽂件的Makefile的编写,熟悉各种形式的Makefile,并且进⼀步加深对Makefile中⽤户⾃定义变量、⾃动变量及预定义变量的理解。
【实验平台】PC机、CentOS 5 操作系统、gcc等⼯具。
【实验步骤】1.⽤vi在同⼀⽬录下编辑两个简单的Hello程序,如下所⽰:#hello.c#include "hello.h"int main(){printf("Hello everyone!\n");}#hello.h#include2.仍在同⼀⽬录下⽤vim编辑Makefile,不使⽤变量替换,⽤⼀个⽬标体实现(即直接将hello.c和hello.h编译成hello⽬标体)。
并⽤make验证所编写的Makefile是否正确。
3.将上述Makefile使⽤变量替换实现。
同样⽤make验证所编写的Makefile是否正确4.⽤编辑另⼀Makefile,取名为Makefile1,不使⽤变量替换,但⽤两个⽬标体实现(也就是⾸先将hello.c和hello.h编译为hello.o,再将hello.o编译为hello),再⽤make 的‘-f’选项验证这个Makefile1的正确性。
5.将上述Makefile1使⽤变量替换实现【详细步骤】1.⽤vi打开上述两个代码⽂件…hello.c?和…hello.h?2.在shell命令⾏中⽤gcc尝试编译,使⽤命令:…gcc hello.c -o hello?,并运⾏hello可执⾏⽂件查看结果。
3.删除此次编译的可执⾏⽂件:rm –rf hello4.⽤vim编辑Makefile,如下所⽰:hello:hello.c hello.hgcc hello.c -o hello5.退出保存,在shell中键⼊:make查看结果6.再次⽤vim打开Makefile,⽤变量进⾏替换,如下所⽰:OBJS :=hello.oCC :=gcchello:$(OBJS)$(CC) $^ -o $@7.退出保存,在shell中键⼊:make查看结果8.⽤vim编辑Makefile1,如下所⽰:hello:hello.ogcc hello.o -o hellohello.o:hello.c hello.hgcc -c hello.c -o hello.o9.退出保存,在shell中键⼊:make –f Makefile1查看结果10.再次⽤vi编辑Makefile1,如下所⽰:OBJS1 :=hello.oOBJS2 :=hello.c hello.hCC :=gcchello:$(OBJS1)$(CC) $^ -o $@$(OBJS1):$(OBJS2)$(CC) -c $< -o $@在这⾥请注意区别…$^?和…$11.退出保存,在shell中键⼊:make –f Makefile1查看结果14.2嵌套Makefile实验【实验⽬的】1、读懂makefile⽂件,能根据makefile⽂件理清程序结构2、能编写简单makefile3、掌握嵌套执⾏makefile【实验环境】PC机、CentOS 5 操作系统,gcc等⼯具。
实验二Makefile实验【实验目的】1、了解Makefile的基本概念和基本结构2、初步掌握编写简单Makefile的方法3、了解递归Make的编译过程4、初步掌握利用GNU Make编译应用程序的方法【实验原理】在Linux或Unix环境下,对于只含有几个源代码文件的小程序(如hello.c)的编译,可以手工键入gcc命令对源代码文件逐个进行编译;然而在大型的项目开发中,可能涉及几十到几百个源文件,采用手工键入的方式进行编译,则非常不方便,而且一旦修改了源代码,尤其头文件发生了的修改,采用手工方式进行编译和维护的工作量相当大,而且容易出错。
所以在Linux或Unix环境下,人们通常利用GNU make工具来自动完成应用程序的维护和编译工作。
实际上,GNU make工具通过一个称为Makefile的文件来完成对应用程序的自动维护和编译工作。
Makefile是按照某种脚本语法编写的文本文件,而GNU make能够对Makefile中指令进行解释并执行编译操作。
Makefile文件定义了一系列的规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。
GNU make工作时的执行步骤如下:1、读入所有的Makefile。
2、读入被include的其它Makefile。
3、初始化文件中的变量。
4、推导隐晦规则,并分析所有规则。
5、为所有的目标文件创建依赖关系链。
6、根据依赖关系,决定哪些目标要重新生成。
7、执行生成命令。
1-5步为第一个阶段,6-7为第二个阶段。
第一个阶段中,如果定义的变量被使用了,那么,make会把其展开在使用的位置。
但make并不会完全马上展开,make使用的是拖延战术,如果变量出现在依赖关系的规则中,那么仅当这条依赖被决定要使用了,变量才会在其内部展开。
下面对makefile的相关问题进行简单介绍:1、Makefile的基本结构Makefile的一般结构:target……:dependency……command……结构中各部分的含义:(1)、target(目标):一个目标文件,可以是Object文件,也可以是执行文件。
还可以是一个标签(Label)。
(2)、dependency(依赖):要生成目标文件(target)所依赖哪些文件(3)、command(命令):创建项目时需要运行的shell命令(注:命令(command)部分的每行的缩进必须要使用Tab而不能使用多个空格)。
Makefile实际上是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于dependency中的文件,其生成规则定义在命令command中。
如果依赖文件(dependency)中有一个以上的文件比目标(target)文件要新的话,shell命令(command)所定义的命令就会被执行。
这就是Makefile的规则。
也就是Makefile中最核心的内容。
例如,假设有一个C源文件test.c,该源文件包含有自定义的头文件test.h,则目标文件test.o明确依赖于两个源文件:test.c和test.h。
如果只希望利用gcc命令来生成test.o目标文件,这时,就可以利用如下的makefile来定义test.o的创建规则:#This makefile just is a example.test.o:test.c test.hgcc–c test.c从上面的例子注意到,第一个字符为#的行表示注释行。
第一个非注释行指定test.o为目标,并且依赖于test.c和test.h文件。
随后的行指定了如何从目标所依赖的文件建立目标。
当test.c或test.h文件在编译之后又被修改,则make工具可自动重新编译test.o,如果在前后两次编译之间,test.c和test.h均没有被修改,而且test.o还存在的话,就没有必要重新编译。
这种依赖关系在多源文件的程序编译中尤其重要。
通过这种依赖关系的定义,make 工具可避免许多不必要的编译工作。
一个makefile文件中可定义多个目标,利用make target命令可指定要编译的目标,如果不指定目标,则使用第一个目标。
通常,makefile中定义有clean目标,可用来清除编译过程中的中间文件#This makefile just is a example.test.o:test.c test.hgcc-c test.cclean:rm-f*.o运行make clean时,执行rm–f*.o命令,删除编译过程中生成的所有中间文件。
2、Makefile的基本内容Makefile一般包括包含:显式规则、隐晦规则、变量定义、文件指示和注释等五个内容。
(1)、显式规则:显式规则说明如何生成一个或多个的目标文件。
这是由Makefile的书写者明显指出,要生成的文件,文件的依赖文件,生成的命令。
(2)、变量定义。
在Makefile中可以定义一系列的变量,变量一般都是字符串,当Makefile 被执行时,变量的值会被扩展到相应的引用位置上。
(3)、隐含规则:由于GNU make具有自动推导功能,所以隐晦规则可以比较粗糙地简略地书写Makefile,然后由GNU make的自动推导功能完成隐晦规则的内容。
(4)、文件指示。
其包括了三个部分,一个是在一个Makefile中引用另一个Makefile,就像C语言中的include一样;另一个是指根据某些情况指定Makefile中的有效部分,就像C语言中的预编译#if一样;还有就是定义一个多行的命令。
(5)、注释。
Makefile中只有行注释,和UNIX的Shell脚本一样,其注释是用“#”字符,如果你要在你的Makefile中使用“#”字符,可以用反斜框进行转义,如:“\#”。
2.1Makefile中的变量(1)、Makefile中定义的变量,与C/C++语言中的宏一样,代表一个文本字串,在Makefile 被执行时候变量会自动地展开在所使用的地方。
Makefile中的变量可以使用在“目标”,“依赖目标”,“命令”或Makefile的其它部分中。
(2)、Makefile中变量的命名字可以包含字符、数字,下划线(可以是数字开头),但不应该含有“:”、“#”、“=”或是空字符(空格、回车等)。
(3)、Makefile中变量是大小写敏感的,“foo”、“Foo”和“FOO”是三个不同的变量名。
传统的Makefile的变量名是全大写的命名方式(4)、变量在声明时需要给予初值,而在使用时,需要在变量名前加上“$”符号#makefile test for hello program#written by EmdoorCC=gccCFLAGS=OBJS=hello.oall:hellohello:$(OBJS)$(CC)$(CFLAGS)$(OBJS)–o hellohello.o:hello.c$(CC)$(CFLAGS)–c hello.c–o$(OBJS)clean:rm–rf hello*.o上面自定义变量OBJS表示hello.o,当makefile被执行时,变量会在使用它的地方精确地展开,就像C/C++中的宏一样。
上述makfile变量展开后的形式为:#makefile test for hello program#written by EmdoorCC=gccCFLAGS=OBJS=hello.oall:hellohello:hello.ogcc hello.o–o hellohello.o:hello.cgcc–c hello.c–o hello.oclean:rm–rf hello*.oGNU make的主要预定义变量GNU make有许多预定义的变量,这些变量具有特殊的含义,可在规则中使用。
以下给出了一些主要的预定义变量,除这些变量外,GNU make还将所有的环境变量作为自己的预定义变量。
$@——表示规则中的目标文件集。
在模式规则中,如果有多个目标,那么,"$@"就是匹配于目标中模式定义的集合。
$%——仅当目标是函数库文件中,表示规则中的目标成员名。
例如,如果一个目标是"foo.a(bar.o)",那么,"$%"就是"bar.o","$@"就是"foo.a"。
如果目标不是函数库文件(Unix 下是[.a],Windows下是[.lib]),那么,其值为空。
$<——依赖目标中的第一个目标名字。
如果依赖目标是以模式(即"%")定义的,那么"$<"将是符合模式的一系列的文件集。
注意,其是一个一个取出来的。
$?——所有比目标新的依赖目标的集合。
以空格分隔。
$^——所有的依赖目标的集合。
以空格分隔。
如果在依赖目标中有多个重复的,那个这个变量会去除重复的依赖目标,只保留一份。
$+——这个变量很像"$^",也是所有依赖目标的集合。
只是它不去除重复的依赖目标。
命令的变量。
AR函数库打包程序。
默认命令是“ar”。
AS汇编语言编译程序。
默认命令是“as”。
CC C语言编译程序。
默认命令是“cc”。
CXX C++语言编译程序。
默认命令是“g++”。
CO从RCS文件中扩展文件程序。
默认命令是“co”。
CPP C程序的预处理器(输出是标准输出设备)。
默认命令是“$(CC)–E”。
FC Fortran和Ratfor的编译器和预处理程序。
默认命令是“f77”。
GET从SCCS文件中扩展文件的程序。
默认命令是“get”。
LEX Lex方法分析器程序(针对于C或Ratfor)。
默认命令是“lex”。
PC Pascal语言编译程序。
默认命令是“pc”。
YACC Yacc文法分析器(针对于C程序)。
默认命令是“yacc”。
YACCR Yacc文法分析器(针对于Ratfor程序)。
默认命令是“yacc–r”。
MAKEINFO转换Texinfo源文件(.texi)到Info文件程序。
默认命令是“makeinfo”。
TEX从TeX源文件创建TeX DVI文件的程序。
默认命令是“tex”。
TEXI2DVI从Texinfo源文件创建军TeX DVI文件的程序。
默认命令是“texi2dvi”。
WEAVE转换Web到TeX的程序。
默认命令是“weave”。
CWEAVE转换C Web到TeX的程序。
默认命令是“cweave”。
TANGLE转换Web到Pascal语言的程序。
默认命令是“tangle”。
CTANGLE转换C Web到C。
默认命令是“ctangle”。
RM删除文件命令。