当前位置:文档之家› synopsis VCS makefile编写

synopsis VCS makefile编写

synopsis VCS makefile编写
synopsis VCS makefile编写

SYNOPSYS VCS Makefile文件编写与研究

SYNOPSYS VCS Makefile文件编写与研究

这个Makefile是synopsys提供的模板,看上去非常好用,你只要按部就班提供实际项目的参数就可以了。我们来看这个文件的头部说明:

makefile 其实完全可以用csh或其他脚本来编写,只是VCS使用的linux内置的make命令定义了一个标准的仿真脚本,make命令是专门用来

做项目的源文件管理和编译控制的命令。这篇文章重点看synpsys的标准仿真脚本都做了哪些操作,然后使用其他脚本来实现。这里主要是自己

写的一点东西,有些地方是猜测的或者不准确。

#---------------------------------------------------------------------------------------------------------------------------

# SYNOPSYS CONFIDENTIAL - This is an unpublished, proprietary work of

# Synopsys, Inc., and is fully protected under copyright and trade secret

# laws. You may not view, use, disclose, copy, or distribute this file or

# any information contained herein except pursuant to a valid written

# license from Synopsys.

# SYNOPSYS公司的版权声明,没有权限不可使用

#-----------------------------------------------------------------------------------------------------------------------------

# Filename : $Id: Makefile,v 1.0 2006/07/18 23:59:59 vangundy Exp $

# Created by : Synopsys Inc. 07/17/2006

# $Author : vangundy $

# Description : Demonstrates Verilog DUT and SVTB using VCS

# makefile文件头

#---------------------------------------------------------------------------------------------------------------------------

# The Makefile works on two seperate flows. The DEBUG flow is intended to be used # During debugging of a testcase and/or the DUT. The REGRESSION flow is used # During regression runs and collects coverage data.

#该makefile模版包括两部分流程,debug(查错)流程和regress(回归测试)流程,两个

