1# SPDX-License-Identifier: BSD-3-Clause 2# Copyright(c) 2017-2019 Intel Corporation 3 4# check the OS is supported, rather than going any further 5supported_exec_envs = ['freebsd', 'linux', 'windows'] 6exec_env = host_machine.system() 7if not supported_exec_envs.contains(exec_env) 8 error('unsupported system type "@0@"'.format(exec_env)) 9endif 10 11# define a handy variable for checking which OS we have. 12# gives us "is_windows", "is_freebsd" and "is_linux" 13foreach env:supported_exec_envs 14 set_variable('is_' + env, exec_env == env) 15endforeach 16 17exec_envs = {'freebsd': 0, 'linux': 1, 'windows': 2} 18foreach env, id:exec_envs 19 dpdk_conf.set('RTE_ENV_' + env.to_upper(), id) 20 dpdk_conf.set10('RTE_EXEC_ENV_IS_' + env.to_upper(), (exec_env == env)) 21endforeach 22dpdk_conf.set('RTE_EXEC_ENV', exec_envs[exec_env]) 23dpdk_conf.set('RTE_EXEC_ENV_' + exec_env.to_upper(), 1) 24 25# MS linker requires special treatment. 26# TODO: use cc.get_linker_id() with Meson >= 0.54 27is_ms_compiler = is_windows and (cc.get_id() == 'msvc') 28is_ms_linker = is_windows and (cc.get_id() == 'clang' or is_ms_compiler) 29 30if is_ms_compiler 31 # force the use of intrinsics the MSVC compiler (except x86) 32 # does not support inline assembly 33 dpdk_conf.set('RTE_FORCE_INTRINSICS', 1) 34 35 # force the use of C++11 memory model in lib/ring 36 dpdk_conf.set('RTE_USE_C11_MEM_MODEL', true) 37 38 # suppress warnings raised for using standard library functions 39 # the MSVC compiler regards as unsafe but are used by DPDK 40 dpdk_conf.set('_CRT_SECURE_NO_WARNINGS', 1) 41 42 # temporarily disable msvc specific warnings 43 # - 4244 compiler detected conversion of integer to smaller type 44 # - 4267 compiler detected conversion of size_t to smaller type 45 # - 4146 unary minus applied to unsigned type 46 add_project_arguments('/wd4244', '/wd4267', '/wd4146', language: 'c') 47 48 # enable non-locking atomic operations 49 add_project_arguments('/experimental:c11atomics', language: 'c') 50 51 # enable typeof operator 52 add_project_arguments('/d1experimental:typeof', language: 'c') 53 54 # enable statement expressions extension 55 add_project_arguments('/experimental:statementExpressions', language: 'c') 56endif 57 58# set the major version, which might be used by drivers and libraries 59# depending on the configuration options 60pver = meson.project_version().split('.') 61major_version = '@0@.@1@'.format(pver.get(0), pver.get(1)) 62abi_version = run_command(find_program('cat', 'more'), abi_version_file, 63 check: true).stdout().strip() 64 65# Libraries have the abi_version as the filename extension 66# and have the soname be all but the final part of the abi_version. 67# e.g. v20.1 => librte_foo.so.20.1 68# sonames => librte_foo.so.20 69so_version = abi_version.split('.')[0] 70 71# extract all version information into the build configuration 72dpdk_conf.set('RTE_VER_YEAR', pver.get(0).to_int()) 73dpdk_conf.set('RTE_VER_MONTH', pver.get(1).to_int()) 74if pver.get(2).contains('-rc') 75 rc_ver = pver.get(2).split('-rc') 76 dpdk_conf.set('RTE_VER_MINOR', rc_ver.get(0).to_int()) 77 dpdk_conf.set_quoted('RTE_VER_SUFFIX', '-rc') 78 dpdk_conf.set('RTE_VER_RELEASE', rc_ver.get(1).to_int()) 79else 80 dpdk_conf.set('RTE_VER_MINOR', pver.get(2).to_int()) 81 dpdk_conf.set_quoted('RTE_VER_SUFFIX', '') 82# for actual, non-rc releases, set the release value to 99 to ensure releases 83# have higher version numbers than their respective release candidates 84 dpdk_conf.set('RTE_VER_RELEASE', 99) 85endif 86 87pmd_subdir_opt = get_option('drivers_install_subdir') 88if pmd_subdir_opt.contains('<VERSION>') 89 pmd_subdir_opt = abi_version.join(pmd_subdir_opt.split('<VERSION>')) 90endif 91driver_install_path = join_paths(get_option('libdir'), pmd_subdir_opt) 92eal_pmd_path = join_paths(get_option('prefix'), driver_install_path) 93 94# driver .so files often depend upon the bus drivers for their connect bus, 95# e.g. ixgbe depends on librte_bus_pci. This means that the bus drivers need 96# to be in the library path, so symlink the drivers from the main lib directory. 97if not is_windows 98 # skip symlink-drivers-solibs.sh execution on no sub directory 99 if pmd_subdir_opt != '' and pmd_subdir_opt != '.' 100 meson.add_install_script('../buildtools/symlink-drivers-solibs.sh', 101 get_option('libdir'), pmd_subdir_opt) 102 endif 103else 104 meson.add_install_script(py3, 105 files('../buildtools/symlink-drivers-solibs.py'), 106 get_option('libdir'), pmd_subdir_opt, get_option('bindir')) 107endif 108 109# init disable/enable driver lists that will be populated in different places 110disable_drivers = '' 111enable_drivers = '' 112 113platform = get_option('platform') 114 115# set the cpu_instruction_set and cflags for it 116if meson.is_cross_build() 117 cpu_instruction_set = host_machine.cpu() 118else 119 cpu_instruction_set = get_option('cpu_instruction_set') 120 machine = get_option('machine') 121 if machine != 'auto' 122 warning('The "machine" option is deprecated. ' + 123 'Please use "cpu_instruction_set" instead.') 124 if cpu_instruction_set != 'auto' 125 error('Setting both "machine" and ' + 126 '"cpu_instruction_set" is unsupported.') 127 endif 128 cpu_instruction_set = machine 129 if cpu_instruction_set == 'default' 130 cpu_instruction_set = 'generic' 131 endif 132 endif 133 if platform == 'native' 134 if cpu_instruction_set == 'auto' 135 cpu_instruction_set = 'native' 136 endif 137 endif 138endif 139 140if platform == 'generic' 141 if cpu_instruction_set == 'auto' 142 cpu_instruction_set = 'generic' 143 endif 144endif 145 146# cpu_instruction_set 'generic' is special, it selects the per arch agreed 147# common minimal baseline needed for DPDK. cpu_instruction_set 'default' is 148# also supported with the same meaning for backwards compatibility. 149# That might not be the most optimized, but the most portable version while 150# still being able to support the CPU features required for DPDK. 151# This can be bumped up by the DPDK project, but it can never be an 152# invariant like 'native' 153if cpu_instruction_set == 'generic' 154 if host_machine.cpu_family().startswith('x86') 155 # matches the old pre-meson build systems generic cpu_instruction_set 156 cpu_instruction_set = 'corei7' 157 elif host_machine.cpu_family().startswith('arm') 158 cpu_instruction_set = 'armv7-a' 159 elif host_machine.cpu_family().startswith('aarch') 160 # arm64 manages generic config in config/arm/meson.build 161 cpu_instruction_set = 'generic' 162 elif host_machine.cpu_family().startswith('ppc') 163 cpu_instruction_set = 'power8' 164 elif host_machine.cpu_family().startswith('riscv') 165 cpu_instruction_set = 'rv64gc' 166 endif 167endif 168 169dpdk_conf.set('RTE_MACHINE', cpu_instruction_set) 170machine_args = [] 171 172if not is_ms_compiler 173 # ppc64 does not support -march= at all, use -mcpu and -mtune for that 174 if host_machine.cpu_family().startswith('ppc') 175 machine_args += '-mcpu=' + cpu_instruction_set 176 machine_args += '-mtune=' + cpu_instruction_set 177 compiler_arch_support = cc.has_argument('-mcpu=' + cpu_instruction_set) 178 else 179 machine_args += '-march=' + cpu_instruction_set 180 # arm manages generic/auto config in config/arm/meson.build 181 if cpu_instruction_set != 'generic' and cpu_instruction_set != 'auto' 182 compiler_arch_support = cc.has_argument('-march=' + cpu_instruction_set) 183 else 184 compiler_arch_support = true 185 endif 186 endif 187 if not compiler_arch_support 188 error('Compiler does not support "@0@" arch flag.'.format(cpu_instruction_set)) 189 endif 190endif 191 192toolchain = cc.get_id() 193 194dpdk_conf.set('RTE_ARCH_64', cc.sizeof('void *') == 8) 195dpdk_conf.set('RTE_ARCH_32', cc.sizeof('void *') == 4) 196 197if not is_windows 198 add_project_link_arguments('-Wl,--no-as-needed', language: 'c') 199 if cc.has_link_argument('-Wl,--undefined-version') 200 add_project_link_arguments('-Wl,--undefined-version', language: 'c') 201 endif 202endif 203 204# use pthreads if available for the platform 205if not is_windows 206 add_project_link_arguments('-pthread', language: 'c') 207 dpdk_extra_ldflags += '-pthread' 208endif 209 210# on some OS, maths functions are in a separate library 211if cc.find_library('m', required : false).found() 212 # some libs depend on maths lib 213 add_project_link_arguments('-lm', language: 'c') 214 dpdk_extra_ldflags += '-lm' 215endif 216 217if is_linux 218 link_lib = 'dl' 219else 220 link_lib = '' 221endif 222 223# if link_lib is empty, do not add it to project properties 224if link_lib != '' 225 add_project_link_arguments('-l' + link_lib, language: 'c') 226 dpdk_extra_ldflags += '-l' + link_lib 227endif 228 229# check for libraries used in multiple places in DPDK 230has_libnuma = false 231find_libnuma = true 232if meson.is_cross_build() and not meson.get_external_property('numa', true) 233 # don't look for libnuma if explicitly disabled in cross build 234 find_libnuma = false 235endif 236if find_libnuma 237 numa_dep = cc.find_library('numa', required: false) 238 if numa_dep.found() and cc.has_header('numaif.h') 239 dpdk_conf.set10('RTE_HAS_LIBNUMA', true) 240 has_libnuma = true 241 add_project_link_arguments('-lnuma', language: 'c') 242 dpdk_extra_ldflags += '-lnuma' 243 endif 244endif 245 246has_libfdt = false 247fdt_dep = cc.find_library('fdt', required: false) 248if fdt_dep.found() and cc.has_header('fdt.h') 249 dpdk_conf.set10('RTE_HAS_LIBFDT', true) 250 has_libfdt = true 251 add_project_link_arguments('-lfdt', language: 'c') 252 dpdk_extra_ldflags += '-lfdt' 253endif 254 255libexecinfo = cc.find_library('execinfo', required: false) 256if libexecinfo.found() 257 add_project_link_arguments('-lexecinfo', language: 'c') 258 dpdk_extra_ldflags += '-lexecinfo' 259endif 260dpdk_conf.set('RTE_BACKTRACE', cc.has_header('execinfo.h') or is_windows) 261 262libarchive = dependency('libarchive', required: false, method: 'pkg-config') 263if libarchive.found() 264 dpdk_conf.set('RTE_HAS_LIBARCHIVE', 1) 265endif 266 267# check for libbsd 268libbsd = dependency('libbsd', required: false, method: 'pkg-config') 269if libbsd.found() 270 dpdk_conf.set('RTE_USE_LIBBSD', 1) 271endif 272 273jansson_dep = dependency('jansson', required: false, method: 'pkg-config') 274if jansson_dep.found() 275 dpdk_conf.set('RTE_HAS_JANSSON', 1) 276endif 277 278# check for OpenSSL 279openssl_dep = dependency('openssl', required: false, method: 'pkg-config') 280if openssl_dep.found() 281 dpdk_conf.set('RTE_HAS_OPENSSL', 1) 282endif 283 284# check for pcap 285pcap_dep = dependency('libpcap', required: false, method: 'pkg-config') 286pcap_lib = is_windows ? 'wpcap' : 'pcap' 287if not pcap_dep.found() 288 # pcap got a pkg-config file only in 1.9.0 289 pcap_dep = cc.find_library(pcap_lib, required: false) 290endif 291if pcap_dep.found() and cc.has_header('pcap.h', dependencies: pcap_dep) 292 dpdk_conf.set('RTE_HAS_LIBPCAP', 1) 293 dpdk_extra_ldflags += '-l@0@'.format(pcap_lib) 294endif 295 296# for clang 32-bit compiles we need libatomic for 64-bit atomic ops 297if cc.get_id() == 'clang' and dpdk_conf.get('RTE_ARCH_64') == false 298 atomic_dep = cc.find_library('atomic', required: true) 299 add_project_link_arguments('-latomic', language: 'c') 300 dpdk_extra_ldflags += '-latomic' 301endif 302 303# add -include rte_config to cflags 304if is_ms_compiler 305 add_project_arguments('/FI', 'rte_config.h', language: 'c') 306else 307 add_project_arguments('-include', 'rte_config.h', language: 'c') 308endif 309 310# enable extra warnings and disable any unwanted warnings 311# -Wall is added by default at warning level 1, and -Wextra 312# at warning level 2 (DPDK default) 313warning_flags = [ 314 # additional warnings in alphabetical order 315 '-Wcast-qual', 316 '-Wdeprecated', 317 '-Wformat', 318 '-Wformat-nonliteral', 319 '-Wformat-security', 320 '-Wmissing-declarations', 321 '-Wmissing-prototypes', 322 '-Wnested-externs', 323 '-Wold-style-definition', 324 '-Wpointer-arith', 325 '-Wsign-compare', 326 '-Wstrict-prototypes', 327 '-Wundef', 328 '-Wwrite-strings', 329 330 # globally disabled warnings 331 '-Wno-packed-not-aligned', 332 '-Wno-missing-field-initializers', 333] 334 335if not dpdk_conf.get('RTE_ARCH_64') 336# for 32-bit, don't warn about casting a 32-bit pointer to 64-bit int - it's fine!! 337 warning_flags += '-Wno-pointer-to-int-cast' 338endif 339if cc.get_id() == 'intel' 340 warning_ids = [181, 188, 2203, 2279, 2557, 3179, 3656] 341 foreach i:warning_ids 342 warning_flags += '-diag-disable=@0@'.format(i) 343 endforeach 344endif 345foreach arg: warning_flags 346 if cc.has_argument(arg) 347 add_project_arguments(arg, language: 'c') 348 endif 349endforeach 350 351# set other values pulled from the build options 352dpdk_conf.set('RTE_MAX_ETHPORTS', get_option('max_ethports')) 353dpdk_conf.set('RTE_LIBEAL_USE_HPET', get_option('use_hpet')) 354dpdk_conf.set('RTE_ENABLE_STDATOMIC', get_option('enable_stdatomic')) 355dpdk_conf.set('RTE_ENABLE_TRACE_FP', get_option('enable_trace_fp')) 356dpdk_conf.set('RTE_PKTMBUF_HEADROOM', get_option('pkt_mbuf_headroom')) 357# values which have defaults which may be overridden 358dpdk_conf.set('RTE_MAX_VFIO_GROUPS', 64) 359dpdk_conf.set('RTE_DRIVER_MEMPOOL_BUCKET_SIZE_KB', 64) 360dpdk_conf.set('RTE_LIBRTE_DPAA2_USE_PHYS_IOVA', true) 361if dpdk_conf.get('RTE_ARCH_64') 362 dpdk_conf.set('RTE_MAX_MEM_MB', 524288) 363else # for 32-bit we need smaller reserved memory areas 364 dpdk_conf.set('RTE_MAX_MEM_MB', 2048) 365endif 366if get_option('mbuf_refcnt_atomic') 367 dpdk_conf.set('RTE_MBUF_REFCNT_ATOMIC', true) 368endif 369dpdk_conf.set10('RTE_IOVA_IN_MBUF', get_option('enable_iova_as_pa')) 370 371compile_time_cpuflags = [] 372subdir(arch_subdir) 373dpdk_conf.set('RTE_COMPILE_TIME_CPUFLAGS', ','.join(compile_time_cpuflags)) 374 375# apply cross-specific options 376if meson.is_cross_build() 377 # configure RTE_MAX_LCORE and RTE_MAX_NUMA_NODES from cross file 378 cross_max_lcores = meson.get_external_property('max_lcores', 0) 379 if cross_max_lcores != 0 380 message('Setting RTE_MAX_LCORE from cross file') 381 dpdk_conf.set('RTE_MAX_LCORE', cross_max_lcores) 382 endif 383 cross_max_numa_nodes = meson.get_external_property('max_numa_nodes', 0) 384 if cross_max_numa_nodes != 0 385 message('Setting RTE_MAX_NUMA_NODES from cross file') 386 dpdk_conf.set('RTE_MAX_NUMA_NODES', cross_max_numa_nodes) 387 endif 388endif 389 390max_lcores = get_option('max_lcores') 391if max_lcores == 'detect' 392 # discovery makes sense only for non-cross builds 393 if meson.is_cross_build() 394 error('Discovery of max_lcores is not supported for cross-compilation.') 395 endif 396 # overwrite the default value with discovered values 397 max_lcores = run_command(get_cpu_count_cmd, check: true).stdout().to_int() 398 min_lcores = 2 399 # DPDK must be built for at least 2 cores 400 if max_lcores < min_lcores 401 message('Found less than @0@ cores, building for @0@ cores'.format(min_lcores)) 402 max_lcores = min_lcores 403 else 404 message('Found @0@ cores'.format(max_lcores)) 405 endif 406 dpdk_conf.set('RTE_MAX_LCORE', max_lcores) 407elif max_lcores != 'default' 408 # overwrite the default value from arch_subdir with user input 409 dpdk_conf.set('RTE_MAX_LCORE', max_lcores.to_int()) 410endif 411 412max_numa_nodes = get_option('max_numa_nodes') 413if max_numa_nodes == 'detect' 414 # discovery makes sense only for non-cross builds 415 if meson.is_cross_build() 416 error('Discovery of max_numa_nodes not supported for cross-compilation.') 417 endif 418 # overwrite the default value with discovered values 419 max_numa_nodes = run_command(get_numa_count_cmd, check: true).stdout().to_int() 420 message('Found @0@ numa nodes'.format(max_numa_nodes)) 421 dpdk_conf.set('RTE_MAX_NUMA_NODES', max_numa_nodes) 422elif max_numa_nodes != 'default' 423 # overwrite the default value from arch_subdir with user input 424 dpdk_conf.set('RTE_MAX_NUMA_NODES', max_numa_nodes.to_int()) 425endif 426 427# check that CPU and NUMA counts are set 428if not dpdk_conf.has('RTE_MAX_LCORE') 429 error('Number of CPU cores not specified.') 430endif 431if not dpdk_conf.has('RTE_MAX_NUMA_NODES') 432 error('Number of NUMA nodes not specified.') 433endif 434if (is_linux and 435 dpdk_conf.get('RTE_MAX_NUMA_NODES') > 1 and 436 not meson.is_cross_build() and 437 not has_libnuma) 438 error(''' 439No NUMA library (development package) found, yet DPDK configured for multiple NUMA nodes. 440Please install libnuma, or set 'max_numa_nodes' option to '1' to build without NUMA support. 441''') 442endif 443 444# set the install path for the drivers 445dpdk_conf.set_quoted('RTE_EAL_PMD_PATH', eal_pmd_path) 446 447install_headers(['rte_config.h'], 448 subdir: get_option('include_subdir_arch')) 449 450# enable VFIO only if it is linux OS 451dpdk_conf.set('RTE_EAL_VFIO', is_linux) 452 453# specify -D_GNU_SOURCE unconditionally 454add_project_arguments('-D_GNU_SOURCE', language: 'c') 455 456# specify -D__BSD_VISIBLE for FreeBSD 457if is_freebsd 458 add_project_arguments('-D__BSD_VISIBLE', language: 'c') 459endif 460 461if is_windows 462 # VirtualAlloc2() is available since Windows 10 / Server 2019. 463 # It's essential for EAL, so we don't support older versions. 464 add_project_arguments('-D_WIN32_WINNT=0x0A00', language: 'c') 465 466 # Use MinGW-w64 stdio, because DPDK assumes ANSI-compliant formatting. 467 if cc.get_id() == 'gcc' 468 add_project_arguments('-D__USE_MINGW_ANSI_STDIO', language: 'c') 469 endif 470 471 # Disable secure CRT deprecated warnings for clang 472 if cc.get_id() == 'clang' 473 add_project_arguments('-D_CRT_SECURE_NO_WARNINGS', language: 'c') 474 endif 475endif 476 477if get_option('b_lto') 478 if cc.has_argument('-ffat-lto-objects') 479 add_project_arguments('-ffat-lto-objects', language: 'c') 480 else 481 error('compiler does not support fat LTO objects - please turn LTO off') 482 endif 483 # workaround for gcc bug 81440 484 if cc.get_id() == 'gcc' and cc.version().version_compare('<8.0') 485 add_project_arguments('-Wno-lto-type-mismatch', language: 'c') 486 add_project_link_arguments('-Wno-lto-type-mismatch', language: 'c') 487 endif 488endif 489 490if get_option('b_sanitize') == 'address' or get_option('b_sanitize') == 'address,undefined' 491 if is_windows 492 error('ASan is not supported on windows') 493 endif 494 495 if cc.get_id() == 'gcc' 496 asan_dep = cc.find_library('asan', required: true) 497 if (not cc.links('int main(int argc, char *argv[]) { return 0; }', 498 dependencies: asan_dep)) 499 error('broken dependency, "libasan"') 500 endif 501 add_project_link_arguments('-lasan', language: 'c') 502 dpdk_extra_ldflags += '-lasan' 503 endif 504 505 if is_linux and dpdk_conf.get('RTE_ARCH_64') 506 dpdk_conf.set10('RTE_MALLOC_ASAN', true) 507 endif 508endif 509 510if get_option('default_library') == 'both' 511 error( ''' 512 Unsupported value "both" for "default_library" option. 513 514 NOTE: DPDK always builds both shared and static libraries. Please set 515 "default_library" to either "static" or "shared" to select default linkage 516 for apps and any examples.''') 517endif 518