summaryrefslogtreecommitdiffstats
path: root/src/spdk/dpdk/drivers/meson.build
blob: cfb6a833c98b94990f7d90ba39ee389d9de788cd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2017-2019 Intel Corporation

if is_windows
	subdir_done()
endif

# Defines the order in which the drivers are buit.
dpdk_driver_classes = ['common',
	       'bus',
	       'mempool', # depends on common and bus.
	       'net',     # depends on common, bus, mempool
	       'raw',     # depends on common, bus and net.
	       'crypto',  # depends on common, bus and mempool (net in future).
	       'compress', # depends on common, bus, mempool.
	       'vdpa',    # depends on common, bus and mempool.
	       'event',   # depends on common, bus, mempool and net.
	       'baseband'] # depends on common and bus.

disabled_drivers = run_command(list_dir_globs, get_option('disable_drivers'),
		).stdout().split()

default_cflags = machine_args
default_cflags += ['-DALLOW_EXPERIMENTAL_API']
default_cflags += ['-DALLOW_INTERNAL_API']

if cc.has_argument('-Wno-format-truncation')
	default_cflags += '-Wno-format-truncation'
endif

foreach class:dpdk_driver_classes
	drivers = []
	std_deps = []
	config_flag_fmt = '' # format string used to set the value in dpdk_conf
	driver_name_fmt = '' # format string for driver name, used to name
	                     # the library, the dependency and to find the
	                     # version file for linking

	subdir(class)
	class_drivers = []

	foreach drv:drivers
		drv_path = join_paths(class, drv)

		# set up empty variables used for build
		build = true # set to false to disable, e.g. missing deps
		reason = '<unknown reason>' # set if build == false to explain
		name = drv
		fmt_name = ''
		sources = []
		objs = []
		cflags = default_cflags
		includes = [include_directories(drv_path)]
		# set up internal deps. Drivers can append/override as necessary
		deps = std_deps
		# ext_deps: Stores external library dependency got
		# using dependency() (preferred) or find_library().
		# For the find_library() case (but not with dependency()) we also
		# need to specify the "-l" flags in pkgconfig_extra_libs variable
		# too, so that it can be reflected in the pkgconfig output for
		# static builds.
		ext_deps = []
		pkgconfig_extra_libs = []

		if disabled_drivers.contains(drv_path)
			build = false
			reason = 'Explicitly disabled via build config'
		else
			# pull in driver directory which should update all the local variables
			subdir(drv_path)
		endif

		if build
			# get dependency objs from strings
			shared_deps = ext_deps
			static_deps = ext_deps
			foreach d:deps
				if not is_variable('shared_rte_' + d)
					build = false
					reason = 'Missing internal dependency, "@0@"'.format(d)
					message('Disabling @1@ [@2@]: missing internal dependency "@0@"'
							.format(d, name, 'drivers/' + drv_path))
				else
					shared_deps += [get_variable('shared_rte_' + d)]
					static_deps += [get_variable('static_rte_' + d)]
				endif
			endforeach
		endif

		if not build
			# some driver directories are placeholders which
			# are never built, so we allow suppression of the
			# component disable printout in those cases
			if reason != ''
				dpdk_drvs_disabled += drv_path
				set_variable(drv_path.underscorify() +
						'_disable_reason', reason)
			endif
		else
			class_drivers += name

			if fmt_name == ''
				fmt_name = name
			endif
			dpdk_conf.set(config_flag_fmt.format(fmt_name.to_upper()),1)
			lib_name = driver_name_fmt.format(fmt_name)

			dpdk_extra_ldflags += pkgconfig_extra_libs

			# generate pmdinfo sources by building a temporary
			# lib and then running pmdinfogen on the contents of
			# that lib. The final lib reuses the object files and
			# adds in the new source file.
			out_filename = lib_name + '.pmd.c'
			tmp_lib = static_library('tmp_' + lib_name,
					sources,
					include_directories: includes,
					dependencies: static_deps,
					c_args: cflags)
			objs += tmp_lib.extract_all_objects()
			sources = custom_target(out_filename,
					command: [pmdinfo, tmp_lib.full_path(),
						'@OUTPUT@', pmdinfogen],
					output: out_filename,
					depends: [pmdinfogen, tmp_lib])

			version_map = '@0@/@1@/@2@_version.map'.format(
					meson.current_source_dir(),
					drv_path, lib_name)

			is_stable = run_command(is_stable_cmd,
				files(version_map)).returncode() == 0

			if is_stable
				lib_version = abi_version
				so_version = stable_so_version
			else
				lib_version = experimental_abi_version
				so_version = experimental_so_version
			endif

			# now build the static driver
			static_lib = static_library(lib_name,
				sources,
				objects: objs,
				include_directories: includes,
				dependencies: static_deps,
				c_args: cflags,
				install: true)

			# now build the shared driver
			version_map = '@0@/@1@/@2@_version.map'.format(
					meson.current_source_dir(),
					drv_path, lib_name)
			implib = dir_name + '.dll.a'

			def_file = custom_target(lib_name + '_def',
				command: [map_to_def_cmd, '@INPUT@', '@OUTPUT@'],
				input: version_map,
				output: '@0@_exports.def'.format(lib_name))
			lk_deps = [version_map, def_file]
			if is_windows
				lk_args = ['-Wl,/def:' + def_file.full_path(),
					'-Wl,/implib:lib\\' + implib]
			else
				lk_args = ['-Wl,--version-script=' + version_map]
				# on unix systems check the output of the
				# check-symbols.sh script, using it as a
				# dependency of the .so build
				lk_deps += custom_target(lib_name + '.sym_chk',
					command: [check_symbols,
						version_map, '@INPUT@'],
					capture: true,
					input: static_lib,
					output: lib_name + '.sym_chk')
			endif

			shared_lib = shared_library(lib_name,
				sources,
				objects: objs,
				include_directories: includes,
				dependencies: shared_deps,
				c_args: cflags,
				link_args: lk_args,
				link_depends: lk_deps,
				version: lib_version,
				soversion: so_version,
				install: true,
				install_dir: driver_install_path)

			# create a dependency object and add it to the global dictionary so
			# testpmd or other built-in apps can find it if necessary
			shared_dep = declare_dependency(link_with: shared_lib,
					include_directories: includes,
					dependencies: shared_deps)
			static_dep = declare_dependency(link_with: static_lib,
					include_directories: includes,
					dependencies: static_deps)

			dpdk_drivers += static_lib

			set_variable('shared_@0@'.format(lib_name), shared_dep)
			set_variable('static_@0@'.format(lib_name), static_dep)
			dependency_name = ''.join(lib_name.split('rte_'))
			message('drivers/@0@: Defining dependency "@1@"'.format(
					drv_path, dependency_name))
		endif # build
	endforeach

	set_variable(class + '_drivers', class_drivers)
endforeach