流程大致步骤都相同都是:Compile,SIM(urg,覆盖

#率的分析和采集),debug时主要是跑一个pattern,并dump VPD文件,SIM的同时可以打开DVE视图界面,结束后观察波形,regress主要用

#于采集覆盖率,一般要跑多个pattern,这时就无需dump VPD文件(节约时间),由于是debug 后有进行的重复运行,所以叫regress(回归)。

# 在我们的验证平台中,若不做代码覆盖率的功能,可以不写regress,只要写debug的流程和跑多个pattern的脚本就好了。

#---------------------------------------------------------------------------------------------------------------------

# The DEBUG flow turns on VPD dumping and turns off coverage collection. After # building a testcase using the debug targets, you can debug the TB and the DUT # source code using the testbench debugger and DVE. Of course, you can turn on # coverage metrics and run in debug mode by changing compile and runtime options # in the makefile. These changes are independent of the regression flow so that # the regressions will still run optimally without the interference of VPD dumping. # debug流程打开VPD文件的dump并关闭覆盖率在build了一个包含DUT的testcase后,可以使用VCS的debugger和DVE进行debug。当

# 然,你也以通过改变makefile文件中的compile和runtime选项参数来开启覆盖率功能。Debug流程和regress流程是各自独立的,regression

# 流程一般不生成VPD。

#

--------------------------------------------------------------------------------------------------------------------------------

# The REGRESSION flow turns off VPD dumping and turns on Coverage Metrics and TB # coverage collection. This flow is intended to support verification engineers who # are working through the regression process and are interested in coverage

# collection and urg.

# REGRESSION流程关闭VPD dump并打开Coverage collection功能,该流程是为了支持验证引擎进行“流水线验证“(跑多个testcase)和

# 代码覆盖率功能。??在验证平台中可以将运行多个testcase的脚本命名为regress,运行单个testcase的脚本命名为regone??,这只是

# synopsys的模版,我们不必完全遵守,可以不区分debug和regress,然后将是否打开波形和coverage设置成参数。

#

-------------------------------------------------------------------------------------------------------------------------------

# Command Line make命令行

# -----------------

# The Makefile supports the following command line

# makefile支持下列命令行

# % make target_name_*

# makefile文件放在哪?放在仿真路径。make [-f makefile文件名][选项][宏定义][目标] # -f 指定makefile 若没有则make程序首先在当前目录查找名为makefile的文件,如果没有找到,它就会转而查找名为Makefile的文件。

# Where target_name is the name of a testcase located in the test directory. Every # test in the test directory is named using test_{test_name}. All of the test targets

# are listed in the TEST TARGETS section of the makefile.

# target_name是test路径下的一个testcase的名字,test路径下的testcase的名字使用test_{test_name}来命名,例如test_1

# 所有的test target 都在makefile文件中的TEST TARGETS部分列出

#

---------------------------------------------------------------------------------------------------------------------------

# Compile and Run Testcases 编译与运行testcase

# -------------------------------

# To compile and run a tescase use the test_* and regress_test_* targets.

# 编译与运行testcase,(test_1 就是执行了下面的两个命令先编译在运行)test_1 ==> compile_1 run_1 详见下面命令定义

# % make test_1 // Builds and runs test 1 with VPD dumping 其实就是debug的前边的流程

# % make regress_test_1 // Builds and runs test 1 with coverage turned on

# -------------------------------------------------------------------------------------------------------------------------

# Debugging Testcases Debug 实在上面命令之后在进行的

# ------------------------

# You can use DVE and the testbench debugger to visualize waveforms and testbench # execution. You must first build the testbench using the make compile_* command. # dubug必须是在DVE(VCS的debug工具,与debussy一样的功能)下进行,因为要看波形嘛,但是debug之前必须先compile

# % make compile_1 // Builds test 1 for debugging //需要重新编译一次吗?# Once you have built the environment with the proper debug switches, you can use DVE and the testbench debugger.

# # testbench debugger 是否是指编译后的那个simv可执行文件呢?其实gui_1 和上面test_1中的run_1是一样的只是增加了-gui项

# 即增加了打开gui界面的参数,其他雷同

# % make gui_1 // Debug test 1 with DVE

# % make tb_gui_1 // Debug test 1 with the testbench debugger

# % make both_guis_1 // Debug using both guis

# % make pp_1 // Debug using the VPD file VPD文件要在执行simv之后才有吧?

# If you want, you can turn on coverage for the DEBUG flow by uncommenting the # coverage flag in the makefile. If you do this, you can still look at coverage. # This may be useful in helping those who are debugging coverage related issues. # 如果在makefile中的debug流程中使用了coverage功能,那么可以使用下面命令观察覆盖率

# % make urg // Visualize coverage data from debug runs

# -----------------------------------------------------------------------------------------------------------------------------

# Regression Testcases

# --------------------

# Regression tests are used to collect coverage information. To build a testcase # for coverage collection use a command similar to the following.

# regress流程主要是为了收集代码覆盖率信息,在执行regress之前需要重新build testcase 类似debug时的compile

# % make regress_build_1 // Build and run a regression test with a default seed

# Once the test has been built, you can run it again with a new seed.

# 与debug不同的是regress需要重新run(使用新的SEED)一下,【还是debug的时候也要run一下?】

# % make regress_run_1 SEED=1234

# After running one or more regression runs, you can visualize the coverage data # using urg and the following command

# run完之后可以用下面命令看代码覆盖率

# % make regress_urg

#----------------------------------------------------------------------------------------------------------------------------

# HOW TO REUSE THIS FILE ON ANOTHER DUT //如何重用该模版

# STEP 1: Update the file locations as required //设置file所属的路径

# STEP 2: Update the DUT section with directory and source location info//更新模版中DUT部分,指定DUT的路径和include的路径

# STEP 3: Update the TB section with directory and source location info//更新模版中TB部分,指定TB的路径和include的路径

# STEP 4: Update the Coverage section with name of dut top (eg top.dut) //跟新模版中Coverage部分,指定要测试代码覆盖率的dut的top

# STEP 5: Add test targets to the debug and regression targets section//将debug

和regress的target加入模版中对应的部分

# STEP 5: Adjust the debug and regression compile and run time arguments//调整debug 和regress的compile和runtime的命令参数

# STEP 7: Adjust command line options as required//调整命令行命令(后边带百分号和冒号的就表示可以在make命令行中使用的命令)

# STEP 8: Update the env class so that it extends dkm_env//更新env class(环境类)使得它可以提供dkm_env

# You will need to have a copy of the dkm directory and it should //dkm是什么?# be located at $(TB_SRC_DIR)/dkm

# a) Add [`include "dkm_env.sv"]

# b) Add [extends dkm_env] to the environment class definition

# c) Call the super.new("name") from the constructor

# STEP 9: Run the debug and regression targets

# % make testbench_target_* // testbench_target_* 是指test_1之类的

testcase

#-----------------------------------------------------------------------------

看了上文,大家应该可以简单了解这个Makefile的功能了。接下来就按照step1~9来填空即可:

.PHONY : default help clean regress_clean

default: help

#-----------------------------------------------------------------------------

# DIRECTORIES 总路径

#----------------------------------------------------------------------------- OUTPUT_DIR = ./output //为什么debug和regress没有分开? debug和regress 的Coverage在COV_DIR下是有区分的

COV_DIR = ./coverage //为什么没有VPD的路径?

LOG_DIR = ./logs //output是做什么的? VPD文件 simv文件还有一写其他文件在这里

# Set this to the location where you installed the designware models. This

# depends on whether you ran the setup_vip_dw_home to install the models or

# the setup_vip_here script.

#DW_MODELS_DIR = $(DESIGNWARE_HOME)

DW_MODELS_DIR = /user/synopsys/designware //软件路径 VCS的路径?

#DESIGNWARE_HOME = ~synopsys/bk/designware

#DW_MODELS_DIR = ./designware

#----------------------------------------------------------------------------

# DEVICE UNDER TEST DUT路径

#----------------------------------------------------------------------------- DUT_SRC_DIR = ./source/Verilog //SRC source

DUT_SRC = -f $(DUT_SRC_DIR)/rtl_list.f //待编译的rtl文件列表文件 SRC 是什么意思?

DUT_INC += +incdir+/user/myproj/PROJECT/RTL/SRC/mymodule/

DUT_INC += +incdir+/user/myproj/PROJECT/RTL/SRC/mymodule/mymodule_inc.v

DUT_CMP_OPTIONS += +libext+.v+.V //这个参数是干什么的?指定VCS搜索文件时的文件后缀.v

#DUT_CMP_OPTIONS += -timescale=1ps/1ps //CMP是compile的意思不是compare

#DUT_CMP_OPTIONS += -override_timescale=1ps/1ps

#-----------------------------------------------------------------------------

# TESTBENCH TB路径设置

#-----------------------------------------------------------------------------

TB_SRC_DIR = ./source/svtb

# AXI TESTBENCH, VIP Sources first

#TB_SRC += -f $(TB_SRC_DIR)/mac_if_tb/vip/gslv_model_package.f

TB_SRC += $(TB_SRC_DIR)/mpdu_trx_tb/tests/mpdu_tb_top.sv

TB_SRC += $(TB_SRC_DIR)/mpdu_trx_tb/tests/$(TB_TEST).sv //为什么有两个SV

TB_INC += +incdir+$(TB_SRC_DIR)/mpdu_trx_tb/vip

TB_INC += +incdir+$(TB_SRC_DIR)/mpdu_trx_tb/env

TB_INC += +incdir+$(TB_SRC_DIR)/mpdu_trx_tb/tests

TB_INC += +incdir+$(DW_MODELS_DIR)/include/svtb //这部分为了支持sv吗?TB_INC += +incdir+$(DW_MODELS_DIR)/include/verilog

TB_INC += +incdir+$(DW_MODELS_DIR)/svtb

#TB_CMP_OPTIONS += -tb_timescale=1ns/1ps

#TB_CMP_OPTIONS += -lca Y-2006.06-SP2

TB_CMP_OPTIONS += +pkgdir+$(DW_MODELS_DIR)/include/svtb //TB的编译选项和DUT不同?sv 和verilog的区别吗?

TB_CMP_OPTIONS += -ntb_incdir $(DW_MODELS_DIR)/include/vera

TB_CMP_OPTIONS += -ntb_incdir $(DESIGNWARE_HOME)/vip/vmt/latest/vera/src

TB_CMP_OPTIONS += -ntb_incdir $(DESIGNWARE_HOME)/vip/amba/latest/vera/src

TB_CMP_OPTIONS += -ntb_incdir

$(DESIGNWARE_HOME)/vip/amba/latest/axi_master_vmt/vera/src //TB中使用的一些模型TB_CMP_OPTIONS += -ntb_incdir

$(DESIGNWARE_HOME)/vip/amba/latest/axi_master_rvm_vera_vmt/vera/src

TB_CMP_OPTIONS += -ntb_incdir

$(DESIGNWARE_HOME)/vip/amba/latest/axi_slave_vmt/vera/src

TB_CMP_OPTIONS += -ntb_incdir

$(DESIGNWARE_HOME)/vip/amba/latest/axi_slave_rvm_vera_vmt/vera/src

TB_CMP_OPTIONS += -ntb_incdir

$(DESIGNWARE_HOME)/vip/amba/latest/axi_monitor_vmt/vera/src

TB_CMP_OPTIONS += -ntb_incdir

$(DESIGNWARE_HOME)/vip/amba/latest/axi_monitor_rvm_vera_vmt/vera/src

TB_CMP_OPTIONS += -ntb_incdir

$(DESIGNWARE_HOME)/vip/amba/latest/axi_port_monitor_vmt/vera/src

TB_CMP_OPTIONS += -ntb_incdir

$(DESIGNWARE_HOME)/vip/amba/latest/axi_port_monitor_rvm_vera_vmt/vera/src TB_CMP_OPTIONS += -ntb_incdir

$(DESIGNWARE_HOME)/vip/amba/latest/axi_interconnect_vmt/vera/src

TB_CMP_OPTIONS += -ntb_incdir

$(DESIGNWARE_HOME)/vip/amba/latest/axi_interconnect_rvm_vera_vmt/vera/src TB_CMP_OPTIONS += -ntb_incdir

${DESIGNWARE_HOME}/vip/amba/latest/ahb_master_vmt/vera/src

TB_CMP_OPTIONS += -ntb_incdir

${DESIGNWARE_HOME}/vip/amba/latest/ahb_slave_vmt/vera/src

TB_CMP_OPTIONS += -ntb_incdir

${DESIGNWARE_HOME}/vip/amba/latest/ahb_monitor_vmt/vera/src

TB_CMP_OPTIONS += -ntb_incdir

${DESIGNWARE_HOME}/vip/amba/latest/ahb_bus_vmt/vera/src

TB_CMP_OPTIONS += -ntb_incdir

${DESIGNWARE_HOME}/vip/amba/latest/ahb_master_rvm_vera_vmt/vera/src

TB_CMP_OPTIONS += -ntb_incdir

${DESIGNWARE_HOME}/vip/amba/latest/ahb_slave_rvm_vera_vmt/vera/src

TB_CMP_OPTIONS += -ntb_incdir

${DESIGNWARE_HOME}/vip/amba/latest/ahb_monitor_rvm_vera_vmt/vera/src

TB_CMP_OPTIONS += -ntb_incdir

${DESIGNWARE_HOME}/vip/amba/latest/ahb_bus_rvm_vera_vmt/vera/src

TB_CMP_OPTIONS += -ntb_define NTB

TB_CMP_OPTIONS += -ntb_define DW_VIP_AXI_MAX_NO_MSTRS=6

TB_CMP_OPTIONS += -ntb_define DW_VIP_AXI_MAX_NO_SLVS=2

TB_CMP_OPTIONS += +define+DW_VIP_AXI_MAX_NO_MSTRS_6

TB_CMP_OPTIONS += +define+DW_VIP_AXI_MAX_NO_SLVS_2

TB_CMP_OPTIONS += -ntb_opts rvm

TB_CMP_OPTIONS += -ntb_opts dtm

TB_CMP_OPTIONS += -ntb_opts use_sigprop

TB_CMP_OPTIONS += -ntb_opts interop

TB_CMP_OPTIONS += -ntb_opts dw_vip

TB_CMP_OPTIONS += +define+NT

# AIP Related files and compilation options

#TB_CMP_OPTIONS += +incdir+../BP062-BU-01000-r0p0-00rel0/sva \

+incdir+../BP062-BU-01000-r0p0-00rel0/verilog \

../BP062-BU-01000-r0p0-00rel0/sva/AxiPC.sv \

../BP062-BU-01000-r0p0-00rel0/verilog/Axi.v \

./source/svtb/platform_tb/env/Snps_ARMAXI_CheckerBind.sv

#${VCS_HOME}/packages/aip/DDR2_AIP/src/Snps_DDR2_Checker.sv \

-assert enable_diag \

+incdir+.+${VCS_HOME}/packages/aip/DDR2_AIP/src/ \

./source/svtb/platform_tb/env/Snps_DDR2_Bind.sv \

+incdir+../BP062-BU-01000-r0p0-00rel0/sva \

+incdir+../BP062-BU-01000-r0p0-00rel0/verilog \

../BP062-BU-01000-r0p0-00rel0/sva/AxiPC.sv \

../BP062-BU-01000-r0p0-00rel0/verilog/Axi.v \

./source/svtb/platform_tb/env/Snps_ARMAXI_CheckerBind.sv

#----------------------------------------------------------------------------- # COVERAGE 覆盖率的设置

#----------------------------------------------------------------------------- COV_TREE += '+tree mpdu_tb_top'

COV_CM_OPTIONS += -cm line+cond+fsm+assert 注意CM和CMP不一样

#----------------------------------------------------------------------------- # TEST TARGETS 总命令

#----------------------------------------------------------------------------- # debug targets

test_1: compile_1 run_1 与前边对应test_1 就是debug流程(debug还可以将run_1 换成 gui_1);regress_test_1就是regress流程

test_11: compile_11 run_11

test_12: compile_12 run_12

test_13: compile_13 run_13

test_14: compile_14 run_14

test_2: compile_2 run_2

test_perf: compile_perf run_perf

# regression targets

regress_test_1: regress_build_1 regress_run_1

regress_test_11: regress_build_11 regress_run_11

regress_test_12: regress_build_12 regress_run_12

regress_test_13: regress_build_13 regress_run_13

regress_test_14: regress_build_14 regress_run_14

regress_test_2: regress_build_2 regress_run_2

regress_test_perf: regress_build_perf regress_run_perf

#-----------------------------------------------------------------------------

# COMPILE AND RUN TIME ARGUMENTS 编译与运行时的参数设置(run和sim可以看成一个意思,run就是run simv)

#-----------------------------------------------------------------------------

# Debug compile time arguments

DBG_CMP += $(COV_CMP_OPTIONS) //debug 编译的参数

DBG_CMP += -debug_all //使能DVE debugging (包括 line stepping)

//DBG_CMP += -debug_pp //使能VPD dump 和assertion debug

DBG_CMP += +define+VPD_ON //debug compile的时候定义一个VPD_ON 的宏,注意VPD是SIM时生成的

#DBG_CMP += +define+VPD_OFF //若CMP时参数把VPD关了,但是在SIM 时输出一个VPD会怎么样?

#DBG_CMP += +define+LOG_FMT_OFF //应该是这样,在verilog代码中将VPD dump的代码写在 ifdefine VPD_ON 后面

# Debug run time arguments

DBG_RUN += $(COV_SIM_OPTIONS) //COV_SIM_OPTION 和 COV_CMP_OPTION的区别

# Regression compile time arguments

REG_CMP += $(COV_CMP_OPTIONS)

REG_CMP += +define+VPD_OFF //regress compile的时候定义了

VPD_OFF,debug和regress的区别其实主要就是这,

//因为debug时也可以做urg,所以在CMP 和SIM参数中关于覆盖率实际上是一致的

# Regression run time arguments //注意在debug和regress各自的流程中urg命令(make 命令行命令)是不同的

REG_RUN += $(COV_SIM_OPTIONS)

# Define where the coverage data is for URG //覆盖率数据,这个是给后边urg命令用的,产生覆盖率实在CMP和SIM之后进行的

COV_DBG_DATA += -dir $(COV_DIR)/debug/simv.vdb -dir $(COV_DIR)/debug/simv.cm COV_REG_DATA += -dir $(COV_DIR)/regress/simv.vdb

-dir $(COV_DIR)/debug/simv.cm

#-----------------------------------------------------------------------------

# COMMAND LINE ARGUMENTS make命令行参数

#----------------------------------------------------------------------------- SEED = 766

#234567

#DEFINES = "+rvm_log_default=DEBUG"

DEFINES = "+vmm_log_default=DEBUG"

#DEFINES = "+vmm_log_default=NOTE"

#DEFINES = "+rvm_log_default=WARNING"

#DEFINES = "+vmm_log_default=ERROR"

##############################################################################

##############################################################################

# PRIVATE //私有部分,用户可以不改

# You should not need to modify anything below this point

# The following code supports a SV DUT and SVTB.

##############################################################################

############################################################################## DIR = $(/user/synopsys/Gaon/Platform)

##########################################################################

# DEVICE UNDER TEST DUT CMP和SIM参数设置,之前已经设置过debug和regress在Compile 时的参数

##########################################################################

DUT_CMP_OPTIONS += -sverilog +v2k

DUT_CMP_OPTIONS += -o $(DUT_SIM_EXEC)

DUT_CMP_OPTIONS += -Mdir=$(OUTPUT_DIR)/$(TB_TEST_ID)_csrc

DUT_CMP_OPTIONS += -l $(LOG_DIR)/$(TB_TEST).cmp_log

DUT_CMP_OPTIONS += +vcs+lic+wait +plusarg_save

DUT_CMP_OPTIONS += $(DUT_INC)

DUT_SIM_OPTIONS += -l $(LOG_DIR)/$(TB_TEST_ID).run_log

DUT_SIM_OPTIONS += +vcs+lic+wait

DUT_SIM_OPTIONS += +vpdfile+$(OUTPUT_DIR)/$(TB_TEST_ID).vpd

//vpd实在执行sim后生成的,但是在debugcompile的时候为什么有个vdp_on的参数呢?

#DUT_SIM_OPTIONS += +ntb_random_seed=$(SEED)

DUT_SIM_OPTIONS += +ntb_random_seed_automatic

DUT_SIM_OPTIONS += -assert nopostproc+report=$(LOG_DIR)/$(TB_TEST_ID).sva_log DUT_SIM_OPTIONS += -cm_assert_name $(TB_TEST_ID)

DUT_SIM_OPTIONS += $(DEFINES)

DUT_SIM_EXEC += $(OUTPUT_DIR)/$(TB_TEST)_simv

# TESTBENCH TB CMP和SIM参数设置,之前已经设置过debug和regress在Compile时的参数

##########################################################################

TB_TEST += test_$* //$*是什么意思,$* :去掉后缀的当前目标名(?)。例如,若当前目标是pro.o,则$*表示pro。

TB_TEST_ID += $(TB_TEST)_$(SEED)

# VK ENVIRONMENT

TB_INC += +incdir+$(TB_SRC_DIR)/vk

TB_CMP_OPTIONS += $(TB_INC)

##########################################################################

# COVERAGE 覆盖率设置

##########################################################################

#COV_CM_OPTIONS += +tb_cov_db_name=$(TB_TEST_ID)

COV_CM_OPTIONS += -cm_name $(TB_TEST_ID)

COV_CMP_OPTIONS += $(COV_CM_OPTIONS) -cm_hier $(COV_HIER)

COV_SIM_OPTIONS += $(COV_CM_OPTIONS)

COV_SIM_OPTIONS += -cm_log $(LOG_DIR)/$(TB_TEST_ID).cm_log

COV_HIER += $(OUTPUT_DIR)/vcm.cfg

# Coverage options for build and run with debug

COV_CM_DBG += -cm_dir $(COV_DIR)/debug/simv.cm

#COV_CM_DBG += -ova_dir $(COV_DIR)/debug/simv.vdb

#COV_CM_DBG += +tb_cov_db_dir=$(COV_DIR)/debug/simv.vdb

# Coverage options for build and run with regressions

COV_CM_REG += -cm_dir $(COV_DIR)/regress/simv.cm

COV_CM_REG += -ova_dir $(COV_DIR)/regress/simv.vdb

COV_CM_REG += +tb_cov_db_dir=$(COV_DIR)/regress/simv.vdb

##########################################################################

# DEBUG TARGETS

compile_%:

echo $(COV_TREE) > $(COV_HIER); //debug 编译时主要有下面几个参

数 TB_CMP DUT_CMP DBG_CMP COV_CM_DBG

vcs $(TB_CMP_OPTIONS) \ //请详细查看上面几个变量的设置

$(DUT_CMP_OPTIONS) \

$(DUT_SRC) \

$(TB_SRC) \

$(SVA_SRC) \

$(SVA_OPTIONS) \

$(COV_CM_DBG) \

$(DBG_CMP)

run_%:

$(DUT_SIM_EXEC) $(DUT_SIM_OPTIONS) $(DBG_RUN) $(COV_CM_DBG)

//run 是上面说的test_1中的第二步,属于debug流程,其实就是执行simv,参数有DUT_SIM 和DBG_RUN

//注意TB在run(sim)时没有相关参数

gui_%: //gui_1和run_1的区别就是打开了视图界面,他们都是执行sim

$(DUT_SIM_EXEC) $(DUT_SIM_OPTIONS) $(DBG_RUN) $(COV_CM_DBG) \

-gui

tb_gui_%: //-tb_gui 和-gui的区别是什么(上文提到DVE和testbenchdebugeer的含义),猜测-gui是打开DVE软件,-tb_gui就不知道是神马

$(DUT_SIM_EXEC) $(DUT_SIM_OPTIONS) $(DBG_RUN) $(COV_CM_DBG) \

-tb_gui +ntb_debug_on_start

both_guis_%:

$(DUT_SIM_EXEC) $(DUT_SIM_OPTIONS) $(DBG_RUN) $(COV_CM_DBG) \

-gui \

-tb_gui +ntb_debug_on_start

new_gui_%: //打开一个新的 DVE软件窗口?

$(DUT_SIM_EXEC) $(DUT_SIM_OPTIONS) $(DBG_RUN) $(COV_CM_DBG) \

-gui \

-tbug

pp_%: //这个命令应该就是打开VPD波形

dve -vpd $(OUTPUT_DIR)/$(TB_TEST_ID).vpd

urg: //执行代码覆盖率操作?代码覆盖律不是在sim的时候产生的吗(在CMP和SIM的时候都有COV的参数啊)?这个要具体查一下

urg $(COV_DBG_DATA) -report $(COV_DIR)/debug/urgReport -lca

mozilla $(DIR)/$(COV_DIR)/debug/urgReport/dashboard.html &

dve_cov: //该命令应该是使用DVE软件查看coverage结果

@echo ""

@echo "WARNING: Did you run this command?"

@echo ""

@echo " % source ./utils/setup_dve_cov"

@echo ""

dve -cov &

##########################################################################

# REGRESSION TARGETS

########################################################################## regress_clean: clean

@rm -rf $(COV_DIR)/*

@mkdir -p $(COV_DIR)/debug //怎么把debug的路径也给删除了?

@mkdir -p $(COV_DIR)/regress

@mkdir -p $(LOG_DIR)

@mkdir -p $(OUTPUT_DIR)

regress_build_%: //regress compile 的时候就$(REG_CMP)和debug不同仔细检查两者的差异

echo $(COV_TREE) > $(COV_HIER);

vcs $(TB_CMP_OPTIONS) $(DUT_CMP_OPTIONS) \

$(DUT_SRC) \

$(TB_SRC) \

$(SVA_SRC) \

$(SVA_OPTIONS) \

$(COV_CM_REG) \

$(REG_CMP)

regress_run_%: //观察各参数和debug流程的有什么差异

$(DUT_SIM_EXEC) $(DUT_SIM_OPTIONS) $(REG_RUN) $(COV_CM_REG)

regress_urg: //看来VPD是SIM时产生的,但是覆盖率不是SIM时产生的,可能因为覆盖律要跑多个case才有意义

urg $(COV_REG_DATA) -grade -report $(COV_DIR)/regress/urgReport

mozilla $(DIR)/$(COV_DIR)/regress/urgReport/dashboard.html &

regress_dve_cov:

@echo ""

@echo "WARNING: Did you run this command?"

@echo ""

@echo " % source ./utils/setup_dve_cov"

@echo ""

dve -cov &

# 综上,debug和regress流程类似,都是四步,compile,sim,urg,dve_cov

##########################################################################

# ADMINISTRATIVE 管理命令

##########################################################################

help:

@echo ======================================================================= @echo " "

@echo " USAGE: %make target_name_* " @echo " "

@echo " ------------------------ DEBUG TARGETS ----------------------------" @echo " test_* => Compile TB and DUT files, runs the simulation. " @echo " clean => Clean the intermediate files. "

@echo " compile_* => Compile the TB and DUT. "

@echo " run_* => Run the simulation. " @echo " gui_* => Run simulation interactively with DVE. "

@echo " tb_gui_* => Runs simulation interactively with TB Debugger. " @echo " both_guis_* => Run both debuggers. " @echo " new_gui_* => Run new integrated debuggers. "

@echo " pp_* => Post process VPD with DVE. "

@echo " urg => Make a coverage report for debug runs. "

@echo " dve_cov => Brings up DVE for coverage reporting. " @echo " " @echo " ----------------------- REGRESSION TARGETS ------------------------" @echo " regress_test_* => Compile and run with coverage. " @echo " regress_clean => Remove all coverage files. "

@echo " regress_build_* => Build test_*. " @echo " regress_run_* => Run test * collecting coverage information. " @echo " regress_urg => Make a coverage report for regression runs. " @echo " regress_dve_cov => Brings up DVE for coverage reporting. " @echo " " @echo " -------------------- ADMINISTRATIVE TARGETS -----------------------" @echo " help => Displays this message. " @echo " init => Clean all files, including coverage files. "

@echo " tar => Tar and zip kit and place at ../ " @echo " "

@echo " e.g. gmake test_1 " @echo =======================================================================

tar: clean

cd ..; \

tar cvf ${DIR}.tar ${DIR}; \

rm -f ${DIR}.tgz; \

gzip ${DIR}.tar; \

mv ${DIR}.tar.gz ${DIR}.tgz

clean:

@rm -rf $(OUTPUT_DIR)/* $(COV_DIR)/debug/* $(LOG_DIR)/* ./DVEfiles

@rm -rf urgReport *.tcl *.tcl.old vc_hdrs.h testbench_debugger_rc

@rm -rf ucli.key vcs.key vera_debugger_rc .vera_debugger_rc.lock

@rm -rf .test* .vlog* .dummyDir *.db *.vdb verilog.dump

@rm -rf ._* .dw* *.log

init: regress_clean

@rm -rf include

@rm -rf examples

总结:

经过研究,首先使用VCS验证的流程是:

1.对各个源文件(包括DUT和TB)进行编译,生成可执行文件(默认名字为simv)

2.执行simv文件进行仿真,这时会将testcase的仿真结果输出,包括VPD(若开启了VPD

dumpping)文件等输出文件

3.若进行代码覆盖率检查,在simv后可以使用urg命令收集覆盖率信息(须跑多个case)Makefile 完成的功能是:

1.对源文件的管理:主要是将DUT文件和TB文件以及一些必要的文件的路径写入变量

($DUT_SRC_DIR $TB_SRC_DIR等),还有include的路径(供VCS搜索)。在使用VCS命令进行编译时,可以将该路径加入命令中。我们可以使用脚本将需要编译的文件输出为一个file_list.f文件,然后用vcs –f file_list.f 进行编译。

2.对路径的管理:将源文件路径和输出文件路径写入各自的变量,一遍在后边使用vcs命令

时调用。

3.对VCS命令参数的调整:这部分是重要的步骤,根据需要的不同(debug和regress的需要

就不相同),参数设置也有不同,但有一些参数是不管怎样的流程都需要的,在我们的验证平台中,我们可以将参数分为两部分,一部分是都需要的可以公用的,一部分是可以灵活使用的,可以更改的。

4.对VCS命令的调整:这部分就是将VCS的几个主要命令(其实就是VCS 和 SIMV)加上对

应的参数设置。我们的验证平台可以将不同的命令写成不同的脚本,然后写一个总的脚本进行调用。

5.其实需要灵活配置的主要就是VPD文件和覆盖率的设置(VPD 在rtl级实际上应该每次都

生成)

跟我一起写Makefile

跟我一起写Makefile 陈皓 1 概述 什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一个好的和professional的程序员,makefile还是要懂。这就好像现在有这么多的HTML的编辑器,但如果你想成为一个专业人士,你还是要了解HTML的标识的含义。特别在Unix下的软件编译,你就不能不自己写makefile了,会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。 因为,makefile关系到了整个工程的编译规则。一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。 makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。 现在讲述如何写makefile的文章比较少,这是我想写这篇文章的原因。当然,不同产商的make各不相同,也有不同的语法,但其本质都是在“文件依赖性”上做文章,这里,我仅对GNU的make进行讲述,我的环境是RedHat Linux 8.0,make的版本是3.80。必竟,这个make是应用最为广泛的,也是用得最多的。而且其还是最遵循于IEEE 1003.2-1992 标准的(POSIX.2)。 在这篇文档中,将以C/C++的源码作为我们基础,所以必然涉及一些关于C/C++的编译的知识,相关于这方面的内容,还请各位查看相关的编译器的文档。这里所默认的编译器是UNIX下的GCC和CC。 2 关于程序的编译和链接 在此,我想多说关于程序编译的一些规范和方法,一般来说,无论是C、C++、还是pas,首先要把源文件编译成中间代码文件,在Windows下也就是.obj 文件,UNIX下是.o 文件,即Object File,这个动作叫做编译(compile)。然后再把大量的Object File合成执行文件,这个动作叫作链接(link)。 编译时,编译器需要的是语法的正确,函数与变量的声明的正确。对于后者,通常是你需要告诉编译器头文件的所在位置(头文件中应该只是声明,而定义应该放在C/C++文件中),只要所有的语法正确,编译器就可以编译出中间目标文件。一般来说,每个源文件都应该对应于一个中间目标文件(O文件或是OBJ 文件)。 链接时,主要是链接函数和全局变量,所以,我们可以使用这些中间目标文件(O文件或是OBJ文件)来链接我们的应用程序。链接器并不管函数所在的源文件,只管函数的中间目标文件(Object File),在大多数时候,由于源文件太多,编译生成的中间目标文件太多,而在链接时需要明显地指出中间目标文件名,这对于编译很不方便,所以,我们要给中间目标文件打个包,在Windows下这种包叫“库文件”(Library File),也就是.lib 文件,在UNIX下,是Archive File,也就是.a 文件。 总结一下,源文件首先会生成中间目标文件,再由中间目标文件生成执行文件。在编译时,编译器只检测程序语法,和函数、变量是否被声明。如果函数未被声明,编译器会给出一个警告,但可以生成Object File。而在链接程序时,链接器会在所有的Object File中找寻函数的实现,如果找不到,那到就会报链接错

手动建立makefile简单实例解析

手动建立makefile简单实例解析 假设我们有一个程序由5个文件组成,源代码如下:/*main.c*/ #include "mytool1.h" #include "mytool2.h" int main() { mytool1_print("hello mytool1!"); mytool2_print("hello mytool2!"); return 0; } /*mytool1.c*/ #include "mytool1.h" #include void mytool1_print(char *print_str) { printf("This is mytool1 print : %s ",print_str); } /*mytool1.h*/ #ifndef _MYTOOL_1_H #define _MYTOOL_1_H void mytool1_print(char *print_str); #endif /*mytool2.c*/ #include "mytool2.h" #include void mytool2_print(char *print_str) { printf("This is mytool2 print : %s ",print_str); }

/*mytool2.h*/ #ifndef _MYTOOL_2_H #define _MYTOOL_2_H void mytool2_print(char *print_str); #endif 首先了解一下make和Makefile。GNU make是一个工程管理器,它可以管理较多的文件。我所使用的RedHat 9.0的make版本为GNU Make version 3.79.1。使用make的最大好处就是实现了“自动化编译”。如果有一个上百个文件的代码构成的项目,其中一个或者几个文件进行了修改,make就能够自动识别更新了的文件代码,不需要输入冗长的命令行就可以完成最后的编译工作。make执行时,自动寻找Makefile(makefile)文件,然后执行编译工作。所以我们需要编写Makefile文件,这样可以提高实际项目的工作效率。 在一个Makefile中通常包含下面内容: 1、需要由make工具创建的目标体(target),通常是目标文件或可执行文件。 2、要创建的目标体所依赖的文件(dependency_file)。 3、创建每个目标体时需要运行的命令(command)。 格式如下: target:dependency_files command target:规则的目标。通常是程序中间或者最后需要生成的文件名,可以是.o文件、也可以是最后的可执行程序的文件名。另外,目标也可以是一个make执行的动作的名称,如目标“clean”,这样的目标称为“伪目标”。 dependency_files:规则的依赖。生成规则目标所需要的文件名列表。通常一个目标依赖于一个或者多个文件。 command:规则的命令行。是make程序所有执行的动作(任意的shell命令或者可在shell下执行的程序)。一个规则可以有多个命令行,每一条命令占一行。注意:每一个命令行必须以[Tab]字符开始,[Tab]字符告诉make此行是一个命令行。make按照命令完成相应的动作。这也是书写Makefile中容易产生,而且比较隐蔽的错误。命令就是在任何一个目标的依赖文件发生变化后重建目标的动作描述。一个目标可以没有依赖而只有动作(指定的命令)。比如Makefile中的目标“clean”,此目标没有依赖,只有命令。它所指定的命令用来删除make过程产生的中间文件(清理工作)。 在Makefile中“规则”就是描述在什么情况下、如何重建规则的目标文件,通常规则

Makefile下编写Helloworld的例子

什么是makefile?或许很多Windows的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得 要作一个好的和professional的程序员,makefile还是要懂。这就好像现在有这么多的HTML的编辑器,但如果你想成为一个专 业人士,你还是要了解HTML的标识的含义。特别在Unix下的软件编译,你就不能不自己写makefile了,会不会写makefile, 从一个侧面说明了一个人是否具备完成大型工程的能力。 因为,makefile关系到了整个工程的编译规则。一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中, makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复 杂的功能操作,因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。 makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make 命令,整个工程完全自动编译,极大的提高了软件 开发的效率。make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如: Delphi的make,VisualC++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。 更新版本 hello.c程序 #include int main(){printf("Hello,World!\n");

return 0;}=== makefile开始=== Helloworld: hello.o gcc hello.o–o Helloworld Hello.o: hello.c hello.h gcc–MM hello.c gcc–c hello.c–o hello.o .PHONY: clean Clean: rm–rf*.o hellworld === makefile结束===

