]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
cmake: build spdk/dpdk in cmake modules
authorKefu Chai <kchai@redhat.com>
Wed, 15 Nov 2017 12:54:46 +0000 (20:54 +0800)
committerKefu Chai <kchai@redhat.com>
Fri, 17 Nov 2017 07:37:53 +0000 (15:37 +0800)
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>
CMakeLists.txt
cmake/modules/BuildDPDK.cmake [new file with mode: 0644]
cmake/modules/BuildSPDK.cmake [new file with mode: 0644]
cmake/modules/FindCUnit.cmake [new file with mode: 0644]
src/os/CMakeLists.txt

index 5a9360b604c55d2163a819ccd2bd0245a6b81e70..520c70200779dcf8cde434e1a0b6072f9fcd94b5 100644 (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)
 
diff --git a/cmake/modules/BuildDPDK.cmake b/cmake/modules/BuildDPDK.cmake
new file mode 100644 (file)
index 0000000..4ae38ca
--- /dev/null
@@ -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()
diff --git a/cmake/modules/BuildSPDK.cmake b/cmake/modules/BuildSPDK.cmake
new file mode 100644 (file)
index 0000000..4209d48
--- /dev/null
@@ -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()
diff --git a/cmake/modules/FindCUnit.cmake b/cmake/modules/FindCUnit.cmake
new file mode 100644 (file)
index 0000000..26fea55
--- /dev/null
@@ -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)
index 0744272534764cd511aefbf6d5d3f8f52ff54486..16ac95d0cd7303dd7db111c82aeb985f2f56728d 100644 (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)