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