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):
267 return "\\n\\\"E-No\\\""
270 return "\\n\\\"No Pussyfooting\\\""
272 return "\\n\\\"Here Come the Warm Jets\\\""
274 return "\\n\\\"Taking Tiger Mountain\\\""
276 return "\\n\\\"Lady June's Linguistic Leprosy\\\""
278 return "\\n\\\"Discreet Music\\\""
280 return "\\n\\\"Another Green World\\\""
282 return "\\n\\\"Evening Star\\\""
286 autowaf.set_options(opt)
290 conf.load('compiler_cxx')
291 autowaf.configure(conf)
293 # TODO: Insert a sanity check for on OS X to ensure CoreAudio is present
295 autowaf.check_pkg(conf, 'fftw3f', uselib_store='FFTW3F',
297 autowaf.check_pkg(conf, 'fftw3f', uselib_store='FFTW35F',
298 atleast_version='3.3.5', mandatory=False)
299 autowaf.check_pkg(conf, 'flac', uselib_store='FLAC',
300 atleast_version='1.2.1')
301 autowaf.check_pkg(conf, 'gthread-2.0', uselib_store='GTHREAD',
302 atleast_version='2.10.1')
303 autowaf.check_pkg(conf, 'gtk+-2.0', uselib_store='GTK',
304 atleast_version='2.18')
305 autowaf.check_pkg(conf, 'gtkmm-2.4', uselib_store='GTKMM',
306 atleast_version='2.18')
307 autowaf.check_pkg(conf, 'ogg', uselib_store='OGG', atleast_version='1.1.2')
308 autowaf.check_pkg(conf, 'x11', uselib_store='X11', atleast_version='1.1', mandatory=False)
309 autowaf.check_pkg(conf, 'fontconfig', uselib_store='FONTCONFIG')
311 conf.write_config_header('gtk2ardour-config.h', remove=False)
313 bak = conf.env['define_key']
314 conf.define('VERSIONSTRING', str (conf.env['VERSION']))
315 conf.define('CODENAME', enoify(int(conf.env['MAJOR']), int(conf.env['MINOR'])))
316 conf.env['define_key'] = ['VERSIONSTRING', 'CODENAME' ]
317 conf.write_config_header('gtk2ardour-version.h')
318 conf.env['define_key'] = bak;
321 autowaf.check_header(conf, 'cxx', 'boost/shared_ptr.hpp')
322 autowaf.check_header(conf, 'cxx', 'boost/weak_ptr.hpp')
324 # Add a waf `feature' to allow compilation of things using winegcc
325 from waflib.TaskGen import feature
327 def set_winegcc(self):
328 self.env.LINK_CXX = self.env.LINK_CC = 'wineg++'
329 self.env.CC = 'winegcc'
331 def _doPyp(infileName, deps = False):
334 re_spaces = re.compile("\s+")
336 if infileName == '-':
339 fd = open(infileName)
340 inLines = fd.readlines()
346 bits = re_spaces.split(line)
347 if bits[0] == '##include':
352 # assume included file comes from same place as source file
353 incName = os.path.join (os.path.dirname (infileName), incName);
354 outStr += _doPyp(incName)
365 def include_processor(task):
366 infileName = task.inputs[0].srcpath()
367 outfileName = os.path.join(out, task.outputs[0].bldpath())
368 fdOut = open (outfileName, "w")
369 fdOut.write (_doPyp(infileName))
373 def build_color_scheme(path, prefix):
377 if re.search ('^#@color', line):
378 line.strip() # remove newline
380 if len(color_scheme):
382 color_scheme += prefix
384 color_scheme += words[1]
386 color_scheme += words[2]
392 VERSION = "%s.%s" % (bld.env['MAJOR'], bld.env['MINOR'])
393 I18N_PACKAGE = 'gtk2_ardour' + bld.env['MAJOR']
395 if bld.is_defined('WINDOWS_VST_SUPPORT') and bld.env['build_target'] != 'mingw':
396 # Windows VST support w/wine
397 # If we require VST support we build a stub main() and the FST library
398 # here using winegcc, and link it to the GTK front-end library
399 obj = bld (features = 'cxx c cxxprogram wine')
400 obj.source = ( '../libs/fst/vstwin.c', '../vst/winmain.c' )
402 # XXX do we really need to explicitly link to all of these for the wine executable?
404 obj.use = [ 'libpbd',
415 obj.target = 'ardour-' + str (bld.env['VERSION']) + '-vst.exe.so'
416 obj.includes = [ '../libs/fst', '.' ]
417 obj.linkflags = ['-mwindows', '-Wl,--export-dynamic']
418 obj.linkflags += bld.env['LDFLAGS']
419 obj.defines = ['_POSIX_SOURCE', 'USE_WS_PREFIX']
420 obj.install_path = bld.env['DLLDIR']
421 # end of the wine executable
423 # now the shared library containing the GTK GUI for ardour
424 obj = bld (features = 'cxx c cxxshlib')
425 obj.source = gtk2_ardour_sources
426 obj.includes = [ '../libs/fst', '.' ]
427 obj.name = 'libgtk2_ardour'
428 obj.target = 'gtk2_ardour'
431 # just the normal executable version of the GTK GUI
432 if bld.env['build_target'] == 'mingw':
433 obj = bld (features = 'cxx c cxxprogram winres')
435 obj = bld (features = 'cxx c cxxprogram')
436 obj.source = gtk2_ardour_sources
437 obj.target = 'ardour-' + str (bld.env['VERSION'])
439 obj.ldflags = ['-no-undefined']
441 if bld.is_defined('WINDOWS_VST_SUPPORT'):
442 # Windows VST support mingw
443 obj.includes += [ '../libs/fst' ]
445 # at this point, "obj" refers to either the normal native executable
446 # OR the shared library built for use with wine on linux.
448 obj.use = [ 'libpbd',
459 'PACKAGE="' + I18N_PACKAGE + '"',
460 'DATA_DIR="' + os.path.normpath(bld.env['DATADIR']) + '"',
461 'CONFIG_DIR="' + os.path.normpath(bld.env['SYSCONFDIR']) + '"',
462 'LOCALEDIR="' + os.path.normpath(bld.env['LOCALEDIR']) + '"',
464 obj.install_path = bld.env['DLLDIR']
466 obj.uselib = 'UUID FLAC FONTCONFIG GLIBMM GTHREAD GTK OGG CURL DL'
467 obj.uselib += ' GTKMM CANVAS FFTW3F'
468 obj.uselib += ' AUDIOUNITS OSX GTKOSX LO '
469 obj.uselib += ' TAGLIB '
471 if sys.platform == 'darwin':
472 obj.uselib += ' AUDIOUNITS OSX GTKOSX'
473 obj.use += ' libappleutility'
474 obj.source += [ 'cocoacarbon.mm', 'bundle_env_cocoa.cc' ]
475 elif bld.env['build_target'] == 'mingw':
476 obj.source += [ 'bundle_env_mingw.cc' ]
477 obj.source += [ 'windows_icon.rc' ]
479 obj.source += [ 'bundle_env_linux.cc' ]
481 obj.includes += ['../libs']
483 obj.use += 'libptformat'
485 if bld.env['build_target'] == 'mingw':
486 obj.linkflags += ' -mwindows'
488 if bld.is_defined('HAVE_SUIL'):
489 obj.source += [ 'lv2_plugin_ui.cc' ]
490 obj.use += [ 'SUIL' ]
492 if bld.is_defined('HAVE_FFTW35F') and bld.env['build_target'] != 'mingw':
493 obj.linkflags += ' -lfftw3f_threads'
495 if bld.is_defined('NEED_INTL'):
496 obj.linkflags += ' -lintl'
498 if bld.is_defined('WINDOWS_VST_SUPPORT'):
499 obj.source += [ 'windows_vst_plugin_ui.cc' ]
500 obj.defines += [ 'WINDOWS_VST_SUPPORT' ]
501 if bld.env['build_target'] != 'mingw':
504 if bld.is_defined('LXVST_SUPPORT'):
505 obj.source += [ 'linux_vst_gui_support.cc', 'lxvst_plugin_ui.cc' ]
506 obj.defines += [ 'LXVST_SUPPORT' ]
509 if bld.is_defined('WINDOWS_VST_SUPPORT') or bld.is_defined('LXVST_SUPPORT'):
510 obj.source += [ 'vst_plugin_ui.cc' ]
512 if bld.is_defined('PHONE_HOME'):
513 obj.defines += [ 'PHONE_HOME' ]
515 if bld.is_defined('HAVE_COREAUDIO'):
516 TaskGen.task_gen.mappings['.mm'] = TaskGen.task_gen.mappings['.cc']
517 obj.use += ' libappleutility '
519 if bld.is_defined('AUDIOUNIT_SUPPORT'):
520 obj.source += [ 'au_pluginui.mm' ]
524 wrapper_subst_dict = {
525 'INSTALL_PREFIX' : bld.env['PREFIX'],
526 'LIBDIR' : os.path.normpath(bld.env['DLLDIR']),
527 'DATADIR' : os.path.normpath(bld.env['DATADIR']),
528 'CONFDIR' : os.path.normpath(bld.env['CONFDIR']),
529 'LIBS' : 'build/libs',
530 'VERSION' : str (bld.env['VERSION']),
531 'EXECUTABLE' : 'build/gtk2_ardour/ardour-' + str (bld.env['VERSION'])
534 def set_subst_dict(obj, dict):
536 setattr(obj, i, dict[i])
538 obj = bld(features = 'subst')
539 obj.source = 'ardev_common.sh.in'
540 obj.target = 'ardev_common_waf.sh'
541 obj.chmod = Utils.O755
542 obj.dict = wrapper_subst_dict
543 set_subst_dict(obj, wrapper_subst_dict)
545 obj = bld(features = 'subst')
546 obj.source = 'ardour.sh.in'
547 obj.target = 'ardour' + str (bld.env['MAJOR'])
548 obj.chmod = Utils.O755
549 obj.dict = wrapper_subst_dict
550 obj.install_path = bld.env['BINDIR']
551 set_subst_dict(obj, wrapper_subst_dict)
553 if bld.is_defined('WINDOWS_VST_SUPPORT'):
554 obj = bld(features = 'subst')
555 obj.source = '../vst/ardourvst.in'
556 obj.target = 'ardourvst' + str (bld.env['MAJOR'])
557 obj.chmod = Utils.O755
558 obj.dict = wrapper_subst_dict
559 obj.install_path = bld.env['BINDIR']
560 set_subst_dict(obj, wrapper_subst_dict)
569 if bld.is_defined('GTKOSX'): # OS X fonts
583 # There is no acceptable monospace font available on older versions of OS X
584 # and no API on those versions to load TTF files that will work with
585 # GTK/fontconfig/pango.
587 # In addition, the ArdourMono font gets clipped for some reason on OS X
589 # Moreover, Lucida Grande just seems to work even though it is not monospace
593 'MONOSPACE' : 'Monaco',
594 'CLOCKFONT' : 'Lucida Grande',
596 else: # Linux/X11 fonts
597 basefont = '' # unspecified - use system defaults
610 'MONOSPACE' : 'ArdourMono',
611 'CLOCKFONT' : 'ArdourMono',
614 # Set up font substitution dictionary
616 for style in ['', 'BOLD', 'ITALIC']:
617 for sizename,points in iter(font_sizes.items()):
619 key = "_".join (['FONT',style,sizename])
620 fontstyle = " ".join ([basefont,style.lower(),points])
622 key = "_".join (['FONT',sizename])
623 fontstyle = " ".join ([basefont,points])
625 font_subst_dict[key] = fontstyle
628 for sizename,points in iter(font_sizes.items()):
629 key = "_".join (['FONT_SIZE',sizename])
630 font_subst_dict[key] = points
632 # various font names, eg @BOLD_MONOSPACE@
633 for font_sym,text in iter(font_names.items()):
635 font_subst_dict[key] = text
639 obj = bld(features = 'subst')
640 obj.source = [ 'clearlooks.rc.in' ]
641 obj.target = 'clearlooks.rc'
642 obj.install_path = bld.env['CONFDIR']
643 set_subst_dict(obj, font_subst_dict)
645 obj = bld(features = 'subst')
646 obj.source = [ 'default_ui_config.in' ]
647 obj.target = 'default_ui_config'
648 obj.install_path = bld.env['CONFDIR']
649 set_subst_dict(obj, font_subst_dict)
653 if bld.is_defined('GTKOSX'):
654 menus_argv = [ '-E', '-P', '-DGTKOSX' ]
656 menus_argv = [ '-E', '-P' ]
658 if bld.is_defined('PTFORMAT'):
659 menus_argv += [ '-DPTFORMAT' ]
661 # always build all versions of the menu definitions
662 # so that we can try them out with different program builds.
663 for program in [ 'ardour', 'trx' ]:
664 obj = bld(features = 'command-output')
666 obj.command_is_external = True
668 obj.argv = menus_argv
669 obj.dep_vars = ['PTFORMAT', 'GTKOSX', 'WINDOWS']
670 obj.stdin = program + '.menus.in'
671 obj.stdout = program + '.menus'
672 bld.install_files (bld.env['CONFDIR'], program + '.menus')
675 freedesktop_subst_dict = {
676 'ARDOUR_EXEC' : str (bld.env['lwrcase_dirname']),
677 'ARDOUR_ICON' : str (bld.env['lwrcase_dirname']),
678 'VERSION': str (bld.env['VERSION']),
681 if bld.env['FREEDESKTOP']:
682 obj = bld(features = 'subst')
683 obj.source = 'ardour.desktop.in'
684 obj.target = str (bld.env['lwrcase_dirname']) + '.desktop'
685 obj.chmod = Utils.O644
686 obj.dict = freedesktop_subst_dict
687 set_subst_dict(obj, freedesktop_subst_dict)
689 obj = bld(features = 'subst')
690 obj.source = 'ardour-mime-info.xml'
691 obj.target = 'ardour.xml'
692 obj.chmod = Utils.O644
694 # build appdata with translations
696 appdata_i18n_xmlin(bld)
697 obj = bld(features = 'subst')
698 obj.source = 'ardour.appdata.xml.in'
699 obj.target = str (bld.env['lwrcase_dirname']) + '.appdata.xml'
700 obj.chmod = Utils.O644
701 obj.dict = freedesktop_subst_dict
702 set_subst_dict(obj, freedesktop_subst_dict)
706 # 'SAE-de-keypad', 'SAE-de-nokeypad', 'SAE-us-keypad',
707 # 'SAE-us-nokeypad', 'ergonomic-us'
710 # explicitly state the use of perl here so that it works on windows too
712 a_rule = 'perl ../tools/fmt-bindings --platform="%s" --winkey="%s" --accelmap <${SRC} >${TGT}' % (sys.platform, bld.env['WINDOWS_KEY'] )
713 for b in [ 'mnemonic-us' ] :
715 target = b + '.bindings',
716 source = b + '.bindings.in',
719 obj.install_path = bld.env['CONFDIR']
721 # not modified at present
722 bld.install_files(bld.env['CONFDIR'], 'dark.colors')
723 bld.install_files(bld.env['CONFDIR'], 'step_editing.bindings')
724 bld.install_files(bld.env['CONFDIR'], 'mixer.bindings')
727 bld.install_files(os.path.join (bld.env['DATADIR'], 'icons'), bld.path.ant_glob('icons/*.png'))
728 bld.install_files(os.path.join (bld.env['DATADIR'], 'pixmaps'), bld.path.ant_glob('pixmaps/*.xpm'))
729 bld.install_files(bld.env['DATADIR'], 'splash.png')
730 bld.install_files(bld.env['DATADIR'], 'small-splash.png')
731 bld.install_files(bld.env['DATADIR'], 'ArdourMono.ttf')
733 if bld.env['build_target'] == 'mingw':
734 # These icons need to overwrite the files already installed in the icons
735 # directory above. Do this in the external packaging scripts for now.
736 #bld.install_files(os.path.join (bld.env['DATADIR'], 'icons'), bld.path.ant_glob('icons/cursor_square/*.png'))
737 bld.install_files(os.path.join (bld.env['DATADIR'], 'icons'), 'icons/cursor_square/hotspots')
739 # Default UI configuration
740 bld.install_files(bld.env['CONFDIR'], 'default_ui_config')
742 bld.install_files(bld.env['CONFDIR'], 'dark.colors')
744 # Default export stuff
745 bld.install_files(os.path.join(bld.env['CONFDIR'], 'export'), bld.path.ant_glob('export/*.format'))
748 if bld.is_defined('ENABLE_NLS'):
749 mo_files = bld.path.ant_glob('po/*.mo')
751 lang = os.path.basename(mo.srcpath()).replace('.mo', '')
752 bld.install_as (os.path.join(os.path.normpath(bld.env['LOCALEDIR']), lang, 'LC_MESSAGES', I18N_PACKAGE + '.mo'),
756 I18N_PACKAGE = 'gtk2_ardour' + bld.env['MAJOR']
757 autowaf.build_i18n(bld, top, 'gtk2_ardour', I18N_PACKAGE, gtk2_ardour_sources,
759 appdata_i18n_pot(bld)
763 I18N_PACKAGE = 'gtk2_ardour' + bld.env['MAJOR']
764 autowaf.build_i18n_pot(bld, top, 'gtk2_ardour', I18N_PACKAGE, gtk2_ardour_sources,
766 appdata_i18n_pot(bld)
769 I18N_PACKAGE = 'gtk2_ardour' + bld.env['MAJOR']
770 autowaf.build_i18n_po(bld, top, 'gtk2_ardour', I18N_PACKAGE, gtk2_ardour_sources,
775 I18N_PACKAGE = 'gtk2_ardour' + bld.env['MAJOR']
776 autowaf.build_i18n_mo(bld, top, 'gtk2_ardour', I18N_PACKAGE, gtk2_ardour_sources,
779 def appdata_i18n_pot(bld):
780 potfile = os.path.join(bld.top_dir, 'gtk2_ardour', 'appdata',
781 'ardour.appdata.pot')
782 if bld.cmd == 'build':
783 Logs.info('Generating pot file from Ardour appdata')
784 itsfile = os.path.join(bld.top_dir, 'tools', 'as-metainfo.its')
785 adsource = os.path.join(bld.top_dir, 'gtk2_ardour',
786 'ardour.appdata.xml.in.in')
787 Logs.info('Updating ' + potfile)
788 subprocess.call(('itstool', '-i', itsfile, '-o', potfile, adsource))
789 elif bld.cmd == 'clean' and os.path.exists(potfile):
790 Logs.info('Removing Ardour appdata pot file')
793 def appdata_i18n_po(bld):
794 autowaf.build_i18n_po(bld, bld.top_dir, os.path.join(
795 'gtk2_ardour', 'appdata'), 'ardour.appdata', 'dummy', 'dummy')
797 def appdata_i18n_mo(bld):
798 autowaf.build_i18n_mo(bld, bld.top_dir, os.path.join(
799 'gtk2_ardour', 'appdata'), 'ardour.appdata', 'dummy', 'dummy')
801 def appdata_i18n_xmlin(bld):
802 adxmlinfile = os.path.join(bld.top_dir, 'gtk2_ardour',
803 'ardour.appdata.xml.in')
804 if bld.cmd == 'build':
805 itsfile = os.path.join(bld.top_dir, 'tools', 'as-metainfo.its')
806 adxmlininfile = os.path.join(bld.top_dir, 'gtk2_ardour',
807 'ardour.appdata.xml.in.in')
808 mo_glob = os.path.join(bld.top_dir, 'gtk2_ardour', 'appdata', 'po', '*.mo')
809 mo_files = glob.glob(mo_glob)
810 Logs.info('Generating ' + adxmlinfile)
811 subprocess.call(['itstool', '-i', itsfile, '-o', adxmlinfile,
812 '-j', adxmlininfile] + mo_files)
813 elif bld.cmd == 'clean' and os.path.exists(adxmlinfile):
814 Logs.info('Removing ' + adxmlinfile)
815 os.remove(adxmlinfile)