Linux如何写makefile文件

Linux如何写makefile文件 关于程序的编译和链接 —————————— 在此,我想多说关于程序编译的一些规范和方法,一般来说,无论是C、C++、还是pas,首先要把源文件编译成中间代码文件,在Windows下也就是 .obj 文件,UNIX下是 .o 文件,即 Object File,这个动作叫做编译(compile)。然后再把大量的Object File合成执行文件,这个动作叫作链接(link)。 编译时,编译器需要的是语法的正确,函数与变量的声明的正确。对于后者,通常是你需要告诉编译器头文件的所在位置(头文件中应该只是声明,而定义应该放在 C/C++文件中),只要所有的语法正确,编译器就可以编译出中间目标文件。一般来说,每个源文件都应该对应于一个中间目标文件(O文件或是OBJ文 件)。 链接时,主要是链接函数和全局变量,所以,我们可以使用这些中间目标文件(O文件或是OBJ文件)来链接我们的应用程序。链接器并不管函数所在的源文件, 只管函数的中间目标文件(Object File),在大多数时候,由于源文件太多,编译生成的中间目标文件太多,而在链接时需要明显地指出中间目标文件名,这对于编译很不方便,所以,我们要给 中间目标文件打个包,在Windows 下这种包叫“库文件”(Library File),也就是 .lib 文件,在UNIX下,是Archive File,也就是 .a 文件。 总结一下,源文件首先会生成中间目标文件,再由中间目标文件生成执行文件。在编译时,编译器只检测程序语法,和函数、变量是否被声明。如果函数未被声明, 编译器会给出一个警告,但可以生成Object File。而在链接程序时,链接器会在所有的Object File中找寻函数的实现,如果找不到,那到就会报链接错误码(Linker Error),在VC下,这种错误一般是:Link 2001错误,意思说是说,链接器未能找到函数的实现。你需要指定函数的Object File. 好,言归正传,GNU的make有许多的内容,闲言少叙,还是让我们开始吧。 Makefile 介绍 ——————— make命令执行时,需要一个 Makefile 文件,以告诉make命令需要怎么样的去编译和链接程序。 首先,我们用一个示例来说明Makefile的书写规则。以便给大家一个感兴认识。这个示例来源于GNU的make使用手册,在这个示例中,我们的工程有 8

