Makefile的简单使用
led.bin: led.o
arm-linux-ld -Ttext 0x0 -o led.elf $^
arm-linux-objcopy -O binary led.elf led.bin
arm-linux-objdump -D led.elf > led_elf.dis %.o : %.S
arm-linux-gcc -o $@ $< -c %.o : %.c
arm-linux-gcc -o $@ $< -c clean:
rm *.o *.elf *.bin *.dis mkx210 -f
Makefile中的一些基本概念
目标:目标定格写,后面是冒号(冒号后面是依赖)
依赖:依赖是用来产生目标的原材料。
命令:命令前面一定是Tab,不能是定格,也不能说多个空格。命令就是要生成那个目标需要做的动作。
Makefile的基本工作原理
其一,当我们执行 make xx 的时候,Makefile会自动执行xx这个目标下面的命令语句。
其二,当我们make xx的时候,是否执行命令是取决于依赖的。依赖如果成立就会执行命令,否则不执行。
其三,我们直接执行make 和make 第一个目标 效果是一样的。(第一个目标其实就是默认目标)
make 时 默认执行make led.bin make clean 时才会执行
rm *.o *.elf *.bin *.dis mkx210 -f 代码
1、Makefile中定义和使用变量
(1)Makefile中定义和使用变量,和shell脚本中非常相似。不同在于Makefile中$后需要用括号将变量括起来引用。
相似是说:都没有变量类型,直接定义使用,引用变量时用$var
使用变量$(xx)
2、伪目标(.PHONY)
(1)伪目标意思是这个目标本身不代表一个文件,执行这个目标不是为了得到某个文件或东西,而是单纯为了执行这个目标下面的命令。
(2)伪目标一般都没有依赖,因为执行伪目标就是为了执行目标下面的命令。既然一定要执行命令了那就不必加依赖,因为不加依赖意思就是无条件执行。
(3)伪目标可以直接写,不影响使用;但是有时候为了明确声明这个目标是伪目标会在伪目标的前面用.PHONY来明确声明它是伪目标。
3、Makefile中的注释用#
(1)Makefile中注释使用#,和shell一样。
4、命令前面的@用来静默执行
(1)在makefile的命令行中前面的@表示静默执行。
(2)Makefile中默认情况下在执行一行命令前会先把这行命令给打印出来,然后再执行这行命令。
(3)如果你不想看到命令本身,只想看到命令执行就静默执行即可。
5、Makefile中几种变量赋值运算符
(1)= 最简单的赋值
(2):= 一般也是赋值
以上这两个大部分情况下效果是一样的,但是有时候不一样。
用=赋值的变量,在被解析时他的值取决于最后一次赋值时的值,所以你看变量引用的值时不能只往前面看,还要往后面看。
用:=来赋值的,则是就地直接解析,只用往前看即可。
(3)?= 如果变量前面并没有赋值过则执行这条赋值,如果前面已经赋值过了则本行被忽略。(实验可以看出:所谓的没有赋值过其实就是这个变量没有被定义过)
(4)+= 用来给一个已经赋值的变量接续赋值,意思就是把这次的值加到原来的值的后面,有点类似于strcat。(在shell makefile等文件中,可以认为所有变量都是字符串,+=就相当于给字符串stcat接续内容)(注意一个细节,+=续接的内容和原来的内容之间会自动加一个空格隔开)
#=与=: A=abc
B=$(A)def
A=gh
C=abc
D:=$(C)def
C=gh
all:
echo $(B) #ghdef
echo $(D) #abcdef #var="abc"
#var ?="abcd"
#var+="abcd"
## @echo "lalala"
#all:
# @echo $(var)
6、Makefile的环境变量
(1)makefile中用export导出的就是环境变量。一般情况下要求环境变量名用大写,普通变量名用小写。
(2)环境变量和普通变量不同,可以这样理解:环境变量类似于整个工程中所有Makefile之间可以共享的全局变量,而普通变量只是当前本Makefile中使用的局部变量。所以要注意:定义了一个环境变量会影响到工程中别的Makefile文件,因此要小心。
(3)Makefile中可能有一些环境变量可能是makefile本身自己定义的内部的环境变量或者是当前的执行环境提供的环境变量(譬如我们在make执行时给makefile传参。make CC=arm-linux-gcc,其实就是给当前Makefile传了一个环境变量CC,值是arm-linux-gcc。我们在make时给makefile传的环境变量值优先级最高的,可以覆盖makefile中的赋值)。这就好像C语言中编译器预定义的宏__LINE__ __FUNCTION__等一样。
7、Makefile中使用通配符
(1)* 若干个任意字符
(2)? 1个任意字符
(3)[] 将[]中的字符依次去和外面的结合匹配
还有个%,也是通配符,表示任意多个字符,和*很相似,但是%一般只用于规则描述中,又叫做规则通配符。
8、Makefile的自动变量
(1)为什么使用自动变量。在有些情况下文件集合中文件非常多,描述的时候很麻烦,所以我们Makefile就用一些特殊的符号来替代符合某种条件的文件集,这就形成了自动变量。
(2)自动变量的含义:预定义的特殊意义的符号。就类似于C语言编译器中预制的那些宏__FILE__一样。
(3)常见自动变量:
$@ 规则的目标文件名
$< 规则的依赖文件名
$^ 依赖的文件集合
all: .c .c .c test.c
echo ?.c
echo *.c
echo [].c
echo $@
echo $<
echo $^
CC = arm-linux-gcc
LD = arm-linux-ld
OBJCOPY = arm-linux-objcopy
OBJDUMP = arm-linux-objdump
AR = arm-linux-ar INCDIR := $(shell pwd)
# C预处理器的flag,flag就是编译器可选的选项
CPPFLAGS := -nostdlib -nostdinc -I$(INCDIR)/include
# C编译器的flag
CFLAGS := -Wall -O2 -fno-builtin #导出这些变量到全局,其实就是给子文件夹下面的Makefile使用
export CC LD OBJCOPY OBJDUMP AR CPPFLAGS CFLAGS objs := start.o lcd.o clock.o uart.o main.o sdram_init.o
objs += lib/libc.a uart.bin: $(objs)
$(LD) -Tlink.lds -o uart.elf $^
$(OBJCOPY) -O binary uart.elf uart.bin
$(OBJDUMP) -D uart.elf > uart_elf.dis
gcc mkv210_image.c -o mkx210
./mkx210 uart.bin .bin lib/libc.a:
cd lib; make; cd .. %.o : %.S
$(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $< -c %.o : %.c
$(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $< -c clean:
rm *.o *.elf *.bin *.dis mkx210 -f
cd lib; make clean; cd ..
Makefile的简单使用的更多相关文章
- Makefile的简单编写【学习笔记】
首先我们先创建两个简单的文件: main.c #include <stdio.h> extern void hi_fun(); int main() { printf("hell ...
- Ubuntu下makefile的简单使用
在Windows下,只需要简单的点击以下make,rebuild即可.而在Linux下,这样的IDE环境并没有提供,难道必须每一步都执行一遍吗?比较ok的做法自然是能够利用批处理脚本来进行操作了,这样 ...
- Linux系列之makefile的简单入门
什么是makefile呢? 一个工程中的源文件不计其数,其按类型.功能.模块分别放在若干个目录中,makefile定义了一系列的规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译, ...
- Makefile文件简单整理
.PHONY:clean main:hello.o gcc -o main hello.c hello.o:hello.c gcc -c hello.c clean: rm -f hello.o ma ...
- makefile的简单写法
makefile 使用方法: vi 一个Makefile文件 CC = g++ // 指的是用什么编译器RM = rm -rf // 定义一个删除的指令(变量)CFLAGS = -c -Wal ...
- Makefile的简单例子
1.生成test可执行文件,源文件有prog.c prog.h cord.h test:prog.o code.o gcc -o test prog.o code.o prog.o:prog.c pr ...
- vcs+Makefile实现简单的testbench
网络上找的文章,实现了一遍. 步骤如下: 1. 创建verilog代码, 包括8位加法器代码和testbench代码. adder8.v module adder8 ( input clk, inpu ...
- 一步一步写一个简单通用的makefile(三)
上一篇一步一步写一个简单通用的makefile(二) 里面的makefile 实现对通用的代码进行编译,这一章我将会对上一次的makefile 进行进一步的优化. 优化后的makefile: #Hel ...
- Makefile简单编写实例
介绍一下Makefile的简单编写例子. 编写Makefile的规则就是: 目标文件:依赖文件 (tab)编译规则 现在我有一个文件目录结构为: 解释一下这几个文件.首先我创建makefile目录,底 ...
随机推荐
- #pragma pack(n)对齐格式
#pragma pack(n)对齐格式 #pragma pack(n) 是预处理器用来指定对齐格式的指令,表示n对齐.当元素字节小于n时,要扩展到n:若元素字节大于n则占用其实际大小. struct ...
- Some good articles
https://alligator.io/vuejs/introduction-render-functions/ https://alligator.io/vuejs/vue-jwt-pattern ...
- 软件工程第四周作业-PSP
psp表格 类别 内容 开始时间 结束时间 中断时间 delta时间 学习 学习C# 10.6下午7:00 10.6下午8:00 - 60min 写代码 写主函数以及一些小的方法 10.7下午2:00 ...
- Android框架 与 源码结构
一. Android 框架 Android框架层级 : Android 自下 而 上 分为 4层; -- Linux内核层; -- 各种库 和 Android运行环境层; -- 应用框架层; -- 应 ...
- 什么是BCL
原文: 原文:https://www.cnblogs.com/1996V/p/9037603.html 什么是BCL 当你通过VS创建一个项目后,你这个项目就已经引用好了通过.NET下的语言编写好的一 ...
- HashMap get()返回值问题
问题描述:在进行mysql查询必要字段后,需要根据id进行es其它数据字段的查询拼接.使用HashMap以id为key 以查询过来的数据值为value. 代码如下: Map<String,Int ...
- iOS- Exception异常处理
1.Exception 前言 在iOS里对异常的处理及捕获,并没有其它语言里那么常见,相信很多iOS程序员都知道,更多的时候是对内存的的检测与分析,检测相关内存方面的问题. 而在app闪退并不是因为内 ...
- HDU 2124 Repair the Wall
http://acm.hdu.edu.cn/showproblem.php?pid=2124 Problem Description Long time ago , Kitty lived in a ...
- Thinkphp5的使用phpmailer实现发邮件功能(163邮箱)
Thinkphp5本身并没有实现发邮件的功能,至少据我所知. 本文利用网易邮箱作为发邮件的邮箱.作为发送邮件的前提是需要开启SMTP服务,打开网易邮件,点击设置按钮,如下图所示 勾选smtp服务 保存 ...
- 【Linux】- 文件基本属性
Linux系统是一种典型的多用户系统,不同的用户处于不同的地位,拥有不同的权限.为了保护系统的安全性,Linux系统对不同的用户访问同一文件(包括目录文件)的权限做了不同的规定. 在Linux中我们可 ...