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