跟我一起写Makefile(可以注释版)

跟我一起写 Makefile 作者:陈皓 整理:祝冬华

第一部分、概述 (6) 第二部分、关于程序的编译和链接 (6) 第三部分、Makefile 介绍 (7) 一、Makefile的规则 (7) 二、一个示例 (8) 三、make是如何工作的 (9) 四、makefile中使用变量 (10) 五、让make自动推导 (11) 六、另类风格的makefile (12) 七、清空目标文件的规则 (13) 第四部分、Makefile 总述 (13) 一、Makefile里有什么? (13) 1、显式规则。 (14) 2、隐晦规则。 (14) 3、变量的定义。 (14) 4、文件指示。 (14) 5、注释。 (14) 二、Makefile的文件名 (15) 三、引用其它的Makefile (15) 四、环境变量 MAKEFILES (16) 五、make的工作方式 (16) 第五部分、书写规则 (17) 一、规则举例 (17) 二、规则的语法 (17) 三、在规则中使用通配符 (18) 四、文件搜寻 (19) 五、伪目标 (20) 六、多目标 (22) 七、静态模式 (22) 八、自动生成依赖性 (24) 第六部分书写命令 (25) 一、显示命令 (26) 二、命令执行 (26) 三、命令出错 (27) 四、嵌套执行make (28) 五、定义命令包 (30) 第七部分使用变量 (30) 一、变量的基础 (31) 二、变量中的变量 (32) 三、变量高级用法 (34) 四、追加变量值 (37) 五、override 指示符 (37) 六、多行变量 (38)

