makefile的特殊变量,类似$@, $+等 (copied)

本文详细介绍了Makefile中的特殊变量,包括它们的作用、用途和常见应用实例,旨在帮助开发者更高效地编写Makefile。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

来源:http://hi.baidu.com/jingweiyoung/item/dea74399c40eb24cf14215cf






Makefile 特殊变量

常用特殊变量

例:

%.o:%.c

          ¥(CC) -c $(CFLAGS) $< -o $@

 

$@ 表示所有目标,这里是.o文件

$<  表示依赖目标中第一个目标的名子,这里是 .c文件。如果依赖目标是以模式(%)定义的,那么"$<"将是符合模式的一系列文件集。(注:是一个一个取出来的)

$?  所有比目标新的依赖目标的集合,以空格分隔。

$^  所有依赖目标的集合,以空格分隔。如果在依赖目标中有多个重复的,那个这个变量会去除重复的依赖目标,只保留一份。

$+  这个变量很像"$^",也是所有依赖目标的集合。只是它不去除重复的依赖目标。

$*  这个变量表示目标模式中"%"及其之前的部分。如果目标是"dir/a.foo.b",并且目标的模
式是"a.%.b",那么,"$*"的值就是"dir/a.foo"。这个变量对于构造有关联的文件名是比
较有较。如果目标中没有模式的定义,那么"$*"也就不能被推导出,但是,如果目标文
件的后缀是make所识别的,那么"$*"就是除了后缀的那一部分。例如:如果目标
是"foo.c",因为".c"是make所能识别的后缀名,所以,"$*"的值就是"foo"。这个特性
是GNU make的,很有可能不兼容于其它版本的make,所以,你应该尽量避免使用"$
*",除非是在隐含规则或是静态模式中。如果目标中的后缀是make所不能识别的,那
么"$*"就是空值。
当你希望只对更新过的依赖文件进行操作时,"$?"在显式规则中很有用,例如,假设
有一个函数库文件叫"lib",其由其它几个object文件更新。那么把object文件打包的比
较有效率的Makefile 规则是:
lib : foo.o bar.o lose.o win.o
ar r lib $?
在上述所列出来的自动量变量中。四个变量($@、$<、$%、$*)在扩展时只会有一个文
件,而另三个的值是一个文件列表。这七个自动化变量还可以取得文件的目录名或是在
当前目录下的符合模式的文件名,只需要搭配上"D"或"F"字样。这是GNU make中老版
本的特性,在新版本中,我们使用函数"dir"或"notdir"就可以做到了。"D"的含义就是
Directory,就是目录,"F"的含义就是File,就是文件。

 

摘自:《跟我一起写Makefile》作者:陈皓

 

实例:

 

.SUFFIXES: .pc .c .o
CC=gcc
PROC=proc
AR=ar
INCL = ../../include
SYSINCL1 = -L../lib -lc -lnsl -lm
GFLAG = -g
VPATH = ../common


COMM_SRC = readini.c timetool.c syslog.c cfgfresh.c almstatmsg.c  msgproc.c filetool.c dupauth.c hbproc.c code.c nettool.c
COMM_TGT = $(COMM_SRC:.c=.o)

all:$(COMM_TGT)
.c.o:
        $(CC)   $(GFLAG) -c -I$(INCL) $?

#make without DB
#DUP_SRC = tickfilter.c hash.c
#DUP_TGT        = $(DUP_SRC:.c=.o) $(COMM_TGT)
#TickFilter: $(DUP_TGT)
#       $(CC) $(GFLAG) -o $@ $(DUP_TGT) -I$(INCL) $(SYSINCL1)
#       mv $@ ../../

.PHONY:clean
clean:
        -rm -f *.o


