1# Copyright (C) 2020-2021 Alexandros Theodotou <alex at zrythm dot org>
2#
3# This file is part of ZPlugins
4#
5# ZPlugins is free software: you can redistribute it and/or modify
6# it under the terms of the GNU Affero General Public License as published by
7# the Free Software Foundation, either version 3 of the License, or
8# (at your option) any later version.
9#
10# ZPlugins is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU Affero General Public License for more details.
14#
15# You should have received a copy of the GNU Affero General Public License
16# along with ZPlugins.  If not, see <https://www.gnu.org/licenses/>.
17
18# name, type, version
19plugins = [
20  ['Chordz', 'MIDIPlugin', '1.0.0'],
21  ['CompressorSP', 'CompressorPlugin', '1.0.0'],
22  ['LimiterSP', 'LimiterPlugin', '0.1.0'],
23  ['LFO', 'OscillatorPlugin', '1.0.2'],
24  ['PhaserSP', 'PhaserPlugin', '0.1.0'],
25  ['PitchSP', 'PitchPlugin', '0.1.0'],
26  #['Saturator', 'DistortionPlugin', '0.1.0'],
27  ['Saw', 'InstrumentPlugin', '1.0.0'],
28  ['VerbSP', 'ReverbPlugin', '0.1.0'],
29  ['TestPlugin', 'MIDIPlugin', '0.1.0'],
30  ]
31
32if os_darwin
33  libext = '.dylib'
34elif os_windows
35  libext = '.dll'
36else
37  libext = '.so'
38endif
39
40guile_path = guile.path ()
41if os_windows
42  guile_path = 'guile'
43endif
44manifest_gen_wrap = configure_file (
45  input: 'manifest_gen_wrap.sh',
46  output: 'manifest_gen_wrap.sh',
47  configuration: {
48    'CURRENT_SOURCE_DIR': meson.current_source_dir(),
49    'GUILE': guile_path,
50    },
51  )
52
53foreach pl : plugins
54if get_option ('plugins').contains (pl[0])
55
56  plugin_name = pl[0]
57  plugin_name_for_export = plugin_name
58  if get_option ('trial_ver')
59    plugin_name_for_export = plugin_name + '-trial'
60  endif
61
62  pl_str = 'Z' + plugin_name_for_export
63  pl_caps = plugin_name.to_upper ()
64  pl_lowercase = plugin_name.to_lower ()
65  pl_dsp_lib_name_noext = pl_str + '_dsp'
66  pl_ui_lib_name_noext = pl_str + '_ui'
67  pl_type = pl[1]
68  pl_version = pl[2]
69  pl_minor_version = pl_version.split('.')[1]
70  pl_micro_version = pl_version.split('.')[1]
71
72  pl_install_dir = lv2dir / pl_str + '.lv2'
73  project_uri = 'https://www.zrythm.org/plugins'
74  pl_uri = project_uri + '/' + pl_str
75  pl_ui_uri = pl_uri + '#UI'
76  pl_dsp_binary = pl_dsp_lib_name_noext + libext
77  pl_ui_binary = pl_ui_lib_name_noext + libext
78  pl_ttl = pl_str + '.ttl'
79
80  resources_exist = fs.is_dir (
81    join_paths (pl_lowercase, 'resources'))
82
83  # get UI data
84  ui_type = 'none'
85  ui_uri = 'none'
86  ui_binary = 'none'
87  ui_exists = fs.is_file (
88    join_paths (pl_lowercase, 'ui.c'))
89  if ui_exists
90    if os_windows
91      ui_type = 'WindowsUI'
92    elif os_linux or os_dragonfly
93      ui_type = 'X11UI'
94    elif os_darwin
95      ui_type = 'CocoaUI'
96    endif
97    ui_uri = pl_ui_uri
98    ui_binary = pl_ui_binary
99  endif
100
101  # set config.h data
102  config_h_data = configuration_data ()
103  config_h_data.set_quoted (
104    'PROJECT_URI', project_uri)
105  config_h_data.set_quoted (
106    'PLUGIN_NAME', pl_str)
107  config_h_data.set_quoted (
108    'PLUGIN_URI', pl_uri)
109  config_h_data.set_quoted (
110    'PLUGIN_UI_URI', pl_ui_uri)
111  config_h_data.set_quoted (
112    'PLUGIN_UI_TYPE', ui_type)
113  config_h_data.set_quoted (
114    'PLUGIN_TYPE', pl_type)
115  config_h_data.set_quoted (
116    'PLUGIN_COMMON',
117    join_paths (pl_lowercase, 'common.h'))
118  config_h_data.set_quoted (
119    'PLUGIN_TTL_H', join_paths (pl_lowercase, 'ttl.h'))
120  config_h_data.set_quoted (
121    'INSTALL_PATH', pl_install_dir)
122  if get_option('buildtype') == 'release'
123    config_h_data.set ('RELEASE', 1)
124  endif
125  if get_option ('trial_ver')
126    config_h_data.set ('TRIAL_VER', 1)
127    config_h_data.set ('SECONDS_TO_SILENCE', 900)
128  endif
129  config_h_data.set_quoted (
130    pl_caps + '_VERSION', pl[2])
131
132  # create config.h
133  pl_config_h = configure_file (
134    output: pl_lowercase + '_config.h',
135    configuration: config_h_data,
136    )
137  pl_config_h_dep = declare_dependency (
138    sources: pl_config_h,
139    )
140
141  if not lv2_dep.found()
142    lilv_proj = subproject('lilv')
143    lv2_dep = lilv_proj.get_variable('lv2_dep')
144  endif
145
146  pl_deps = [
147    pl_config_h_dep,
148    cc.find_library ('m'),
149    lv2_dep,
150    pre_soundpipe_dep,
151    ]
152
153  # create dsp shared library
154  pl_inc_dirs = include_directories([
155    '.', pl_lowercase,
156    join_paths ('..', 'ext', 'Soundpipe', 'h'),
157    ])
158  pl_dsp_lib = shared_library (
159    pl_dsp_lib_name_noext,
160    name_prefix: '',
161    sources: [
162      join_paths (
163        pl_lowercase, 'dsp.c'),
164      ],
165    dependencies: pl_deps,
166    include_directories: pl_inc_dirs,
167    link_with: soundpipe_lib,
168    install: true,
169    install_dir: pl_install_dir,
170    c_args: [
171      common_cflags,
172      '-DPLUGIN_CONFIG="../' + pl_lowercase + '_config.h"',
173      ],
174    )
175
176  # create UI shared library if UI exists
177  if ui_exists
178    ui_inc_dirs = include_directories([
179      '.', pl_lowercase,
180      ])
181    pl_ui_lib = shared_library (
182      pl_ui_lib_name_noext,
183      name_prefix: '',
184      sources: [
185        join_paths (
186          pl_lowercase, 'ui.c'),
187        ],
188      dependencies: [
189        pl_deps,
190        ztoolkit_dep,
191        dependency ('librsvg-2.0'),
192        ],
193      include_directories: ui_inc_dirs,
194      install: true,
195      install_dir: pl_install_dir,
196      c_args: [
197        common_cflags,
198        '-DPLUGIN_CONFIG="../' + pl_lowercase + '_config.h"',
199        ],
200      )
201  endif
202
203  # installs resources if any
204  if resources_exist
205    install_subdir (
206      join_paths (pl_lowercase, 'resources'),
207      install_dir: pl_install_dir)
208  endif
209
210  presets_file = 'none'
211  # TODO add presets
212
213  # create and install manifest ttl
214  manifest_ttl = configure_file (
215    output: pl_str + '_manifest.ttl',
216    command: [
217      sh,
218      meson.current_build_dir () / 'manifest_gen_wrap.sh',
219      '@OUTPUT@',
220      project_uri, pl_type, pl_uri,
221      pl_dsp_binary, pl_minor_version,
222      pl_micro_version, pl_ttl,
223      ui_type, ui_uri, ui_binary, presets_file,
224      ],
225    )
226  install_data (
227    manifest_ttl,
228    install_dir: pl_install_dir,
229    rename: 'manifest.ttl',
230    )
231
232  # create and install ttl
233  lv2_ttl_gen = executable (
234    pl_lowercase + '_ttl_gen',
235    sources: [
236      'ttl_gen.c'
237      ],
238    include_directories: pl_inc_dirs,
239    dependencies: lv2_dep,
240    c_args: [
241      common_cflags,
242      '-DPLUGIN_CONFIG="../' + pl_lowercase + '_config.h"',
243      ],
244    install: false,
245    native: true,
246    )
247  pl_ttl = custom_target (
248    pl_str + '.ttl',
249    output: pl_str + '.ttl',
250    input: [ lv2_ttl_gen, pl_config_h ],
251    command: [
252      lv2_ttl_gen, '@OUTPUT@' ],
253    install: true,
254    install_dir: pl_install_dir,
255    )
256
257  # test
258  pl_build_dir = meson.current_build_dir ()
259  test_env = environment ({
260    'PL_BUILD_DIR': pl_build_dir,
261    'PL_NAME': pl_str,
262    'PL_URI': pl_uri,
263    'LIBEXT': libext,
264    'LV2_DIR': lv2_core_path,
265    })
266  if not os_windows
267    if lv2lint.found() and (os_linux or os_dragonfly)
268      test (
269        'LV2 lint', lv2lint_wrap,
270        args: [ lv2lint.path () ],
271        env: test_env,
272        suite: pl[0])
273    endif
274    if lv2_validate.found() and sord_validate.found()
275      test (
276        'LV2 validate', lv2_validate_wrap,
277        args: [ lv2_validate.path() ],
278        env: test_env,
279        suite: pl[0])
280    endif
281    if carla_single.found () and not pl_str.contains ('LFO')
282      test (
283        'Carla single', carla_single_wrap,
284        args: [ carla_single.path () ],
285        env: test_env,
286        timeout: 60,
287        suite: pl[0])
288    endif
289  endif
290endif
291endforeach
292