1# SPDX-License-Identifier: BSD-3-Clause 2# Copyright(c) 2017-2019 Intel Corporation 3 4if is_ms_compiler 5 subdir_done() 6endif 7 8fs = import('fs') 9 10# Defines the order of dependencies evaluation 11subdirs = [ 12 'common', 13 'bus', 14 'common/cnxk', # depends on bus. 15 'common/mlx5', # depends on bus. 16 'common/nfp', # depends on bus. 17 'common/nitrox', # depends on bus. 18 'common/qat', # depends on bus. 19 'common/sfc_efx', # depends on bus. 20 'mempool', # depends on common and bus. 21 'dma', # depends on common and bus. 22 'net', # depends on common, bus, mempool 23 'raw', # depends on common, bus, dma and net. 24 'crypto', # depends on common, bus and mempool (net in future). 25 'compress', # depends on common, bus, mempool. 26 'regex', # depends on common, bus, regexdev. 27 'ml', # depends on common, bus and mempool 28 'vdpa', # depends on common, bus and mempool. 29 'event', # depends on common, bus, mempool and net. 30 'baseband', # depends on common and bus. 31 'gpu', # depends on common and bus. 32 'power', 33] 34 35if meson.is_cross_build() 36 disable_drivers += ',' + meson.get_external_property('disable_drivers', '') 37 enable_drivers += ',' + meson.get_external_property('enable_drivers', '') 38endif 39 40# add cmdline disabled drivers and meson disabled drivers together 41disable_drivers += ',' + get_option('disable_drivers') 42disable_drivers = run_command(list_dir_globs, disable_drivers, check: true).stdout().split() 43 44# add cmdline enabled drivers and meson enabled drivers together 45enable_drivers = ',' + get_option('enable_drivers') 46enable_drivers = run_command(list_dir_globs, enable_drivers, check: true).stdout().split() 47require_drivers = true 48if enable_drivers.length() == 0 49 require_drivers = false 50 enable_drivers = run_command(list_dir_globs, '*/*,*/*/*', check: true).stdout().split() 51endif 52 53# these drivers must always be enabled, otherwise the build breaks 54always_enable = ['bus/pci', 'bus/vdev'] 55# we always need a mempool driver, and ring is default, so make it mandatory 56always_enable += ['mempool/ring'] 57enable_drivers += always_enable 58 59default_cflags = machine_args 60default_cflags += ['-DALLOW_EXPERIMENTAL_API'] 61default_cflags += ['-DALLOW_INTERNAL_API'] 62 63warning_disable_cflags = ['-Wno-format-truncation', '-Wno-address-of-packed-member'] 64foreach cflag:warning_disable_cflags 65 if cc.has_argument(cflag) 66 default_cflags += cflag 67 endif 68endforeach 69 70dpdk_drivers_build_dir = meson.current_build_dir() 71 72foreach subpath:subdirs 73 drivers = [] 74 std_deps = [] 75 log_prefix = '' 76 77 # subpath can be either "class" or "class/driver" 78 if subpath.contains('/') 79 driver_path = subpath.split('/') 80 class = driver_path[0] 81 drivers += driver_path[1] 82 else 83 class = subpath 84 subdir(class) 85 skip_class = false 86 foreach d:std_deps 87 if not is_variable('shared_rte_' + d) 88 skip_class = true 89 reason = 'missing internal dependency, "@0@"'.format(d) 90 if dpdk_libs_deprecated.contains(d) 91 reason += ' (deprecated lib)' 92 endif 93 message('Disabling @1@/* drivers: missing internal dependency "@0@"' 94 .format(d, class)) 95 break 96 endif 97 endforeach 98 if skip_class 99 drv_path = join_paths(class, '*') 100 dpdk_drvs_disabled += drv_path 101 set_variable('drv_' + drv_path.underscorify() + '_disable_reason', reason) 102 continue 103 endif 104 endif 105 106 # save class name on first occurrence 107 if not dpdk_driver_classes.contains(class) 108 dpdk_driver_classes += class 109 endif 110 # get already enabled drivers of the same class 111 enabled_drivers = get_variable(class + '_drivers', []) 112 113 # default log prefix can be defined per class 114 if log_prefix == '' 115 # default log name is pmd.class.driver 116 log_prefix = 'pmd.' + class 117 endif 118 119 foreach drv:drivers 120 drv_path = join_paths(class, drv) 121 122 # set up empty variables used for build 123 build = true # set to false to disable, e.g. missing deps 124 reason = '<unknown reason>' # set if build == false to explain 125 name = drv 126 annotate_locks = true 127 sources = [] 128 headers = [] 129 driver_sdk_headers = [] # public headers included by drivers 130 objs = [] 131 cflags = default_cflags 132 includes = [include_directories(drv_path)] 133 # set up internal deps. Drivers can append/override as necessary 134 deps = std_deps 135 # ext_deps: Stores external library dependency got 136 # using dependency() (preferred) or find_library(). 137 # For the find_library() case (but not with dependency()) we also 138 # need to specify the "-l" flags in pkgconfig_extra_libs variable 139 # too, so that it can be reflected in the pkgconfig output for 140 # static builds. 141 ext_deps = [] 142 pkgconfig_extra_libs = [] 143 testpmd_sources = [] 144 require_iova_in_mbuf = true 145 146 if name.contains('/') 147 name = name.split('/')[1] 148 endif 149 150 if not enable_drivers.contains(drv_path) 151 build = false 152 reason = 'not in enabled drivers build config' 153 elif disable_drivers.contains(drv_path) 154 if always_enable.contains(drv_path) 155 message('Driver @0@ cannot be disabled, not disabling.'.format(drv_path)) 156 else 157 build = false 158 reason = 'explicitly disabled via build config' 159 endif 160 endif 161 162 if build 163 # pull in driver directory which should update all the local variables 164 subdir(drv_path) 165 166 if dpdk_conf.get('RTE_IOVA_IN_MBUF') == 0 and require_iova_in_mbuf 167 build = false 168 reason = 'requires IOVA in mbuf (set enable_iova_as_pa option)' 169 endif 170 # error out if we can't build a driver and that driver was explicitly requested, 171 # i.e. not via wildcard. 172 if not build and require_drivers and get_option('enable_drivers').contains(drv_path) 173 error('Cannot build explicitly requested driver "@0@".\n'.format(drv_path) 174 +'\tReason: ' + reason) 175 endif 176 177 # get dependency objs from strings 178 shared_deps = ext_deps 179 static_deps = ext_deps 180 foreach d:deps 181 if not build 182 break 183 endif 184 if not is_variable('shared_rte_' + d) 185 build = false 186 reason = 'missing internal dependency, "@0@"'.format(d) 187 if dpdk_libs_deprecated.contains(d) 188 reason += ' (deprecated lib)' 189 endif 190 message('Disabling @1@ [@2@]: missing internal dependency "@0@"' 191 .format(d, name, 'drivers/' + drv_path)) 192 # error out if we can't build a driver and that driver was explicitly 193 # requested, i.e. not via wildcard. 194 if require_drivers and get_option('enable_drivers').contains(drv_path) 195 error('Cannot build explicitly requested driver "@0@".\n'.format(drv_path) 196 +'\tPlease enable missing dependency "@0@"'.format(d)) 197 endif 198 else 199 shared_deps += [get_variable('shared_rte_' + d)] 200 static_deps += [get_variable('static_rte_' + d)] 201 endif 202 endforeach 203 endif 204 205 if not build 206 # some driver directories are placeholders which 207 # are never built, so we allow suppression of the 208 # component disable printout in those cases 209 if reason != '' 210 dpdk_drvs_disabled += drv_path 211 set_variable('drv_' + drv_path.underscorify() + '_disable_reason', reason) 212 endif 213 continue 214 endif 215 216 enabled_drivers += name 217 lib_name = '_'.join(['rte', class, name]) 218 cflags += '-DRTE_LOG_DEFAULT_LOGTYPE=' + '.'.join([log_prefix, name]) 219 if annotate_locks and cc.get_id() == 'clang' and cc.version().version_compare('>=3.5.0') 220 cflags += '-DRTE_ANNOTATE_LOCKS' 221 cflags += '-Wthread-safety' 222 endif 223 dpdk_conf.set(lib_name.to_upper(), 1) 224 225 dpdk_extra_ldflags += pkgconfig_extra_libs 226 227 install_headers(headers) 228 if get_option('enable_driver_sdk') 229 install_headers(driver_sdk_headers) 230 endif 231 dpdk_chkinc_headers += driver_sdk_headers 232 233 if headers.length() > 0 234 dpdk_includes += include_directories(drv_path) 235 endif 236 237 # generate pmdinfo sources by building a temporary 238 # lib and then running pmdinfogen on the contents of 239 # that lib. The final lib reuses the object files and 240 # adds in the new source file. 241 out_filename = lib_name + '.pmd.c' 242 tmp_lib = static_library('tmp_' + lib_name, sources, 243 include_directories: includes, 244 dependencies: static_deps, 245 c_args: cflags) 246 objs += tmp_lib.extract_all_objects(recursive: true) 247 sources = custom_target(out_filename, 248 command: [pmdinfo, tmp_lib.full_path(), '@OUTPUT@', pmdinfogen], 249 output: out_filename, 250 depends: [tmp_lib]) 251 252 # now build the static driver 253 static_lib = static_library(lib_name, 254 sources, 255 objects: objs, 256 include_directories: includes, 257 dependencies: static_deps, 258 c_args: cflags, 259 install: true) 260 261 # now build the shared driver 262 version_map = '@0@/@1@/version.map'.format(meson.current_source_dir(), drv_path) 263 264 lk_deps = [] 265 lk_args = [] 266 if not fs.is_file(version_map) 267 version_map = '@0@/version.map'.format(meson.current_source_dir()) 268 lk_deps += [version_map] 269 else 270 lk_deps += [version_map] 271 if not is_windows and developer_mode 272 # on unix systems check the output of the 273 # check-symbols.sh script, using it as a 274 # dependency of the .so build 275 lk_deps += custom_target(lib_name + '.sym_chk', 276 command: [check_symbols, version_map, '@INPUT@'], 277 capture: true, 278 input: static_lib, 279 output: lib_name + '.sym_chk') 280 endif 281 endif 282 283 if is_windows 284 if is_ms_linker 285 def_file = custom_target(lib_name + '_def', 286 command: [map_to_win_cmd, '@INPUT@', '@OUTPUT@'], 287 input: version_map, 288 output: '@0@_exports.def'.format(lib_name)) 289 lk_deps += [def_file] 290 291 lk_args = ['-Wl,/def:' + def_file.full_path()] 292 else 293 mingw_map = custom_target(lib_name + '_mingw', 294 command: [map_to_win_cmd, '@INPUT@', '@OUTPUT@'], 295 input: version_map, 296 output: '@0@_mingw.map'.format(lib_name)) 297 lk_deps += [mingw_map] 298 299 lk_args = ['-Wl,--version-script=' + mingw_map.full_path()] 300 endif 301 else 302 lk_args = ['-Wl,--version-script=' + version_map] 303 endif 304 305 shared_lib = shared_library(lib_name, sources, 306 objects: objs, 307 include_directories: includes, 308 dependencies: shared_deps, 309 c_args: cflags, 310 link_args: lk_args, 311 link_depends: lk_deps, 312 version: abi_version, 313 soversion: so_version, 314 install: true, 315 install_dir: driver_install_path) 316 317 # create a dependency object and add it to the global dictionary so 318 # testpmd or other built-in apps can find it if necessary 319 shared_dep = declare_dependency(link_with: shared_lib, 320 include_directories: includes, 321 dependencies: shared_deps) 322 static_dep = declare_dependency( 323 include_directories: includes, 324 dependencies: static_deps) 325 326 dpdk_drivers += static_lib 327 328 set_variable('shared_@0@'.format(lib_name), shared_dep) 329 set_variable('static_@0@'.format(lib_name), static_dep) 330 # for drivers, we only need to add dependency objects for static libs, 331 # shared lib drivers are not linked in 332 dpdk_static_lib_deps += static_dep 333 334 dependency_name = ''.join(lib_name.split('rte_')) 335 if testpmd_sources.length() != 0 336 testpmd_drivers_sources += testpmd_sources 337 testpmd_drivers_deps += dependency_name 338 endif 339 if developer_mode 340 message('drivers/@0@: Defining dependency "@1@"'.format( 341 drv_path, dependency_name)) 342 endif 343 endforeach 344 345 set_variable(class + '_drivers', enabled_drivers) 346endforeach 347