dpdk版本17.11
config
config/defconfig_x86_64-native-linuxapp-gcc
config/common_linuxapp
config/common_base
修改以上文件,make config T=$(RTE_TARGET) O=$(RTE_OUTPUT),生成新的$(RTE_OUTPUT)/.config
注意$(RTE_TARGET)和$(RTE_OUTPUT)最好保持一致
make config
make config,进入GNUmakefile:
include $(RTE_SDK)/mk/rte.sdkroot.mk
在GNUmakefile中,include rte.sdkroot.mk,进入rte.sdkroot.mk:
config defconfig showconfigs showversion showversionum:
$(Q)$(MAKE) -f $(RTE_SDK)/mk/rte.sdkconfig.mk $@
在rte.sdkroot.mk中,匹配config,进入rte.sdkconfig.mk:
ifeq ($(RTE_CONFIG_TEMPLATE),)
config: notemplate
else
config: $(RTE_OUTPUT)/include/rte_config.h $(RTE_OUTPUT)/Makefile
@echo "Configuration done using" \
$(patsubst defconfig_%,%,$(notdir $(RTE_CONFIG_TEMPLATE)))
endif
在rte.sdkconfig.mk中,匹配config,config依赖$(RTE_OUTPUT)/include/rte_config.h和$(RTE_OUTPUT)/Makefile
$(RTE_OUTPUT)/include/rte_config.h
$(RTE_OUTPUT)/include/rte_config.h依赖$(RTE_OUTPUT)/.config,$(RTE_OUTPUT)/.config依赖$(RTE_CONFIG_TEMPLATE):
$(RTE_OUTPUT)/include/rte_config.h: $(RTE_OUTPUT)/.config
$(Q)rm -rf $(RTE_OUTPUT)/include $(RTE_OUTPUT)/app \
$(RTE_OUTPUT)/lib \
$(RTE_OUTPUT)/hostlib $(RTE_OUTPUT)/kmod $(RTE_OUTPUT)/build
$(Q)mkdir -p $(RTE_OUTPUT)/include
$(Q)$(RTE_SDK)/buildtools/gen-config-h.sh $(RTE_OUTPUT)/.config \
> $(RTE_OUTPUT)/include/rte_config.h
ifdef NODOTCONF
$(RTE_OUTPUT)/.config: ;
else
# Generate config from template, if there are duplicates keep only the last.
# To do so the temp config is checked for duplicate keys with cut/sort/uniq
# Then for each of those identified duplicates as long as there are more than
# just one left the last match is removed.
$(RTE_OUTPUT)/.config: $(RTE_CONFIG_TEMPLATE) FORCE | $(RTE_OUTPUT)
$(Q)if [ "$(RTE_CONFIG_TEMPLATE)" != "" -a -f "$(RTE_CONFIG_TEMPLATE)" ]; then \
$(CPP) -undef -P -x assembler-with-cpp \
-ffreestanding \
-o $(RTE_OUTPUT)/.config_tmp $(RTE_CONFIG_TEMPLATE) ; \
config=$$(cat $(RTE_OUTPUT)/.config_tmp) ; \
echo "$$config" | awk -F '=' 'BEGIN {i=1} \
/^#/ {pos[i++]=$$0} \
!/^#/ {if (!s[$$1]) {pos[i]=$$0; s[$$1]=i++} \
else {pos[s[$$1]]=$$0}} END \
{for (j=1; j<i; j++) print pos[j]}' \
> $(RTE_OUTPUT)/.config_tmp ; \
if ! cmp -s $(RTE_OUTPUT)/.config_tmp $(RTE_OUTPUT)/.config; then \
cp $(RTE_OUTPUT)/.config_tmp $(RTE_OUTPUT)/.config ; \
cp $(RTE_OUTPUT)/.config_tmp $(RTE_OUTPUT)/.config.orig ; \
fi ; \
rm -f $(RTE_OUTPUT)/.config_tmp ; \
else \
$(MAKE) -rRf $(RTE_SDK)/mk/rte.sdkconfig.mk notemplate; \
fi
endif
RTE_CONFIG_TEMPLATE :=
ifdef T
ifeq ("$(origin T)", "command line")
RTE_CONFIG_TEMPLATE := $(RTE_SRCDIR)/config/defconfig_$(T)
endif
endif
$(RTE_OUTPUT)/Makefile
$(RTE_OUTPUT)/Makefile: | $(RTE_OUTPUT)
$(Q)$(RTE_SDK)/buildtools/gen-build-mk.sh $(SDK_RELPATH) $(OUTPUT_RELPATH) \
> $(RTE_OUTPUT)/Makefile
综上所述,make config主要做了2件事:
1、先根据RTE_CONFIG_TEMPLATE生成$(RTE_OUTPUT)/.config,再根据gen-config-h.sh生成$(RTE_OUTPUT)/include/rte_config.h
2、根据gen-build-mk.sh生成$(RTE_OUTPUT)/Makefile
make
执行make,进入GNUmakefile -> rte.sdkroot.mk:
default: all
%:
$(Q)$(MAKE) -f $(RTE_SDK)/mk/rte.sdkconfig.mk checkconfig
$(Q)$(MAKE) -f $(RTE_SDK)/mk/rte.sdkbuild.mk $@
在rte.sdkroot.mk中,匹配default,default依赖all,all匹配%:,进入rte.sdkbuild.mk:
all: build
build: $(ROOTDIRS-y)
@echo "Build complete [$(RTE_TARGET)]"
$(ROOTDIRS-y) $(ROOTDIRS-):
@[ -d $(BUILDDIR)/$@ ] || mkdir -p $(BUILDDIR)/$@
@echo "== Build $@"
$(Q)$(MAKE) S=$@ -f $(RTE_SRCDIR)/$@/Makefile -C $(BUILDDIR)/$@ all
@if [ $@ = drivers ]; then \
$(MAKE) -f $(RTE_SDK)/mk/rte.combinedlib.mk; \
fi
在rte.sdkbuild.mk中,匹配all,all依赖build,build依赖ROOTDIRS-y,进入ROOTDIRS-y/Makefile
ROOTDIRS-y
ROOTDIRS-y定义在GNUmakefile中:
ROOTDIRS-y := buildtools lib drivers app
在ROOTDIRS-y/Makefile中,定义DIRS-y和DEPDIRS-xxx,作为rte.subdir.mk的输入:
buildtools/Makefile
include $(RTE_SDK)/mk/rte.vars.mk
DIRS-y += pmdinfogen
include $(RTE_SDK)/mk/rte.subdir.mk
lib/Makefile
include $(RTE_SDK)/mk/rte.vars.mk
DIRS-y += librte_compat
DIRS-$(CONFIG_RTE_LIBRTE_EAL) += librte_eal
DIRS-$(CONFIG_RTE_LIBRTE_PCI) += librte_pci
DEPDIRS-librte_pci := librte_eal
DIRS-$(CONFIG_RTE_LIBRTE_RING) += librte_ring
DEPDIRS-librte_ring := librte_eal
DIRS-$(CONFIG_RTE_LIBRTE_MEMPOOL) += librte_mempool
DEPDIRS-librte_mempool := librte_eal librte_ring
DIRS-$(CONFIG_RTE_LIBRTE_MBUF) += librte_mbuf
DEPDIRS-librte_mbuf := librte_eal librte_mempool
DIRS-$(CONFIG_RTE_LIBRTE_TIMER) += librte_timer
DEPDIRS-librte_timer := librte_eal
DIRS-$(CONFIG_RTE_LIBRTE_CFGFILE) += librte_cfgfile
DIRS-$(CONFIG_RTE_LIBRTE_CMDLINE) += librte_cmdline
DEPDIRS-librte_cmdline := librte_eal
DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ether
DEPDIRS-librte_ether := librte_net librte_eal librte_mempool librte_ring
DEPDIRS-librte_ether += librte_mbuf
DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += librte_cryptodev
DEPDIRS-librte_cryptodev := librte_eal librte_mempool librte_ring librte_mbuf
DEPDIRS-librte_cryptodev += librte_kvargs
DIRS-$(CONFIG_RTE_LIBRTE_SECURITY) += librte_security
DEPDIRS-librte_security := librte_eal librte_mempool librte_ring librte_mbuf
DEPDIRS-librte_security += librte_ether
DEPDIRS-librte_security += librte_cryptodev
DIRS-$(CONFIG_RTE_LIBRTE_EVENTDEV) += librte_eventdev
DEPDIRS-librte_eventdev := librte_eal librte_ring librte_ether librte_hash
DIRS-$(CONFIG_RTE_LIBRTE_VHOST) += librte_vhost
DEPDIRS-librte_vhost := librte_eal librte_mempool librte_mbuf librte_ether
DIRS-$(CONFIG_RTE_LIBRTE_HASH) += librte_hash
DEPDIRS-librte_hash := librte_eal librte_ring
DIRS-$(CONFIG_RTE_LIBRTE_EFD) += librte_efd
DEPDIRS-librte_efd := librte_eal librte_ring librte_hash
DIRS-$(CONFIG_RTE_LIBRTE_LPM) += librte_lpm
DEPDIRS-librte_lpm := librte_eal
DIRS-$(CONFIG_RTE_LIBRTE_ACL) += librte_acl
DEPDIRS-librte_acl := librte_eal
DIRS-$(CONFIG_RTE_LIBRTE_MEMBER) += librte_member
DEPDIRS-librte_member := librte_eal librte_hash
DIRS-$(CONFIG_RTE_LIBRTE_NET) += librte_net
DEPDIRS-librte_net := librte_mbuf librte_eal
DIRS-$(CONFIG_RTE_LIBRTE_IP_FRAG) += librte_ip_frag
DEPDIRS-librte_ip_frag := librte_eal librte_mempool librte_mbuf librte_ether
DEPDIRS-librte_ip_frag += librte_hash
DIRS-$(CONFIG_RTE_LIBRTE_GRO) += librte_gro
DEPDIRS-librte_gro := librte_eal librte_mbuf librte_ether librte_net
DIRS-$(CONFIG_RTE_LIBRTE_JOBSTATS) += librte_jobstats
DEPDIRS-librte_jobstats := librte_eal
DIRS-$(CONFIG_RTE_LIBRTE_METRICS) += librte_metrics
DEPDIRS-librte_metrics := librte_eal
DIRS-$(CONFIG_RTE_LIBRTE_BITRATE) += librte_bitratestats
DEPDIRS-librte_bitratestats := librte_eal librte_metrics librte_ether
DIRS-$(CONFIG_RTE_LIBRTE_LATENCY_STATS) += librte_latencystats
DEPDIRS-librte_latencystats := librte_eal librte_metrics librte_ether librte_mbuf
DIRS-$(CONFIG_RTE_LIBRTE_POWER) += librte_power
DEPDIRS-librte_power := librte_eal
DIRS-$(CONFIG_RTE_LIBRTE_METER) += librte_meter
DEPDIRS-librte_meter := librte_eal
DIRS-$(CONFIG_RTE_LIBRTE_FLOW_CLASSIFY) += librte_flow_classify
DEPDIRS-librte_flow_classify := librte_net librte_table librte_acl
DIRS-$(CONFIG_RTE_LIBRTE_SCHED) += librte_sched
DEPDIRS-librte_sched := librte_eal librte_mempool librte_mbuf librte_net
DEPDIRS-librte_sched += librte_timer
DIRS-$(CONFIG_RTE_LIBRTE_KVARGS) += librte_kvargs
DEPDIRS-librte_kvargs := librte_eal
DIRS-$(CONFIG_RTE_LIBRTE_DISTRIBUTOR) += librte_distributor
DEPDIRS-librte_distributor := librte_eal librte_mbuf librte_ether
DIRS-$(CONFIG_RTE_LIBRTE_PORT) += librte_port
DEPDIRS-librte_port := librte_eal librte_mempool librte_mbuf librte_ether
DEPDIRS-librte_port += librte_ip_frag librte_sched
ifeq ($(CONFIG_RTE_LIBRTE_KNI),y)
DEPDIRS-librte_port += librte_kni
endif
DIRS-$(CONFIG_RTE_LIBRTE_TABLE) += librte_table
DEPDIRS-librte_table := librte_eal librte_mempool librte_mbuf
DEPDIRS-librte_table += librte_port librte_lpm librte_hash
ifeq ($(CONFIG_RTE_LIBRTE_ACL),y)
DEPDIRS-librte_table += librte_acl
endif
DIRS-$(CONFIG_RTE_LIBRTE_PIPELINE) += librte_pipeline
DEPDIRS-librte_pipeline := librte_eal librte_mempool librte_mbuf
DEPDIRS-librte_pipeline += librte_table librte_port
DIRS-$(CONFIG_RTE_LIBRTE_REORDER) += librte_reorder
DEPDIRS-librte_reorder := librte_eal librte_mempool librte_mbuf
DIRS-$(CONFIG_RTE_LIBRTE_PDUMP) += librte_pdump
DEPDIRS-librte_pdump := librte_eal librte_mempool librte_mbuf librte_ether
DIRS-$(CONFIG_RTE_LIBRTE_GSO) += librte_gso
DEPDIRS-librte_gso := librte_eal librte_mbuf librte_ether librte_net
DEPDIRS-librte_gso += librte_mempool
ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
DIRS-$(CONFIG_RTE_LIBRTE_KNI) += librte_kni
endif
DEPDIRS-librte_kni := librte_eal librte_mempool librte_mbuf librte_ether
include $(RTE_SDK)/mk/rte.subdir.mk
drivers/Makefile
include $(RTE_SDK)/mk/rte.vars.mk
DIRS-y += bus
DIRS-y += mempool
DEPDIRS-mempool := bus
DIRS-y += net
DEPDIRS-net := bus mempool
DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += crypto
DEPDIRS-crypto := bus mempool
DIRS-$(CONFIG_RTE_LIBRTE_EVENTDEV) += event
DEPDIRS-event := bus mempool net
include $(RTE_SDK)/mk/rte.subdir.mk
app/Makefile
include $(RTE_SDK)/mk/rte.vars.mk
DIRS-$(CONFIG_RTE_TEST_PMD) += test-pmd
DIRS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += proc_info
DIRS-$(CONFIG_RTE_LIBRTE_PDUMP) += pdump
ifeq ($(CONFIG_RTE_LIBRTE_CRYPTODEV),y)
DIRS-$(CONFIG_RTE_APP_CRYPTO_PERF) += test-crypto-perf
endif
ifeq ($(CONFIG_RTE_LIBRTE_EVENTDEV),y)
DIRS-$(CONFIG_RTE_APP_EVENTDEV) += test-eventdev
endif
include $(RTE_SDK)/mk/rte.subdir.mk
rte.subdir.mk
all: install
install: build _postinstall
build: _postbuild
_postbuild: $(_BUILD)
@touch _postbuild
_BUILD = $(DIRS-y)
$(DIRS-y):
@[ -d $(CURDIR)/$@ ] || mkdir -p $(CURDIR)/$@
@echo "== Build $S/$@"
@$(MAKE) S=$S/$@ -f $(SRCDIR)/$@/Makefile -C $(CURDIR)/$@ all
在rte.subdir.mk中,匹配all,all依赖install,install依赖build,build依赖_postbuild,_postbuild依赖_BUILD,_BUILD定义为DIRS-y,进入ROOTDIRS-y/DIRS-y/Makefile
DIRS-y
如上所述,DIRS-y定义在ROOTDIRS-y/Makefile中
在ROOTDIRS-y/DIRS-y/Makefile中,定义LIB和SRCS-y,作为rte.lib.mk的输入:
lib/librte_mbuf/Makefile
include $(RTE_SDK)/mk/rte.vars.mk
# library name
LIB = librte_mbuf.a
CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -O3
LDLIBS += -lrte_eal -lrte_mempool
EXPORT_MAP := rte_mbuf_version.map
LIBABIVER := 3
# all source are stored in SRCS-y
SRCS-$(CONFIG_RTE_LIBRTE_MBUF) := rte_mbuf.c rte_mbuf_ptype.c
# install includes
SYMLINK-$(CONFIG_RTE_LIBRTE_MBUF)-include := rte_mbuf.h rte_mbuf_ptype.h
include $(RTE_SDK)/mk/rte.lib.mk
rte.lib.mk
all: install
install: build _postinstall
build: _postbuild
_postbuild: $(_BUILD)
@touch _postbuild
_BUILD = $(LIB)
$(LIB): $(OBJS-y) $(DEP_$(LIB)) FORCE
@[ -d $(dir $@) ] || mkdir -p $(dir $@)
$(if $(D),\
@echo -n "$< -> $@ " ; \
echo -n "file_missing=$(call boolean,$(file_missing)) " ; \
echo -n "cmdline_changed=$(call boolean,$(call cmdline_changed,$(O_TO_A_STR))) " ; \
echo -n "depfile_missing=$(call boolean,$(depfile_missing)) " ; \
echo "depfile_newer=$(call boolean,$(depfile_newer)) ")
$(if $(or \
$(file_missing),\
$(call cmdline_changed,$(O_TO_A_STR)),\
$(depfile_missing),\
$(depfile_newer)),\
$(O_TO_A_DO))
O_TO_A_DO = @set -e; \
echo $(O_TO_A_DISP); \
$(O_TO_A) && \
echo $(O_TO_A_CMD) > $(call exe2cmd,$(@))
O_TO_A = $(AR) crDs $(LIB) $(OBJS-y)
OBJS-y := $(call src2obj,$(SRCS-y))
在rte.lib.mk中,匹配all,all依赖install,install依赖build,build依赖_postbuild,_postbuild依赖_BUILD,_BUILD定义为LIB,LIB依赖OBJS-y,OBJS-y根据SRCS-y生成
helloworld/Makefile
在helloworld/Makefile中定义APP和SRCS-y,作为rte.app.mk的输入
ifeq ($(RTE_SDK),)
$(error "Please define RTE_SDK environment variable")
endif
# Default target, can be overridden by command line or environment
RTE_TARGET ?= x86_64-native-linuxapp-gcc
include $(RTE_SDK)/mk/rte.vars.mk
# binary name
APP = helloworld
# all source are stored in SRCS-y
SRCS-y := main.c
CFLAGS += -O3
CFLAGS += $(WERROR_FLAGS)
include $(RTE_SDK)/mk/rte.extapp.mk
rte.extapp.mk
ifeq ($(NOT_FIRST_CALL),)
NOT_FIRST_CALL = 1
export NOT_FIRST_CALL
all:
$(Q)mkdir -p $(RTE_OUTPUT)
$(Q)$(MAKE) -C $(RTE_OUTPUT) -f $(RTE_EXTMK) \
S=$(RTE_SRCDIR) O=$(RTE_OUTPUT) SRCDIR=$(RTE_SRCDIR)
%::
$(Q)mkdir -p $(RTE_OUTPUT)
$(Q)$(MAKE) -C $(RTE_OUTPUT) -f $(RTE_EXTMK) $@ \
S=$(RTE_SRCDIR) O=$(RTE_OUTPUT) SRCDIR=$(RTE_SRCDIR)
else
include $(RTE_SDK)/mk/rte.app.mk
endif
rte.app.mk
all: install
install: build _postinstall
build: _postbuild
_postbuild: $(_BUILD)
@touch _postbuild
_BUILD = $(APP)
$(APP): $(OBJS-y) $(LDLIBS_FILES) $(DEP_$(APP)) $(LDSCRIPT) FORCE
@[ -d $(dir $@) ] || mkdir -p $(dir $@)
$(if $(D),\
@echo -n "$< -> $@ " ; \
echo -n "file_missing=$(call boolean,$(file_missing)) " ; \
echo -n "cmdline_changed=$(call boolean,$(call cmdline_changed,$(O_TO_EXE_STR))) " ; \
echo -n "depfile_missing=$(call boolean,$(depfile_missing)) " ; \
echo "depfile_newer=$(call boolean,$(depfile_newer)) ")
$(if $(or \
$(file_missing),\
$(call cmdline_changed,$(O_TO_EXE_STR)),\
$(depfile_missing),\
$(depfile_newer)),\
$(O_TO_EXE_DO))
O_TO_EXE_DO = @set -e; \
echo $(O_TO_EXE_DISP); \
$(O_TO_EXE) && \
echo $(O_TO_EXE_CMD) > $(call exe2cmd,$(@))
ifeq ($(LINK_USING_CC),1)
O_TO_EXE = $(CC) -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $(OBJS-y) $(call linkerprefix, \
$(LDLIBS) $(LDFLAGS) $(LDFLAGS_$(@)) $(EXTRA_LDFLAGS) \
$(MAPFLAGS))
else
O_TO_EXE = $(LD) -o $@ $(OBJS-y) \
$(LDLIBS) $(LDFLAGS) $(LDFLAGS_$(@)) $(EXTRA_LDFLAGS) \
$(MAPFLAGS)
OBJS-y := $(call src2obj,$(SRCS-y))
在rte.app.mk中,匹配all,all依赖install,install依赖build,build依赖_postbuild,_postbuild依赖_BUILD,_BUILD定义为APP,APP依赖OBJS-y,OBJS-y根据SRCS-y生成