dpdk 源代码是用 c 语言编写的。example 目录下的例子也都是 c 语言代码,编译时默认使用 gcc 编译。如果用户想仿照这些例子编写自己的 c++ 源码,那么第一个问题便是编译器的问题,因为 gcc 无法编译 c++ 代码。dpdk 邮件组里的 Daniel Kan 给出了如下的解决方案,涉及到 mk/internal/rte.compile-pre.mk 和 mk/toolchain/gcc/rte.vars.mk 两个文件:
1. 修改 mk/internal/rte.compile-pre.mk
以下是修改后的文件和修改前文件的 diff 结果:
@@ -33,11 +33,14 @@ # Common to rte.lib.mk, rte.app.mk, rte.obj.mk # +CXX-suffix = cpp + SRCS-all := $(SRCS-y) $(SRCS-n) $(SRCS-) # convert source to obj file src2obj = $(strip $(patsubst %.c,%.o,\ - $(patsubst %.S,%_s.o,$(1)))) + $(patsubst %.$(CXX-suffix),%.o,\ + $(patsubst %.S,%_s.o,$(1))))) # add a dot in front of the file name dotfile = $(strip $(foreach f,$(1),\ @@ -46,12 +49,14 @@ # convert source/obj files into dot-dep filename (does not # include .S files) src2dep = $(strip $(call dotfile,$(patsubst %.c,%.o.d, \ - $(patsubst %.S,,$(1))))) + $(patsubst %.$(CXX-suffix),%.o.d, \ + $(patsubst %.S,,$(1)))))) obj2dep = $(strip $(call dotfile,$(patsubst %.o,%.o.d,$(1)))) # convert source/obj files into dot-cmd filename src2cmd = $(strip $(call dotfile,$(patsubst %.c,%.o.cmd, \ - $(patsubst %.S,%_s.o.cmd,$(1))))) + $(patsubst %.$(CXX-suffix),%.o.cmd, \ + $(patsubst %.S,%_s.o.cmd,$(1)))))) obj2cmd = $(strip $(call dotfile,$(patsubst %.o,%.o.cmd,$(1)))) OBJS-y := $(call src2obj,$(SRCS-y)) @@ -137,6 +142,22 @@ $(depfile_newer)),\ $(C_TO_O_DO)) +%.o: %.$(CXX-suffix) $$(wildcard $$(dep_$$@)) $$(DEP_$$(@)) 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,$(C_TO_O))) " ; \ + echo -n "depfile_missing=$(call boolean,$(depfile_missing)) " ; \ + echo "depfile_newer=$(call boolean,$(depfile_newer))") + $(if $(or \ + $(file_missing),\ + $(call cmdline_changed,$(C_TO_O)),\ + $(depfile_missing),\ + $(depfile_newer)),\ + $(C_TO_O_DO)) + + # command to assemble a .S file to generate an object ifeq ($(USE_HOST),1) S_TO_O = $(CPP) $(HOST_CPPFLAGS) $($(@)_CPPFLAGS) $(HOST_EXTRA_CPPFLAGS) $< $(@).tmp && \
2. 修改 mk/toolchain/gcc/rte.vars.mk
以下是修改后的文件和修改前文件的 diff 结果:
diff -ur ../temp/dpdk-1.5.1r2/mk/toolchain/gcc/rte.vars.mk mk/toolchain/gcc/rte.vars.mk --- ../temp/dpdk-1.5.1r2/mk/toolchain/gcc/rte.vars.mk 2014-01-02 07:03:19.000000000 -0800 +++ mk/toolchain/gcc/rte.vars.mk 2014-01-13 14:07:33.148292590 -0800 @@ -68,9 +68,16 @@ endif endif +ifeq ($(CC), $(CROSS)g++) +TOOLCHAIN_CFLAGS += -D__STDC_LIMIT_MACROS +WERROR_FLAGS := -W -Wall -Werror +WERROR_FLAGS += -Wmissing-declarations -Wpointer-arith +WERROR_FLAGS += -Wcast-align -Wcast-qual +else WERROR_FLAGS := -W -Wall -Werror -Wstrict-prototypes -Wmissing-prototypes WERROR_FLAGS += -Wmissing-declarations -Wold-style-definition -Wpointer-arith WERROR_FLAGS += -Wcast-align -Wnested-externs -Wcast-qual +endif WERROR_FLAGS += -Wformat-nonliteral -Wformat-security ifeq ($(CONFIG_RTE_EXEC_ENV),"linuxapp")
编译时,如果想使用 g++ 编译,可以指定 make 的 CC 参数:
$ make CC=g++
默认情况下,g++ 只认识 .cpp 扩展名,可以通过 CXX-suffix 指定自己的扩展名
$ make CC=g++ CXX-suffix=cc