八、目标变量 (39) 九、模式变量 (40) 第八部分使用条件判断 (40) 一、示例 (40) 二、语法 (42) 第九部分使用函数 (43) 一、函数的调用语法 (44) 二、字符串处理函数 (44) 1、subst (44) 2、patsubst (45) 3、strip (45) 4、findstring (46) 5、filter (46) 6、filter-out (46) 7、sort (47) 8、word (47) 9、wordlist (47) 10、words (47) 11、firstword (48) 12、字符串函数实例 (48) 三、文件名操作函数 (48) 1、dir (48) 2、notdir (48) 3、suffix (49) 4、basename (49) 5、addsuffix (49) 6、addprefix (49) 7、join (50) 四、foreach 函数 (50) 五、if 函数 (50) 六、call函数 (51) 七、origin函数 (51) “undefined” (52) “default” (52) “file” (52) “command line” (52) “override” (52) “automatic” (52) 八、shell函数 (53) 九、控制make的函数 (53) 1、error (53) 2、warning (54) 第十部分 make 的运行 (54)

makefile 中 $@ $^ % 使用

makefile 中$@ $^ %< 使用 https://www.doczj.com/doc/0412667326.html,/kesaihao862/article/details/7332528 这篇文章介绍在LINUX下进行C语言编程所需要的基础知识。在这篇文章当中,我们将会学到以下内容:源程序编译Makefile的编写程序库的链接程序的调试头文件和系统求助1.源程序的编译在Linux下面,如果要编译一个C语言源程序,我们要使用GNU的gcc编译器。下面我们以一个实例来说明如何使用gcc编译器。假设我们有下面一个非常简单的源程序(hello.c):int main(int argc,char **argv){printf("Hello Linux\n");}要编译这个程序,我们只要在命令行下执行:gcc -o hello hello.cgcc 编译器就会为我们生成一个hello的可执行文件。执行./hello就可以看到程序的输出结果了。命令行中gcc表示我们是用gcc来编译我们的源程序,-o 选项表示我们要求编译器给我们输出的可执行文件名为hello 而hello.c是我们的源程序文件。gcc编译器有许多选项,一般来说我们只要知道其中的几个就够了。-o 选项我们已经知道了,表示我们要求输出的可执行文件名。-c选项表示我们只要求编译器输出目标代码,而不必要输出可执行文件。-g选项表示我们要求编译器在编译的时候提供我们以后对程序进行调试的信息。知道了这三个选项,我

