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 # operate on copy to avoid adding sources twice
426 obj.source = list(gtk2_ardour_sources)
427 obj.includes = [ '../libs/fst', '.' ]
428 obj.name = 'libgtk2_ardour'
429 obj.target = 'gtk2_ardour'
432 # just the normal executable version of the GTK GUI
433 if bld.env['build_target'] == 'mingw':
434 obj = bld (features = 'cxx c cxxprogram winres')
436 obj = bld (features = 'cxx c cxxprogram')
437 # operate on copy to avoid adding sources twice
438 obj.source = list(gtk2_ardour_sources)
439 obj.target = 'ardour-' + str (bld.env['VERSION'])
441 obj.ldflags = ['-no-undefined']
443 if bld.is_defined('WINDOWS_VST_SUPPORT'):
444 # Windows VST support mingw
445 obj.includes += [ '../libs/fst' ]
447 # at this point, "obj" refers to either the normal native executable
448 # OR the shared library built for use with wine on linux.
450 obj.use = [ 'libpbd',
461 'PACKAGE="' + I18N_PACKAGE + '"',
462 'DATA_DIR="' + os.path.normpath(bld.env['DATADIR']) + '"',
463 'CONFIG_DIR="' + os.path.normpath(bld.env['SYSCONFDIR']) + '"',
464 'LOCALEDIR="' + os.path.normpath(bld.env['LOCALEDIR']) + '"',
466 obj.install_path = bld.env['DLLDIR']
468 obj.uselib = 'UUID FLAC FONTCONFIG GLIBMM GTHREAD GTK OGG CURL DL'
469 obj.uselib += ' GTKMM CANVAS FFTW3F'
470 obj.uselib += ' AUDIOUNITS OSX GTKOSX LO '
471 obj.uselib += ' TAGLIB '
473 if sys.platform == 'darwin':
474 obj.uselib += ' AUDIOUNITS OSX GTKOSX'
475 obj.use += ' libappleutility'
476 obj.source += [ 'cocoacarbon.mm', 'bundle_env_cocoa.cc' ]
477 elif bld.env['build_target'] == 'mingw':
478 obj.source += [ 'bundle_env_mingw.cc' ]
479 obj.source += [ 'windows_icon.rc' ]
481 obj.source += [ 'bundle_env_linux.cc' ]
483 obj.includes += ['../libs']
485 obj.use += 'libptformat'
487 if bld.env['build_target'] == 'mingw':
488 obj.linkflags += ' -mwindows'
490 if bld.is_defined('HAVE_SUIL'):
491 obj.source += [ 'lv2_plugin_ui.cc' ]
492 obj.use += [ 'SUIL' ]
494 if bld.is_defined('HAVE_FFTW35F') and bld.env['build_target'] != 'mingw':
495 obj.linkflags += ' -lfftw3f_threads'
497 if bld.is_defined('NEED_INTL'):
498 obj.linkflags += ' -lintl'
500 if bld.is_defined('WINDOWS_VST_SUPPORT'):
501 obj.source += [ 'windows_vst_plugin_ui.cc' ]
502 obj.defines += [ 'WINDOWS_VST_SUPPORT' ]
503 if bld.env['build_target'] != 'mingw':
506 if bld.is_defined('LXVST_SUPPORT'):
507 obj.source += [ 'linux_vst_gui_support.cc', 'lxvst_plugin_ui.cc' ]
508 obj.defines += [ 'LXVST_SUPPORT' ]
511 if bld.is_defined('WINDOWS_VST_SUPPORT') or bld.is_defined('LXVST_SUPPORT'):
512 obj.source += [ 'vst_plugin_ui.cc' ]
514 if bld.is_defined('PHONE_HOME'):
515 obj.defines += [ 'PHONE_HOME' ]
517 if bld.is_defined('HAVE_COREAUDIO'):
518 TaskGen.task_gen.mappings['.mm'] = TaskGen.task_gen.mappings['.cc']
519 obj.use += ' libappleutility '
521 if bld.is_defined('AUDIOUNIT_SUPPORT'):
522 obj.source += [ 'au_pluginui.mm' ]
526 wrapper_subst_dict = {
527 'INSTALL_PREFIX' : bld.env['PREFIX'],
528 'LIBDIR' : os.path.normpath(bld.env['DLLDIR']),
529 'DATADIR' : os.path.normpath(bld.env['DATADIR']),
530 'CONFDIR' : os.path.normpath(bld.env['CONFDIR']),
531 'LIBS' : 'build/libs',
532 'VERSION' : str (bld.env['VERSION']),
533 'EXECUTABLE' : 'build/gtk2_ardour/ardour-' + str (bld.env['VERSION'])
536 def set_subst_dict(obj, dict):
538 setattr(obj, i, dict[i])
540 obj = bld(features = 'subst')
541 obj.source = 'ardev_common.sh.in'
542 obj.target = 'ardev_common_waf.sh'
543 obj.chmod = Utils.O755
544 obj.dict = wrapper_subst_dict
545 set_subst_dict(obj, wrapper_subst_dict)
547 obj = bld(features = 'subst')
548 obj.source = 'ardour.sh.in'
549 obj.target = 'ardour' + str (bld.env['MAJOR'])
550 obj.chmod = Utils.O755
551 obj.dict = wrapper_subst_dict
552 obj.install_path = bld.env['BINDIR']
553 set_subst_dict(obj, wrapper_subst_dict)
555 if bld.is_defined('WINDOWS_VST_SUPPORT'):
556 obj = bld(features = 'subst')
557 obj.source = '../vst/ardourvst.in'
558 obj.target = 'ardourvst' + str (bld.env['MAJOR'])
559 obj.chmod = Utils.O755
560 obj.dict = wrapper_subst_dict
561 obj.install_path = bld.env['BINDIR']
562 set_subst_dict(obj, wrapper_subst_dict)
571 if bld.is_defined('GTKOSX'): # OS X fonts
585 # There is no acceptable monospace font available on older versions of OS X
586 # and no API on those versions to load TTF files that will work with
587 # GTK/fontconfig/pango.
589 # In addition, the ArdourMono font gets clipped for some reason on OS X
591 # Moreover, Lucida Grande just seems to work even though it is not monospace
595 'MONOSPACE' : 'Monaco',
596 'CLOCKFONT' : 'Lucida Grande',
598 else: # Linux/X11 fonts
599 basefont = '' # unspecified - use system defaults
612 'MONOSPACE' : 'ArdourMono',
613 'CLOCKFONT' : 'ArdourMono',
616 # Set up font substitution dictionary
618 for style in ['', 'BOLD', 'ITALIC']:
619 for sizename,points in iter(font_sizes.items()):
621 key = "_".join (['FONT',style,sizename])
622 fontstyle = " ".join ([basefont,style.lower(),points])
624 key = "_".join (['FONT',sizename])
625 fontstyle = " ".join ([basefont,points])
627 font_subst_dict[key] = fontstyle
630 for sizename,points in iter(font_sizes.items()):
631 key = "_".join (['FONT_SIZE',sizename])
632 font_subst_dict[key] = points
634 # various font names, eg @BOLD_MONOSPACE@
635 for font_sym,text in iter(font_names.items()):
637 font_subst_dict[key] = text
641 obj = bld(features = 'subst')
642 obj.source = [ 'clearlooks.rc.in' ]
643 obj.target = 'clearlooks.rc'
644 obj.install_path = bld.env['CONFDIR']
645 set_subst_dict(obj, font_subst_dict)
647 obj = bld(features = 'subst')
648 obj.source = [ 'default_ui_config.in' ]
649 obj.target = 'default_ui_config'
650 obj.install_path = bld.env['CONFDIR']
651 set_subst_dict(obj, font_subst_dict)
655 if bld.is_defined('GTKOSX'):
656 menus_argv = [ '-E', '-P', '-DGTKOSX' ]
658 menus_argv = [ '-E', '-P' ]
660 if bld.is_defined('PTFORMAT'):
661 menus_argv += [ '-DPTFORMAT' ]
663 # always build all versions of the menu definitions
664 # so that we can try them out with different program builds.
665 for program in [ 'ardour', 'trx' ]:
666 obj = bld(features = 'command-output')
668 obj.command_is_external = True
670 obj.argv = menus_argv
671 obj.dep_vars = ['PTFORMAT', 'GTKOSX', 'WINDOWS']
672 obj.stdin = program + '.menus.in'
673 obj.stdout = program + '.menus'
674 bld.install_files (bld.env['CONFDIR'], program + '.menus')
677 freedesktop_subst_dict = {
678 'ARDOUR_EXEC' : str (bld.env['lwrcase_dirname']),
679 'ARDOUR_ICON' : str (bld.env['lwrcase_dirname']),
680 'VERSION': str (bld.env['VERSION']),
683 if bld.env['FREEDESKTOP']:
684 obj = bld(features = 'subst')
685 obj.source = 'ardour.desktop.in'
686 obj.target = str (bld.env['lwrcase_dirname']) + '.desktop'
687 obj.chmod = Utils.O644
688 obj.dict = freedesktop_subst_dict
689 set_subst_dict(obj, freedesktop_subst_dict)
691 obj = bld(features = 'subst')
692 obj.source = 'ardour-mime-info.xml'
693 obj.target = 'ardour.xml'
694 obj.chmod = Utils.O644
696 # build appdata with translations
698 appdata_i18n_xmlin(bld)
699 obj = bld(features = 'subst')
700 obj.source = 'ardour.appdata.xml.in'
701 obj.target = str (bld.env['lwrcase_dirname']) + '.appdata.xml'
702 obj.chmod = Utils.O644
703 obj.dict = freedesktop_subst_dict
704 set_subst_dict(obj, freedesktop_subst_dict)
708 # 'SAE-de-keypad', 'SAE-de-nokeypad', 'SAE-us-keypad',
709 # 'SAE-us-nokeypad', 'ergonomic-us'
712 # explicitly state the use of perl here so that it works on windows too
714 a_rule = 'perl ../tools/fmt-bindings --platform="%s" --winkey="%s" --accelmap <${SRC} >${TGT}' % (sys.platform, bld.env['WINDOWS_KEY'] )
715 for b in [ 'mnemonic-us' ] :
717 target = b + '.bindings',
718 source = b + '.bindings.in',
721 obj.install_path = bld.env['CONFDIR']
723 # not modified at present
724 bld.install_files(bld.env['CONFDIR'], 'dark.colors')
725 bld.install_files(bld.env['CONFDIR'], 'step_editing.bindings')
726 bld.install_files(bld.env['CONFDIR'], 'mixer.bindings')
729 bld.install_files(os.path.join (bld.env['DATADIR'], 'icons'), bld.path.ant_glob('icons/*.png'))
730 bld.install_files(os.path.join (bld.env['DATADIR'], 'pixmaps'), bld.path.ant_glob('pixmaps/*.xpm'))
731 bld.install_files(bld.env['DATADIR'], 'splash.png')
732 bld.install_files(bld.env['DATADIR'], 'small-splash.png')
733 bld.install_files(bld.env['DATADIR'], 'ArdourMono.ttf')
735 if bld.env['build_target'] == 'mingw':
736 # These icons need to overwrite the files already installed in the icons
737 # directory above. Do this in the external packaging scripts for now.
738 #bld.install_files(os.path.join (bld.env['DATADIR'], 'icons'), bld.path.ant_glob('icons/cursor_square/*.png'))
739 bld.install_files(os.path.join (bld.env['DATADIR'], 'icons'), 'icons/cursor_square/hotspots')
741 # Default UI configuration
742 bld.install_files(bld.env['CONFDIR'], 'default_ui_config')
744 bld.install_files(bld.env['CONFDIR'], 'dark.colors')
746 # Default export stuff
747 bld.install_files(os.path.join(bld.env['CONFDIR'], 'export'), bld.path.ant_glob('export/*.format'))
750 if bld.is_defined('ENABLE_NLS'):
751 mo_files = bld.path.ant_glob('po/*.mo')
753 lang = os.path.basename(mo.srcpath()).replace('.mo', '')
754 bld.install_as (os.path.join(os.path.normpath(bld.env['LOCALEDIR']), lang, 'LC_MESSAGES', I18N_PACKAGE + '.mo'),
758 I18N_PACKAGE = 'gtk2_ardour' + bld.env['MAJOR']
759 autowaf.build_i18n(bld, top, 'gtk2_ardour', I18N_PACKAGE, gtk2_ardour_sources,
761 appdata_i18n_pot(bld)
765 I18N_PACKAGE = 'gtk2_ardour' + bld.env['MAJOR']
766 autowaf.build_i18n_pot(bld, top, 'gtk2_ardour', I18N_PACKAGE, gtk2_ardour_sources,
768 appdata_i18n_pot(bld)
771 I18N_PACKAGE = 'gtk2_ardour' + bld.env['MAJOR']
772 autowaf.build_i18n_po(bld, top, 'gtk2_ardour', I18N_PACKAGE, gtk2_ardour_sources,
777 I18N_PACKAGE = 'gtk2_ardour' + bld.env['MAJOR']
778 autowaf.build_i18n_mo(bld, top, 'gtk2_ardour', I18N_PACKAGE, gtk2_ardour_sources,
781 def appdata_i18n_pot(bld):
782 potfile = os.path.join(bld.top_dir, 'gtk2_ardour', 'appdata',
783 'ardour.appdata.pot')
784 if bld.cmd == 'build':
785 Logs.info('Generating pot file from Ardour appdata')
786 itsfile = os.path.join(bld.top_dir, 'tools', 'as-metainfo.its')
787 adsource = os.path.join(bld.top_dir, 'gtk2_ardour',
788 'ardour.appdata.xml.in.in')
789 Logs.info('Updating ' + potfile)
790 subprocess.call(('itstool', '-i', itsfile, '-o', potfile, adsource))
791 elif bld.cmd == 'clean' and os.path.exists(potfile):
792 Logs.info('Removing Ardour appdata pot file')
795 def appdata_i18n_po(bld):
796 autowaf.build_i18n_po(bld, bld.top_dir, os.path.join(
797 'gtk2_ardour', 'appdata'), 'ardour.appdata', 'dummy', 'dummy')
799 def appdata_i18n_mo(bld):
800 autowaf.build_i18n_mo(bld, bld.top_dir, os.path.join(
801 'gtk2_ardour', 'appdata'), 'ardour.appdata', 'dummy', 'dummy')
803 def appdata_i18n_xmlin(bld):
804 adxmlinfile = os.path.join(bld.top_dir, 'gtk2_ardour',
805 'ardour.appdata.xml.in')
806 if bld.cmd == 'build':
807 itsfile = os.path.join(bld.top_dir, 'tools', 'as-metainfo.its')
808 adxmlininfile = os.path.join(bld.top_dir, 'gtk2_ardour',
809 'ardour.appdata.xml.in.in')
810 mo_glob = os.path.join(bld.top_dir, 'gtk2_ardour', 'appdata', 'po', '*.mo')
811 mo_files = glob.glob(mo_glob)
812 Logs.info('Generating ' + adxmlinfile)
813 subprocess.call(['itstool', '-i', itsfile, '-o', adxmlinfile,
814 '-j', adxmlininfile] + mo_files)
815 elif bld.cmd == 'clean' and os.path.exists(adxmlinfile):
816 Logs.info('Removing ' + adxmlinfile)
817 os.remove(adxmlinfile)