# settings.mk is not under source control. Put variables into this # file to avoid having to adding the to the make command line. -include settings.mk # ============================================================================== # Uncomment or add the design to run # ============================================================================== DESIGN_CONFIG=./designs/nangate45/counter/config.mk # DESIGN_CONFIG=./designs/nangate45/aes/config.mk # DESIGN_CONFIG=./designs/nangate45/ariane133/config.mk # DESIGN_CONFIG=./designs/nangate45/ariane136/config.mk # DESIGN_CONFIG=./designs/nangate45/black_parrot/config.mk # DESIGN_CONFIG=./designs/nangate45/bp_be_top/config.mk # DESIGN_CONFIG=./designs/nangate45/bp_fe_top/config.mk # DESIGN_CONFIG=./designs/nangate45/bp_multi_top/config.mk # DESIGN_CONFIG=./designs/nangate45/bp_quad/config.mk # DESIGN_CONFIG=./designs/nangate45/dynamic_node/config.mk # DESIGN_CONFIG=./designs/nangate45/gcd/config.mk # DESIGN_CONFIG=./designs/nangate45/ibex/config.mk # DESIGN_CONFIG=./designs/nangate45/jpeg/config.mk # DESIGN_CONFIG=./designs/nangate45/mempool_group/config.mk # DESIGN_CONFIG=./designs/nangate45/swerv/config.mk # DESIGN_CONFIG=./designs/nangate45/swerv_wrapper/config.mk # DESIGN_CONFIG=./designs/nangate45/tinyRocket/config.mk # DESIGN_CONFIG=./designs/gf12/aes/config.mk # DESIGN_CONFIG=./designs/gf12/ariane/config.mk # DESIGN_CONFIG=./designs/gf12/ca53/config.mk # DESIGN_CONFIG=./designs/gf12/coyote/config.mk # DESIGN_CONFIG=./designs/gf12/gcd/config.mk # DESIGN_CONFIG=./designs/gf12/ibex/config.mk # DESIGN_CONFIG=./designs/gf12/jpeg/config.mk # DESIGN_CONFIG=./designs/gf12/swerv_wrapper/config.mk # DESIGN_CONFIG=./designs/gf12/tinyRocket/config.mk # DESIGN_CONFIG=./designs/gf12/ariane133/config.mk # DESIGN_CONFIG=./designs/gf12/bp_dual/config.mk # DESIGN_CONFIG=./designs/gf12/bp_quad/config.mk # DESIGN_CONFIG=./designs/gf12/bp_single/config.mk # DESIGN_CONFIG=./designs/sky130hd/aes/config.mk # DESIGN_CONFIG=./designs/sky130hd/chameleon/config.mk # DESIGN_CONFIG=./designs/sky130hd/gcd/config.mk # DESIGN_CONFIG=./designs/sky130hd/ibex/config.mk # DESIGN_CONFIG=./designs/sky130hd/jpeg/config.mk # DESIGN_CONFIG=./designs/sky130hd/microwatt/config.mk # DESIGN_CONFIG=./designs/sky130hd/riscv32i/config.mk # DESIGN_CONFIG=./designs/sky130hs/aes/config.mk # DESIGN_CONFIG=./designs/sky130hs/gcd/config.mk # DESIGN_CONFIG=./designs/sky130hs/ibex/config.mk # DESIGN_CONFIG=./designs/sky130hs/jpeg/config.mk # DESIGN_CONFIG=./designs/sky130hs/riscv32i/config.mk # DESIGN_CONFIG=./designs/asap7/aes/config.mk # DESIGN_CONFIG=./designs/asap7/ethmac/config.mk # DESIGN_CONFIG=./designs/asap7/gcd/config.mk # DESIGN_CONFIG=./designs/asap7/ibex/config.mk # DESIGN_CONFIG=./designs/asap7/jpeg/config.mk # DESIGN_CONFIG=./designs/asap7/megaboom/config.mk # DESIGN_CONFIG=./designs/asap7/mock-array/config.mk # DESIGN_CONFIG=./designs/asap7/riscv32i/config.mk # DESIGN_CONFIG=./designs/asap7/swerv_wrapper/config.mk # DESIGN_CONFIG=./designs/asap7/uart/config.mk # DESIGN_CONFIG=./designs/intel16/aes/config.mk # DESIGN_CONFIG=./designs/intel16/gcd/config.mk # DESIGN_CONFIG=./designs/intel22/ibex/config.mk # DESIGN_CONFIG=./designs/intel22/jpeg/config.mk # DESIGN_CONFIG=./designs/gf180/aes/config.mk # DESIGN_CONFIG=./designs/gf180/ibex/config.mk # DESIGN_CONFIG=./designs/gf180/jpeg/config.mk # DESIGN_CONFIG=./designs/gf180/riscv32i/config.mk # DESIGN_CONFIG=./designs/gf180/uart-blocks/config.mk #DESIGN_CONFIG=./designs/ihp-sg13g2/aes/config.mk #DESIGN_CONFIG=./designs/ihp-sg13g2/ibex/config.mk #DESIGN_CONFIG=./designs/ihp-sg13g2/gcd/config.mk #DESIGN_CONFIG=./designs/ihp-sg13g2/spi/config.mk #DESIGN_CONFIG=./designs/ihp-sg13g2/riscv32i/config.mk #DESIGN_CONFIG=./designs/ihp-sg13g2/i2c-gpio-expander/config.mk # Default design DESIGN_CONFIG ?= ./designs/nangate45/gcd/config.mk export DESIGN_CONFIG include $(DESIGN_CONFIG) export DESIGN_DIR = $(dir $(DESIGN_CONFIG)) # default value "base" is duplicated from variables.yaml because we need it # earlier in the flow for BLOCKS. BLOCKS is a feature specific to the # ORFS Makefile. export FLOW_VARIANT?=base # BLOCKS is a ORFS make flow specific feature. ifneq ($(BLOCKS),) # Normally this comes from variables.yaml, but we need it here to set up these variables # which are part of the DESIGN_CONFIG. BLOCKS is a Makefile specific concept. $(foreach block,$(BLOCKS),$(eval BLOCK_LEFS += ./results/$(PLATFORM)/$(DESIGN_NICKNAME)_$(block)/$(FLOW_VARIANT)/${block}.lef)) $(foreach block,$(BLOCKS),$(eval BLOCK_LIBS += ./results/$(PLATFORM)/$(DESIGN_NICKNAME)_$(block)/$(FLOW_VARIANT)/${block}.lib)) $(foreach block,$(BLOCKS),$(eval BLOCK_GDS += ./results/$(PLATFORM)/$(DESIGN_NICKNAME)_$(block)/$(FLOW_VARIANT)/6_final.gds)) $(foreach block,$(BLOCKS),$(eval BLOCK_CDL += ./results/$(PLATFORM)/$(DESIGN_NICKNAME)_$(block)/$(FLOW_VARIANT)/6_final.cdl)) $(foreach block,$(BLOCKS),$(eval BLOCK_LOG_FOLDERS += ./logs/$(PLATFORM)/$(DESIGN_NICKNAME)_$(block)/$(FLOW_VARIANT)/)) export ADDITIONAL_LEFS += $(BLOCK_LEFS) export ADDITIONAL_LIBS += $(BLOCK_LIBS) export ADDITIONAL_GDS += $(BLOCK_GDS) export GDS_FILES += $(BLOCK_GDS) ifneq ($(CDL_FILES),) export CDL_FILES += $(BLOCK_CDL) endif endif # ============================================================================== # ____ _____ _____ _ _ ____ # / ___|| ____|_ _| | | | _ \ # \___ \| _| | | | | | | |_) | # ___) | |___ | | | |_| | __/ # |____/|_____| |_| \___/|_| # # ============================================================================== # Disable make's implicit rules MAKEFLAGS += --no-builtin-rules .SUFFIXES: #------------------------------------------------------------------------------- # Default target when invoking without specific target. .DEFAULT_GOAL := finish #------------------------------------------------------------------------------- # Proper way to initiate SHELL for make SHELL := /usr/bin/env bash .SHELLFLAGS := -o pipefail -c #------------------------------------------------------------------------------- # Setup variables to point to root / head of the OpenROAD directory # - the following settings allowed user to point OpenROAD binaries to different # location # - default is current install / clone directory ifeq ($(origin FLOW_HOME), undefined) FLOW_HOME := $(abspath $(dir $(firstword $(MAKEFILE_LIST)))) endif export FLOW_HOME include $(FLOW_HOME)/scripts/variables.mk define GENERATE_ABSTRACT_RULE ifeq ($(wildcard $(3)),) # There is no unique config.mk for this module, use the shared # block.mk that, by convention, is in the same folder as config.mk # of the parent macro. # # At an early stage, before refining each of the macros, a shared # block.mk file can be useful to run through the flow to explore # more global concerns instead of getting mired in the details of # each macro. block := $(patsubst ./designs/$(PLATFORM)/$(DESIGN_NICKNAME)/%,%,$(dir $(3))) $(1) $(2) &: $$(UNSET_AND_MAKE) DESIGN_NAME=${block} DESIGN_NICKNAME=$$(DESIGN_NICKNAME)_${block} DESIGN_CONFIG=$$(shell dirname $$(DESIGN_CONFIG))/block.mk generate_abstract else # There is a unique config.mk for this Verilog module $(1) $(2) &: $$(UNSET_AND_MAKE) DESIGN_CONFIG=$(3) generate_abstract endif endef # Targets to harden Blocks in case of hierarchical flow is triggered .PHONY: build_macros build_macros: $(BLOCK_LEFS) $(BLOCK_LIBS) $(foreach block,$(BLOCKS),$(eval $(call GENERATE_ABSTRACT_RULE,./results/$(PLATFORM)/$(DESIGN_NICKNAME)_$(block)/$(FLOW_VARIANT)/${block}.lef,./results/$(PLATFORM)/$(DESIGN_NICKNAME)_$(block)/$(FLOW_VARIANT)/${block}.lib,$(shell dirname $(DESIGN_CONFIG))/${block}/config.mk))) $(foreach block,$(BLOCKS),$(eval ./results/$(PLATFORM)/$(DESIGN_NICKNAME)_$(block)/$(FLOW_VARIANT)/6_final.gds: ./results/$(PLATFORM)/$(DESIGN_NICKNAME)_$(block)/$(FLOW_VARIANT)/${block}.lef)) # Utility to print tool version information #------------------------------------------------------------------------------- .PHONY: versions.txt versions.txt: mkdir -p $(OBJECTS_DIR) @if [ -z "$(YOSYS_EXE)" ]; then \ echo >> $(OBJECTS_DIR)/$@ "yosys not installed"; \ else \ $(YOSYS_EXE) -V > $(OBJECTS_DIR)/$@; \ fi @echo openroad `$(OPENROAD_EXE) -version` >> $(OBJECTS_DIR)/$@ @if [ -z "$(KLAYOUT_CMD)" ]; then \ echo >> $(OBJECTS_DIR)/$@ "klayout not installed"; \ else \ $(KLAYOUT_CMD) -zz -v >> $(OBJECTS_DIR)/$@; \ fi # Pre-process libraries # ============================================================================== # Create temporary Liberty files which have the proper dont_use properties set # For use with Yosys and ABC .SECONDEXPANSION: $(DONT_USE_LIBS): $$(filter %$$(@F) %$$(@F).gz,$(LIB_FILES)) @mkdir -p $(OBJECTS_DIR)/lib $(UTILS_DIR)/preprocessLib.py -i $^ -o $@ $(OBJECTS_DIR)/lib/merged.lib: $(DONT_USE_LIBS) $(UTILS_DIR)/mergeLib.pl $(PLATFORM)_merged $(DONT_USE_LIBS) > $@ # Pre-process KLayout tech # ============================================================================== $(OBJECTS_DIR)/klayout_tech.lef: $(TECH_LEF) $(UNSET_AND_MAKE) do-klayout_tech .PHONY: do-klayout_tech do-klayout_tech: @mkdir -p $(OBJECTS_DIR) cp $(TECH_LEF) $(OBJECTS_DIR)/klayout_tech.lef $(OBJECTS_DIR)/klayout.lyt: $(KLAYOUT_TECH_FILE) $(OBJECTS_DIR)/klayout_tech.lef $(UNSET_AND_MAKE) do-klayout .PHONY: do-klayout do-klayout: ifeq ($(KLAYOUT_ENV_VAR_IN_PATH),valid) SC_LEF_RELATIVE_PATH="$$\(env('FLOW_HOME')\)/$(shell realpath --relative-to=$(FLOW_HOME) $(SC_LEF))"; \ OTHER_LEFS_RELATIVE_PATHS=$$(echo "$(foreach file, $(OBJECTS_DIR)/klayout_tech.lef $(ADDITIONAL_LEFS),<lef-files>$$(realpath --relative-to=$(RESULTS_DIR) $(file))</lef-files>)"); \ sed 's,<lef-files>.*</lef-files>,<lef-files>'"$$SC_LEF_RELATIVE_PATH"'</lef-files>'"$$OTHER_LEFS_RELATIVE_PATHS"',g' $(KLAYOUT_TECH_FILE) > $(OBJECTS_DIR)/klayout.lyt else sed 's,<lef-files>.*</lef-files>,$(foreach file, $(OBJECTS_DIR)/klayout_tech.lef $(SC_LEF) $(ADDITIONAL_LEFS),<lef-files>$(shell realpath --relative-to=$(RESULTS_DIR) $(file))</lef-files>),g' $(KLAYOUT_TECH_FILE) > $(OBJECTS_DIR)/klayout.lyt endif sed -i 's,<map-file>.*</map-file>,$(foreach file, $(FLOW_HOME)/platforms/$(PLATFORM)/*map,<map-file>$(shell realpath $(file))</map-file>),g' $(OBJECTS_DIR)/klayout.lyt $(OBJECTS_DIR)/klayout_wrap.lyt: $(KLAYOUT_TECH_FILE) $(OBJECTS_DIR)/klayout_tech.lef $(UNSET_AND_MAKE) do-klayout_wrap .PHONY: do-klayout_wrap do-klayout_wrap: sed 's,<lef-files>.*</lef-files>,$(foreach file, $(OBJECTS_DIR)/klayout_tech.lef $(WRAP_LEFS),<lef-files>$(shell realpath --relative-to=$(OBJECTS_DIR)/def $(file))</lef-files>),g' $(KLAYOUT_TECH_FILE) > $(OBJECTS_DIR)/klayout_wrap.lyt $(WRAPPED_LEFS): mkdir -p $(OBJECTS_DIR)/lef $(OBJECTS_DIR)/def util/cell-veneer/wrap.tcl -cfg $(WRAP_CFG) -macro $(filter %$(notdir $(@:_mod.lef=.lef)),$(WRAP_LEFS)) mv $(notdir $@) $@ mv $(notdir $(@:lef=def)) $(dir $@)../def/$(notdir $(@:lef=def)) $(WRAPPED_LIBS): mkdir -p $(OBJECTS_DIR)/lib sed 's/library(\(.*\))/library(\1_mod)/g' $(filter %$(notdir $(@:_mod.lib=.lib)),$(WRAP_LIBS)) | sed 's/cell(\(.*\))/cell(\1_mod)/g' > $@ # ============================================================================== # ______ ___ _ _____ _ _ _____ ____ ___ ____ # / ___\ \ / / \ | |_ _| | | | ____/ ___|_ _/ ___| # \___ \\ V /| \| | | | | |_| | _| \___ \| |\___ \ # ___) || | | |\ | | | | _ | |___ ___) | | ___) | # |____/ |_| |_| \_| |_| |_| |_|_____|____/___|____/ # .PHONY: synth synth: $(RESULTS_DIR)/1_synth.v .PHONY: synth-report synth-report: synth $(UNSET_AND_MAKE) do-synth-report .PHONY: do-synth-report do-synth-report: ($(TIME_CMD) $(OPENROAD_CMD) $(SCRIPTS_DIR)/synth_metrics.tcl) 2>&1 | tee $(abspath $(LOG_DIR)/1_1_yosys_metrics.log) .PHONY: memory memory: if [ -f $(RESULTS_DIR)/mem_hierarchical.json ]; then \ python3 $(SCRIPTS_DIR)/mem_dump.py $(RESULTS_DIR)/mem_hierarchical.json; \ fi python3 $(SCRIPTS_DIR)/mem_dump.py $(RESULTS_DIR)/mem.json # ============================================================================== # Run Synthesis using yosys #------------------------------------------------------------------------------- $(SDC_FILE_CLOCK_PERIOD): $(SDC_FILE) mkdir -p $(dir $@) echo $(ABC_CLOCK_PERIOD_IN_PS) > $@ .PHONY: yosys-dependencies yosys-dependencies: $(YOSYS_DEPENDENCIES) .PHONY: do-yosys do-yosys: $(DONT_USE_SC_LIB) $(SCRIPTS_DIR)/synth.sh $(SYNTH_SCRIPT) $(LOG_DIR)/1_1_yosys.log .PHONY: do-yosys-canonicalize do-yosys-canonicalize: yosys-dependencies $(DONT_USE_SC_LIB) $(SCRIPTS_DIR)/synth.sh $(SCRIPTS_DIR)/synth_canonicalize.tcl $(LOG_DIR)/1_1_yosys_canonicalize.log $(RESULTS_DIR)/1_synth.rtlil: $(YOSYS_DEPENDENCIES) $(UNSET_AND_MAKE) do-yosys-canonicalize $(RESULTS_DIR)/1_1_yosys.v: $(RESULTS_DIR)/1_synth.rtlil $(UNSET_AND_MAKE) do-yosys .PHONY: do-synth do-synth: mkdir -p $(RESULTS_DIR) $(LOG_DIR) $(REPORTS_DIR) cp $(RESULTS_DIR)/1_1_yosys.v $(RESULTS_DIR)/1_synth.v $(RESULTS_DIR)/1_synth.v: $(RESULTS_DIR)/1_1_yosys.v $(UNSET_AND_MAKE) do-synth .PHONY: clean_synth clean_synth: rm -f $(RESULTS_DIR)/1_* $(RESULTS_DIR)/mem*.json rm -f $(REPORTS_DIR)/synth_* rm -f $(LOG_DIR)/1_* rm -f $(SYNTH_STATS) rm -f $(SDC_FILE_CLOCK_PERIOD) rm -rf _tmp_yosys-abc-* # ============================================================================== # _____ _ ___ ___ ____ ____ _ _ _ _ # | ___| | / _ \ / _ \| _ \| _ \| | / \ | \ | | # | |_ | | | | | | | | | |_) | |_) | | / _ \ | \| | # | _| | |__| |_| | |_| | _ <| __/| |___ / ___ \| |\ | # |_| |_____\___/ \___/|_| \_\_| |_____/_/ \_\_| \_| # .PHONY: floorplan floorplan: $(RESULTS_DIR)/2_floorplan.odb \ $(RESULTS_DIR)/2_floorplan.sdc # ============================================================================== UNSET_VARS = for var in $(UNSET_VARIABLES_NAMES); do unset $$var; done # FILE_MAKEFILE is needed when ORFS is invoked with # `make --file=$FLOW_DIR/Makefile` or `make --directory $FLOW_DIR`. # # However, on some versions of make, MAKEFILE_LIST can be empty, so # don't expand it in that case. FILE_MAKEFILE ?= $(if $(firstword $(MAKEFILE_LIST)),--file=$(firstword $(MAKEFILE_LIST)),) SUB_MAKE = $(MAKE) $(foreach V,$(COMMAND_LINE_ARGS), $(if $($V),$V=$(shell echo "$($V)" | $(FLOW_HOME)/scripts/escape.sh),$V='')) --no-print-directory $(FILE_MAKEFILE) DESIGN_CONFIG=$(DESIGN_CONFIG) UNSET_AND_MAKE = @bash -c '$(UNSET_VARS); $(SUB_MAKE) $$@' -- $(OBJECTS_DIR)/copyright.txt: @$(OPENROAD_CMD) $(SCRIPTS_DIR)/noop.tcl mkdir -p $(OBJECTS_DIR) @touch $(OBJECTS_DIR)/copyright.txt define OPEN_GUI_SHORTCUT .PHONY: gui_$(1) open_$(1) gui_$(1): gui_$(2) open_$(1): open_$(2) endef define OPEN_GUI .PHONY: open_$(1) gui_$(1) open_$(1): $(2)=$(RESULTS_DIR)/$(1) $(OPENROAD_NO_EXIT_CMD) $(SCRIPTS_DIR)/open.tcl gui_$(1): $(2)=$(RESULTS_DIR)/$(1) $(OPENROAD_GUI_CMD) $(SCRIPTS_DIR)/open.tcl endef # Separate dependency checking and doing a step. This can # be useful to retest a stage without having to delete the # target, or when building a wafer thin layer on top of # ORFS using CMake, Ninja, Bazel, etc. where makefile # dependency checking only gets in the way. # # Note that there is no "do-synth" step as it is a special # first step that for usecases such as Bazel where it should # always be built when invoked. Latter stages in the build process # are conditionally built by the Bazel implementation. # # A "do-synth" step would be welcomed, but it isn't strictly necessary # for the Bazel use-case. # # do-floorplan, do-place, do-cts, do-route, do-finish are the # supported interface to execute those stages without checking # for dependencies. # # The do- substeps of each of these stages are subject to change. # # $(1) stem, e.g. 2_1_floorplan # $(2) dependencies # $(3) tcl script step # $(4) extension of result, default .odb # $(5) folder of target, default $(RESULTS_DIR) define do-step $(if $(5),$(5),$(RESULTS_DIR))/$(1)$(if $(4),$(4),.odb): $(2) $$(UNSET_AND_MAKE) do-$(1) ifeq ($(if $(4),$(4),.odb),.odb) .PHONY: $(1) $(1): $(RESULTS_DIR)/$(1).odb $(eval $(call OPEN_GUI_SHORTCUT,$(1),$(1).odb)) endif .PHONY: do-$(1) do-$(1): $(OBJECTS_DIR)/copyright.txt $(SCRIPTS_DIR)/flow.sh $(1) $(3) endef # generate make rules to copy a file, if a dependency change and # a do- sibling rule that copies the file unconditionally. # # The file is copied within the $(RESULTS_DIR) # # $(1) stem of target, e.g. 2_1_floorplan # $(2) basename of file to be copied # $(3) further dependencies # $(4) target extension, default .odb define do-copy $(RESULTS_DIR)/$(1)$(if $(4),$(4),.odb): $(RESULTS_DIR)/$(2) $(3) $$(UNSET_AND_MAKE) do-$(1)$(if $(4),$(4),) .PHONY: do-$(1)$(if $(4),$(4),) do-$(1)$(if $(4),$(4),): cp $(RESULTS_DIR)/$(2) $(RESULTS_DIR)/$(1)$(if $(4),$(4),.odb) endef # STEP 1: Translate verilog to odb #------------------------------------------------------------------------------- $(eval $(call do-step,2_1_floorplan,$(RESULTS_DIR)/1_synth.v $(RESULTS_DIR)/1_synth.sdc $(TECH_LEF) $(SC_LEF) $(ADDITIONAL_LEFS) $(FOOTPRINT) $(SIG_MAP_FILE) $(FOOTPRINT_TCL) $(DONT_USE_SC_LIB),floorplan)) $(eval $(call do-copy,2_floorplan,2_1_floorplan.sdc,,.sdc)) # STEP 2: Macro Placement #------------------------------------------------------------------------------- $(eval $(call do-step,2_2_floorplan_macro,$(RESULTS_DIR)/2_1_floorplan.odb $(RESULTS_DIR)/1_synth.v $(RESULTS_DIR)/1_synth.sdc $(MACRO_PLACEMENT) $(MACRO_PLACEMENT_TCL),macro_place)) # STEP 3: Tapcell and Welltie insertion #------------------------------------------------------------------------------- $(eval $(call do-step,2_3_floorplan_tapcell,$(RESULTS_DIR)/2_2_floorplan_macro.odb $(TAPCELL_TCL),tapcell)) # STEP 4: PDN generation #------------------------------------------------------------------------------- $(eval $(call do-step,2_4_floorplan_pdn,$(RESULTS_DIR)/2_3_floorplan_tapcell.odb $(PDN_TCL),pdn)) $(eval $(call do-copy,2_floorplan,2_4_floorplan_pdn.odb,)) $(RESULTS_DIR)/2_floorplan.sdc: $(RESULTS_DIR)/2_1_floorplan.odb .PHONY: do-floorplan do-floorplan: $(UNSET_AND_MAKE) do-2_1_floorplan do-2_2_floorplan_macro do-2_3_floorplan_tapcell do-2_4_floorplan_pdn do-2_floorplan do-2_floorplan.sdc .PHONY: clean_floorplan clean_floorplan: rm -f $(RESULTS_DIR)/2_*floorplan*.odb $(RESULTS_DIR)/2_floorplan.sdc $(RESULTS_DIR)/2_*.v $(RESULTS_DIR)/2_*.def rm -f $(REPORTS_DIR)/2_* rm -f $(LOG_DIR)/2_* # ============================================================================== # ____ _ _ ____ _____ # | _ \| | / \ / ___| ____| # | |_) | | / _ \| | | _| # | __/| |___ / ___ \ |___| |___ # |_| |_____/_/ \_\____|_____| # .PHONY: place place: $(RESULTS_DIR)/3_place.odb \ $(RESULTS_DIR)/3_place.sdc # ============================================================================== # STEP 1: Global placement without placed IOs, timing-driven, and routability-driven. #------------------------------------------------------------------------------- $(eval $(call do-step,3_1_place_gp_skip_io,$(RESULTS_DIR)/2_floorplan.odb $(RESULTS_DIR)/2_floorplan.sdc $(LIB_FILES),global_place_skip_io)) $(eval $(call do-step,3_2_place_iop,$(RESULTS_DIR)/3_1_place_gp_skip_io.odb $(IO_CONSTRAINTS),io_placement)) # STEP 3: Global placement with placed IOs, timing-driven, and routability-driven. #------------------------------------------------------------------------------- $(eval $(call do-step,3_3_place_gp,$(RESULTS_DIR)/3_2_place_iop.odb $(RESULTS_DIR)/2_floorplan.sdc $(LIB_FILES),global_place)) # STEP 4: Resizing & Buffering #------------------------------------------------------------------------------- $(eval $(call do-step,3_4_place_resized,$(RESULTS_DIR)/3_3_place_gp.odb $(RESULTS_DIR)/2_floorplan.sdc,resize)) .PHONY: clean_resize clean_resize: rm -f $(RESULTS_DIR)/3_4_place_resized.odb # STEP 5: Detail placement #------------------------------------------------------------------------------- $(eval $(call do-step,3_5_place_dp,$(RESULTS_DIR)/3_4_place_resized.odb,detail_place)) $(eval $(call do-copy,3_place,3_5_place_dp.odb,)) $(eval $(call do-copy,3_place,2_floorplan.sdc,,.sdc)) .PHONY: do-place do-place: $(UNSET_AND_MAKE) do-3_1_place_gp_skip_io do-3_2_place_iop do-3_3_place_gp do-3_4_place_resized do-3_5_place_dp do-3_place do-3_place.sdc # Clean Targets #------------------------------------------------------------------------------- .PHONY: clean_place clean_place: rm -f $(RESULTS_DIR)/3_*place*.odb rm -f $(RESULTS_DIR)/3_place.sdc rm -f $(RESULTS_DIR)/3_*.def $(RESULTS_DIR)/3_*.v rm -f $(REPORTS_DIR)/3_* rm -f $(LOG_DIR)/3_* # ============================================================================== # ____ _____ ____ # / ___|_ _/ ___| # | | | | \___ \ # | |___ | | ___) | # \____| |_| |____/ # .PHONY: cts cts: $(RESULTS_DIR)/4_cts.odb \ $(RESULTS_DIR)/4_cts.sdc # ============================================================================== # Run TritonCTS # ------------------------------------------------------------------------------ $(eval $(call do-step,4_1_cts,$(RESULTS_DIR)/3_place.odb $(RESULTS_DIR)/3_place.sdc,cts)) $(RESULTS_DIR)/4_cts.sdc: $(RESULTS_DIR)/4_cts.odb $(eval $(call do-copy,4_cts,4_1_cts.odb)) .PHONY: do-cts do-cts: $(UNSET_AND_MAKE) do-4_1_cts do-4_cts .PHONY: clean_cts clean_cts: rm -rf $(RESULTS_DIR)/4_*cts*.odb $(RESULTS_DIR)/4_cts.sdc $(RESULTS_DIR)/4_*.v $(RESULTS_DIR)/4_*.def rm -f $(REPORTS_DIR)/4_* rm -rf $(LOG_DIR)/4_* # ============================================================================== # ____ ___ _ _ _____ ___ _ _ ____ # | _ \ / _ \| | | |_ _|_ _| \ | |/ ___| # | |_) | | | | | | | | | | || \| | | _ # | _ <| |_| | |_| | | | | || |\ | |_| | # |_| \_\\___/ \___/ |_| |___|_| \_|\____| # .PHONY: route route: $(RESULTS_DIR)/5_route.odb \ $(RESULTS_DIR)/5_route.sdc .PHONY: grt grt: $(RESULTS_DIR)/5_1_grt.odb # ============================================================================== # STEP 1: Run global route #------------------------------------------------------------------------------- $(eval $(call do-step,5_1_grt,$(RESULTS_DIR)/4_cts.odb $(FASTROUTE_TCL) $(PRE_GLOBAL_ROUTE),global_route)) # STEP 2: Run detailed route #------------------------------------------------------------------------------- $(eval $(call do-step,5_2_route,$(RESULTS_DIR)/5_1_grt.odb,detail_route)) $(eval $(call do-step,5_3_fillcell,$(RESULTS_DIR)/5_2_route.odb,fillcell)) $(eval $(call do-copy,5_route,5_3_fillcell.odb)) $(eval $(call do-copy,5_route,5_1_grt.sdc,,.sdc)) .PHONY: do-route do-route: $(UNSET_AND_MAKE) do-5_1_grt do-5_2_route do-5_3_fillcell do-5_route do-5_route.sdc .PHONY: do-grt do-grt: $(UNSET_AND_MAKE) do-5_1_grt .PHONY: clean_route clean_route: rm -rf output*/ results*.out.dmp layer_*.mps rm -rf *.gdid *.log *.met *.sav *.res.dmp rm -rf $(RESULTS_DIR)/route.guide $(RESULTS_DIR)/output_guide.mod $(RESULTS_DIR)/updated_clks.sdc rm -rf $(RESULTS_DIR)/5_*.odb $(RESULTS_DIR)/5_route.sdc $(RESULTS_DIR)/5_*.def $(RESULTS_DIR)/5_*.v rm -f $(REPORTS_DIR)/5_* rm -f $(LOG_DIR)/5_* .PHONY: klayout_tr_rpt klayout_tr_rpt: $(RESULTS_DIR)/5_route.def $(OBJECTS_DIR)/klayout.lyt $(call KLAYOUT_FOUND) $(KLAYOUT_CMD) -rd in_drc="$(REPORTS_DIR)/5_route_drc.rpt" \ -rd in_def="$<" \ -rd tech_file=$(OBJECTS_DIR)/klayout.lyt \ -rm $(UTILS_DIR)/viewDrc.py .PHONY: klayout_guides klayout_guides: $(RESULTS_DIR)/5_route.def $(OBJECTS_DIR)/klayout.lyt $(call KLAYOUT_FOUND) $(KLAYOUT_CMD) -rd in_guide="$(RESULTS_DIR)/route.guide" \ -rd in_def="$<" \ -rd net_name=$(GUIDE_NET) \ -rd tech_file=$(OBJECTS_DIR)/klayout.lyt \ -rm $(UTILS_DIR)/viewGuide.py # ============================================================================== # _____ ___ _ _ ___ ____ _ _ ___ _ _ ____ # | ___|_ _| \ | |_ _/ ___|| | | |_ _| \ | |/ ___| # | |_ | || \| || |\___ \| |_| || || \| | | _ # | _| | || |\ || | ___) | _ || || |\ | |_| | # |_| |___|_| \_|___|____/|_| |_|___|_| \_|\____| # .PHONY: finish finish: $(LOG_DIR)/6_report.log \ $(RESULTS_DIR)/6_final.v \ $(RESULTS_DIR)/6_final.sdc \ $(GDS_FINAL_FILE) $(UNSET_AND_MAKE) elapsed .PHONY: elapsed elapsed: -@$(UTILS_DIR)/genElapsedTime.py -d $(BLOCK_LOG_FOLDERS) $(LOG_DIR) # Useful when working with macros, see elapsed time for all macros in platform .PHONY: elapsed-all elapsed-all: @$(UTILS_DIR)/genElapsedTime.py -d $(shell find $(WORK_HOME)/logs/$(PLATFORM)/*/*/ -type d) $(eval $(call do-step,6_1_fill,$(RESULTS_DIR)/5_route.odb $(RESULTS_DIR)/5_route.sdc $(FILL_CONFIG),density_fill)) $(eval $(call do-copy,6_1_fill,5_route.sdc,,.sdc)) $(eval $(call do-copy,6_final,5_route.sdc,,.sdc)) $(eval $(call do-step,6_report,$(RESULTS_DIR)/6_1_fill.odb $(RESULTS_DIR)/6_1_fill.sdc,final_report,.log,$(LOG_DIR))) $(RESULTS_DIR)/6_final.def: $(LOG_DIR)/6_report.log # The final results are called 6_final.*, so it is convenient when scripting # to have the names of the artifacts match the name of the target .PHONY: do-final do-final: do-finish .PHONY: final final: finish .PHONY: do-finish do-finish: $(UNSET_AND_MAKE) do-6_1_fill do-6_1_fill.sdc do-6_final.sdc do-6_report do-gds elapsed .PHONY: generate_abstract generate_abstract: $(RESULTS_DIR)/6_final.gds $(RESULTS_DIR)/6_final.def $(RESULTS_DIR)/6_final.v $(RESULTS_DIR)/6_final.sdc $(UNSET_AND_MAKE) do-generate_abstract # Set ABSTRACT_SOURCE if you want to create an abstract from another stage than 6_final. .PHONY: do-generate_abstract do-generate_abstract: mkdir -p $(LOG_DIR) $(REPORTS_DIR) ($(TIME_CMD) $(OPENROAD_CMD) $(SCRIPTS_DIR)/generate_abstract.tcl -metrics $(LOG_DIR)/generate_abstract.json) 2>&1 | tee $(abspath $(LOG_DIR)/generate_abstract.log) .PHONY: clean_abstract clean_abstract: rm -f $(RESULTS_DIR)/$(DESIGN_NAME).lib $(RESULTS_DIR)/$(DESIGN_NAME).lef # Merge wrapped macros using Klayout #------------------------------------------------------------------------------- $(WRAPPED_GDSOAS): $(OBJECTS_DIR)/klayout_wrap.lyt $(WRAPPED_LEFS) $(call KLAYOUT_FOUND) ($(TIME_CMD) $(KLAYOUT_CMD) -zz -rd design_name=$(basename $(notdir $@)) \ -rd in_def=$(OBJECTS_DIR)/def/$(notdir $(@:$(STREAM_SYSTEM_EXT)=def)) \ -rd in_files="$(ADDITIONAL_GDSOAS)" \ -rd config_file=$(FILL_CONFIG) \ -rd seal_file="" \ -rd out_file=$@ \ -rd tech_file=$(OBJECTS_DIR)/klayout_wrap.lyt \ -rd layer_map=$(GDS_LAYER_MAP) \ -r $(UTILS_DIR)/def2stream.py) 2>&1 | tee $(abspath $(LOG_DIR)/6_merge_$(basename $(notdir $@)).log) # Merge GDS using Klayout #------------------------------------------------------------------------------- $(GDS_MERGED_FILE): $(RESULTS_DIR)/6_final.def $(OBJECTS_DIR)/klayout.lyt $(GDSOAS_FILES) $(WRAPPED_GDSOAS) $(SEAL_GDSOAS) $(UNSET_AND_MAKE) do-gds-merged .PHONY: do-gds-merged do-gds-merged: $(call KLAYOUT_FOUND) ($(TIME_CMD) $(STDBUF_CMD) $(KLAYOUT_CMD) -zz -rd design_name=$(DESIGN_NAME) \ -rd in_def=$(RESULTS_DIR)/6_final.def \ -rd in_files="$(GDSOAS_FILES) $(WRAPPED_GDSOAS)" \ -rd seal_file="$(SEAL_GDSOAS)" \ -rd out_file=$(GDS_MERGED_FILE) \ -rd tech_file=$(OBJECTS_DIR)/klayout.lyt \ -rd layer_map=$(GDS_LAYER_MAP) \ -r $(UTILS_DIR)/def2stream.py) 2>&1 | tee $(abspath $(LOG_DIR)/6_1_merge.log) $(RESULTS_DIR)/6_final.v: $(LOG_DIR)/6_report.log .PHONY: do-gds do-gds: $(UNSET_AND_MAKE) do-klayout_tech do-klayout do-klayout_wrap do-gds-merged cp $(GDS_MERGED_FILE) $(GDS_FINAL_FILE) $(GDS_FINAL_FILE): $(GDS_MERGED_FILE) cp $< $@ .PHONY: drc drc: $(REPORTS_DIR)/6_drc.lyrdb $(REPORTS_DIR)/6_drc.lyrdb: $(GDS_FINAL_FILE) $(KLAYOUT_DRC_FILE) ifneq ($(KLAYOUT_DRC_FILE),) $(call KLAYOUT_FOUND) ($(TIME_CMD) $(KLAYOUT_CMD) -zz -rd in_gds="$<" \ -rd report_file=$(abspath $@) \ -r $(KLAYOUT_DRC_FILE)) 2>&1 | tee $(abspath $(LOG_DIR)/6_drc.log) # Hacky way of getting DRV count (don't error on no matches) grep -c "<value>" $@ > $(REPORTS_DIR)/6_drc_count.rpt || [[ $$? == 1 ]] else echo "DRC not supported on this platform" > $@ endif $(RESULTS_DIR)/6_final.cdl: $(RESULTS_DIR)/6_final.v ($(TIME_CMD) $(OPENROAD_CMD) $(SCRIPTS_DIR)/cdl.tcl) 2>&1 | tee $(abspath $(LOG_DIR)/6_cdl.log) $(OBJECTS_DIR)/6_final_concat.cdl: $(RESULTS_DIR)/6_final.cdl $(CDL_FILE) cat $^ > $@ .PHONY: lvs lvs: $(RESULTS_DIR)/6_lvs.lvsdb $(RESULTS_DIR)/6_lvs.lvsdb: $(GDS_FINAL_FILE) $(KLAYOUT_LVS_FILE) $(OBJECTS_DIR)/6_final_concat.cdl ifneq ($(KLAYOUT_LVS_FILE),) $(call KLAYOUT_FOUND) ($(TIME_CMD) $(KLAYOUT_CMD) -b -rd in_gds="$<" \ -rd cdl_file=$(abspath $(OBJECTS_DIR)/6_final_concat.cdl) \ -rd report_file=$(abspath $@) \ -r $(KLAYOUT_LVS_FILE)) 2>&1 | tee $(abspath $(LOG_DIR)/6_lvs.log) else echo "LVS not supported on this platform" > $@ endif .PHONY: clean_finish clean_finish: rm -rf $(RESULTS_DIR)/6_*.gds $(RESULTS_DIR)/6_*.oas $(RESULTS_DIR)/6_*.odb $(RESULTS_DIR)/6_*.v $(RESULTS_DIR)/6_*.def $(RESULTS_DIR)/6_*.sdc $(RESULTS_DIR)/6_*.spef rm -rf $(REPORTS_DIR)/6_*.rpt rm -f $(LOG_DIR)/6_* # ============================================================================== # __ __ ___ ____ ____ # | \/ |_ _/ ___| / ___| # | |\/| || |\___ \| | # | | | || | ___) | |___ # |_| |_|___|____/ \____| # # ============================================================================== .PHONY: all all: synth floorplan place cts route finish .PHONY: clean clean: @echo @echo "Make clean disabled." @echo "Use make clean_all or clean individual steps:" @echo " clean_synth clean_floorplan clean_place clean_cts clean_route clean_finish" @echo .PHONY: clean_all clean_all: clean_synth clean_floorplan clean_place clean_cts clean_route clean_finish clean_metadata clean_abstract rm -rf $(OBJECTS_DIR) .PHONY: nuke nuke: clean_test clean_issues rm -rf ./results ./logs ./reports ./objects rm -rf layer_*.mps macrocell.list *best.plt *_pdn.def rm -rf *.rpt *.rpt.old *.def.v pin_dumper.log rm -f $(OBJECTS_DIR)/versions.txt $(OBJECTS_DIR)/copyright.txt dummy.guide # DEF/GDS/OAS viewer shortcuts #------------------------------------------------------------------------------- .PHONY: $(foreach file,$(RESULTS_DEF) $(RESULTS_GDS) $(RESULTS_OAS),klayout_$(file)) $(foreach file,$(RESULTS_DEF) $(RESULTS_GDS) $(RESULTS_OAS),klayout_$(file)): klayout_%: $(OBJECTS_DIR)/klayout.lyt $(KLAYOUT_CMD) -nn $(OBJECTS_DIR)/klayout.lyt $(RESULTS_DIR)/$* .PHONY: gui_synth gui_synth: $(OPENROAD_GUI_CMD) $(SCRIPTS_DIR)/sta-synth.tcl .PHONY: open_synth open_synth: $(OPENROAD_NO_EXIT_CMD) $(SCRIPTS_DIR)/sta-synth.tcl $(eval $(call OPEN_GUI_SHORTCUT,floorplan,2_floorplan.odb)) $(eval $(call OPEN_GUI_SHORTCUT,place,3_place.odb)) $(eval $(call OPEN_GUI_SHORTCUT,cts,4_cts.odb)) $(eval $(call OPEN_GUI_SHORTCUT,route,5_route.odb)) $(eval $(call OPEN_GUI_SHORTCUT,grt,5_1_grt.odb)) $(eval $(call OPEN_GUI_SHORTCUT,final,6_final.odb)) $(foreach file,$(RESULTS_DEF),$(eval $(call OPEN_GUI,$(file),DEF_FILE))) $(foreach file,$(RESULTS_ODB),$(eval $(call OPEN_GUI,$(file),ODB_FILE))) # Write a def for the corresponding odb $(foreach file,$(RESULTS_ODB),$(file).def): %.def: ODB_FILE=$(RESULTS_DIR)/$* DEF_FILE=$(RESULTS_DIR)/$@ $(OPENROAD_CMD) $(SCRIPTS_DIR)/write_def.tcl # # Write a verilog for the corresponding odb $(foreach file,$(RESULTS_ODB),$(file).v): %.v: ODB_FILE=$(RESULTS_DIR)/$* VERILOG_FILE=$(RESULTS_DIR)/$@ $(OPENROAD_CMD) $(SCRIPTS_DIR)/write_verilog.tcl # Drop into yosys with all environment variables, useful to for instance # debug synthesis, or run other commands aftewards, such as "show" to # generate a .dot file of the design to visualize designs. .PHONY: yosys yosys: $(YOSYS_EXE) # Drop into a bash shell with all environment variables, useful for debugging .PHONY: bash bash: bash --init-file <(echo "PS1='\[\e[32m\]Makefile Environment \[\e[0m\] \w $ '") .PHONY: all_defs all_defs : $(foreach file,$(RESULTS_ODB),$(file).def) .PHONY: all_verilog all_verilog : $(foreach file,$(RESULTS_ODB),$(file).v) .PHONY: handoff handoff : all_defs all_verilog .PHONY: test-unset-and-make-% test-unset-and-make-%: ; $(UNSET_AND_MAKE) $* .phony: klayout klayout: $(KLAYOUT_CMD) .phony: run run: @mkdir -p $(RESULTS_DIR) $(LOG_DIR) $(REPORTS_DIR) $(OBJECTS_DIR) ($(OPENROAD_CMD) -no_splash $(if $(filter %.py,$(RUN_SCRIPT)),-python) $(RUN_SCRIPT) 2>&1 | tee $(abspath $(LOG_DIR)/$(RUN_LOG_NAME_STEM).log)) export RUN_YOSYS_ARGS ?= -c $(SCRIPTS_DIR)/yosys_keep.tcl .phony: run-yosys run-yosys: $(YOSYS_EXE) $(RUN_YOSYS_ARGS) # Utilities #------------------------------------------------------------------------------- include $(UTILS_DIR)/utils.mk export PRIVATE_DIR ?= ../../private_tool_scripts -include $(PRIVATE_DIR)/private.mk 找到YOSYS_EXE定义的位置
07-16
分析代码:################################################################################ # # Linux kernel target # ################################################################################ LINUX_VERSION = $(call qstrip,$(BR2_LINUX_KERNEL_VERSION)) LINUX_LICENSE = GPLv2 LINUX_LICENSE_FILES = COPYING # Compute LINUX_SOURCE and LINUX_SITE from the configuration ifeq ($(BR2_LINUX_KERNEL_CUSTOM_TARBALL),y) LINUX_TARBALL = $(call qstrip,$(BR2_LINUX_KERNEL_CUSTOM_TARBALL_LOCATION)) LINUX_SITE = $(patsubst %/,%,$(dir $(LINUX_TARBALL))) LINUX_SOURCE = $(notdir $(LINUX_TARBALL)) BR_NO_CHECK_HASH_FOR += $(LINUX_SOURCE) else ifeq ($(BR2_LINUX_KERNEL_CUSTOM_LOCAL),y) LINUX_SITE = $(call qstrip,$(BR2_LINUX_KERNEL_CUSTOM_LOCAL_PATH)) LINUX_SITE_METHOD = local else ifeq ($(BR2_LINUX_KERNEL_CUSTOM_GIT),y) LINUX_SITE = $(call qstrip,$(BR2_LINUX_KERNEL_CUSTOM_REPO_URL)) LINUX_SITE_METHOD = git else ifeq ($(BR2_LINUX_KERNEL_CUSTOM_HG),y) LINUX_SITE = $(call qstrip,$(BR2_LINUX_KERNEL_CUSTOM_REPO_URL)) LINUX_SITE_METHOD = hg else LINUX_SOURCE = linux-$(LINUX_VERSION).tar.xz ifeq ($(BR2_LINUX_KERNEL_CUSTOM_VERSION),y) BR_NO_CHECK_HASH_FOR += $(LINUX_SOURCE) endif ifeq ($(BR2_LINUX_KERNEL_SAME_AS_HEADERS)$(BR2_KERNEL_HEADERS_VERSION),yy) BR_NO_CHECK_HASH_FOR += $(LINUX_SOURCE) endif # In X.Y.Z, get X and Y. We replace dots and dashes by spaces in order # to use the $(word) function. We support versions such as 4.0, 3.1, # 2.6.32, 2.6.32-rc1, 3.0-rc6, etc. ifeq ($(findstring x2.6.,x$(LINUX_VERSION)),x2.6.) LINUX_SITE = $(BR2_KERNEL_MIRROR)/linux/kernel/v2.6 else ifeq ($(findstring x3.,x$(LINUX_VERSION)),x3.) LINUX_SITE = $(BR2_KERNEL_MIRROR)/linux/kernel/v3.x else ifeq ($(findstring x4.,x$(LINUX_VERSION)),x4.) LINUX_SITE = $(BR2_KERNEL_MIRROR)/linux/kernel/v4.x endif # release candidates are in testing/ subdir ifneq ($(findstring -rc,$(LINUX_VERSION)),) LINUX_SITE := $(LINUX_SITE)/testing endif # -rc endif LINUX_PATCHES = $(call qstrip,$(BR2_LINUX_KERNEL_PATCH)) # We rely on the generic package infrastructure to download and apply # remote patches (downloaded from ftp, http or https). For local # patches, we can't rely on that infrastructure, because there might # be directories in the patch list (unlike for other packages). LINUX_PATCH = $(filter ftp://% http://% https://%,$(LINUX_PATCHES)) LINUX_INSTALL_IMAGES = YES LINUX_DEPENDENCIES += host-kmod host-lzop host-lzma ifeq ($(BR2_LINUX_KERNEL_UBOOT_IMAGE),y) LINUX_DEPENDENCIES += host-uboot-tools endif LINUX_MAKE_FLAGS = \ HOSTCC="$(HOSTCC)" \ HOSTCFLAGS="$(HOSTCFLAGS)" \ ARCH=$(KERNEL_ARCH) \ INSTALL_MOD_PATH=$(TARGET_DIR) \ CROSS_COMPILE="$(TARGET_CROSS)" \ DEPMOD=$(HOST_DIR)/sbin/depmod LINUX_MAKE_ENV = \ $(TARGET_MAKE_ENV) \ BR_BINARIES_DIR=$(BINARIES_DIR) # Get the real Linux version, which tells us where kernel modules are # going to be installed in the target filesystem. LINUX_VERSION_PROBED = `$(MAKE) $(LINUX_MAKE_FLAGS) -C $(LINUX_DIR) --no-print-directory -s kernelrelease 2>/dev/null` ifeq ($(BR2_LINUX_KERNEL_USE_INTREE_DTS),y) KERNEL_DTS_NAME = $(call qstrip,$(BR2_LINUX_KERNEL_INTREE_DTS_NAME)) else ifeq ($(BR2_LINUX_KERNEL_USE_CUSTOM_DTS),y) # We keep only the .dts files, so that the user can specify both .dts # and .dtsi files in BR2_LINUX_KERNEL_CUSTOM_DTS_PATH. Both will be # copied to arch/<arch>/boot/dts, but only the .dts files will # actually be generated as .dtb. KERNEL_DTS_NAME = $(basename $(filter %.dts,$(notdir $(call qstrip,$(BR2_LINUX_KERNEL_CUSTOM_DTS_PATH))))) endif KERNEL_DTBS = $(addsuffix .dtb,$(KERNEL_DTS_NAME)) ifeq ($(BR2_LINUX_KERNEL_IMAGE_TARGET_CUSTOM),y) LINUX_IMAGE_NAME = $(call qstrip,$(BR2_LINUX_KERNEL_IMAGE_NAME)) LINUX_TARGET_NAME = $(call qstrip,$(BR2_LINUX_KERNEL_IMAGE_TARGET_NAME)) ifeq ($(LINUX_IMAGE_NAME),) LINUX_IMAGE_NAME = $(LINUX_TARGET_NAME) endif else ifeq ($(BR2_LINUX_KERNEL_UIMAGE),y) LINUX_IMAGE_NAME = uImage else ifeq ($(BR2_LINUX_KERNEL_APPENDED_UIMAGE),y) LINUX_IMAGE_NAME = uImage else ifeq ($(BR2_LINUX_KERNEL_BZIMAGE),y) LINUX_IMAGE_NAME = bzImage else ifeq ($(BR2_LINUX_KERNEL_ZIMAGE),y) LINUX_IMAGE_NAME = zImage else ifeq ($(BR2_LINUX_KERNEL_ZIMAGE_EPAPR),y) LINUX_IMAGE_NAME = zImage.epapr else ifeq ($(BR2_LINUX_KERNEL_APPENDED_ZIMAGE),y) LINUX_IMAGE_NAME = zImage else ifeq ($(BR2_LINUX_KERNEL_CUIMAGE),y) LINUX_IMAGE_NAME = cuImage.$(KERNEL_DTS_NAME) else ifeq ($(BR2_LINUX_KERNEL_SIMPLEIMAGE),y) LINUX_IMAGE_NAME = simpleImage.$(KERNEL_DTS_NAME) else ifeq ($(BR2_LINUX_KERNEL_IMAGE),y) LINUX_IMAGE_NAME = Image else ifeq ($(BR2_LINUX_KERNEL_LINUX_BIN),y) LINUX_IMAGE_NAME = linux.bin else ifeq ($(BR2_LINUX_KERNEL_VMLINUX_BIN),y) LINUX_IMAGE_NAME = vmlinux.bin else ifeq ($(BR2_LINUX_KERNEL_VMLINUX),y) LINUX_IMAGE_NAME = vmlinux else ifeq ($(BR2_LINUX_KERNEL_VMLINUZ),y) LINUX_IMAGE_NAME = vmlinuz endif # The if-else blocks above are all the image types we know of, and all # come from a Kconfig choice, so we know we have LINUX_IMAGE_NAME set # to something LINUX_TARGET_NAME = $(LINUX_IMAGE_NAME) endif LINUX_KERNEL_UIMAGE_LOADADDR = $(call qstrip,$(BR2_LINUX_KERNEL_UIMAGE_LOADADDR)) ifneq ($(LINUX_KERNEL_UIMAGE_LOADADDR),) LINUX_MAKE_FLAGS += LOADADDR="$(LINUX_KERNEL_UIMAGE_LOADADDR)" endif # Compute the arch path, since i386 and x86_64 are in arch/x86 and not # in arch/$(KERNEL_ARCH). Even if the kernel creates symbolic links # for bzImage, arch/i386 and arch/x86_64 do not exist when copying the # defconfig file. ifeq ($(KERNEL_ARCH),i386) KERNEL_ARCH_PATH = $(LINUX_DIR)/arch/x86 else ifeq ($(KERNEL_ARCH),x86_64) KERNEL_ARCH_PATH = $(LINUX_DIR)/arch/x86 else KERNEL_ARCH_PATH = $(LINUX_DIR)/arch/$(KERNEL_ARCH) endif ifeq ($(BR2_LINUX_KERNEL_VMLINUX),y) LINUX_IMAGE_PATH = $(LINUX_DIR)/$(LINUX_IMAGE_NAME) else ifeq ($(BR2_LINUX_KERNEL_VMLINUZ),y) LINUX_IMAGE_PATH = $(LINUX_DIR)/$(LINUX_IMAGE_NAME) else LINUX_IMAGE_PATH = $(KERNEL_ARCH_PATH)/boot/$(LINUX_IMAGE_NAME) endif # BR2_LINUX_KERNEL_VMLINUX define LINUX_APPLY_LOCAL_PATCHES for p in $(filter-out ftp://% http://% https://%,$(LINUX_PATCHES)) ; do \ if test -d $$p ; then \ $(APPLY_PATCHES) $(@D) $$p \*.patch || exit 1 ; \ else \ $(APPLY_PATCHES) $(@D) `dirname $$p` `basename $$p` || exit 1; \ fi \ done endef LINUX_POST_PATCH_HOOKS += LINUX_APPLY_LOCAL_PATCHES ifeq ($(BR2_LINUX_KERNEL_USE_DEFCONFIG),y) KERNEL_SOURCE_CONFIG = $(KERNEL_ARCH_PATH)/configs/$(call qstrip,$(BR2_LINUX_KERNEL_DEFCONFIG))_defconfig else ifeq ($(BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG),y) KERNEL_SOURCE_CONFIG = $(call qstrip,$(BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE)) endif LINUX_KCONFIG_FILE = $(KERNEL_SOURCE_CONFIG) LINUX_KCONFIG_FRAGMENT_FILES = $(call qstrip,$(BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES)) LINUX_KCONFIG_EDITORS = menuconfig xconfig gconfig nconfig LINUX_KCONFIG_OPTS = $(LINUX_MAKE_FLAGS) define LINUX_KCONFIG_FIXUP_CMDS $(if $(LINUX_NEEDS_MODULES), $(call KCONFIG_ENABLE_OPT,CONFIG_MODULES,$(@D)/.config)) $(if $(BR2_arm)$(BR2_armeb), $(call KCONFIG_ENABLE_OPT,CONFIG_AEABI,$(@D)/.config)) $(if $(BR2_TARGET_ROOTFS_CPIO), $(call KCONFIG_ENABLE_OPT,CONFIG_BLK_DEV_INITRD,$(@D)/.config)) # As the kernel gets compiled before root filesystems are # built, we create a fake cpio file. It'll be # replaced later by the real cpio archive, and the kernel will be # rebuilt using the linux-rebuild-with-initramfs target. $(if $(BR2_TARGET_ROOTFS_INITRAMFS), touch $(BINARIES_DIR)/rootfs.cpio $(call KCONFIG_SET_OPT,CONFIG_INITRAMFS_SOURCE,"$${BR_BINARIES_DIR}/rootfs.cpio",$(@D)/.config) $(call KCONFIG_SET_OPT,CONFIG_INITRAMFS_ROOT_UID,0,$(@D)/.config) $(call KCONFIG_SET_OPT,CONFIG_INITRAMFS_ROOT_GID,0,$(@D)/.config)) $(if $(BR2_ROOTFS_DEVICE_CREATION_STATIC),, $(call KCONFIG_ENABLE_OPT,CONFIG_DEVTMPFS,$(@D)/.config) $(call KCONFIG_ENABLE_OPT,CONFIG_DEVTMPFS_MOUNT,$(@D)/.config)) $(if $(BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_EUDEV), $(call KCONFIG_ENABLE_OPT,CONFIG_INOTIFY_USER,$(@D)/.config)) $(if $(BR2_PACKAGE_KTAP), $(call KCONFIG_ENABLE_OPT,CONFIG_DEBUG_FS,$(@D)/.config) $(call KCONFIG_ENABLE_OPT,CONFIG_ENABLE_DEFAULT_TRACERS,$(@D)/.config) $(call KCONFIG_ENABLE_OPT,CONFIG_PERF_EVENTS,$(@D)/.config) $(call KCONFIG_ENABLE_OPT,CONFIG_FUNCTION_TRACER,$(@D)/.config)) $(if $(BR2_PACKAGE_SYSTEMD), $(call KCONFIG_ENABLE_OPT,CONFIG_CGROUPS,$(@D)/.config) $(call KCONFIG_ENABLE_OPT,CONFIG_INOTIFY_USER,$(@D)/.config) $(call KCONFIG_ENABLE_OPT,CONFIG_FHANDLE,$(@D)/.config) $(call KCONFIG_ENABLE_OPT,CONFIG_AUTOFS4_FS,$(@D)/.config) $(call KCONFIG_ENABLE_OPT,CONFIG_TMPFS_POSIX_ACL,$(@D)/.config) $(call KCONFIG_ENABLE_OPT,CONFIG_TMPFS_POSIX_XATTR,$(@D)/.config)) $(if $(BR2_PACKAGE_SMACK), $(call KCONFIG_ENABLE_OPT,CONFIG_SECURITY,$(@D)/.config) $(call KCONFIG_ENABLE_OPT,CONFIG_SECURITY_SMACK,$(@D)/.config) $(call KCONFIG_ENABLE_OPT,CONFIG_SECURITY_NETWORK,$(@D)/.config)) $(if $(BR2_PACKAGE_IPTABLES), $(call KCONFIG_ENABLE_OPT,CONFIG_IP_NF_IPTABLES,$(@D)/.config) $(call KCONFIG_ENABLE_OPT,CONFIG_IP_NF_FILTER,$(@D)/.config) $(call KCONFIG_ENABLE_OPT,CONFIG_NETFILTER,$(@D)/.config) $(call KCONFIG_ENABLE_OPT,CONFIG_NETFILTER_XTABLES,$(@D)/.config)) $(if $(BR2_PACKAGE_XTABLES_ADDONS), $(call KCONFIG_ENABLE_OPT,CONFIG_NETFILTER_ADVANCED,$(@D)/.config) $(call KCONFIG_ENABLE_OPT,CONFIG_NF_CONNTRACK,$(@D)/.config) $(call KCONFIG_ENABLE_OPT,CONFIG_NF_CONNTRACK_MARK,$(@D)/.config)) $(if $(BR2_LINUX_KERNEL_APPENDED_DTB), $(call KCONFIG_ENABLE_OPT,CONFIG_ARM_APPENDED_DTB,$(@D)/.config)) endef ifeq ($(BR2_LINUX_KERNEL_DTS_SUPPORT),y) ifeq ($(BR2_LINUX_KERNEL_DTB_IS_SELF_BUILT),) define LINUX_BUILD_DTB $(LINUX_MAKE_ENV) $(MAKE) $(LINUX_MAKE_FLAGS) -C $(@D) $(KERNEL_DTBS) endef define LINUX_INSTALL_DTB # dtbs moved from arch/<ARCH>/boot to arch/<ARCH>/boot/dts since 3.8-rc1 cp $(addprefix \ $(KERNEL_ARCH_PATH)/boot/$(if $(wildcard \ $(addprefix $(KERNEL_ARCH_PATH)/boot/dts/,$(KERNEL_DTBS))),dts/),$(KERNEL_DTBS)) \ $(BINARIES_DIR)/ endef define LINUX_INSTALL_DTB_TARGET # dtbs moved from arch/<ARCH>/boot to arch/<ARCH>/boot/dts since 3.8-rc1 cp $(addprefix \ $(KERNEL_ARCH_PATH)/boot/$(if $(wildcard \ $(addprefix $(KERNEL_ARCH_PATH)/boot/dts/,$(KERNEL_DTBS))),dts/),$(KERNEL_DTBS)) \ $(TARGET_DIR)/boot/ endef endif endif ifeq ($(BR2_LINUX_KERNEL_APPENDED_DTB),y) # dtbs moved from arch/$ARCH/boot to arch/$ARCH/boot/dts since 3.8-rc1 define LINUX_APPEND_DTB if [ -e $(KERNEL_ARCH_PATH)/boot/$(KERNEL_DTS_NAME).dtb ]; then \ cat $(KERNEL_ARCH_PATH)/boot/$(KERNEL_DTS_NAME).dtb; \ else \ cat $(KERNEL_ARCH_PATH)/boot/dts/$(KERNEL_DTS_NAME).dtb; \ fi >> $(KERNEL_ARCH_PATH)/boot/zImage endef ifeq ($(BR2_LINUX_KERNEL_APPENDED_UIMAGE),y) # We need to generate a new u-boot image that takes into # account the extra-size added by the device tree at the end # of the image. To do so, we first need to retrieve both load # address and entry point for the kernel from the already # generate uboot image before using mkimage -l. LINUX_APPEND_DTB += $(sep) MKIMAGE_ARGS=`$(MKIMAGE) -l $(LINUX_IMAGE_PATH) |\ sed -n -e 's/Image Name:[ ]*\(.*\)/-n \1/p' -e 's/Load Address:/-a/p' -e 's/Entry Point:/-e/p'`; \ $(MKIMAGE) -A $(MKIMAGE_ARCH) -O linux \ -T kernel -C none $${MKIMAGE_ARGS} \ -d $(KERNEL_ARCH_PATH)/boot/zImage $(LINUX_IMAGE_PATH); endif endif # Compilation. We make sure the kernel gets rebuilt when the # configuration has changed. define LINUX_BUILD_CMDS $(if $(BR2_LINUX_KERNEL_USE_CUSTOM_DTS), cp $(call qstrip,$(BR2_LINUX_KERNEL_CUSTOM_DTS_PATH)) $(KERNEL_ARCH_PATH)/boot/dts/) $(LINUX_MAKE_ENV) $(MAKE) $(LINUX_MAKE_FLAGS) -C $(@D) $(LINUX_TARGET_NAME) @if grep -q "CONFIG_MODULES=y" $(@D)/.config; then \ $(LINUX_MAKE_ENV) $(MAKE) $(LINUX_MAKE_FLAGS) -C $(@D) modules ; \ fi $(LINUX_BUILD_DTB) $(LINUX_APPEND_DTB) endef ifeq ($(BR2_LINUX_KERNEL_INSTALL_TARGET),y) define LINUX_INSTALL_KERNEL_IMAGE_TO_TARGET install -m 0644 -D $(LINUX_IMAGE_PATH) $(TARGET_DIR)/boot/$(LINUX_IMAGE_NAME) $(LINUX_INSTALL_DTB_TARGET) endef endif define LINUX_INSTALL_HOST_TOOLS # Installing dtc (device tree compiler) as host tool, if selected if grep -q "CONFIG_DTC=y" $(@D)/.config; then \ $(INSTALL) -D -m 0755 $(@D)/scripts/dtc/dtc $(HOST_DIR)/usr/bin/linux-dtc ; \ fi endef define LINUX_INSTALL_IMAGES_CMDS cp $(LINUX_IMAGE_PATH) $(BINARIES_DIR) $(LINUX_INSTALL_DTB) endef define LINUX_INSTALL_TARGET_CMDS $(LINUX_INSTALL_KERNEL_IMAGE_TO_TARGET) # Install modules and remove symbolic links pointing to build # directories, not relevant on the target @if grep -q "CONFIG_MODULES=y" $(@D)/.config; then \ $(LINUX_MAKE_ENV) $(MAKE1) $(LINUX_MAKE_FLAGS) -C $(@D) modules_install; \ rm -f $(TARGET_DIR)/lib/modules/$(LINUX_VERSION_PROBED)/build ; \ rm -f $(TARGET_DIR)/lib/modules/$(LINUX_VERSION_PROBED)/source ; \ fi $(LINUX_INSTALL_HOST_TOOLS) endef # Include all our extensions and tools definitions. # # Note: our package infrastructure uses the full-path of the last-scanned # Makefile to determine what package we're currently defining, using the # last directory component in the path. As such, including other Makefile, # like below, before we call one of the *-package macro is usally not # working. # However, since the files we include here are in the same directory as # the current Makefile, we are OK. But this is a hard requirement: files # included here *must* be in the same directory! include $(sort $(wildcard linux/linux-ext-*.mk)) include $(sort $(wildcard linux/linux-tool-*.mk)) LINUX_PATCH_DEPENDENCIES += $(foreach ext,$(LINUX_EXTENSIONS),\ $(if $(BR2_LINUX_KERNEL_EXT_$(call UPPERCASE,$(ext))),$(ext))) LINUX_PRE_PATCH_HOOKS += $(foreach ext,$(LINUX_EXTENSIONS),\ $(if $(BR2_LINUX_KERNEL_EXT_$(call UPPERCASE,$(ext))),\ $(call UPPERCASE,$(ext))_PREPARE_KERNEL)) # Install Linux kernel tools in the staging directory since some tools # may install shared libraries and headers (e.g. cpupower). The kernel # image is NOT installed in the staging directory. LINUX_INSTALL_STAGING = YES LINUX_DEPENDENCIES += $(foreach tool,$(LINUX_TOOLS),\ $(if $(BR2_LINUX_KERNEL_TOOL_$(call UPPERCASE,$(tool))),\ $($(call UPPERCASE,$(tool))_DEPENDENCIES))) LINUX_POST_BUILD_HOOKS += $(foreach tool,$(LINUX_TOOLS),\ $(if $(BR2_LINUX_KERNEL_TOOL_$(call UPPERCASE,$(tool))),\ $(call UPPERCASE,$(tool))_BUILD_CMDS)) LINUX_POST_INSTALL_STAGING_HOOKS += $(foreach tool,$(LINUX_TOOLS),\ $(if $(BR2_LINUX_KERNEL_TOOL_$(call UPPERCASE,$(tool))),\ $(call UPPERCASE,$(tool))_INSTALL_STAGING_CMDS)) LINUX_POST_INSTALL_TARGET_HOOKS += $(foreach tool,$(LINUX_TOOLS),\ $(if $(BR2_LINUX_KERNEL_TOOL_$(call UPPERCASE,$(tool))),\ $(call UPPERCASE,$(tool))_INSTALL_TARGET_CMDS)) # Checks to give errors that the user can understand ifeq ($(BR_BUILDING),y) ifeq ($(BR2_LINUX_KERNEL_USE_DEFCONFIG),y) ifeq ($(call qstrip,$(BR2_LINUX_KERNEL_DEFCONFIG)),) $(error No kernel defconfig name specified, check your BR2_LINUX_KERNEL_DEFCONFIG setting) endif endif ifeq ($(BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG),y) ifeq ($(call qstrip,$(BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE)),) $(error No kernel configuration file specified, check your BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE setting) endif endif ifeq ($(BR2_LINUX_KERNEL_DTS_SUPPORT)$(KERNEL_DTS_NAME),y) $(error No kernel device tree source specified, check your \ BR2_LINUX_KERNEL_USE_INTREE_DTS / BR2_LINUX_KERNEL_USE_CUSTOM_DTS settings) endif ifeq ($(BR2_LINUX_KERNEL_APPENDED_DTB),y) ifneq ($(words $(KERNEL_DTS_NAME)),1) $(error Kernel with appended device tree needs exactly one DTS source. \ Check BR2_LINUX_KERNEL_INTREE_DTS_NAME or BR2_LINUX_KERNEL_CUSTOM_DTS_PATH.) endif endif endif # BR_BUILDING $(eval $(kconfig-package)) # Support for rebuilding the kernel after the cpio archive has # been generated in $(BINARIES_DIR)/rootfs.cpio. $(LINUX_DIR)/.stamp_initramfs_rebuilt: $(LINUX_DIR)/.stamp_target_installed $(LINUX_DIR)/.stamp_images_installed $(BINARIES_DIR)/rootfs.cpio @$(call MESSAGE,"Rebuilding kernel with initramfs") # Build the kernel. $(LINUX_MAKE_ENV) $(MAKE) $(LINUX_MAKE_FLAGS) -C $(@D) $(LINUX_TARGET_NAME) $(LINUX_APPEND_DTB) # Copy the kernel image to its final destination cp $(LINUX_IMAGE_PATH) $(BINARIES_DIR) # If there is a .ub file copy it to the final destination test ! -f $(LINUX_IMAGE_PATH).ub || cp $(LINUX_IMAGE_PATH).ub $(BINARIES_DIR) $(Q)touch $@ # The initramfs building code must make sure this target gets called # after it generated the initramfs list of files. linux-rebuild-with-initramfs: $(LINUX_DIR)/.stamp_initramfs_rebuilt
最新发布
08-13
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值