xref: /dpdk/drivers/meson.build (revision d014dddb)
1# SPDX-License-Identifier: BSD-3-Clause
2# Copyright(c) 2017-2019 Intel Corporation
3
4# Defines the order of dependencies evaluation
5subdirs = [
6	'common',
7	'bus',
8	'common/cnxk', # depends on bus.
9	'common/mlx5', # depends on bus.
10	'common/qat', # depends on bus.
11	'common/sfc_efx', # depends on bus.
12	'mempool', # depends on common and bus.
13	'net',     # depends on common, bus, mempool
14	'raw',     # depends on common, bus and net.
15	'crypto',  # depends on common, bus and mempool (net in future).
16	'compress', # depends on common, bus, mempool.
17	'regex', # depends on common, bus, regexdev.
18	'vdpa',    # depends on common, bus and mempool.
19	'event',   # depends on common, bus, mempool and net.
20	'baseband', # depends on common and bus.
21]
22
23if meson.is_cross_build()
24	disable_drivers += ',' + meson.get_cross_property('disable_drivers', '')
25	enable_drivers += ',' + meson.get_cross_property('enable_drivers', '')
26endif
27
28# add cmdline disabled drivers and meson disabled drivers together
29disable_drivers += ',' + get_option('disable_drivers')
30disable_drivers = run_command(list_dir_globs, disable_drivers).stdout().split()
31
32# add cmdline enabled drivers and meson enabled drivers together
33enable_drivers = ',' + get_option('enable_drivers')
34enable_drivers = run_command(list_dir_globs, enable_drivers).stdout().split()
35if enable_drivers.length() == 0
36	enable_drivers = run_command(list_dir_globs, '*/*').stdout().split()
37endif
38
39# these drivers must always be enabled, otherwise the build breaks
40always_enable = ['bus/pci', 'bus/vdev']
41enable_drivers += always_enable
42
43default_cflags = machine_args
44default_cflags += ['-DALLOW_EXPERIMENTAL_API']
45default_cflags += ['-DALLOW_INTERNAL_API']
46
47if cc.has_argument('-Wno-format-truncation')
48	default_cflags += '-Wno-format-truncation'
49endif
50
51foreach subpath:subdirs
52	drivers = []
53	std_deps = []
54
55	# subpath can be either "class" or "class/driver"
56	if subpath.contains('/')
57		driver_path = subpath.split('/')
58		class = driver_path[0]
59		drivers += driver_path[1]
60	else
61		class = subpath
62		subdir(class)
63	endif
64
65	# save class name on first occurrence
66	if not dpdk_driver_classes.contains(class)
67		dpdk_driver_classes += class
68	endif
69	# get already enabled drivers of the same class
70	enabled_drivers = get_variable(class + '_drivers', [])
71
72	foreach drv:drivers
73		drv_path = join_paths(class, drv)
74
75		# set up empty variables used for build
76		build = true # set to false to disable, e.g. missing deps
77		reason = '<unknown reason>' # set if build == false to explain
78		name = drv
79		sources = []
80		headers = []
81		objs = []
82		cflags = default_cflags
83		includes = [include_directories(drv_path)]
84		# set up internal deps. Drivers can append/override as necessary
85		deps = std_deps
86		# ext_deps: Stores external library dependency got
87		# using dependency() (preferred) or find_library().
88		# For the find_library() case (but not with dependency()) we also
89		# need to specify the "-l" flags in pkgconfig_extra_libs variable
90		# too, so that it can be reflected in the pkgconfig output for
91		# static builds.
92		ext_deps = []
93		pkgconfig_extra_libs = []
94
95		if not enable_drivers.contains(drv_path)
96			build = false
97			reason = 'not in enabled drivers build config'
98		elif disable_drivers.contains(drv_path)
99			if always_enable.contains(drv_path)
100				message('Driver @0@ cannot be disabled, not disabling.'.format(drv_path))
101			else
102				build = false
103				reason = 'explicitly disabled via build config'
104			endif
105		else
106			# pull in driver directory which should update all the local variables
107			subdir(drv_path)
108		endif
109
110		if build
111			# get dependency objs from strings
112			shared_deps = ext_deps
113			static_deps = ext_deps
114			foreach d:deps
115				if not is_variable('shared_rte_' + d)
116					build = false
117					reason = 'missing internal dependency, "@0@"'.format(d)
118					message('Disabling @1@ [@2@]: missing internal dependency "@0@"'
119							.format(d, name, 'drivers/' + drv_path))
120				else
121					shared_deps += [get_variable('shared_rte_' + d)]
122					static_deps += [get_variable('static_rte_' + d)]
123				endif
124			endforeach
125		endif
126
127		if not build
128			# some driver directories are placeholders which
129			# are never built, so we allow suppression of the
130			# component disable printout in those cases
131			if reason != ''
132				dpdk_drvs_disabled += drv_path
133				set_variable(drv_path.underscorify() +
134						'_disable_reason', reason)
135			endif
136		else
137			enabled_drivers += name
138			lib_name = '_'.join(['rte', class, name])
139			dpdk_conf.set(lib_name.to_upper(), 1)
140
141			dpdk_extra_ldflags += pkgconfig_extra_libs
142
143			install_headers(headers)
144
145			# generate pmdinfo sources by building a temporary
146			# lib and then running pmdinfogen on the contents of
147			# that lib. The final lib reuses the object files and
148			# adds in the new source file.
149			out_filename = lib_name + '.pmd.c'
150			tmp_lib = static_library('tmp_' + lib_name,
151					sources,
152					include_directories: includes,
153					dependencies: static_deps,
154					c_args: cflags)
155			objs += tmp_lib.extract_all_objects()
156			sources = custom_target(out_filename,
157					command: [pmdinfo, tmp_lib.full_path(),
158						'@OUTPUT@', pmdinfogen],
159					output: out_filename,
160					depends: [tmp_lib])
161
162			# now build the static driver
163			static_lib = static_library(lib_name,
164				sources,
165				objects: objs,
166				include_directories: includes,
167				dependencies: static_deps,
168				c_args: cflags,
169				install: true)
170
171			# now build the shared driver
172			version_map = '@0@/@1@/version.map'.format(
173					meson.current_source_dir(),
174					drv_path)
175			implib = 'lib' + lib_name + '.dll.a'
176
177			def_file = custom_target(lib_name + '_def',
178				command: [map_to_win_cmd, '@INPUT@', '@OUTPUT@'],
179				input: version_map,
180				output: '@0@_exports.def'.format(lib_name))
181
182			mingw_map = custom_target(lib_name + '_mingw',
183				command: [map_to_win_cmd, '@INPUT@', '@OUTPUT@'],
184				input: version_map,
185				output: '@0@_mingw.map'.format(lib_name))
186
187			lk_deps = [version_map, def_file, mingw_map]
188			if is_windows
189				if is_ms_linker
190					lk_args = ['-Wl,/def:' + def_file.full_path()]
191					if meson.version().version_compare('<0.54.0')
192						lk_args += ['-Wl,/implib:drivers\\' + implib]
193					endif
194				else
195					lk_args = ['-Wl,--version-script=' + mingw_map.full_path()]
196				endif
197			else
198				lk_args = ['-Wl,--version-script=' + version_map]
199				if developer_mode
200					# on unix systems check the output of the
201					# check-symbols.sh script, using it as a
202					# dependency of the .so build
203					lk_deps += custom_target(lib_name + '.sym_chk',
204						command: [check_symbols,
205							version_map, '@INPUT@'],
206						capture: true,
207						input: static_lib,
208						output: lib_name + '.sym_chk')
209				endif
210			endif
211
212			shared_lib = shared_library(lib_name,
213				sources,
214				objects: objs,
215				include_directories: includes,
216				dependencies: shared_deps,
217				c_args: cflags,
218				link_args: lk_args,
219				link_depends: lk_deps,
220				version: abi_version,
221				soversion: so_version,
222				install: true,
223				install_dir: driver_install_path)
224
225			# create a dependency object and add it to the global dictionary so
226			# testpmd or other built-in apps can find it if necessary
227			shared_dep = declare_dependency(link_with: shared_lib,
228					include_directories: includes,
229					dependencies: shared_deps)
230			static_dep = declare_dependency(
231					include_directories: includes,
232					dependencies: static_deps)
233
234			dpdk_drivers += static_lib
235
236			set_variable('shared_@0@'.format(lib_name), shared_dep)
237			set_variable('static_@0@'.format(lib_name), static_dep)
238			dependency_name = ''.join(lib_name.split('rte_'))
239			if developer_mode
240				message('drivers/@0@: Defining dependency "@1@"'.format(
241						drv_path, dependency_name))
242			endif
243		endif # build
244	endforeach
245
246	set_variable(class + '_drivers', enabled_drivers)
247endforeach
248