1project('moony.lv2', 'c', default_options : [
2	'buildtype=release',
3	'warning_level=1',
4	'werror=false',
5	'b_lto=false',
6	'c_std=gnu11'])
7
8d2tk = subproject('d2tk')
9nk_pugl = subproject('nk_pugl')
10
11lv2libdir = get_option('lv2libdir')
12build_tests = get_option('build-tests')
13gc_method = get_option('gc-method')
14
15inst_dir = join_paths(lv2libdir, meson.project_name())
16
17if get_option('use-backend-nanovg').enabled()
18	d2tk_dep = d2tk.get_variable('d2tk_nanovg')
19elif get_option('use-backend-cairo').enabled()
20	d2tk_dep = d2tk.get_variable('d2tk_cairo')
21else
22	error('no valid UI backend given')
23endif
24
25nk_pugl_dep = nk_pugl.get_variable('nk_pugl_gl')
26cousine_regular_ttf = nk_pugl.get_variable('cousine_regular_ttf')
27
28source_root = meson.source_root()
29build_root = meson.build_root()
30
31build_opengl_ui = get_option('build-opengl-ui')
32build_next_ui = get_option('build-next-ui')
33build_inline_disp = get_option('build-inline-disp')
34
35static_link = meson.is_cross_build()
36
37cc = meson.get_compiler('c')
38
39m_dep = cc.find_library('m')
40lv2_dep = dependency('lv2', version : '>=1.14.0')
41cairo_dep = dependency('cairo', version : '>=1.15.0',
42	required : build_inline_disp,
43	static : static_link)
44thread_dep = dependency('threads')
45
46dsp_deps = [m_dep, lv2_dep, cairo_dep, thread_dep]
47nk_ui_deps = [m_dep, lv2_dep, cairo_dep, thread_dep, nk_pugl_dep]
48d2tk_ui_deps = [m_dep, lv2_dep, d2tk_dep]
49
50if cc.has_member('LV2UI_Request_Value', 'request',
51		prefix : '#include <lv2/lv2plug.in/ns/extensions/ui/ui.h>')
52	add_project_arguments('-D_LV2_HAS_REQUEST_VALUE', language : 'c')
53	message('building with ui:requestValue support')
54endif
55
56if host_machine.system() == 'windows'
57	# nothing to do for DSP
58elif host_machine.system() == 'darwin'
59	# nothing to do for DSP
60else
61	dsp_deps += cc.find_library('rt')
62endif
63
64lpeg_prefix = 'lpeg-1.0.2'
65lua_prefix = 'lua-5.4.2'
66
67canvas_inc = include_directories('canvas.lv2')
68extui_inc = include_directories('ext_ui.lv2')
69include_inc= include_directories('include')
70api_inc = include_directories('api')
71plugin_inc = include_directories('plugin')
72laes128_inc = include_directories('laes128')
73tinyaes_inc = include_directories('tiny-AES128-C')
74lascii85_inc = include_directories('lascii85')
75lbase64_inc = include_directories('lbase64')
76lcomplex_inc = include_directories('lcomplex')
77lmathx_inc = include_directories('lmathx')
78lpeg_inc = include_directories(lpeg_prefix)
79lrandom_inc = include_directories('lrandom')
80lua_inc = include_directories(lua_prefix)
81osc_inc = include_directories('osc.lv2')
82timely_inc = include_directories('timely.lv2')
83tlsf_inc = include_directories('tlsf-3.0')
84varchunk_inc = include_directories('varchunk')
85xpress_inc = include_directories('xpress.lv2')
86nk_pugl_inc = include_directories(join_paths('subprojects', 'nk_pugl'))
87d2tk_inc = include_directories(join_paths('subprojects', 'd2tk'))
88props_inc = include_directories('props.lv2')
89ser_atom_inc = include_directories('ser_atom.lv2')
90inc_dir = [canvas_inc, extui_inc, include_inc, api_inc, plugin_inc, laes128_inc, tinyaes_inc, lascii85_inc, lbase64_inc, lcomplex_inc, lmathx_inc, lpeg_inc, lrandom_inc, lua_inc, osc_inc, timely_inc, tlsf_inc, varchunk_inc, xpress_inc, nk_pugl_inc, d2tk_inc, props_inc, ser_atom_inc]
91
92rawvers = run_command('cat', 'VERSION').stdout().strip()
93version = rawvers.split('.')
94
95conf_data = configuration_data()
96conf_data.set('MAJOR_VERSION', version[0])
97conf_data.set('MINOR_VERSION', version[1])
98conf_data.set('MICRO_VERSION', version[2])
99
100add_project_arguments('-DMOONY_VERSION="'+rawvers+'"', language : 'c')
101add_project_arguments('-DMOONY_MINOR_VERSION='+version[1], language : 'c')
102add_project_arguments('-DMOONY_MICRO_VERSION='+version[2], language : 'c')
103add_project_arguments('-D_GNU_SOURCE', language : 'c')
104if build_inline_disp
105	add_project_arguments('-DBUILD_INLINE_DISP', language : 'c')
106endif
107
108if gc_method == 'manual'
109	message('using manual gc method')
110	add_project_arguments('-DUSE_MANUAL_GC', language : 'c')
111elif gc_method == 'incremental'
112	message('using incremental gc method')
113	add_project_arguments('-DUSE_INCREMENTAL_GC', language : 'c')
114elif gc_method == 'generational'
115	message('using generational gc method')
116	add_project_arguments('-DUSE_GENERATIONAL_GC', language : 'c')
117else
118	error('gc method invalid')
119endif
120
121lv2_validate = find_program('lv2_validate', native : true, required : false)
122sord_validate = find_program('sord_validate', native : true, required : false)
123lv2lint = find_program('lv2lint', required : false)
124
125c_args = [
126	'-fvisibility=hidden',
127	'-Wno-attributes',
128	'-Wno-unused-function']
129
130laes128_lib = static_library('laes128',
131	join_paths('laes128', 'laes128.c'),
132	join_paths('tiny-AES128-C', 'aes.c'),
133	include_directories : inc_dir,
134	c_args : c_args)
135
136lascii85_lib = static_library('lascii85',
137	join_paths('lascii85', 'lascii85.c'),
138	include_directories : inc_dir,
139	c_args : c_args)
140
141lbase64_lib = static_library('lbase64',
142	join_paths('lbase64', 'lbase64.c'),
143	include_directories : inc_dir,
144	c_args : c_args)
145
146lcomplex_lib = static_library('lcomplex',
147	join_paths('lcomplex', 'lcomplex.c'),
148	include_directories : inc_dir,
149	c_args : c_args)
150
151lmathx_lib = static_library('lmathx',
152	join_paths('lmathx', 'lmathx.c'),
153	include_directories : inc_dir,
154	c_args : c_args)
155
156lrandom_lib = static_library('lrandom',
157	join_paths('lrandom', 'lrandom.c'),
158	include_directories : inc_dir,
159	c_args : c_args)
160
161lpeg_lib = static_library('lpeg',
162	join_paths(lpeg_prefix, 'lpcap.c'),
163	join_paths(lpeg_prefix, 'lpcode.c'),
164	join_paths(lpeg_prefix, 'lpprint.c'),
165	join_paths(lpeg_prefix, 'lptree.c'),
166	join_paths(lpeg_prefix, 'lpvm.c'),
167	include_directories : inc_dir,
168	c_args : c_args)
169
170lua_lib = static_library('lua',
171	join_paths(lua_prefix, 'lapi.c'),
172	join_paths(lua_prefix, 'lcode.c'),
173	join_paths(lua_prefix, 'lctype.c'),
174	join_paths(lua_prefix, 'ldebug.c'),
175	join_paths(lua_prefix, 'ldo.c'),
176	join_paths(lua_prefix, 'ldump.c'),
177	join_paths(lua_prefix, 'lfunc.c'),
178	join_paths(lua_prefix, 'lgc.c'),
179	join_paths(lua_prefix, 'llex.c'),
180	join_paths(lua_prefix, 'lmem.c'),
181	join_paths(lua_prefix, 'lobject.c'),
182	join_paths(lua_prefix, 'lopcodes.c'),
183	join_paths(lua_prefix, 'lparser.c'),
184	join_paths(lua_prefix, 'lstate.c'),
185	join_paths(lua_prefix, 'lstring.c'),
186	join_paths(lua_prefix, 'ltable.c'),
187	join_paths(lua_prefix, 'ltm.c'),
188	join_paths(lua_prefix, 'lundump.c'),
189	join_paths(lua_prefix, 'lvm.c'),
190	join_paths(lua_prefix, 'lzio.c'),
191
192	join_paths(lua_prefix, 'liolib.c'),
193	join_paths(lua_prefix, 'loadlib.c'),
194	#join_paths(lua_prefix, 'lbitlib.c'),
195	#join_paths(lua_prefix, 'loslib.c'),
196	#join_paths(lua_prefix, 'linit.c'),
197
198	join_paths(lua_prefix, 'ldblib.c'),
199	join_paths(lua_prefix, 'lbaselib.c'),
200	join_paths(lua_prefix, 'lauxlib.c'),
201	join_paths(lua_prefix, 'lcorolib.c'),
202	join_paths(lua_prefix, 'lmathlib.c'),
203	join_paths(lua_prefix, 'lstrlib.c'),
204	join_paths(lua_prefix, 'ltablib.c'),
205	join_paths(lua_prefix, 'lutf8lib.c'),
206	include_directories : inc_dir,
207	c_args : c_args)
208
209tlsf_lib = static_library('tlsf',
210	join_paths('tlsf-3.0', 'tlsf.c'),
211	include_directories : inc_dir,
212	c_args : c_args)
213
214api_lib = static_library('api',
215	join_paths('api', 'api_atom.c'),
216	join_paths('api', 'api.c'),
217	join_paths('api', 'api_forge.c'),
218	join_paths('api', 'api_midi.c'),
219	join_paths('api', 'api_osc.c'),
220	join_paths('api', 'api_parameter.c'),
221	join_paths('api', 'api_stash.c'),
222	join_paths('api', 'api_state.c'),
223	join_paths('api', 'api_time.c'),
224	join_paths('api', 'api_vm.c'),
225	include_directories : inc_dir,
226	dependencies : dsp_deps,
227	c_args : c_args)
228
229dsp_links = [laes128_lib, lascii85_lib, lbase64_lib, lcomplex_lib, lmathx_lib, lrandom_lib, lpeg_lib, lua_lib, tlsf_lib, api_lib]
230
231ui_with = [lpeg_lib, lua_lib]
232
233dsp_srcs = [
234	join_paths('plugin', 'moony.c'),
235	join_paths('plugin', 'axa.c'),
236	join_paths('plugin', 'caxca.c'),
237	join_paths('plugin', 'cxc.c')]
238
239app_srcs = [
240	join_paths('test', 'moony_test.c')]
241
242mod = shared_module('moony', dsp_srcs,
243	c_args : c_args,
244	include_directories : inc_dir,
245	name_prefix : '',
246	dependencies : dsp_deps,
247	link_with : dsp_links,
248	install : true,
249	install_dir : inst_dir)
250
251suffix = mod.full_path().strip().split('.')[-1]
252conf_data.set('MODULE_SUFFIX', '.' + suffix)
253conf_data.set('UI', '#')
254conf_data.set('UI_TYPE', 'UI')
255
256if build_inline_disp
257	conf_data.set('BUILD_INLINE_DISPLAY', '')
258else
259	conf_data.set('BUILD_INLINE_DISPLAY', '#')
260endif
261
262if build_opengl_ui
263	message('building OpenGL UI')
264	conf_data.set('UI', '')
265	conf_data.set('UI_OPENGL', '')
266else
267	conf_data.set('UI_OPENGL', '#')
268endif
269
270if build_next_ui
271	message('building Simple UI')
272	conf_data.set('UI', '')
273	conf_data.set('UI_NEXT', '')
274else
275	conf_data.set('UI_NEXT', '#')
276endif
277
278if host_machine.system() == 'windows'
279	conf_data.set('UI_TYPE', 'WindowsUI')
280elif host_machine.system() == 'darwin'
281	conf_data.set('UI_TYPE', 'CocoaUI')
282else
283	conf_data.set('UI_TYPE', 'X11UI')
284endif
285
286if build_opengl_ui
287	nk_ui_srcs = [
288		join_paths('plugin', 'nk_ui.c')]
289
290	nk_ui = shared_module('moony_ui', nk_ui_srcs,
291		c_args : c_args,
292		include_directories : inc_dir,
293		name_prefix : '',
294		dependencies : nk_ui_deps,
295		link_with : ui_with,
296		install : true,
297		install_dir : inst_dir)
298endif
299
300if build_next_ui
301	d2tk_ui_srcs = [
302		join_paths('plugin', 'd2tk_ui.c')]
303
304	d2tk_ui = shared_module('moony_d2tk', d2tk_ui_srcs,
305		c_args : c_args,
306		include_directories : inc_dir,
307		name_prefix : '',
308		dependencies : d2tk_ui_deps,
309		install : true,
310		install_dir : inst_dir)
311
312	use_fontconfig = get_option('use-fontconfig')
313	if not use_fontconfig.enabled()
314		fira_sans_bold_ttf = d2tk.get_variable('fira_sans_bold_ttf')
315		fira_code_bold_ttf = d2tk.get_variable('fira_code_bold_ttf')
316		fira_code_light_ttf = d2tk.get_variable('fira_code_light_ttf')
317		fira_code_medium_ttf = d2tk.get_variable('fira_code_medium_ttf')
318		fira_code_regular_ttf = d2tk.get_variable('fira_code_regular_ttf')
319
320		configure_file(
321			input : fira_sans_bold_ttf,
322			output : 'FiraSans:bold.ttf',
323			copy : true,
324			install : true,
325			install_dir : inst_dir)
326		configure_file(
327			input : fira_code_bold_ttf,
328			output : 'FiraCode:bold.ttf',
329			copy : true,
330			install : true,
331			install_dir : inst_dir)
332		configure_file(
333			input : fira_code_light_ttf,
334			output : 'FiraCode:light.ttf',
335			copy : true,
336			install : true,
337			install_dir : inst_dir)
338		configure_file(
339			input : fira_code_medium_ttf,
340			output : 'FiraCode:medium.ttf',
341			copy : true,
342			install : true,
343			install_dir : inst_dir)
344		configure_file(
345			input : fira_code_regular_ttf,
346			output : 'FiraCode:regular.ttf',
347			copy : true,
348			install : true,
349			install_dir : inst_dir)
350	endif
351endif
352
353manifest_ttl = configure_file(
354	input : join_paths('plugin', 'manifest.ttl.in'),
355	output : 'manifest.ttl',
356	configuration : conf_data,
357	install : true,
358	install_dir : inst_dir)
359
360dsp_ttl = configure_file(
361	input : join_paths('plugin', 'moony.ttl.in'),
362	output : 'moony.ttl',
363	configuration: conf_data,
364	install : true,
365	install_dir : inst_dir)
366
367ui_ttl = configure_file(
368	input : join_paths('plugin', 'moony_ui.ttl'),
369	output : 'moony_ui.ttl',
370	copy : true,
371	install : true,
372	install_dir : inst_dir)
373
374pset_ttl = configure_file(
375	input : join_paths('plugin', 'presets.ttl'),
376	output : 'presets.ttl',
377	copy : true,
378	install : true,
379	install_dir : inst_dir)
380
381configure_file(
382	input : cousine_regular_ttf,
383	output : 'Cousine-Regular.ttf',
384	copy : true,
385	install : true,
386	install_dir : inst_dir)
387
388lexer_lua = configure_file(
389	input : join_paths('plugin', 'lexer.lua'),
390	output : 'lexer.lua',
391	copy : true,
392	install : true,
393	install_dir : inst_dir)
394moony_lua = configure_file(
395	input : join_paths('plugin', 'moony.lua'),
396	output : 'moony.lua',
397	copy : true,
398	install : true,
399	install_dir : inst_dir)
400
401configure_file(
402	input : join_paths('png', 'libre-gui-exclamation-circle.png'),
403	output : 'libre-gui-exclamation-circle.png',
404	copy : true,
405	install : true,
406	install_dir : inst_dir)
407configure_file(
408	input : join_paths('png', 'bell.png'),
409	output : 'bell.png',
410	copy : true,
411	install : true,
412	install_dir : inst_dir)
413configure_file(
414	input : join_paths('png', 'cancel-1.png'),
415	output : 'cancel-1.png',
416	copy : true,
417	install : true,
418	install_dir : inst_dir)
419configure_file(
420	input : join_paths('png', 'cancel.png'),
421	output : 'cancel.png',
422	copy : true,
423	install : true,
424	install_dir : inst_dir)
425configure_file(
426	input : join_paths('png', 'checked.png'),
427	output : 'checked.png',
428	copy : true,
429	install : true,
430	install_dir : inst_dir)
431configure_file(
432	input : join_paths('png', 'download.png'),
433	output : 'download.png',
434	copy : true,
435	install : true,
436	install_dir : inst_dir)
437configure_file(
438	input : join_paths('png', 'envelope.png'),
439	output : 'envelope.png',
440	copy : true,
441	install : true,
442	install_dir : inst_dir)
443configure_file(
444	input : join_paths('png', 'house.png'),
445	output : 'house.png',
446	copy : true,
447	install : true,
448	install_dir : inst_dir)
449configure_file(
450	input : join_paths('png', 'layers.png'),
451	output : 'layers.png',
452	copy : true,
453	install : true,
454	install_dir : inst_dir)
455configure_file(
456	input : join_paths('png', 'menu.png'),
457	output : 'menu.png',
458	copy : true,
459	install : true,
460	install_dir : inst_dir)
461configure_file(
462	input : join_paths('png', 'next.png'),
463	output : 'next.png',
464	copy : true,
465	install : true,
466	install_dir : inst_dir)
467configure_file(
468	input : join_paths('png', 'pencil.png'),
469	output : 'pencil.png',
470	copy : true,
471	install : true,
472	install_dir : inst_dir)
473configure_file(
474	input : join_paths('png', 'plus.png'),
475	output : 'plus.png',
476	copy : true,
477	install : true,
478	install_dir : inst_dir)
479configure_file(
480	input : join_paths('png', 'question.png'),
481	output : 'question.png',
482	copy : true,
483	install : true,
484	install_dir : inst_dir)
485configure_file(
486	input : join_paths('png', 'reload.png'),
487	output : 'reload.png',
488	copy : true,
489	install : true,
490	install_dir : inst_dir)
491configure_file(
492	input : join_paths('png', 'screen.png'),
493	output : 'screen.png',
494	copy : true,
495	install : true,
496	install_dir : inst_dir)
497configure_file(
498	input : join_paths('png', 'settings.png'),
499	output : 'settings.png',
500	copy : true,
501	install : true,
502	install_dir : inst_dir)
503configure_file(
504	input : join_paths('png', 'sort.png'),
505	output : 'sort.png',
506	copy : true,
507	install : true,
508	install_dir : inst_dir)
509configure_file(
510	input : join_paths('png', 'upload.png'),
511	output : 'upload.png',
512	copy : true,
513	install : true,
514	install_dir : inst_dir)
515configure_file(
516	input : join_paths('png', 'user.png'),
517	output : 'user.png',
518	copy : true,
519	install : true,
520	install_dir : inst_dir)
521configure_file(
522	input : join_paths('logo', 'omk_logo_256x256.png'),
523	output : 'omk_logo_256x256.png',
524	copy : true,
525	install : true,
526	install_dir : inst_dir)
527configure_file(
528	input : join_paths('logo', 'moony_logo.png'),
529	output : 'moony_logo.png',
530	copy : true,
531	install : true,
532	install_dir : inst_dir)
533
534alert_triangle_png = configure_file(
535	input : join_paths('png2', 'alert-triangle.png'),
536	output : 'alert-triangle.png',
537	copy : true,
538	install : true,
539	install_dir : inst_dir)
540clipboard_png = configure_file(
541	input : join_paths('png2', 'clipboard.png'),
542	output : 'clipboard.png',
543	copy: true,
544	install : true,
545	install_dir : inst_dir)
546copy_png = configure_file(
547	input : join_paths('png2', 'copy.png'),
548	output : 'copy.png',
549	copy: true,
550	install : true,
551	install_dir : inst_dir)
552delete_png = configure_file(
553	input : join_paths('png2', 'delete.png'),
554	output : 'delete.png',
555	copy: true,
556	install : true,
557	install_dir : inst_dir)
558eye_off_png = configure_file(
559	input : join_paths('png2', 'eye-off.png'),
560	output : 'eye-off.png',
561	copy: true,
562	install : true,
563	install_dir : inst_dir)
564eye_png = configure_file(
565	input : join_paths('png2', 'eye.png'),
566	output : 'eye.png',
567	copy: true,
568	install : true,
569	install_dir : inst_dir)
570save_png = configure_file(
571	input : join_paths('png2', 'save.png'),
572	output : 'save.png',
573	copy: true,
574	install : true,
575	install_dir : inst_dir)
576info_png = configure_file(
577	input : join_paths('png2', 'info.png'),
578	output : 'info.png',
579	copy: true,
580	install : true,
581	install_dir : inst_dir)
582
583moony_test_lua = configure_file(
584	input : join_paths('test', 'moony_test.lua'),
585	output : 'moony_test.lua',
586	copy : true,
587	install : false)
588moony_overflow_lua = configure_file(
589	input : join_paths('test', 'moony_overflow.lua'),
590	output : 'moony_overflow.lua',
591	copy : true,
592	install : false)
593moony_manual_lua = configure_file(
594	input : join_paths('test', 'moony_manual.lua'),
595	output : 'moony_manual.lua',
596	copy : true,
597	install : false)
598moony_presets_lua = configure_file(
599	input : join_paths('test', 'moony_presets.lua'),
600	output : 'moony_presets.lua',
601	copy : true,
602	install : false)
603
604manual_html_in = configure_file(
605	input : join_paths('manual', 'manual.html.in'),
606	output : 'manual.html.in',
607	copy: true,
608	install : false)
609hilight_lua = configure_file(
610	input : join_paths('manual', 'hilight.lua'),
611	output : 'hilight.lua',
612	copy : true,
613	install : false)
614
615if build_tests
616	app = executable('moony_test', app_srcs,
617		c_args : c_args,
618		include_directories : inc_dir,
619		name_prefix : '',
620		dependencies : dsp_deps,
621		link_with : dsp_links,
622		install : false)
623
624	if host_machine.system() != 'darwin'
625		custom_target('manual_html',
626			input : hilight_lua,
627			output : 'manual.html',
628			capture : true,
629			command : [app, '@INPUT@'],
630			#depends : [lexer_lua, moony_lua, manual_html_in], FIXME
631			install : true,
632			install_dir : inst_dir)
633
634		test('API', app,
635			args : [moony_test_lua])
636		test('Overflow', app,
637			args : [moony_overflow_lua, '0'])
638		test('Manual', app,
639			args : [moony_manual_lua])
640		test('Presets', app,
641			args : [moony_presets_lua])
642	endif
643
644	if lv2_validate.found() and sord_validate.found()
645		test('LV2 validate', lv2_validate,
646			args : [manifest_ttl, dsp_ttl, ui_ttl, pset_ttl])
647	endif
648
649	if lv2lint.found()
650		test('LV2 lint', lv2lint,
651			args : [ '-I', join_paths(build_root, ''),
652				'http://open-music-kontrollers.ch/lv2/moony#a1xa1',
653				'http://open-music-kontrollers.ch/lv2/moony#a2xa2',
654				'http://open-music-kontrollers.ch/lv2/moony#a4xa4',
655				'http://open-music-kontrollers.ch/lv2/moony#c1a1xc1a1',
656				'http://open-music-kontrollers.ch/lv2/moony#c1xc1',
657				'http://open-music-kontrollers.ch/lv2/moony#c2a1xc2a1',
658				'http://open-music-kontrollers.ch/lv2/moony#c2xc2',
659				'http://open-music-kontrollers.ch/lv2/moony#c4a1xc4a1',
660				'http://open-music-kontrollers.ch/lv2/moony#c4xc4'])
661	endif
662endif
663