Makefile笔记
Makefile笔记
1、Makefile作用以及语法
一个企业级项目,通常会有很多源文件,有时也会按功能、类型、模块分门别类的放在不同的目录中,有时候也会在一个目录里存放了多个程序的源代码。
这时,如何对这些代码的编译就成了个问题。Makefile 就是为这个问题而生的,它定义了一套规则,决定了哪些文件要先编译,哪些文件后编译,哪些文件要重新编译。
整个工程通常只要一个make命令就可以完成编译、链接,甚至更复杂的功能。可以说,任何一个 Linux 源程序都带有一个Makefile 文件。
makefile文件规则如下:
目标(target)…: 依赖(prerequiries)…
<tab>命令(command)
目标(target)通常是要生成的文件的名称,可以是可执行文件或OBJ文件,也可以是一个执行的动作名称,诸如`clean’。
依赖是用来产生目标的材料(比如源文件),一个目标经常有几个依赖。
命令是生成目标时执行的动作,一个规则可以含有几个命令,每个命令占一行。
最简单的Makefile文件如下:
all:test
@echo "hello xjj"
test:
@echo "hello xcc"
makefile可以用来编译c文件,例子如下所示:
---------------------a.c--------------
#include <stdio.h>
#include <stdlib.h>
#include "b.h"
int main(int argc,char **argv)
{
int c;
c=add(1,2);
printf("c = %d\n",c);
return 0;
}
---------------------b.c-----------------
#include "b.h"
int add(int a,int b)
{
return a+b;
}
---------------------b.h------------------
#ifndef _B_H
#define _B_H
int add(int a,int b);
#endif
makefile编写如下:
test : a.c b.c b.h
gcc -o test a.c b.c
clean:
rm *.o test -f
1.1、Makefile中的变量
Makefile中的变量分为三种:简单变量,延时变量,export变量
A := XXX
:A的值定义时就确定为XXXB = XXX
:XXX定义之后B的值才确定下来C ?= XXX
:第一次定义才起效,前面若已经定义,则忽略D += XXX
:追加赋值
例子如下所示:
A := 123
B = $(C)
C = abc
D = ASK
D ?= 100ASK
E = HELLO
E += $(D)
print:
@echo $(A)
@echo $(B)
@echo $(C)
@echo $(D)
@echo $(E)
运行结果如下所示:
1.2、条件语句
关键字如下表所示:
关键字 | 含义 |
---|---|
ifeq | ifeq(p1,p2) p1,p2 是否相等 |
ifneq | ifneq(p1,p2) 判断 p1,p2 是否不相等 |
ifdef | ifdef p1 判断p1是否定义 |
ifndef | ifndef p1 判断p1是否未定义 |
例子如下所示:
flag = 1
eq:
ifeq ($(flag),1)
@echo "flag is 1"
else
@echo "flag is not 1"
endif
neq:
ifneq ($(flag),1)
@echo "flag is not 1"
else
@echo "flag is 1"
endif
def:
ifdef flag
@echo "flag is define"
else
@echo "flag is not define"
endif
ndef:
ifndef flag
@echo "flag is not difine"
else
@echo "flag is define"
endif
2、VCS&VERDI常用编译指令
2.1、常见的编译命令
-v lib_file:lib_file 是 Verilog 文件,包含了引用的 module 的定义,可以是绝对路径,也可以是相对路径。
-y lib_dir:lib_dir 是参考库的目录,vcs 从该目录下寻找包含引用的 module 的 Verilog 文件,这些文件的文件名必须和引用的 module 的名一样。
-f file_list.f:file_list.f是*.v或*.sv文件的目录列表。
-full64:vcs 以 64 位模式编译,生成 64 位的 simv,如果不加这条命令则无法生成 simv。
-R:编译后立即进行仿真。
+v2k:支持 Verilog 2001 标准。
-sverilog:提供对 Systemverilog 的支持。
-l log_file:用于将编译产生的信息放在 log 文件内。
-debug_all:用于产生debug所需的文件。
-Mupdate:源文件有修改时,只重新编译有改动的.v文件,节约编译时间。
-timescale=1ns/1ns 设置仿真精度,可以根据实际需要进行更改。
-kdb:-kdb 选项支持输出 kdb 格式的数据,用于与 Verdi 在交互模式交换数据,而 kdb 格式属于 “Limited Customer Availability” 特性,必须通过 -lca 选项开启。
需注意,在使用VCS & Verdi 联合仿真时,需要在tb文件中加上以下内容:
initial begin
$fsdbDumpfile("*.fsdb");
$fsdbDumpvars(0);
end
2.2、编写脚本
编写.v文件和tb.v文件(.sv文件),之后创建file_list.f文件:
./xxx.v
./xxx_tb.v
file_list.f文件为.v/.sv文件的列表,方便后续用vcs编译和仿真时直接调用,不用一个一个打。
编写Makefile文件:
#-------------------------------------------------------------------------------------------------------
all : clean vcs verdi
#-------------------------------------------------------------------------------------------------------
vcs :
vcs \
-f filelist.f \
-timescale=1ns/1ps \
-full64 -R +vc +v2k -sverilog -debug_access+all\
| tee vcs.log
#-------------------------------------------------------------------------------------------------------
verdi :
verdi -f filelist.f -ssf tb.fsdb &
#-------------------------------------------------------------------------------------------------------
clean :
rm -rf *~ core csrc simv* vc_hdrs.h ucli.key urg* *.log novas.* *.fsdb* verdiLog 64* DVEfiles *.vpd
#-------------------------------------------------------------------------------------------------------
之后运行make all就可以用VCS & Verdi 联合仿真,make vcs后出现如下现象,即代表编译成功。