forked from robbert-vdh/yabridge
-
Notifications
You must be signed in to change notification settings - Fork 0
/
meson.build
412 lines (369 loc) · 15.6 KB
/
meson.build
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
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
project(
'yabridge',
'cpp',
version : '5.1.0',
meson_version : '>=0.56',
default_options : [
'warning_level=3',
'cpp_std=c++2a',
# Even though Meson will complain that this option does not exist, without
# this Meson will not apply the above option to native targets
'build.cpp_std=c++2a',
],
)
#
# Build options
#
# In theory yabridge should compile fine on a 32-bit system, but you will always
# need to pass `-Dbitbridge=true`. We just make sure that we won't build
# any 64-bit binaries in that situation.
is_64bit_system = build_machine.cpu_family() not in ['x86', 'arm']
with_32bit_libraries = (not is_64bit_system) or get_option('build.cpp_args').contains('-m32')
with_bitbridge = get_option('bitbridge')
with_clap = get_option('clap')
with_system_asio = get_option('system-asio')
with_winedbg = get_option('winedbg')
with_vst3 = get_option('vst3')
# Cookies can't be stored correctly when the native host is 32-bit and the
# bridged plugin is 64-bit
if with_clap and with_32bit_libraries and is_64bit_system
error('CLAP support will not work correctly when using 32-bit yabridge libraries together with 64-bit host binaries.')
endif
#
# Compiler flags
#
# Depending on the `bitbridge` flag we'll enable building secondary 32-bit
# host applications that can act as a bit bridge for using 32-bit Windows
# plugins in 64-bit Linux VST hosts. The plugin will determine which host
# application to use based on the `.dll` file it's trying to load. This setup is
# necessary until Meson provides a way to have multiple cross-builds for a
# single build directory: https://github.com/mesonbuild/meson/issues/5125
# These variables are used to generate a `config.h` file. The library names will
# be prefixed with `lib` and suffixed with `.so`, and the host names will be
# suffixed with `.exe`.
clap_plugin_name = 'yabridge-clap'
vst2_plugin_name = 'yabridge-vst2'
vst3_plugin_name = 'yabridge-vst3'
host_name_64bit = 'yabridge-host'
host_name_32bit = 'yabridge-host-32'
compiler_options = [
'-fvisibility=hidden',
'-fvisibility-inlines-hidden',
# We use an intrinsic to force flush-to-zero. SSE2 is always enabled in x86_64
# CPUs, but when we're compiling the 32-bit bitbridge we need to manually add
# this flag.
'-msse2',
# FIXME: Bitsery relies on the definitions from `<cstdint>`, which is no
# longer included transitively with GCC 13. This should be removed once
# bitsery is updated to support GCC 13.
'-include',
'cstdint',
]
chainloader_compiler_options = [
# We use our process library for sending notifications from the chainloaders,
# but we don't need the Asio pipe support there
'-DWITHOUT_ASIO',
]
# HACK: Some stuff from `windows.h` that we don't need results in conflicting
# definitions, so we'll try to exclude those bits
wine_compiler_options = [
'-DNOMINMAX',
# Since Wine 5.12 any use of attributes (like visibility specifiers, or
# calling conventions) in templated member or variable types causes a warning
'-Wno-attributes',
'-Wno-ignored-attributes',
# Winsock conflicts with the Posix sockets API. Before Wine 6.8 there was a
# `WINE_NOWINSOCK` that would exclude just `winsock.h` from `windows.h`, but
# they got rid of that so we now need to explicitly define the ifdef guards
'-D__WINE_WINSOCKAPI_STDLIB_H',
'-D_WINSOCKAPI_',
# This is only relevant for Wine 6.2, but commit
# `0c19e2e487d36a89531daf4897c0b6390d82a843`, broke compilation of
# `shobjidl.h` under C++.
#
# https://bugs.winehq.org/show_bug.cgi?id=50670
'-D__IFileOperation_INTERFACE_DEFINED__',
# This Wine 6.20 commit `dfdf56fbe47f8ff50ebe533e6d73f2de6546f008` added a
# bunch of new SAL includes to `windows.h`, which include things like `__in`
# and `__out`. This breaks libstdc++ compilation since they often use those
# names for function parameters.
#
# https://bugs.winehq.org/show_bug.cgi?id=51919
'-D__WINE_SAL_H__',
]
# NOTE: GCC doesn't 8-byte align doubles in structs on x86 for ABI-compatibilty
# reasons, but MSVC++ does. We need to force this same alignment to be
# ABI-compatible with 32-bit binaries created with MSVC++ on Windows.
wine_32bit_compiler_options = wine_compiler_options + ['-m32', '-malign-double']
wine_64bit_compiler_options = wine_compiler_options + ['-m64']
# Enable addition assertions on the STL containers during debug builds. Meson
# has a `cpp_debugstl` option, but it's nicer having this automatically tied to
# debug builds.
if get_option('buildtype') == 'debug'
compiler_options += ['-D_GLIBCXX_DEBUG']
endif
if with_bitbridge
compiler_options += '-DWITH_BITBRIDGE'
endif
if with_clap
compiler_options += '-DWITH_CLAP'
endif
# This provides an easy way to start the Wine plugin host using winedbg since it
# can be quite a pain to set up
if with_winedbg
compiler_options += '-DWITH_WINEDBG'
endif
if with_vst3
compiler_options += '-DWITH_VST3'
endif
#
# Wine checks
#
# Meson does not let us set a default cross compiler, which makes sense, but it
# also means that it's easy to forget. This will cause the setup process to
# abort if no cross compiler has been set up.
winelib_check = '''#ifndef __WINE__
#error 1
#endif'''
if not meson.get_compiler('cpp').compiles(winelib_check)
error('You need to set up a cross compiler, check the README for compilation instructions.')
endif
# Wine versions after Wine 5.6 and before 6.0 require a `__cdecl` calling
# convention to be specified on the `main()` functions or else `argc` and `argv`
# will point to the wrong memory. Similarly, with other versions of Wine this
# should _not_ be specified for the same reason. We'll try to figure out the
# current Wine version and add this calling convention based on that. Also,
# printing the configure-time Wine version might be useful in diagnosing build
# issues so we'll do just that.
#
# https://bugs.winehq.org/show_bug.cgi?id=49138
wine_version = run_command(
'sh', '-c', '''wine --version | grep --only-matching -E '[0-9]+\.[0-9]+(-?rc[0-9]+)?' | head -n1''',
check : false
)
if wine_version.returncode() == 0
wine_version = wine_version.stdout()
message('Targetting Wine @0@'.format(wine_version))
# Wine versions below 5.7 will segfault in `CoCreateGuid` which gets called
# during static initialization. I'm not exactly sure why this is happening,
# but to prevent this from causing more headaches and confusion in the future
# we should just immediately error out when building yabridge's VST3 support
# with these older Wine versions.
if wine_version.version_compare('<5.7') and with_vst3
error('Because of a bug in Wine < 5.7\n' +
'you cannot build yabridge with VST3 support using these older Wine versions.\n' +
'Use the \'-Dvst3=false\' build option to disable VST3 support.\n\n' +
'https://github.com/robbert-vdh/yabridge/issues/63#issuecomment-757369645')
endif
# This version of yabridge will not work when built against Wine 7.21, 7.22,
# or 8.0-rc1 because of https://bugs.winehq.org/show_bug.cgi?id=53912. We'll
# outright prevent building yabridge with these versions to avoid broken
# yabridge builds. If anyone's reading this because you ran into the error
# below, either build with Wine 8.0-rc2+, or stick with yabridge 5.0.2 if
# you're stuck with Wine 7.22.
# NOTE: Meson considers 8.0 to be below 8.0rc2, so this third check is also
# needed
if wine_version.version_compare('>=7.21') and \
wine_version.version_compare('<8.0rc2') and \
wine_version.version_compare('!=8.0')
error('Building this version of yabridge against Wine ' + wine_version +
'would result in nonfunctional binaries. Either build yabridge 5.0.2 ' +
'with Wine 7.22, or switch to Wine 8.0-rc2+. Yabridge built with 8.0-rc2+ ' +
'will also work with older Wine versions, but yabridge built against older ' +
'Wine versions will not work with Wine 7.21+.\n\n' +
'https://bugs.winehq.org/show_bug.cgi?id=53912')
endif
if wine_version.version_compare('>=5.7') and \
wine_version.version_compare('<6.0')
message('- Using the cdecl calling convention')
compiler_options += '-DWINE_USE_CDECL'
endif
if wine_version.version_compare('<6.23') and with_winedbg
message('- Using legacy winedbg argument quoting')
compiler_options += '-DWINEDBG_LEGACY_ARGUMENT_QUOTING'
endif
else
warning('Unable to determine the current Wine version')
endif
#
# Dependencies
#
include_dir = include_directories('src/include', is_system : true)
# These dependencies require separate linking flags for the 32-bit and 64-bit
# versions
# I honestly have no idea what the correct way is to have `dependency()` or
# `compiler.find_dependency()` search for 32-bit versions of libraries when
# cross-compiling. Meson also doesn't seem to respect the default linker
# search path set by the system in `find_library()`. If anyone does know how
# to properly do this, please let me know!
winegcc = meson.get_compiler('cpp', native : false)
if is_64bit_system
xcb_64bit_dep = dependency('xcb')
endif
if with_32bit_libraries or with_bitbridge
xcb_32bit_dep = winegcc.find_library('xcb')
endif
# These are all headers-only libraries, and thus won't require separate 32-bit
# and 64-bit versions
# NOTE: The standalone asio library does not come with a pkgconfig or CMake
# build definition, and Meson thus also won't be able to detect it this
# way. As a workaround for distro packaging, configuring the project with
# `-Dsystem-asio=true` will use `<asio.h>` from the standard include
# directories instead.
if with_system_asio
if not meson.get_compiler('cpp', native : true).check_header('asio.hpp')
error('The \'system-asio\' build option was set, but <asio.hpp> was not found')
endif
asio_version = meson.get_compiler('cpp', native : true).get_define('ASIO_VERSION', prefix : '#include <asio.hpp>')
if asio_version.to_int() < 102800
error('Expected version 1.28.0 of the asio library or higher, found @0@ (MMmmrr)'.format(asio_version))
endif
# This is a dummy dependency, since the library is only accessible implicitly through the system include path
asio_dep = declare_dependency()
else
asio_dep = dependency('asio', version : '>=1.28.0')
endif
if meson.version().version_compare('>=0.60')
# Bitsery's CMake build definition is capitalized for some reason
bitsery_dep = dependency('bitsery', 'Bitsery', version : '>=5.2.0')
else
# Mmeson <=0.6.0 didn't support multiple names for a dependency, and since at
# the moment this is only relevant for packing on Arch btw, it's probably
# better to remove this conditional later than it is to bump the minimum Meson
# version now.
bitsery_dep = dependency('bitsery', version : '>=5.2.0')
endif
# The D-Bus headers are also only accessed through the include path. We don't
# link to libdbus-1 to make soname changes don't completely break yabridge.
dbus_dep = dependency('dbus-1').partial_dependency(compile_args : true, includes : true)
function2_dep = dependency('function2', version : '>=4.0.0')
ghc_filesystem_dep = dependency('ghc_filesystem', modules : 'ghcFilesystem::ghc_filesystem', version : '>=1.5.0')
threads_dep = dependency('threads')
# Tomlplusplus recently added a shraed library version. We don't want to link to
# that. `compile_library` is deprecated but it (incorrectly) defaults to `true`
# so we can't omit it.
tomlplusplus_dep = dependency('tomlplusplus', version : '>=3.4.0', default_options : ['compile_library=false']).partial_dependency(compile_args : true, includes : true)
dl_dep = declare_dependency(link_args : '-ldl')
rt_dep = declare_dependency(link_args : '-lrt')
wine_ole32_dep = declare_dependency(link_args : '-lole32')
# The SDK includes a comment pragma that would link to this on MSVC
wine_shell32_dep = declare_dependency(link_args : '-lshell32')
# The built in threads dependency does not know how to handle winegcc
wine_threads_dep = declare_dependency(link_args : '-lpthread')
wine_uuid_dep = declare_dependency(link_args : '-luuid')
if with_clap
clap_dep = dependency('clap', version : ['>=1.1.7', '<1.2'])
endif
# We need to build the VST3 SDK dependencies in tree because Meson won't let us
# build both native, 32-bit cross compiled and 64-bit cross compiled
# dependencies from a (CMake) subproject
if with_vst3
subdir('src/common/vst3')
endif
#
# Binaries
#
# The application consists of a plugin (`libyabridge-{clap,vst2,vst3}.so`) that calls
# a Winelib application (`yabridge-host{,-32}.exe`) that can host Windows VST2
# and VST3 plugins. These plugins can in turn be loaded from small stub
# libraries dubbed chainloaders to avoid having to copy large plugin libraries
# around. More information about the way these two components work together can
# be found in `docs/architecture.md`.
#
# Generate header files for configuration variables such as the current git tag
# and the name of the host binary
subdir('src/common/config')
# These only contain the definitions for sources and dependencies. It would be
# nice to define the libraries and executables inside of these meson.build
# files, but that will also scatter the build artifacts around in the `build/`
# directory and it's much more convenient having all of the important files
# directory under `build/`.
# https://github.com/mesonbuild/meson/pull/4037
subdir('src/chainloader')
subdir('src/plugin')
subdir('src/wine-host')
shared_library(
vst2_plugin_name,
vst2_plugin_sources,
native : true,
include_directories : include_dir,
dependencies : vst2_plugin_deps,
# NOTE: LTO does not support Winelibs, and it seems to break
# `libyabridge-vst2.so` in Bitwig for some reason. It should be left
# turned off for the time being except for on the chainloader
# libraries.
cpp_args : compiler_options,
)
shared_library(
'yabridge-chainloader-vst2',
vst2_chainloader_sources,
native : true,
dependencies : chainloader_deps,
cpp_args : compiler_options + chainloader_compiler_options,
# LTO is useful here to get rid of unused code
override_options : ['b_lto=true'],
)
if with_clap
# This is the CLAP equivalent of `libyabridge-vst2.so`. The Wine host
# applications can handle VST2, VST3, and CLAP plugins.
shared_library(
clap_plugin_name,
clap_plugin_sources,
native : true,
include_directories : include_dir,
dependencies : clap_plugin_deps,
cpp_args : compiler_options,
)
shared_library(
'yabridge-chainloader-clap',
clap_chainloader_sources,
native : true,
dependencies : clap_chainloader_deps,
cpp_args : compiler_options + chainloader_compiler_options,
# See above
override_options : ['b_lto=true'],
)
endif
if with_vst3
# This is the VST3 equivalent of `libyabridge-vst2.so`. The Wine host
# applications can handle both VST2, VST3 and CLAP plugins.
shared_library(
vst3_plugin_name,
vst3_plugin_sources,
native : true,
include_directories : include_dir,
dependencies : vst3_plugin_deps,
cpp_args : compiler_options,
)
shared_library(
'yabridge-chainloader-vst3',
vst3_chainloader_sources,
native : true,
dependencies : chainloader_deps,
cpp_args : compiler_options + chainloader_compiler_options,
# See above
override_options : ['b_lto=true'],
)
endif
if is_64bit_system
executable(
host_name_64bit,
host_sources,
native : false,
include_directories : include_dir,
dependencies : host_64bit_deps,
cpp_args : compiler_options + wine_64bit_compiler_options,
link_args : ['-m64'],
)
endif
if with_bitbridge
executable(
host_name_32bit,
host_sources,
native : false,
include_directories : include_dir,
dependencies : host_32bit_deps,
cpp_args : compiler_options + wine_32bit_compiler_options,
link_args : ['-m32'],
)
endif