2 from waflib.extras import autowaf as autowaf
3 from waflib import Options, TaskGen
4 import waflib.Logs as Logs, waflib.Utils as Utils
10 from waflib.Task import Task
11 from waflib.Tools import winres
19 path_prefix = 'gtk2_ardour/'
21 gtk2_ardour_sources = [
24 'add_route_dialog.cc',
25 'ambiguous_file_dialog.cc',
34 'ardour_ui_dependents.cc',
35 'ardour_ui_dialogs.cc',
38 'ardour_ui_options.cc',
41 'audio_region_editor.cc',
42 'audio_region_view.cc',
43 'audio_streamview.cc',
45 'automation_controller.cc',
47 'automation_region_view.cc',
48 'automation_streamview.cc',
49 'automation_time_axis.cc',
51 'big_clock_window.cc',
57 'control_point_dialog.cc',
61 'duplicate_routes_dialog.cc',
62 'edit_note_dialog.cc',
66 'editor_audio_import.cc',
67 'editor_pt_import.cc',
68 'editor_audiotrack.cc',
70 'editor_canvas_events.cc',
71 'editor_component.cc',
74 'editor_route_groups.cc',
75 'editor_export_audio.cc',
76 'editor_group_tabs.cc',
78 'editor_locations.cc',
86 'editor_selection.cc',
87 'editor_snapshots.cc',
89 'editor_tempodisplay.cc',
93 'export_channel_selector.cc',
95 'export_file_notebook.cc',
96 'export_filename_selector.cc',
97 'export_format_dialog.cc',
98 'export_format_selector.cc',
99 'export_preset_selector.cc',
100 'export_timespan_selector.cc',
104 'floating_text_entry.cc',
105 'sfdb_freesound_mootcher.cc',
107 'generic_pluginui.cc',
109 'global_port_matrix.cc',
111 'gtk_pianokeyboard.c',
113 'insert_remove_time_dialog.cc',
114 'instrument_selector.cc',
115 'interthread_progress_window.cc',
127 'midi_automation_line.cc',
128 'midi_channel_dialog.cc',
129 'midi_channel_selector.cc',
130 'midi_cut_buffer.cc',
131 'midi_export_dialog.cc',
132 'midi_list_editor.cc',
133 'midi_port_dialog.cc',
134 'midi_region_view.cc',
137 'midi_streamview.cc',
140 'midi_velocity_dialog.cc',
141 'missing_file_dialog.cc',
142 'missing_plugin_dialog.cc',
144 'mixer_group_tabs.cc',
150 'monitor_section.cc',
151 'monitor_selector.cc',
153 'mono_panner_editor.cc',
156 'new_plugin_preset_dialog.cc',
157 'normalize_dialog.cc',
161 'note_select_dialog.cc',
168 'panner_interface.cc',
171 'piano_roll_header.cc',
173 'playlist_selector.cc',
175 'plugin_selector.cc',
180 'port_matrix_body.cc',
181 'port_matrix_column_labels.cc',
182 'port_matrix_component.cc',
183 'port_matrix_grid.cc',
184 'port_matrix_labels.cc',
185 'port_matrix_row_labels.cc',
187 'patch_change_dialog.cc',
188 'progress_reporter.cc',
191 'quantize_dialog.cc',
192 'rc_option_editor.cc',
194 'region_gain_line.cc',
195 'region_layering_order_editor.cc',
196 'region_selection.cc',
200 'route_group_dialog.cc',
201 'route_group_menu.cc',
202 'route_params_ui.cc',
203 'route_processor_selection.cc',
204 'route_time_axis.cc',
208 'search_path_option.cc',
210 'selection_memento.cc',
213 'session_import_dialog.cc',
214 'session_metadata_dialog.cc',
215 'session_option_editor.cc',
217 'shuttle_control.cc',
218 'soundcloud_export_selector.cc',
225 'stereo_panner_editor.cc',
227 'strip_silence_dialog.cc',
229 'tape_region_view.cc',
234 'time_axis_view_item.cc',
240 'track_selection.cc',
241 'track_view_list.cc',
242 'transform_dialog.cc',
243 'transpose_dialog.cc',
247 'visibility_group.cc',
248 'volume_controller.cc',
250 # video-timeline related sources:
251 'video_image_frame.cc',
252 'add_video_dialog.cc',
253 'editor_videotimeline.cc',
256 'transcode_ffmpeg.cc',
257 'transcode_video_dialog.cc',
258 'video_server_dialog.cc',
260 'export_video_dialog.cc',
261 'export_video_infobox.cc',
262 'video_tool_paths.cc'
265 def enoify (major, minor):
266 # Code names based on
267 # https://en.wikipedia.org/wiki/Brian_Eno_discography
269 # sort Studio albums + Collaborative albums + Compilation albums by Month/Year.
270 # (no Singles, no EPs, no Video Albums, no Production)
272 return "\\n\\\"E-No\\\""
275 return "\\n\\\"No Pussyfooting\\\""
277 return "\\n\\\"Here Come the Warm Jets\\\""
279 return "\\n\\\"Taking Tiger Mountain\\\""
281 return "\\n\\\"Lady June's Linguistic Leprosy\\\""
283 return "\\n\\\"Discreet Music\\\""
285 return "\\n\\\"Another Green World\\\""
287 return "\\n\\\"Evening Star\\\""
289 return "\\n\\\"Cluster and Eno\\\""
291 return "\\n\\\"Before and After Science\\\""
295 autowaf.set_options(opt)
299 conf.load('compiler_cxx')
300 autowaf.configure(conf)
302 # TODO: Insert a sanity check for on OS X to ensure CoreAudio is present
304 autowaf.check_pkg(conf, 'fftw3f', uselib_store='FFTW3F',
306 autowaf.check_pkg(conf, 'fftw3f', uselib_store='FFTW35F',
307 atleast_version='3.3.5', mandatory=False)
308 autowaf.check_pkg(conf, 'flac', uselib_store='FLAC',
309 atleast_version='1.2.1')
310 autowaf.check_pkg(conf, 'gthread-2.0', uselib_store='GTHREAD',
311 atleast_version='2.10.1')
312 autowaf.check_pkg(conf, 'gtk+-2.0', uselib_store='GTK',
313 atleast_version='2.18')
314 autowaf.check_pkg(conf, 'gtkmm-2.4', uselib_store='GTKMM',
315 atleast_version='2.18')
316 autowaf.check_pkg(conf, 'ogg', uselib_store='OGG', atleast_version='1.1.2')
317 autowaf.check_pkg(conf, 'x11', uselib_store='X11', atleast_version='1.1', mandatory=False)
318 autowaf.check_pkg(conf, 'fontconfig', uselib_store='FONTCONFIG')
320 conf.write_config_header('gtk2ardour-config.h', remove=False)
322 bak = conf.env['define_key']
323 conf.define('VERSIONSTRING', str (conf.env['VERSION']))
324 conf.define('CODENAME', enoify(int(conf.env['MAJOR']), int(conf.env['MINOR'])))
325 conf.env['define_key'] = ['VERSIONSTRING', 'CODENAME' ]
326 conf.write_config_header('gtk2ardour-version.h')
327 conf.env['define_key'] = bak;
330 autowaf.check_header(conf, 'cxx', 'boost/shared_ptr.hpp')
331 autowaf.check_header(conf, 'cxx', 'boost/weak_ptr.hpp')
333 # Add a waf `feature' to allow compilation of things using winegcc
334 from waflib.TaskGen import feature
336 def set_winegcc(self):
337 self.env.LINK_CXX = self.env.LINK_CC = 'wineg++'
338 self.env.CC = 'winegcc'
340 def _doPyp(infileName, deps = False):
343 re_spaces = re.compile("\s+")
345 if infileName == '-':
348 fd = open(infileName)
349 inLines = fd.readlines()
355 bits = re_spaces.split(line)
356 if bits[0] == '##include':
361 # assume included file comes from same place as source file
362 incName = os.path.join (os.path.dirname (infileName), incName);
363 outStr += _doPyp(incName)
374 def include_processor(task):
375 infileName = task.inputs[0].srcpath()
376 outfileName = os.path.join(out, task.outputs[0].bldpath())
377 fdOut = open (outfileName, "w")
378 fdOut.write (_doPyp(infileName))
382 def build_color_scheme(path, prefix):
386 if re.search ('^#@color', line):
387 line.strip() # remove newline
389 if len(color_scheme):
391 color_scheme += prefix
393 color_scheme += words[1]
395 color_scheme += words[2]
401 VERSION = "%s.%s" % (bld.env['MAJOR'], bld.env['MINOR'])
402 I18N_PACKAGE = 'gtk2_ardour' + bld.env['MAJOR']
404 if bld.is_defined('WINDOWS_VST_SUPPORT') and bld.env['build_target'] != 'mingw':
405 # Windows VST support w/wine
406 # If we require VST support we build a stub main() and the FST library
407 # here using winegcc, and link it to the GTK front-end library
408 obj = bld (features = 'cxx c cxxprogram wine')
409 obj.source = ( '../libs/fst/vstwin.c', '../vst/winmain.c' )
411 # XXX do we really need to explicitly link to all of these for the wine executable?
413 obj.use = [ 'libpbd',
424 obj.target = 'ardour-' + str (bld.env['VERSION']) + '-vst.exe.so'
425 obj.includes = [ '../libs/fst', '.' ]
426 obj.linkflags = ['-mwindows', '-Wl,--export-dynamic']
427 obj.linkflags += bld.env['LDFLAGS']
428 obj.defines = ['_POSIX_SOURCE', 'USE_WS_PREFIX']
429 obj.install_path = bld.env['DLLDIR']
430 # end of the wine executable
432 # now the shared library containing the GTK GUI for ardour
433 obj = bld (features = 'cxx c cxxshlib')
434 # operate on copy to avoid adding sources twice
435 obj.source = list(gtk2_ardour_sources)
436 obj.includes = [ '../libs/fst', '.' ]
437 obj.name = 'libgtk2_ardour'
438 obj.target = 'gtk2_ardour'
439 obj.cflags = [ '-fPIC' ]
442 # just the normal executable version of the GTK GUI
443 if bld.env['build_target'] == 'mingw':
444 obj = bld (features = 'cxx c cxxprogram winres')
446 obj = bld (features = 'cxx c cxxprogram')
447 # operate on copy to avoid adding sources twice
448 obj.source = list(gtk2_ardour_sources)
449 obj.target = 'ardour-' + str (bld.env['VERSION'])
451 obj.ldflags = ['-no-undefined']
453 if bld.is_defined('WINDOWS_VST_SUPPORT'):
454 # Windows VST support mingw
455 obj.includes += [ '../libs/fst' ]
457 # at this point, "obj" refers to either the normal native executable
458 # OR the shared library built for use with wine on linux.
460 obj.use = [ 'libpbd',
471 'PACKAGE="' + I18N_PACKAGE + '"',
472 'DATA_DIR="' + os.path.normpath(bld.env['DATADIR']) + '"',
473 'CONFIG_DIR="' + os.path.normpath(bld.env['SYSCONFDIR']) + '"',
474 'LOCALEDIR="' + os.path.normpath(bld.env['LOCALEDIR']) + '"',
476 obj.install_path = bld.env['DLLDIR']
478 obj.uselib = 'UUID FLAC FONTCONFIG GLIBMM GTHREAD GTK OGG CURL DL'
479 obj.uselib += ' GTKMM CANVAS FFTW3F'
480 obj.uselib += ' AUDIOUNITS OSX GTKOSX LO '
481 obj.uselib += ' TAGLIB '
483 if sys.platform == 'darwin':
484 obj.uselib += ' AUDIOUNITS OSX GTKOSX'
485 obj.use += ' libappleutility'
486 obj.source += [ 'cocoacarbon.mm', 'bundle_env_cocoa.cc' ]
487 elif bld.env['build_target'] == 'mingw':
488 obj.source += [ 'bundle_env_mingw.cc' ]
489 obj.source += [ 'windows_icon.rc' ]
491 obj.source += [ 'bundle_env_linux.cc' ]
493 obj.includes += ['../libs']
495 obj.use += 'libptformat'
497 if bld.env['build_target'] == 'mingw':
498 obj.linkflags += ' -mwindows'
500 if bld.is_defined('HAVE_SUIL'):
501 obj.source += [ 'lv2_plugin_ui.cc' ]
502 obj.use += [ 'SUIL' ]
504 if bld.is_defined('HAVE_FFTW35F') and bld.env['build_target'] != 'mingw':
505 bld.env['LIB_FFTW3F'] += ['fftw3f_threads']
507 if bld.is_defined('NEED_INTL'):
508 obj.linkflags += ' -lintl'
510 if bld.is_defined('WINDOWS_VST_SUPPORT'):
511 obj.source += [ 'windows_vst_plugin_ui.cc' ]
512 obj.defines += [ 'WINDOWS_VST_SUPPORT' ]
513 if bld.env['build_target'] != 'mingw':
516 if bld.is_defined('LXVST_SUPPORT'):
517 obj.source += [ 'linux_vst_gui_support.cc', 'lxvst_plugin_ui.cc' ]
518 obj.defines += [ 'LXVST_SUPPORT' ]
521 if bld.is_defined('WINDOWS_VST_SUPPORT') or bld.is_defined('LXVST_SUPPORT'):
522 obj.source += [ 'vst_plugin_ui.cc' ]
524 if bld.is_defined('PHONE_HOME'):
525 obj.defines += [ 'PHONE_HOME' ]
527 if bld.is_defined('HAVE_COREAUDIO'):
528 TaskGen.task_gen.mappings['.mm'] = TaskGen.task_gen.mappings['.cc']
529 obj.use += ' libappleutility '
531 if bld.is_defined('AUDIOUNIT_SUPPORT'):
532 obj.source += [ 'au_pluginui.mm' ]
536 wrapper_subst_dict = {
537 'INSTALL_PREFIX' : bld.env['PREFIX'],
538 'LIBDIR' : os.path.normpath(bld.env['DLLDIR']),
539 'DATADIR' : os.path.normpath(bld.env['DATADIR']),
540 'CONFDIR' : os.path.normpath(bld.env['CONFDIR']),
541 'LIBS' : 'build/libs',
542 'VERSION' : str (bld.env['VERSION']),
543 'EXECUTABLE' : 'build/gtk2_ardour/ardour-' + str (bld.env['VERSION'])
546 def set_subst_dict(obj, dict):
548 setattr(obj, i, dict[i])
550 obj = bld(features = 'subst')
551 obj.source = 'ardev_common.sh.in'
552 obj.target = 'ardev_common_waf.sh'
553 obj.chmod = Utils.O755
554 obj.dict = wrapper_subst_dict
555 set_subst_dict(obj, wrapper_subst_dict)
557 obj = bld(features = 'subst')
558 obj.source = 'ardour.sh.in'
559 obj.target = 'ardour' + str (bld.env['MAJOR'])
560 obj.chmod = Utils.O755
561 obj.dict = wrapper_subst_dict
562 obj.install_path = bld.env['BINDIR']
563 set_subst_dict(obj, wrapper_subst_dict)
565 if bld.is_defined('WINDOWS_VST_SUPPORT'):
566 obj = bld(features = 'subst')
567 obj.source = '../vst/ardourvst.in'
568 obj.target = 'ardourvst' + str (bld.env['MAJOR'])
569 obj.chmod = Utils.O755
570 obj.dict = wrapper_subst_dict
571 obj.install_path = bld.env['BINDIR']
572 set_subst_dict(obj, wrapper_subst_dict)
581 if bld.is_defined('GTKOSX'): # OS X fonts
595 # There is no acceptable monospace font available on older versions of OS X
596 # and no API on those versions to load TTF files that will work with
597 # GTK/fontconfig/pango.
599 # In addition, the ArdourMono font gets clipped for some reason on OS X
601 # Moreover, Lucida Grande just seems to work even though it is not monospace
605 'MONOSPACE' : 'Monaco',
606 'CLOCKFONT' : 'Lucida Grande',
608 else: # Linux/X11 fonts
609 basefont = '' # unspecified - use system defaults
622 'MONOSPACE' : 'ArdourMono',
623 'CLOCKFONT' : 'ArdourMono',
626 # Set up font substitution dictionary
628 for style in ['', 'BOLD', 'ITALIC']:
629 for sizename,points in iter(font_sizes.items()):
631 key = "_".join (['FONT',style,sizename])
632 fontstyle = " ".join ([basefont,style.lower(),points])
634 key = "_".join (['FONT',sizename])
635 fontstyle = " ".join ([basefont,points])
637 font_subst_dict[key] = fontstyle
640 for sizename,points in iter(font_sizes.items()):
641 key = "_".join (['FONT_SIZE',sizename])
642 font_subst_dict[key] = points
644 # various font names, eg @BOLD_MONOSPACE@
645 for font_sym,text in iter(font_names.items()):
647 font_subst_dict[key] = text
651 obj = bld(features = 'subst')
652 obj.source = [ 'clearlooks.rc.in' ]
653 obj.target = 'clearlooks.rc'
654 obj.install_path = bld.env['CONFDIR']
655 set_subst_dict(obj, font_subst_dict)
657 obj = bld(features = 'subst')
658 obj.source = [ 'default_ui_config.in' ]
659 obj.target = 'default_ui_config'
660 obj.install_path = bld.env['CONFDIR']
661 set_subst_dict(obj, font_subst_dict)
665 if bld.is_defined('GTKOSX'):
666 menus_argv = [ '-E', '-P', '-DGTKOSX', '-' ]
668 menus_argv = [ '-E', '-P' ]
670 if bld.is_defined('PTFORMAT'):
671 menus_argv += [ '-DPTFORMAT' ]
673 # always build all versions of the menu definitions
674 # so that we can try them out with different program builds.
675 for program in [ 'ardour', 'trx' ]:
676 obj = bld(features = 'command-output')
678 obj.command_is_external = True
680 obj.argv = menus_argv
681 obj.dep_vars = ['PTFORMAT', 'GTKOSX', 'WINDOWS']
682 obj.stdin = program + '.menus.in'
683 obj.stdout = program + '.menus'
684 bld.install_files (bld.env['CONFDIR'], program + '.menus')
687 freedesktop_subst_dict = {
688 'ARDOUR_EXEC' : str (bld.env['lwrcase_dirname']),
689 'ARDOUR_ICON' : str (bld.env['lwrcase_dirname']),
690 'VERSION': str (bld.env['VERSION']),
693 if bld.env['FREEDESKTOP']:
694 obj = bld(features = 'subst')
695 obj.source = 'ardour.desktop.in'
696 obj.target = str (bld.env['lwrcase_dirname']) + '.desktop'
697 obj.chmod = Utils.O644
698 obj.dict = freedesktop_subst_dict
699 set_subst_dict(obj, freedesktop_subst_dict)
701 obj = bld(features = 'subst')
702 obj.source = 'ardour-mime-info.xml'
703 obj.target = 'ardour.xml'
704 obj.chmod = Utils.O644
706 # build appdata with translations
708 appdata_i18n_xmlin(bld)
709 obj = bld(features = 'subst')
710 obj.source = 'ardour.appdata.xml.in'
711 obj.target = str (bld.env['lwrcase_dirname']) + '.appdata.xml'
712 obj.chmod = Utils.O644
713 obj.dict = freedesktop_subst_dict
714 set_subst_dict(obj, freedesktop_subst_dict)
718 # 'SAE-de-keypad', 'SAE-de-nokeypad', 'SAE-us-keypad',
719 # 'SAE-us-nokeypad', 'ergonomic-us'
722 # explicitly state the use of perl here so that it works on windows too
724 a_rule = 'perl ../tools/fmt-bindings --platform="%s" --winkey="%s" --accelmap <${SRC} >${TGT}' % (sys.platform, bld.env['WINDOWS_KEY'] )
725 for b in [ 'mnemonic-us' ] :
727 target = b + '.bindings',
728 source = b + '.bindings.in',
731 obj.install_path = bld.env['CONFDIR']
733 # not modified at present
734 bld.install_files(bld.env['CONFDIR'], 'dark.colors')
735 bld.install_files(bld.env['CONFDIR'], 'step_editing.bindings')
736 bld.install_files(bld.env['CONFDIR'], 'mixer.bindings')
739 bld.install_files(os.path.join (bld.env['DATADIR'], 'icons'), bld.path.ant_glob('icons/*.png'))
740 bld.install_files(os.path.join (bld.env['DATADIR'], 'pixmaps'), bld.path.ant_glob('pixmaps/*.xpm'))
741 bld.install_files(bld.env['DATADIR'], 'splash.png')
742 bld.install_files(bld.env['DATADIR'], 'small-splash.png')
743 bld.install_files(bld.env['DATADIR'], 'ArdourMono.ttf')
745 if bld.env['build_target'] == 'mingw':
746 # These icons need to overwrite the files already installed in the icons
747 # directory above. Do this in the external packaging scripts for now.
748 #bld.install_files(os.path.join (bld.env['DATADIR'], 'icons'), bld.path.ant_glob('icons/cursor_square/*.png'))
749 bld.install_files(os.path.join (bld.env['DATADIR'], 'icons'), 'icons/cursor_square/hotspots')
751 # Default UI configuration
752 bld.install_files(bld.env['CONFDIR'], 'default_ui_config')
754 bld.install_files(bld.env['CONFDIR'], 'dark.colors')
756 # Default export stuff
757 bld.install_files(os.path.join(bld.env['CONFDIR'], 'export'), bld.path.ant_glob('export/*.format'))
760 if bld.is_defined('ENABLE_NLS'):
761 mo_files = bld.path.ant_glob('po/*.mo')
763 lang = os.path.basename(mo.srcpath()).replace('.mo', '')
764 bld.install_as (os.path.join(os.path.normpath(bld.env['LOCALEDIR']), lang, 'LC_MESSAGES', I18N_PACKAGE + '.mo'),
768 I18N_PACKAGE = 'gtk2_ardour' + bld.env['MAJOR']
769 autowaf.build_i18n(bld, top, 'gtk2_ardour', I18N_PACKAGE, gtk2_ardour_sources,
771 appdata_i18n_pot(bld)
775 I18N_PACKAGE = 'gtk2_ardour' + bld.env['MAJOR']
776 autowaf.build_i18n_pot(bld, top, 'gtk2_ardour', I18N_PACKAGE, gtk2_ardour_sources,
778 appdata_i18n_pot(bld)
781 I18N_PACKAGE = 'gtk2_ardour' + bld.env['MAJOR']
782 autowaf.build_i18n_po(bld, top, 'gtk2_ardour', I18N_PACKAGE, gtk2_ardour_sources,
787 I18N_PACKAGE = 'gtk2_ardour' + bld.env['MAJOR']
788 autowaf.build_i18n_mo(bld, top, 'gtk2_ardour', I18N_PACKAGE, gtk2_ardour_sources,
791 def appdata_i18n_pot(bld):
792 potfile = os.path.join(bld.top_dir, 'gtk2_ardour', 'appdata',
793 'ardour.appdata.pot')
794 if bld.cmd == 'build':
795 Logs.info('Generating pot file from Ardour appdata')
796 itsfile = os.path.join(bld.top_dir, 'tools', 'as-metainfo.its')
797 adsource = os.path.join(bld.top_dir, 'gtk2_ardour',
798 'ardour.appdata.xml.in.in')
799 Logs.info('Updating ' + potfile)
800 subprocess.call(('itstool', '-i', itsfile, '-o', potfile, adsource))
801 elif bld.cmd == 'clean' and os.path.exists(potfile):
802 Logs.info('Removing Ardour appdata pot file')
805 def appdata_i18n_po(bld):
806 autowaf.build_i18n_po(bld, bld.top_dir, os.path.join(
807 'gtk2_ardour', 'appdata'), 'ardour.appdata', 'dummy', 'dummy')
809 def appdata_i18n_mo(bld):
810 autowaf.build_i18n_mo(bld, bld.top_dir, os.path.join(
811 'gtk2_ardour', 'appdata'), 'ardour.appdata', 'dummy', 'dummy')
813 def appdata_i18n_xmlin(bld):
814 adxmlinfile = os.path.join(bld.top_dir, 'gtk2_ardour',
815 'ardour.appdata.xml.in')
816 if bld.cmd == 'build':
817 itsfile = os.path.join(bld.top_dir, 'tools', 'as-metainfo.its')
818 adxmlininfile = os.path.join(bld.top_dir, 'gtk2_ardour',
819 'ardour.appdata.xml.in.in')
820 mo_glob = os.path.join(bld.top_dir, 'gtk2_ardour', 'appdata', 'po', '*.mo')
821 mo_files = glob.glob(mo_glob)
822 Logs.info('Generating ' + adxmlinfile)
823 subprocess.call(['itstool', '-i', itsfile, '-o', adxmlinfile,
824 '-j', adxmlininfile] + mo_files)
825 elif bld.cmd == 'clean' and os.path.exists(adxmlinfile):
826 Logs.info('Removing ' + adxmlinfile)
827 os.remove(adxmlinfile)