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',
101 'export_timespan_selector.cc',
105 'floating_text_entry.cc',
106 'sfdb_freesound_mootcher.cc',
108 'generic_pluginui.cc',
110 'global_port_matrix.cc',
112 'gtk_pianokeyboard.c',
114 'insert_remove_time_dialog.cc',
115 'instrument_selector.cc',
116 'interthread_progress_window.cc',
130 'midi_automation_line.cc',
131 'midi_channel_dialog.cc',
132 'midi_channel_selector.cc',
133 'midi_cut_buffer.cc',
134 'midi_export_dialog.cc',
135 'midi_list_editor.cc',
136 'midi_port_dialog.cc',
137 'midi_region_view.cc',
140 'midi_streamview.cc',
143 'midi_velocity_dialog.cc',
144 'missing_file_dialog.cc',
145 'missing_plugin_dialog.cc',
147 'mixer_group_tabs.cc',
153 'monitor_section.cc',
154 'monitor_selector.cc',
156 'mono_panner_editor.cc',
159 'new_plugin_preset_dialog.cc',
160 'normalize_dialog.cc',
164 'note_select_dialog.cc',
171 'panner_interface.cc',
174 'piano_roll_header.cc',
176 'playlist_selector.cc',
178 'plugin_selector.cc',
183 'port_matrix_body.cc',
184 'port_matrix_column_labels.cc',
185 'port_matrix_component.cc',
186 'port_matrix_grid.cc',
187 'port_matrix_labels.cc',
188 'port_matrix_row_labels.cc',
190 'patch_change_dialog.cc',
191 'progress_reporter.cc',
194 'quantize_dialog.cc',
195 'rc_option_editor.cc',
197 'region_gain_line.cc',
198 'region_layering_order_editor.cc',
199 'region_selection.cc',
203 'route_group_dialog.cc',
204 'route_group_menu.cc',
205 'route_params_ui.cc',
206 'route_processor_selection.cc',
207 'route_time_axis.cc',
211 'search_path_option.cc',
212 'script_selector.cc',
214 'selection_memento.cc',
217 'session_import_dialog.cc',
218 'session_metadata_dialog.cc',
219 'session_option_editor.cc',
221 'shuttle_control.cc',
222 'soundcloud_export_selector.cc',
229 'stereo_panner_editor.cc',
231 'strip_silence_dialog.cc',
233 'tape_region_view.cc',
238 'time_axis_view_item.cc',
244 'track_selection.cc',
245 'track_view_list.cc',
246 'transform_dialog.cc',
247 'transpose_dialog.cc',
251 'visibility_group.cc',
253 # video-timeline related sources:
254 'video_image_frame.cc',
255 'add_video_dialog.cc',
256 'editor_videotimeline.cc',
259 'transcode_ffmpeg.cc',
260 'transcode_video_dialog.cc',
261 'video_server_dialog.cc',
263 'export_video_dialog.cc',
264 'export_video_infobox.cc',
265 'video_tool_paths.cc'
268 def enoify (major, minor):
269 # Code names based on
270 # https://en.wikipedia.org/wiki/Brian_Eno_discography
272 # sort Studio albums + Collaborative albums + Compilation albums by Month/Year.
273 # (no Singles, no EPs, no Video Albums, no Production)
275 return "\\n\\\"E-No\\\""
278 return "\\n\\\"No Pussyfooting\\\""
280 return "\\n\\\"Here Come the Warm Jets\\\""
282 return "\\n\\\"Taking Tiger Mountain\\\""
284 return "\\n\\\"Lady June's Linguistic Leprosy\\\""
286 return "\\n\\\"Discreet Music\\\""
288 return "\\n\\\"Another Green World\\\""
290 return "\\n\\\"Evening Star\\\""
292 return "\\n\\\"Cluster and Eno\\\""
294 return "\\n\\\"Before and After Science\\\""
298 autowaf.set_options(opt)
302 conf.load('compiler_cxx')
303 autowaf.configure(conf)
305 # TODO: Insert a sanity check for on OS X to ensure CoreAudio is present
307 autowaf.check_pkg(conf, 'fftw3f', uselib_store='FFTW3F',
309 autowaf.check_pkg(conf, 'fftw3f', uselib_store='FFTW35F',
310 atleast_version='3.3.5', mandatory=False)
311 autowaf.check_pkg(conf, 'flac', uselib_store='FLAC',
312 atleast_version='1.2.1')
313 autowaf.check_pkg(conf, 'gthread-2.0', uselib_store='GTHREAD',
314 atleast_version='2.10.1')
315 autowaf.check_pkg(conf, 'gtk+-2.0', uselib_store='GTK',
316 atleast_version='2.18')
317 autowaf.check_pkg(conf, 'gtkmm-2.4', uselib_store='GTKMM',
318 atleast_version='2.18')
319 autowaf.check_pkg(conf, 'ogg', uselib_store='OGG', atleast_version='1.1.2')
320 autowaf.check_pkg(conf, 'x11', uselib_store='X11', atleast_version='1.1', mandatory=False)
321 autowaf.check_pkg(conf, 'fontconfig', uselib_store='FONTCONFIG')
323 conf.write_config_header('gtk2ardour-config.h', remove=False)
325 bak = conf.env['define_key']
326 conf.define('VERSIONSTRING', str (conf.env['VERSION']))
327 conf.define('CODENAME', enoify(int(conf.env['MAJOR']), int(conf.env['MINOR'])))
328 conf.env['define_key'] = ['VERSIONSTRING', 'CODENAME' ]
329 conf.write_config_header('gtk2ardour-version.h')
330 conf.env['define_key'] = bak;
333 autowaf.check_header(conf, 'cxx', 'boost/shared_ptr.hpp')
334 autowaf.check_header(conf, 'cxx', 'boost/weak_ptr.hpp')
336 # Add a waf `feature' to allow compilation of things using winegcc
337 from waflib.TaskGen import feature
339 def set_winegcc(self):
340 self.env.LINK_CXX = self.env.LINK_CC = 'wineg++'
341 self.env.CC = 'winegcc'
343 def _doPyp(infileName, deps = False):
346 re_spaces = re.compile("\s+")
348 if infileName == '-':
351 fd = open(infileName)
352 inLines = fd.readlines()
358 bits = re_spaces.split(line)
359 if bits[0] == '##include':
364 # assume included file comes from same place as source file
365 incName = os.path.join (os.path.dirname (infileName), incName);
366 outStr += _doPyp(incName)
377 def include_processor(task):
378 infileName = task.inputs[0].srcpath()
379 outfileName = os.path.join(out, task.outputs[0].bldpath())
380 fdOut = open (outfileName, "w")
381 fdOut.write (_doPyp(infileName))
385 def build_color_scheme(path, prefix):
389 if re.search ('^#@color', line):
390 line.strip() # remove newline
392 if len(color_scheme):
394 color_scheme += prefix
396 color_scheme += words[1]
398 color_scheme += words[2]
404 VERSION = "%s.%s" % (bld.env['MAJOR'], bld.env['MINOR'])
405 I18N_PACKAGE = 'gtk2_ardour' + bld.env['MAJOR']
407 if bld.is_defined('WINDOWS_VST_SUPPORT') and bld.env['build_target'] != 'mingw':
408 # Windows VST support w/wine
409 # If we require VST support we build a stub main() and the FST library
410 # here using winegcc, and link it to the GTK front-end library
411 obj = bld (features = 'cxx c cxxprogram wine')
412 obj.source = ( '../libs/fst/vstwin.c', '../vst/winmain.c' )
414 # XXX do we really need to explicitly link to all of these for the wine executable?
416 obj.use = [ 'libpbd',
427 obj.target = 'ardour-' + str (bld.env['VERSION']) + '-vst.exe.so'
428 obj.includes = [ '../libs/fst', '.' ]
429 obj.linkflags = ['-mwindows', '-Wl,--export-dynamic']
430 obj.linkflags += bld.env['LDFLAGS']
431 obj.defines = ['_POSIX_SOURCE', 'USE_WS_PREFIX']
432 obj.install_path = bld.env['DLLDIR']
433 # end of the wine executable
435 # now the shared library containing the GTK GUI for ardour
436 obj = bld (features = 'cxx c cxxshlib')
437 # operate on copy to avoid adding sources twice
438 obj.source = list(gtk2_ardour_sources)
439 obj.includes = [ '../libs/fst', '.' ]
440 obj.name = 'libgtk2_ardour'
441 obj.target = 'gtk2_ardour'
442 obj.cflags = [ '-fPIC' ]
445 # just the normal executable version of the GTK GUI
446 if bld.env['build_target'] == 'mingw':
447 obj = bld (features = 'cxx c cxxprogram winres')
449 obj = bld (features = 'cxx c cxxprogram')
450 # operate on copy to avoid adding sources twice
451 obj.source = list(gtk2_ardour_sources)
452 obj.target = 'ardour-' + str (bld.env['VERSION'])
454 obj.ldflags = ['-no-undefined']
456 if bld.is_defined('WINDOWS_VST_SUPPORT'):
457 # Windows VST support mingw
458 obj.includes += [ '../libs/fst' ]
460 # at this point, "obj" refers to either the normal native executable
461 # OR the shared library built for use with wine on linux.
463 obj.use = [ 'libpbd',
474 'PACKAGE="' + I18N_PACKAGE + '"',
475 'DATA_DIR="' + os.path.normpath(bld.env['DATADIR']) + '"',
476 'CONFIG_DIR="' + os.path.normpath(bld.env['SYSCONFDIR']) + '"',
477 'LOCALEDIR="' + os.path.normpath(bld.env['LOCALEDIR']) + '"',
479 obj.install_path = bld.env['DLLDIR']
481 obj.uselib = 'UUID FLAC FONTCONFIG GLIBMM GTHREAD GTK OGG CURL DL GTKMM CANVAS FFTW3F LO TAGLIB '
483 if sys.platform == 'darwin':
484 obj.uselib += ' AUDIOUNITS OSX '
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 sys.platform == 'darwin':
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 sys.platform == 'darwin':
666 menus_argv = [ '-E', '-P', '-D__APPLE__', '-' ]
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 # NATIVE ARDOUR BINDING FILES
719 # explicitly state the use of perl here so that it works on windows too
721 a_rule = 'perl ../tools/fmt-bindings --platform="%s" --winkey="%s" --accelmap ${SRC} >${TGT}' % (sys.platform, bld.env['WINDOWS_KEY'] )
722 for b in [ 'ardour' ] :
724 target = b + '.keys',
725 source = b + '.keys.in',
728 obj.install_path = bld.env['CONFDIR']
730 # not modified at present
731 bld.install_files(bld.env['CONFDIR'], 'dark.colors')
734 bld.install_files(os.path.join (bld.env['DATADIR'], 'icons'), bld.path.ant_glob('icons/*.png'))
735 bld.install_files(os.path.join (bld.env['DATADIR'], 'pixmaps'), bld.path.ant_glob('pixmaps/*.xpm'))
736 bld.install_files(bld.env['DATADIR'], 'splash.png')
737 bld.install_files(bld.env['DATADIR'], 'small-splash.png')
738 bld.install_files(bld.env['DATADIR'], 'ArdourMono.ttf')
740 if bld.env['build_target'] == 'mingw':
741 # These icons need to overwrite the files already installed in the icons
742 # directory above. Do this in the external packaging scripts for now.
743 #bld.install_files(os.path.join (bld.env['DATADIR'], 'icons'), bld.path.ant_glob('icons/cursor_square/*.png'))
744 bld.install_files(os.path.join (bld.env['DATADIR'], 'icons'), 'icons/cursor_square/hotspots')
746 # Default UI configuration
747 bld.install_files(bld.env['CONFDIR'], 'default_ui_config')
749 bld.install_files(bld.env['CONFDIR'], 'dark.colors')
751 # Default export stuff
752 bld.install_files(os.path.join(bld.env['CONFDIR'], 'export'), bld.path.ant_glob('export/*.format'))
755 if bld.is_defined('ENABLE_NLS'):
756 mo_files = bld.path.ant_glob('po/*.mo')
758 lang = os.path.basename(mo.srcpath()).replace('.mo', '')
759 bld.install_as (os.path.join(os.path.normpath(bld.env['LOCALEDIR']), lang, 'LC_MESSAGES', I18N_PACKAGE + '.mo'),
763 I18N_PACKAGE = 'gtk2_ardour' + bld.env['MAJOR']
764 autowaf.build_i18n(bld, top, 'gtk2_ardour', I18N_PACKAGE, gtk2_ardour_sources,
766 appdata_i18n_pot(bld)
770 I18N_PACKAGE = 'gtk2_ardour' + bld.env['MAJOR']
771 autowaf.build_i18n_pot(bld, top, 'gtk2_ardour', I18N_PACKAGE, gtk2_ardour_sources,
773 appdata_i18n_pot(bld)
776 I18N_PACKAGE = 'gtk2_ardour' + bld.env['MAJOR']
777 autowaf.build_i18n_po(bld, top, 'gtk2_ardour', I18N_PACKAGE, gtk2_ardour_sources,
782 I18N_PACKAGE = 'gtk2_ardour' + bld.env['MAJOR']
783 autowaf.build_i18n_mo(bld, top, 'gtk2_ardour', I18N_PACKAGE, gtk2_ardour_sources,
786 def appdata_i18n_pot(bld):
787 potfile = os.path.join(bld.top_dir, 'gtk2_ardour', 'appdata',
788 'ardour.appdata.pot')
789 if bld.cmd == 'build':
790 Logs.info('Generating pot file from Ardour appdata')
791 itsfile = os.path.join(bld.top_dir, 'tools', 'as-metainfo.its')
792 adsource = os.path.join(bld.top_dir, 'gtk2_ardour',
793 'ardour.appdata.xml.in.in')
794 Logs.info('Updating ' + potfile)
795 subprocess.call(('itstool', '-i', itsfile, '-o', potfile, adsource))
796 elif bld.cmd == 'clean' and os.path.exists(potfile):
797 Logs.info('Removing Ardour appdata pot file')
800 def appdata_i18n_po(bld):
801 autowaf.build_i18n_po(bld, bld.top_dir, os.path.join(
802 'gtk2_ardour', 'appdata'), 'ardour.appdata', 'dummy', 'dummy')
804 def appdata_i18n_mo(bld):
805 autowaf.build_i18n_mo(bld, bld.top_dir, os.path.join(
806 'gtk2_ardour', 'appdata'), 'ardour.appdata', 'dummy', 'dummy')
808 def appdata_i18n_xmlin(bld):
809 adxmlinfile = os.path.join(bld.top_dir, 'gtk2_ardour',
810 'ardour.appdata.xml.in')
811 if bld.cmd == 'build':
812 itsfile = os.path.join(bld.top_dir, 'tools', 'as-metainfo.its')
813 adxmlininfile = os.path.join(bld.top_dir, 'gtk2_ardour',
814 'ardour.appdata.xml.in.in')
815 mo_glob = os.path.join(bld.top_dir, 'gtk2_ardour', 'appdata', 'po', '*.mo')
816 mo_files = glob.glob(mo_glob)
817 Logs.info('Generating ' + adxmlinfile)
818 subprocess.call(['itstool', '-i', itsfile, '-o', adxmlinfile,
819 '-j', adxmlininfile] + mo_files)
820 elif bld.cmd == 'clean' and os.path.exists(adxmlinfile):
821 Logs.info('Removing ' + adxmlinfile)
822 os.remove(adxmlinfile)