DPDK — App 的 Makefile 解析

目錄

DPDK App 的 Makefile

本文以 DPDK HelloWorld 示例程序爲例。

  • DPDK 版本:18.08
# 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 這兩個變量:

  • 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:

  • rte.vars.mk:定義了全局編譯打包時需要用到的一些鏈接選項,例如:CFLAGS、ASFLAGS、LDFLAGS 等變量,以及頭文件和庫文件的路徑等,還有一些和體系架構相關編譯選項。
  • rte.extapp.mk:包含了重要的 mk/rte.app.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,$(@))
  • O_TO_EXE 變量的內容爲具體的編譯命令。
  • O_TO_EXE_DO 變量爲 echo 編譯 DPDK 時執行的編譯指令。e.g. 下述的 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 helloworldINSTALL-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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章