cmake: build spdk/dpdk in cmake modules

Signed-off-by: Kefu Chai <kchai@redhat.com>
Signed-off-by: wanjun.lp <wanjun.lp@alibaba-inc.com>
Signed-off-by: Ziye Yang <optimistyzy@gmail.com>
This commit is contained in:
Kefu Chai 2017-11-15 20:54:46 +08:00
parent 407238a42c
commit 01a9f17825
5 changed files with 181 additions and 17 deletions

View File

@ -217,7 +217,8 @@ endif()
option(WITH_SPDK "Enable SPDK" OFF)
if(WITH_SPDK)
find_package(dpdk REQUIRED)
include(BuildSPDK)
build_spdk()
set(HAVE_SPDK TRUE)
endif(WITH_SPDK)

View File

@ -0,0 +1,118 @@
function(do_build_dpdk dpdk_dir)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "i386")
set(arch "x86_64")
set(machine "default")
set(machine_tmpl "native")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "i686")
set(arch "i686")
set(machine "default")
set(machine_tmpl "native")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64|x86_64|AMD64")
set(arch "x86_64")
set(machine "default")
set(machine_tmpl "native")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "arm|ARM")
set(arch "arm")
set(machine "armv7a")
set(machine_tmpl "armv7a")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|AARCH64")
set(arch "arm64")
set(machine "armv8a")
set(machine_tmpl "armv8a")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(powerpc|ppc)64")
set(arch "ppc_64")
set(machine "power8")
set(machine_tmpl "power8")
else()
message(FATAL_ERROR "not able to build DPDK support: "
"unknown arch \"${CMAKE_SYSTEM_PROCESSOR}\"")
endif()
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
set(execenv "linuxapp")
elseif(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
set(execenv "bsdapp")
else()
message(FATAL_ERROR "not able to build DPDK support: "
"unsupported OS \"${CMAKE_SYSTEM_NAME}\"")
endif()
if(CMAKE_C_COMPILER_ID STREQUAL GNU)
set(toolchain "gcc")
elseif(CMAKE_C_COMPILER_ID STREQUAL Clang)
set(toolchain "clang")
elseif(CMAKE_C_COMPILER_ID STREQUAL Intel)
set(toolchain "icc")
else()
message(FATAL_ERROR "not able to build DPDK support: "
"unknown compiler \"${CMAKE_C_COMPILER_ID}\"")
endif()
set(target "${arch}-${machine_tmpl}-${execenv}-${toolchain}")
execute_process(
COMMAND make showconfigs
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/spdk/dpdk
OUTPUT_VARIABLE supported_targets
OUTPUT_STRIP_TRAILING_WHITESPACE)
string(REPLACE "\n" ";" supported_targets "${supported_targets}")
list(FIND supported_targets ${target} found)
if(found EQUAL -1)
message(FATAL_ERROR "not able to build DPDK support: "
"unsupported target \"${target}\"")
endif()
if(WITH_KERNEL_DIR)
if(NOT IS_DIRECTORY ${WITH_KERNEL_DIR})
message(FATAL "not able to build DPDK support: "
"WITH_KERNEL_DIR=\"${WITH_KERNEL_DIR}\" does not exist")
endif()
else()
execute_process(
COMMAND uname -r
OUTPUT_VARIABLE kernel_release
OUTPUT_STRIP_TRAILING_WHITESPACE)
set(kernel_header_dir "/lib/modules/${kernel_release}/build")
if(NOT IS_DIRECTORY ${kernel_header_dir})
message(FATAL "not able to build DPDK support: "
"\"${kernel_header_dir}\" does not exist. DPDK uses it for building "
"kernel modules. Please either disable WITH_DPDK and WITH_SPDK, "
"or install linux-headers of the kernel version of the target machine, "
"and specify \"-DWITH_RTE_KERNEL_DIR=<the-path-to-the-linux-headers-dir> "
"when running \"cmake\"")
endif()
set(WITH_KERNEL_DIR ${kernel_header_dir})
endif(WITH_KERNEL_DIR)
include(ExternalProject)
ExternalProject_Add(dpdk-ext
SOURCE_DIR ${CMAKE_SOURCE_DIR}/src/spdk/dpdk
CONFIGURE_COMMAND $(MAKE) config O=${dpdk_dir} T=${target}
BUILD_COMMAND env CC=${CMAKE_C_COMPILER} $(MAKE) O=${dpdk_dir} EXTRA_CFLAGS=-fPIC RTE_KERNELDIR=${WITH_KERNEL_DIR}
BUILD_IN_SOURCE 1
INSTALL_COMMAND "true")
ExternalProject_Add_Step(dpdk-ext patch-config
COMMAND ${CMAKE_MODULE_PATH}/patch-dpdk-conf.sh ${dpdk_dir} ${machine}
DEPENDEES configure
DEPENDERS build)
# easier to adjust the config
ExternalProject_Add_StepTargets(dpdk-ext configure patch-config build)
endfunction()
macro(build_dpdk)
set(DPDK_DIR ${CMAKE_BINARY_DIR}/src/dpdk)
do_build_dpdk(${DPDK_DIR})
set(DPDK_INCLUDE_DIR ${DPDK_DIR}/include)
# create the directory so cmake won't complain when looking at the imported
# target
file(MAKE_DIRECTORY ${DPDK_INCLUDE_DIR})
foreach(c eal mempool mempool_ring mempool_stack ring)
add_library(dpdk::${c} STATIC IMPORTED)
add_dependencies(dpdk::${c} dpdk-ext)
set(dpdk_${c}_LIBRARY
"${DPDK_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}rte_${c}${CMAKE_STATIC_LIBRARY_SUFFIX}")
set_target_properties(dpdk::${c} PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES ${DPDK_INCLUDE_DIR}
IMPORTED_LOCATION "${dpdk_${c}_LIBRARY}")
list(APPEND DPDK_LIBRARIES dpdk::${c})
endforeach()
endmacro()

View File

@ -0,0 +1,33 @@
macro(build_spdk)
if(NOT TARGET dpdk-ext)
include(BuildDPDK)
build_dpdk()
endif()
find_package(CUnit REQUIRED)
include(ExternalProject)
ExternalProject_Add(spdk-ext
DEPENDS dpdk-ext
SOURCE_DIR ${CMAKE_SOURCE_DIR}/src/spdk
CONFIGURE_COMMAND ./configure --with-dpdk=${DPDK_DIR}
# unset $CFLAGS, otherwise it will interfere with how SPDK sets
# its include directory.
# unset $LDFLAGS, otherwise SPDK will fail to mock some functions.
BUILD_COMMAND env -i PATH=$ENV{PATH} CC=${CMAKE_C_COMPILER} $(MAKE) EXTRA_CFLAGS="-fPIC"
BUILD_IN_SOURCE 1
INSTALL_COMMAND "true")
ExternalProject_Get_Property(spdk-ext source_dir)
foreach(c nvme log env_dpdk util)
add_library(spdk::${c} STATIC IMPORTED)
add_dependencies(spdk::${c} spdk-ext)
set_target_properties(spdk::${c} PROPERTIES
IMPORTED_LOCATION "${source_dir}/build/lib/${CMAKE_STATIC_LIBRARY_PREFIX}spdk_${c}${CMAKE_STATIC_LIBRARY_SUFFIX}"
INTERFACE_INCLUDE_DIRECTORIES "${source_dir}/include")
list(APPEND SPDK_LIBRARIES spdk::${c})
endforeach()
list(APPEND iface_libs ${DPDK_LIBRARIES} rt)
set_target_properties(spdk::env_dpdk PROPERTIES
INTERFACE_LINK_LIBRARIES "${iface_libs}")
set(SPDK_INCLUDE_DIR "${source_dir}/include")
unset(source_dir)
unset(iface_libs)
endmacro()

View File

@ -0,0 +1,23 @@
# Try to find CUnit
#
# Once done, this will define
#
# CUNIT_FOUND
find_path(CUNIT_INCLUDE_DIR NAMES CUnit/CUnit.h)
find_library(CUNIT_LIBRARY NAMES
cunit
libcunit
cunitlib)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(CUnit
DEFAULT_MSG CUNIT_LIBRARY CUNIT_INCLUDE_DIR)
if(CUNIT_FOUND)
set(CUNIT_LIBRARIES ${CUNIT_LIBRARY})
set(CUNIT_INCLUDE_DIRS ${CUNIT_INCLUDE_DIR})
endif()
mark_as_advanced(CUNIT_INCLUDE_DIR CUNIT_LIBRARY)

View File

@ -90,8 +90,9 @@ if(HAVE_LIBZFS)
endif()
if(WITH_SPDK)
# librt is used by libspdk_env_dpdk
target_link_libraries(os
${SPDK_LIBRARIES}
${SPDK_LIBRARIES} rt
${DPDK_LIBRARIES})
target_include_directories(os
SYSTEM
@ -119,22 +120,10 @@ if(WITH_BLUESTORE)
endif()
if(WITH_SPDK)
include_directories(SYSTEM "${CMAKE_SOURCE_DIR}/src/spdk/include")
add_custom_target(build_spdk
COMMAND
$(MAKE) DPDK_INC_DIR=${DPDK_INCLUDE_DIR}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/spdk/lib
COMMENT "spdk building")
# TODO: should use add_library(spdk INTERFACE IMPORTED) instead in new cmake,
# if INTERFACE is supported.
include(BuildSPDK)
include_directories(SYSTEM ${SPDK_INCLUDE_DIR})
foreach(lib nvme log env_dpdk util)
add_library(spdk_${lib} STATIC IMPORTED)
add_dependencies(spdk_${lib} build_spdk)
target_link_libraries(os PRIVATE spdk_${lib})
set_target_properties(spdk_${lib} PROPERTIES
IMPORTED_LOCATION "${CMAKE_SOURCE_DIR}/src/spdk/build/lib/libspdk_${lib}.a"
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_SOURCE_DIR}/src/spdk/include")
list(APPEND SPDK_LIBRARIES spdk_${lib})
target_link_libraries(os spdk_${lib})
endforeach()
endif(WITH_SPDK)