本文以 DPDK HelloWorld 示例程序为例。
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2010-2014 Intel Corporation
# binary name
APP = helloworld
# all source are stored in SRCS-y
SRCS-y := main.c
# Build using pkg-config variables if possible
$(shell pkg-config --exists libdpdk)
ifeq ($(.SHELLSTATUS),0)
all: shared
.PHONY: shared static
shared: build/$(APP)-shared
ln -sf $(APP)-shared build/$(APP)
static: build/$(APP)-static
ln -sf $(APP)-static build/$(APP)
PC_FILE := $(shell pkg-config --path libdpdk)
CFLAGS += -O3 $(shell pkg-config --cflags libdpdk)
LDFLAGS_SHARED = $(shell pkg-config --libs libdpdk)
LDFLAGS_STATIC = -Wl,-Bstatic $(shell pkg-config --static --libs libdpdk)
build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build
$(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED)
build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build
$(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC)
build:
@mkdir -p $@
.PHONY: clean
clean:
rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared
rmdir --ignore-fail-on-non-empty build
else
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
CFLAGS += -O3
CFLAGS += $(WERROR_FLAGS)
include $(RTE_SDK)/mk/rte.extapp.mk
endif
文件中必选项为 APP 和 SRCS-y 这两个变量:
所以,上述内容可与简化为:
# binary name
APP = helloworld
# all source are stored in SRCS-y
SRCS-y := main.c
include $(RTE_SDK)/mk/rte.vars.mk
CFLAGS += -O3
CFLAGS += $(WERROR_FLAGS)
include $(RTE_SDK)/mk/rte.extapp.mk
另外两个必选的 Extend Makefile 文件为 rte.vars.mk 和 rte.extapp.mk:
MAKEFLAGS += --no-print-directory
# we must create the output dir first and recall the same Makefile
# from this directory
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 文件中定义了大量的 LDLIBS 变量,用于初始化 DPDK 核心编译过程中生成的所有静态库文件。
_LDLIBS-$(CONFIG_RTE_LIBRTE_FLOW_CLASSIFY) += -lrte_flow_classify
_LDLIBS-$(CONFIG_RTE_LIBRTE_PIPELINE) += --whole-archive
_LDLIBS-y += $(EXECENV_LDLIBS)
LDLIBS += $(_LDLIBS-y) $(CPU_LDLIBS) $(EXTRA_LDLIBS)
LDLIBS 变量包括了 DPDK 所有的库文件,路径为 ${RTE_SDK}/build/lib。
rte.app.mk 文件的编译指令如下:
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)
endif
O_TO_EXE_STR = $(subst ','\'',$(O_TO_EXE)) #'# fix syntax highlight
O_TO_EXE_DISP = $(if $(V),"$(O_TO_EXE_STR)"," LD $(@)")
O_TO_EXE_CMD = "cmd_$@ = $(O_TO_EXE_STR)"
O_TO_EXE_DO = @set -e; \
echo $(O_TO_EXE_DISP); \
$(O_TO_EXE) && \
echo $(O_TO_EXE_CMD) > $(call exe2cmd,$(@))
LD helloworld
。$ cd ${RTE_SDK}/examples/helloworld
$ make
CC main.o
LD helloworld
INSTALL-APP helloworld
INSTALL-MAP helloworld.map
rte.app.mk 文件中的安装指令如下,也会 echo 出编译 DPDK 时执行的安装指令。e.g. INSTALL-APP helloworld
、INSTALL-MAP helloworld.map
。
$(RTE_OUTPUT)/app/$(APP): $(APP)
@echo " INSTALL-APP $(APP)"
@[ -d $(RTE_OUTPUT)/app ] || mkdir -p $(RTE_OUTPUT)/app
$(Q)cp -f $(APP) $(RTE_OUTPUT)/app
$(RTE_OUTPUT)/app/$(APP).map: $(APP)
@echo " INSTALL-MAP $(APP).map"
@[ -d $(RTE_OUTPUT)/app ] || mkdir -p $(RTE_OUTPUT)/app
$(Q)cp -f $(APP).map $(RTE_OUTPUT)/app
安装就是将程序的可执行文件拷贝到特定的目录:
$ ll ${RTE_SDK}/examples/helloworld/build/app
-rwxr-xr-x 1 root root 7174144 6月 19 14:28 helloworld
-rw-r--r-- 1 root root 3733684 6月 19 14:28 helloworld.map
https://blog.csdn.net/sinat_20184565/article/details/89645168