们就可以编译我们自己所写的简单的源程序了,如果你想要知道更多的选项,可以查看gcc的帮助文档,那里有着许多对其它选项的详细说明。2.Makefile的编写假设我们有下面这样的一个程序,源代码如下:/* main.c */#include "mytool1.h"#include "mytool2.h" int main(int argc,char **argv){mytool1_print("hello");mytool2_print("hello");}/* mytool1.h */ #ifndef _MYTOOL_1_H#define _MYTOOL_1_Hvoid mytool1_print(char *print_str);#endif/* mytool1.c */#include "mytool1.h"void mytool1_print(char *print_str){printf("This is mytool1 print %s\n",print_str);}/* mytool2.h */#ifndef _MYTOOL_2_H#define _MYTOOL_2_Hvoid mytool2_print(char *print_str);#endif/* mytool2.c */#include "mytool2.h"void mytool2_print(char *print_str){printf("This is mytool2 print %s\n",print_str);}当然由于这个程序是很短的我们可以这样来编译gcc -c main.cgcc -c mytool1.cgcc -c mytool2.cgcc -o main main.o mytool1.o mytool2.o这样的话我们也可以产生main程序,而且也不时很麻烦。但是如果我们考虑一下如果有一天我们修改了其中的一个文件(比如说mytool1.c)那么我们难道还要重新输入上面的命令?也许你会说,这个很容易解决啊,我写一个SHELL脚本,让她帮我去完成不就可以了。是的对于这个程序来说,是可

C++项目的Makefile编写

