cmake: add support for linking with DPDK shared libs
[vpp.git] / src / plugins / dpdk / CMakeLists.txt
1 # Copyright (c) 2016 Cisco and/or its affiliates.
2 # Licensed under the Apache License, Version 2.0 (the "License");
3 # you may not use this file except in compliance with the License.
4 # You may obtain a copy of the License at:
5 #
6 #     http://www.apache.org/licenses/LICENSE-2.0
7 #
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
13
14 if (CMAKE_CROSSCOMPILING)
15   # not supported yet
16   return()
17 endif()
18
19 ##############################################################################
20 # macros
21 ##############################################################################
22 macro(dpdk_find_library var name)
23   find_library(${var} NAMES ${name} ${ARGN})
24 if (NOT ${var})
25   message(WARNING "-- ${name} library not found - dpdk_plugin disabled")
26   return()
27 endif()
28     message(STATUS "DPDK plugin needs ${name} library - found at ${${var}}")
29 endmacro()
30
31 ##############################################################################
32 # Find lib and include files
33 ##############################################################################
34 find_path(DPDK_INCLUDE_DIR PATH_SUFFIXES dpdk NAMES rte_config.h)
35 find_library(DPDK_LIB NAMES libdpdk.a)
36
37 if (NOT DPDK_INCLUDE_DIR)
38   message(WARNING "-- DPDK headers not found - dpdk_plugin disabled")
39   return()
40 endif()
41
42 if (NOT DPDK_LIB)
43   dpdk_find_library(DPDK_SHLIB "libdpdk.so")
44   set(DPDK_IS_SHARED_LIB 1)
45   message(WARNING "-- linking dpdk plugin against DPDK shared libs")
46 endif()
47
48 ##############################################################################
49 # Find DPDK Version
50 ##############################################################################
51 file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/dpdk_vars.c
52 "
53 #include <stdio.h>
54 #include <rte_version.h>
55 int main()
56 {
57   printf(\"VERSION=%s\\n\", strchr(rte_version(), ' ') + 1);
58   printf(\"RTE_PKTMBUF_HEADROOM=%u\\n\", RTE_PKTMBUF_HEADROOM);
59 #ifdef RTE_LIBRTE_PMD_AESNI_MB
60   printf(\"RTE_LIBRTE_PMD_AESNI_MB=%u\\n\", RTE_LIBRTE_PMD_AESNI_MB);
61 #endif
62 #ifdef RTE_LIBRTE_PMD_AESNI_GCM
63   printf(\"RTE_LIBRTE_PMD_AESNI_GCM=%u\\n\", RTE_LIBRTE_PMD_AESNI_GCM);
64 #endif
65 #ifdef RTE_LIBRTE_MLX4_PMD
66   printf(\"RTE_LIBRTE_MLX4_PMD=%u\\n\", RTE_LIBRTE_MLX4_PMD);
67 #endif
68 #ifdef RTE_LIBRTE_MLX5_PMD
69   printf(\"RTE_LIBRTE_MLX5_PMD=%u\\n\", RTE_LIBRTE_MLX5_PMD);
70 #ifdef RTE_LIBRTE_MLX5_DLOPEN_DEPS
71   printf(\"RTE_LIBRTE_MLX5_DLOPEN_DEPS=%u\\n\", RTE_LIBRTE_MLX5_DLOPEN_DEPS);
72 #endif
73 #endif
74   return 0;
75 }
76 ")
77
78 try_compile(DPDK_VARS_COMPILED
79   ${CMAKE_CURRENT_BINARY_DIR}
80   ${CMAKE_CURRENT_BINARY_DIR}/dpdk_vars.c
81   CMAKE_FLAGS
82   -DINCLUDE_DIRECTORIES=${DPDK_INCLUDE_DIR}
83   COPY_FILE ${CMAKE_CURRENT_BINARY_DIR}/dpdk_vars.bin
84 )
85
86 if(DPDK_VARS_COMPILED)
87   execute_process(
88     WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
89     COMMAND ./dpdk_vars.bin
90     OUTPUT_VARIABLE DPDK_VARS
91     OUTPUT_STRIP_TRAILING_WHITESPACE
92   )
93   string(REPLACE "\n" ";" DPDK_VARS ${DPDK_VARS})
94   foreach(v ${DPDK_VARS})
95     string(REPLACE "=" ";" v ${v})
96     list(GET v 0 name)
97     list(GET v 1 value)
98     set(DPDK_${name} ${value})
99   endforeach()
100 endif()
101
102 file(REMOVE
103   ${CMAKE_CURRENT_BINARY_DIR}/dpdk_vars.c
104   ${CMAKE_CURRENT_BINARY_DIR}/dpdk_vars.bin
105 )
106
107 if(NOT ${DPDK_RTE_PKTMBUF_HEADROOM} EQUAL ${PRE_DATA_SIZE})
108   message(
109     FATAL_ERROR
110     "DPDK RTE_PKTMBUF_HEADROOM (${DPDK_RTE_PKTMBUF_HEADROOM}) "
111      "must be equal to PRE_DATA_SIZE (${PRE_DATA_SIZE})"
112   )
113 endif()
114
115 ##############################################################################
116 # static or dynamic linking
117 ##############################################################################
118 unset(DPDK_LINK_LIBRARIES)
119 unset(DPDK_LINK_FLAGS)
120 message(STATUS "Found DPDK ${DPDK_VERSION} in ${DPDK_INCLUDE_DIR}")
121 include_directories (${DPDK_INCLUDE_DIR})
122
123 if(DPDK_IS_SHARED_LIB)
124   get_filename_component(DPDK_LIB_DIR ${DPDK_SHLIB} DIRECTORY)
125   string_append(DPDK_LINK_FLAGS "-L${DPDK_LIB_DIR}")
126   list(APPEND DPDK_LINK_LIBRARIES ${DPDK_SHLIB})
127 else()
128   get_filename_component(DPDK_LIB_DIR ${DPDK_LIB} DIRECTORY)
129   string_append(DPDK_LINK_FLAGS "-L${DPDK_LIB_DIR}")
130   string_append(DPDK_LINK_FLAGS "-Wl,--whole-archive,${DPDK_LIB},--no-whole-archive")
131 endif()
132
133 ##############################################################################
134 # libnuma
135 ##############################################################################
136 dpdk_find_library(NUMA_LIB "numa")
137 list(APPEND DPDK_LINK_LIBRARIES ${NUMA_LIB})
138
139 ##############################################################################
140 # AESNI libraries
141 ##############################################################################
142 if(DPDK_RTE_LIBRTE_PMD_AESNI_MB OR DPDK_RTE_LIBRTE_PMD_AESNI_GCM)
143   if(DPDK_IS_SHARED_LIB)
144     dpdk_find_library(IPSECMB_LIB "libIPSec_MB.so")
145     list(APPEND DPDK_LINK_LIBRARIES "${IPSECMB_LIB}")
146   else()
147     dpdk_find_library(IPSECMB_LIB "libIPSec_MB.a")
148     get_filename_component(IPSECMB_LIB_DIR ${IPSECMB_LIB} DIRECTORY)
149     string_append(DPDK_LINK_FLAGS "-L${IPSECMB_LIB_DIR}")
150     string_append(DPDK_LINK_FLAGS "-Wl,--exclude-libs,libIPSec_MB.a,-l:libIPSec_MB.a")
151   endif()
152 endif()
153
154 ##############################################################################
155 # Mellanox libraries
156 ##############################################################################
157 if(DPDK_RTE_LIBRTE_MLX4_PMD OR DPDK_RTE_LIBRTE_MLX5_PMD)
158   dpdk_find_library(MNL_LIB "mnl")
159   list(APPEND DPDK_LINK_LIBRARIES "${MNL_LIB}")
160   if (DPDK_RTE_LIBRTE_MLX5_DLOPEN_DEPS)
161     message(STATUS "DPDK depends on libmnl (Mellanox PMD requirement)")
162   else()
163     dpdk_find_library(IBVERBS_LIB "ibverbs")
164     list(APPEND DPDK_LINK_LIBRARIES "${IBVERBS_LIB}")
165     dpdk_find_library(MLX5_LIB "mlx5")
166     list(APPEND DPDK_LINK_LIBRARIES "${MLX5_LIB}")
167     message(STATUS "DPDK depends on libmnl, libibverbs, libmlx5 (Mellanox PMD requirement)")
168   endif()
169 endif()
170
171 ##############################################################################
172 # DPDK plugin
173 ##############################################################################
174 add_vpp_plugin(dpdk
175   SOURCES
176   buffer.c
177   main.c
178   thread.c
179   api/dpdk_api.c
180   api/dpdk_test.c
181   device/cli.c
182   device/common.c
183   device/device.c
184   device/flow.c
185   device/format.c
186   device/init.c
187   device/node.c
188   hqos/hqos.c
189   ipsec/cli.c
190   ipsec/crypto_node.c
191   ipsec/esp_decrypt.c
192   ipsec/esp_encrypt.c
193   ipsec/ipsec.c
194
195   MULTIARCH_SOURCES
196   buffer.c
197   device/device.c
198   device/node.c
199   ipsec/crypto_node.c
200   ipsec/esp_decrypt.c
201   ipsec/esp_encrypt.c
202
203   API_FILES
204   api/dpdk.api
205
206   API_TEST_SOURCES
207   api/dpdk_test.c
208
209   INSTALL_HEADERS
210   device/dpdk.h
211   api/dpdk_all_api_h.h
212   ipsec/ipsec.h
213
214   LINK_FLAGS
215   "${DPDK_LINK_FLAGS}"
216
217   LINK_LIBRARIES
218   ${DPDK_LINK_LIBRARIES}
219
220   COMPONENT
221   vpp-plugin-dpdk
222 )
223