一个C++项目的Makefile编写-Tony与Alex的对话系列- - Tony : Hey Alex, How are you doing? Alex : 不怎么样。(显得很消沉的样子) Tony : Oh , Really ? What is the matter? Alex : 事情是这样的。最近有一个Unix下的C++项目要求我独自完成,以前都是跟着别人做,现在让自己独立完成,还真是不知道该怎么办,就连一个最简单的项目的Makefile都搞不定。昨晚看了一晚上资料也没有什么头绪。唉!! Tony : 别急,我曾经有一段时间研究过一些关于Makefile的东西,也许能帮得上忙,来,我们一起来设计这个项目的Makefile。 Alex : So it is a deal。(一言为定) Tony : 我们现在就开始吧,给我拿把椅子过来。 (Tony坐在Alex电脑的旁边) Tony : 把你的项目情况大概给我讲讲吧。 Alex : No Problem ! 这是一个“半成品”项目,也就是说我将提供一个开发框架供应用开发人员使用,一个类似MFC的东西。 Tony : 继续。 Alex : 我现在头脑中的项目目录结构是这样的: APL (Alex's Programming Library) -Make.properties -Makefile(1) -include //存放头文件 -Module1_1.h -Module1_2.h -Module2_1.h -Module2_2.h -src //存放源文件 -Makefile(2) -module1 -Module1_1.cpp -Module1_2.cpp -Makefile(3) -module2 -Module2_1.cpp -Module2_2.cpp -Makefile(3) -... -lib //存放该Project依赖的库文件,型如libxxx.a -dist //存放该Project编译连接后的库文件libapl.a -examples //存放使用该“半成品”搭建的例子应用的源程序 Makefile(4)

怎样使用Makefile

Mak k e f ile 跟我一 我一起起写Ma 陈皓 (CSDN) 概 述 什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows 的IDE都为你做了这个工作,但我觉得要作一个好的和professional的程序员,makefile还是要懂。这就好像现在有这么多的HTML的编辑器,但如果你想成为一个专业人士,你还是要了解HTML的标识的含义。特别在Unix下的软件编译,你就不能不自己写makefile了,会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。 因为,makefile关系到了整个工程的编译规则。一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能 操作,因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。 makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。make是一个命令工具,是一个 解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。 现在讲述如何写makefile的文章比较少,这是我想写这篇文章的原因。当然,不同产商的make各不相同,也有不同的语法,但其本质都是在“文件依赖性”上做文章,这里,我仅对GNU的make进行讲述,我的环境是RedHat Linux 8.0,make的版本是3.80。必竟,这个make是应用最为广泛的,也是用得最多的。而且其还是最遵循于IEEE 1003.2-1992 标准的(POSIX.2)。 在这篇文档中,将以C/C++的源码作为我们基础,所以必然涉及一些关于C/C++的编译的知识,相关于这方面的内容,还请各位查看相关的编译器的文档。这里所默认的编译器是UNIX下的GCC和CC。 关于程序的编译和链接 在此,我想多说关于程序编译的一些规范和方法,一般来说,无论是C、C++、还是pas,首先要把源文件编译成中间代码文件,在Windows下也就是 .obj 文件,UNIX下是 .o 文件,即 Object File,这个动作叫做编译(compile)。然后再把大量的Object File 合成执行文件,这个动作叫作链接(link)。

如何编写Makefile

概述 —— 什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE 都为你做了这个工作,但我觉得要作一个好的和professional的程序员,makefile还是要懂。这就好像现在有这么多的HTML的编辑器,但如果你想成为一个专业人士,你还是要了解HTML的标识的含义。特别在Unix下的软件编译,你就不能不自己写makefile了,会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。 因为,makefile关系到了整个工程的编译规则。一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。 makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。make是一个命令工具,是一个解释makefile 中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。 现在讲述如何写makefile的文章比较少,这是我想写这篇文章的原因。当然,不同产商的make各不相同,也有不同的语法,但其本质都是在“文件依赖性”上做文章,这里,我仅对GNU的make进行讲述,我的环境是RedHat Linux 8.0,make的版本是3.80。必竟,这个make 是应用最为广泛的,也是用得最多的。而且其还是最遵循于IEEE 1003.2-1992 标准的(POSIX.2)。 在这篇文档中,将以C/C++的源码作为我们基础,所以必然涉及一些关于C/C++的编译的知识,相关于这方面的内容,还请各位查看相关的编译器的文档。这里所默认的编译器是UNIX 下的GCC和CC。 关于程序的编译和链接 —————————— 在此,我想多说关于程序编译的一些规范和方法,一般来说,无论是C、C++、还是pas,首先要把源文件编译成中间代码文件,在Windows下也就是 .obj 文件,UNIX下是 .o 文件,即 Object File,这个动作叫做编译(compile)。然后再把大量的Object File合成执行文件,这个动作叫作链接(link)。 编译时,编译器需要的是语法的正确,函数与变量的声明的正确。对于后者,通常是你需要告诉编译器头文件的所在位置(头文件中应该只是声明,而定义应该放在C/C++文件中),只要所有的语法正确,编译器就可以编译出中间目标文件。一般来说,每个源文件都应该对应于一个中间目标文件(O文件或是OBJ文件)。

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 #include 2.仍在同一目录下用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 hello 4.用vim编辑Makefile,如下所示: hello:hello.c hello.h gcc hello.c -o hello 5.退出保存,在shell中键入:make查看结果 6.再次用vim打开Makefile,用变量进行替换,如下所示: OBJS :=hello.o CC :=gcc hello:$(OBJS) $(CC) $^ -o $@

MakeFile编写规则

MakeFile编写规则 什么是makefile (3) 关于程序的编译和链接 (3) Makefile 介绍 (4) 一、Makefile的规则 (4) 二、一个示例 (4) 三、make是如何工作的 (6) 四、makefile中使用变量 (6) 五、让make自动推导 (7) 六、另类风格的makefile (8) 七、清空目标文件的规则 (8) Makefile 总述 (9) 一、Makefile里有什么 (9) 二、Makefile的文件名 (9) 三、引用其它的Makefile (9) 四、环境变量MAKEFILES (10) 五、make的工作方式 (10) 实例说明 (11) 一、简单例子 (11) 二、规则的语法 (11) 三、在规则中使用通配符 (12) 四、文件搜寻 (12) 五、伪目标 (13) 六、多目标 (14) 七、静态模式 (15) 八、自动生成依赖性 (16) 书写命令 (17) 一、显示命令 (17) 二、命令执行 (18) 三、命令出错 (18) 四、嵌套执行make (19) 五、定义命令包 (20) 使用变量 (21) 一、变量的基础 (21) 二、变量的赋值 (21) 第一种方式 (22) 第二种方式 (22) 三、变量高级用法 (23) 一种是变量值的替换 (23) 第二种高级用法——“把变量的值再当成变量” (24) 四、追加变量值 (25) 五、override 指示符 (26) 六、多行变量 (26)

七、环境变量 (26) 八、目标变量 (27) 九、模式变量 (27) 十、自动化变量 (28) 使用条件判断 (30) makefile的编写规则--语法及函数 (31) 条件表达式 (31) 函数 (32) 一、函数的调用语法 (32) 二、字符串处理函数 (33) $(subst ,, ) (33) $(patsubst ,, ) (33) $(strip ) (34) $(findstring , ) (34) $(filter , ) (34) $(filter-out , ) (34) $(sort ) (35) $(word , ) (35) $(wordlist ,, ) (35) $(words ) (35) $(firstword ) (36) 三、文件名操作函数 (36) $(dir ) . (36) $(notdir ) .. (36) $(suffix ) .. (37) $(basename ) .. (37) $(addsuffix , ) (37) $(addprefix , ) .. (37) 其他函数 (37) $(join , ) (37) foreach 函数 (38) if 函数 (38) call函数 (38) origin函数 (39) shell函数 (40) 控制make的函数 (40) $(error ) . (40) $(warning ) . (40) make 的运行 (41) 一、make的退出码 (41) 二、指定Makefile (41) 三、指定目标 (41) 四、检查规则 (42)

实验三 Makefile的编写及应用

闽江学院电子系 实验报告 学生姓名:3142731班级:学号:课程:实时操作系统 一、实验题目:Makefile的编写及应用 二、实验地点:大成楼A210 三、实验目的: 1、了解Makefile的基本概念和基本结构; 2、初步掌握编写简单Makefile的方法; 3、了解递归Make的编译过程; 4、初步掌握应用GNU Make编译应用程序的方法。 四、实验内容: 1、使用命令行的方式手动编译程序的方法; 五、实验环境(使用的软硬件): 硬件:计算机 软件:Ubuntu Linux 六、实验结果: (1)使用命令行的方式手动编译程序方法 1、利用文本编辑器创建hello.c 文件

2、手动编译hello 应用程序 在hello.c 的目录的终端下输入: #gcc -c hello.c #gcc hello.o -o hello 通过ls 命令查看当前目录下是否生成源代码hello.c 的object 文件hello.o 和可执行文件hello,运行可执行文件hello。查看一下运行结果。 3、修改hello.c 文件,重新手动编译应用程序。

4、删除hello.o 和hello 文件 #rm -f hello.o #rm -f hello (2) 利用GNU make 自动编译应用程序方法 1、利用文本编辑器创建一个Makefile 文件,并将其保存到与hello.c 相同的目录下。 2、先执行如下命令。 #make #ls #./hello 查看并记录所生成的文件和运行的结果。

3、执行make clean 命令: 4、修改hello.c 文件,重复第2、3 步操作,查看并记录所生成的文件和运行结果,并与手动编译进行比较,写出你的结论。 5、重新编辑Makefile 文件(斜黑体表示修改部分)

如何编写makefile文件

目的: 基本掌握了make 的用法,能在Linux系统上编程。 环境: Linux系统,或者有一台Linux服务器,通过终端连接。一句话:有Linux编译环境。准备: 准备三个文件:file1.c, file2.c, file2.h file1.c: #include #include "file2.h" int main() { printf("print file1$$$$$$$$$$$$$$$$$$$$$$$$\n"); File2Print(); return 0; } file2.h: #ifndef FILE2_H_ #define FILE2_H_ #ifdef __cplusplus extern "C" { #endif void File2Print(); #ifdef __cplusplus } #endif #endif file2.c: #include "file2.h" void File2Print() { printf("Print file2**********************\n"); } 基础: 先来个例子: 有这么个Makefile文件。(文件和Makefile在同一目录) === makefile 开始=== helloworld:file1.o file2.o gcc file1.o file2.o -o helloworld file1.o:file1.c file2.h gcc -c file1.c -o file1.o

file2.o:file2.c file2.h gcc -c file2.c -o file2.o clean: rm -rf *.o helloworld === makefile 结束=== 一个makefile 主要含有一系列的规则,如下: A: B (tab) (tab) 每个命令行前都必须有tab符号。 上面的makefile文件目的就是要编译一个helloworld的可执行文件。让我们一句一句来解释:helloworld : file1.o file2.o:helloworld依赖file1.o file2.o两个目标文件。 gcc File1.o File2.o -o helloworld:编译出helloworld可执行文件。-o表示你指定的目标文件名。file1.o : file1.c:file1.o依赖file1.c文件。 gcc -c file1.c -o file1.o:编译出file1.o文件。-c表示gcc 只把给它的文件编译成目标文件,用源码文件的文件名命名但把其后缀由“.c”或“.cc”变成“.o”。在这句中,可以省略-o file1.o,编译器默认生成file1.o文件,这就是-c的作用。 file2.o : file2.c file2.h gcc -c file2.c -o file2.o 这两句和上两句相同。 clean: rm -rf *.o helloworld 当用户键入make clean命令时,会删除*.o 和helloworld文件。 如果要编译cpp文件,只要把gcc改成g++就行了。 写好Makefile文件,在命令行中直接键入make命令,就会执行Makefile中的内容了。 到这步我想你能编一个Helloworld程序了。 上一层楼:使用变量 上面提到一句,如果要编译cpp文件,只要把gcc改成g++就行了。但如果Makefile中有很多gcc,那不就很麻烦了。 第二个例子: === makefile 开始=== OBJS = file1.o file2.o CC = gcc CFLAGS = -Wall -O -g helloworld : $(OBJS) $(CC) $(OBJS) -o helloworld file1.o : file1.c file2.h

linux下makefile文件的编写

linux下Makefile文件的编写- 红联Linux门户- 中国领先 的Linux技... linux下Makefile文件的编写victorywylbc发布于 2009-7-30 | 951次阅读字号: 大中小(网友评论7 条) 我要评论开始使用Linux编程时,一个很讨厌的问题就是如何写Makefile文件,由于在Linux下 不像在Windows下那么熟悉,有那么多好的软件(也许是对Linux孤陋寡闻了)。虽然 象Kylix和Anjuta这样的集成编译环境,但是Kylix太大太慢,用它编写console程序 不亚于高射炮打蚊子——大材小用,而Anjuta又太不稳定,况且字体有那么难看。不 说了,还是言归正传,看看Makefile该如何编写。1. 简单的GCC语法:如果你只有一个文件(或者只有几个文件),那么就可以不写Makefile文件(当然有 Makefile更加方便),用gcc直接编译就行了。在这里我们只介绍几个我经常用的几 个参数,第一是“-o”,它后面的参数表示要输出的目标文件,再一个是“-c”, 表示仅编译(Compile),不连接(Make),如果没有

”-c”参数,那么就表示连接 ,如下面的几个命令:gcc –c test.c,表示只编译test.c 文件,成功时输出目标文件test.ogcc –c test.c –o test.o ,与上一条命令完全相同gcc –o test test.o,将test.o连接成可执行的二进制文件testgcc –o test test.c,将test.c编译并连接成可执行的二进制文件testgcc test.c –o test,与上一条命令相同gcc –c test1.c,只编译test1.c,成功时输出目标文件test1.ogcc –c test2.c,只编译test2.c,成功时输出目标文件test2.ogcc –o test test1.o test2.o,将 test1.o和test2.o连接为可执行的二进制文件testgcc –c test test1.c test2.c,将test1.o和test2.o编译并连接为可执行的二进制 文件test注:如果你想编译cpp文件,那么请用g++,否则会有类似如下莫名其妙的错误: cc3r3i2U.o(.eh_frame+0x12): undefined reference to `__gxx_personality_v0’ ......还有一个参数是”-l”参数,与之紧紧相连的是表示连接时所要的链接库,比如多线 程,如果你使用了pthread_create函数,那么你就应该在编译语句的最后加上”-lpthread ”,”-l”表示连接,

MAKEFILE的编写

MAKEFILE的编写 第一章Makefile简介 什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows 的IDE都为你做了这个工作,但我觉得要作一个好的和professional的程序员,makefile还是要懂。这就好像现在有这么多的HTML的编辑器,但如果你想成为一个专业人士,你还是要了解HTML的标识的含义。特别在Unix下的软件编译,你就不能不自己写makefile了,会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。 因为,makefile关系到了整个工程的编译规则。一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。 makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。 make命令执行时,需要一个Makefile 文件,以告诉make命令需要怎么样的去编译和链接程序。 首先,我们用一个示例来说明Makefile的书写规则。以便给大家一个感兴认识。这个示例来源于GNU的make使用手册,在这个示例中,我们的工程有8个C文件,和3个头文件,我们要写一个Makefile来告诉make命令如何编译和链接这几个文件。我们的规则是:1)如果这个工程没有编译过,那么我们的所有C文件都要编译并被链接。 2)如果这个工程的某几个C文件被修改,那么我们只编译被修改的C文件,并链接目标程序。 3)如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的C文件,并链接目标程序。 只要我们的Makefile写得够好,所有的这一切,我们只用一个make命令就可以完成,make 命令会自动智能地根据当前的文件修改的情况来确定哪些文件需要重编译,从而自己编译所需要的文件和链接目标程序。 以下各章我们将以实际例子详细介绍各类Makefile文件的书写规则。 第二章一个简单的C语言Makefile 红色字体为makefile文件本身,黑色字体为解释。 .SUFFIXES:.ec 用伪目标SUFFIXES来让make知道特定的后缀.ec。后缀规则是一个比较老式的定义隐含规则的方法。后缀规则中,如果没有命令,那是毫无意义的。因为他也不会移去内建的隐含规

相关主题
文本预览