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',
125 'lua_script_manager.cc',
131 'midi_automation_line.cc',
132 'midi_channel_dialog.cc',
133 'midi_channel_selector.cc',
134 'midi_cut_buffer.cc',
135 'midi_export_dialog.cc',
136 'midi_list_editor.cc',
137 'midi_port_dialog.cc',
138 'midi_region_view.cc',
141 'midi_streamview.cc',
144 'midi_velocity_dialog.cc',
145 'missing_file_dialog.cc',
146 'missing_plugin_dialog.cc',
148 'mixer_group_tabs.cc',
154 'monitor_section.cc',
155 'monitor_selector.cc',
157 'mono_panner_editor.cc',
160 'new_plugin_preset_dialog.cc',
161 'normalize_dialog.cc',
165 'note_select_dialog.cc',
172 'panner_interface.cc',
175 'piano_roll_header.cc',
177 'playlist_selector.cc',
179 'plugin_selector.cc',
184 'port_matrix_body.cc',
185 'port_matrix_column_labels.cc',
186 'port_matrix_component.cc',
187 'port_matrix_grid.cc',
188 'port_matrix_labels.cc',
189 'port_matrix_row_labels.cc',
191 'patch_change_dialog.cc',
192 'progress_reporter.cc',
195 'quantize_dialog.cc',
196 'rc_option_editor.cc',
198 'region_gain_line.cc',
199 'region_layering_order_editor.cc',
200 'region_selection.cc',
204 'route_group_dialog.cc',
205 'route_group_menu.cc',
206 'route_params_ui.cc',
207 'route_processor_selection.cc',
208 'route_time_axis.cc',
212 'search_path_option.cc',
213 'script_selector.cc',
215 'selection_memento.cc',
218 'session_import_dialog.cc',
219 'session_metadata_dialog.cc',
220 'session_option_editor.cc',
222 'shuttle_control.cc',
223 'soundcloud_export_selector.cc',
230 'stereo_panner_editor.cc',
232 'strip_silence_dialog.cc',
234 'tape_region_view.cc',
239 'time_axis_view_item.cc',
245 'track_selection.cc',
246 'track_view_list.cc',
247 'transform_dialog.cc',
248 'transpose_dialog.cc',
252 'visibility_group.cc',
254 # video-timeline related sources:
255 'video_image_frame.cc',
256 'add_video_dialog.cc',
257 'editor_videotimeline.cc',
260 'transcode_ffmpeg.cc',
261 'transcode_video_dialog.cc',
262 'video_server_dialog.cc',
264 'export_video_dialog.cc',
265 'export_video_infobox.cc',
266 'video_tool_paths.cc'
269 def enoify (major, minor):
270 # Code names based on
271 # https://en.wikipedia.org/wiki/Brian_Eno_discography
273 # sort Studio albums + Collaborative albums + Compilation albums by Month/Year.
274 # (no Singles, no EPs, no Video Albums, no Production)
276 return "\\n\\\"E-No\\\""
279 return "\\n\\\"No Pussyfooting\\\""
281 return "\\n\\\"Here Come the Warm Jets\\\""
283 return "\\n\\\"Taking Tiger Mountain\\\""
285 return "\\n\\\"Lady June's Linguistic Leprosy\\\""
287 return "\\n\\\"Discreet Music\\\""
289 return "\\n\\\"Another Green World\\\""
291 return "\\n\\\"Evening Star\\\""
293 return "\\n\\\"Cluster and Eno\\\""
295 return "\\n\\\"Before and After Science\\\""
299 autowaf.set_options(opt)
303 conf.load('compiler_cxx')
304 autowaf.configure(conf)
306 # TODO: Insert a sanity check for on OS X to ensure CoreAudio is present
308 autowaf.check_pkg(conf, 'fftw3f', uselib_store='FFTW3F',
310 autowaf.check_pkg(conf, 'fftw3f', uselib_store='FFTW35F',
311 atleast_version='3.3.5', mandatory=False)
312 autowaf.check_pkg(conf, 'flac', uselib_store='FLAC',
313 atleast_version='1.2.1')
314 autowaf.check_pkg(conf, 'gthread-2.0', uselib_store='GTHREAD',
315 atleast_version='2.10.1')
316 autowaf.check_pkg(conf, 'gtk+-2.0', uselib_store='GTK',
317 atleast_version='2.18')
318 autowaf.check_pkg(conf, 'gtkmm-2.4', uselib_store='GTKMM',
319 atleast_version='2.18')
320 autowaf.check_pkg(conf, 'ogg', uselib_store='OGG', atleast_version='1.1.2')
321 autowaf.check_pkg(conf, 'x11', uselib_store='X11', atleast_version='1.1', mandatory=False)
322 autowaf.check_pkg(conf, 'fontconfig', uselib_store='FONTCONFIG')
324 conf.write_config_header('gtk2ardour-config.h', remove=False)
326 bak = conf.env['define_key']
327 conf.define('VERSIONSTRING', str (conf.env['VERSION']))
328 conf.define('CODENAME', enoify(int(conf.env['MAJOR']), int(conf.env['MINOR'])))
329 conf.env['define_key'] = ['VERSIONSTRING', 'CODENAME' ]
330 conf.write_config_header('gtk2ardour-version.h')
331 conf.env['define_key'] = bak;
334 autowaf.check_header(conf, 'cxx', 'boost/shared_ptr.hpp')
335 autowaf.check_header(conf, 'cxx', 'boost/weak_ptr.hpp')
337 # Add a waf `feature' to allow compilation of things using winegcc
338 from waflib.TaskGen import feature
340 def set_winegcc(self):
341 self.env.LINK_CXX = self.env.LINK_CC = 'wineg++'
342 self.env.CC = 'winegcc'
344 def _doPyp(infileName, deps = False):
347 re_spaces = re.compile("\s+")
349 if infileName == '-':
352 fd = open(infileName)
353 inLines = fd.readlines()
359 bits = re_spaces.split(line)
360 if bits[0] == '##include':
365 # assume included file comes from same place as source file
366 incName = os.path.join (os.path.dirname (infileName), incName);
367 outStr += _doPyp(incName)
378 def include_processor(task):
379 infileName = task.inputs[0].srcpath()
380 outfileName = os.path.join(out, task.outputs[0].bldpath())
381 fdOut = open (outfileName, "w")
382 fdOut.write (_doPyp(infileName))
386 def build_color_scheme(path, prefix):
390 if re.search ('^#@color', line):
391 line.strip() # remove newline
393 if len(color_scheme):
395 color_scheme += prefix
397 color_scheme += words[1]
399 color_scheme += words[2]
405 VERSION = "%s.%s" % (bld.env['MAJOR'], bld.env['MINOR'])
406 I18N_PACKAGE = 'gtk2_ardour' + bld.env['MAJOR']
408 if bld.is_defined('WINDOWS_VST_SUPPORT') and bld.env['build_target'] != 'mingw':
409 # Windows VST support w/wine
410 # If we require VST support we build a stub main() and the FST library
411 # here using winegcc, and link it to the GTK front-end library
412 obj = bld (features = 'cxx c cxxprogram wine')
413 obj.source = ( '../libs/fst/vstwin.c', '../vst/winmain.c' )
415 # XXX do we really need to explicitly link to all of these for the wine executable?
417 obj.use = [ 'libpbd',
428 obj.target = 'ardour-' + str (bld.env['VERSION']) + '-vst.exe.so'
429 obj.includes = [ '../libs/fst', '.' ]
430 obj.linkflags = ['-mwindows', '-Wl,--export-dynamic']
431 obj.linkflags += bld.env['LDFLAGS']
432 obj.defines = ['_POSIX_SOURCE', 'USE_WS_PREFIX']
433 obj.install_path = bld.env['DLLDIR']
434 # end of the wine executable
436 # now the shared library containing the GTK GUI for ardour
437 obj = bld (features = 'cxx c cxxshlib')
438 # operate on copy to avoid adding sources twice
439 obj.source = list(gtk2_ardour_sources)
440 obj.includes = [ '../libs/fst', '.' ]
441 obj.name = 'libgtk2_ardour'
442 obj.target = 'gtk2_ardour'
443 obj.cflags = [ '-fPIC' ]
446 # just the normal executable version of the GTK GUI
447 if bld.env['build_target'] == 'mingw':
448 obj = bld (features = 'cxx c cxxprogram winres')
450 obj = bld (features = 'cxx c cxxprogram')
451 # operate on copy to avoid adding sources twice
452 obj.source = list(gtk2_ardour_sources)
453 obj.target = 'ardour-' + str (bld.env['VERSION'])
455 obj.ldflags = ['-no-undefined']
457 if bld.is_defined('WINDOWS_VST_SUPPORT'):
458 # Windows VST support mingw
459 obj.includes += [ '../libs/fst' ]
461 # at this point, "obj" refers to either the normal native executable
462 # OR the shared library built for use with wine on linux.
464 obj.use = [ 'libpbd',
475 'PACKAGE="' + I18N_PACKAGE + '"',
476 'DATA_DIR="' + os.path.normpath(bld.env['DATADIR']) + '"',
477 'CONFIG_DIR="' + os.path.normpath(bld.env['SYSCONFDIR']) + '"',
478 'LOCALEDIR="' + os.path.normpath(bld.env['LOCALEDIR']) + '"',
480 obj.install_path = bld.env['DLLDIR']
482 obj.uselib = 'UUID FLAC FONTCONFIG GLIBMM GTHREAD GTK OGG CURL DL GTKMM CANVAS FFTW3F LO TAGLIB XML '
484 if sys.platform == 'darwin':
485 obj.uselib += ' AUDIOUNITS OSX '
486 obj.use += ' libappleutility'
487 obj.source += [ 'cocoacarbon.mm', 'bundle_env_cocoa.cc' ]
488 elif bld.env['build_target'] == 'mingw':
489 obj.source += [ 'bundle_env_mingw.cc' ]
490 obj.source += [ 'windows_icon.rc' ]
492 obj.source += [ 'bundle_env_linux.cc' ]
494 obj.includes += ['../libs']
496 obj.use += 'libptformat'
498 if bld.env['build_target'] == 'mingw':
499 obj.linkflags += ' -mwindows'
501 if bld.is_defined('HAVE_SUIL'):
502 obj.source += [ 'lv2_plugin_ui.cc' ]
503 obj.use += [ 'SUIL' ]
505 if bld.is_defined('HAVE_FFTW35F') and bld.env['build_target'] != 'mingw':
506 bld.env['LIB_FFTW3F'] += ['fftw3f_threads']
508 if bld.is_defined('NEED_INTL'):
509 obj.linkflags += ' -lintl'
511 if bld.is_defined('WINDOWS_VST_SUPPORT'):
512 obj.source += [ 'windows_vst_plugin_ui.cc' ]
513 obj.defines += [ 'WINDOWS_VST_SUPPORT' ]
514 if bld.env['build_target'] != 'mingw':
517 if bld.is_defined('LXVST_SUPPORT'):
518 obj.source += [ 'linux_vst_gui_support.cc', 'lxvst_plugin_ui.cc' ]
519 obj.defines += [ 'LXVST_SUPPORT' ]
522 if bld.is_defined('WINDOWS_VST_SUPPORT') or bld.is_defined('LXVST_SUPPORT'):
523 obj.source += [ 'vst_plugin_ui.cc' ]
525 if bld.is_defined('PHONE_HOME'):
526 obj.defines += [ 'PHONE_HOME' ]
528 if bld.is_defined('HAVE_COREAUDIO'):
529 TaskGen.task_gen.mappings['.mm'] = TaskGen.task_gen.mappings['.cc']
530 obj.use += ' libappleutility '
532 if bld.is_defined('AUDIOUNIT_SUPPORT'):
533 obj.source += [ 'au_pluginui.mm' ]
537 wrapper_subst_dict = {
538 'INSTALL_PREFIX' : bld.env['PREFIX'],
539 'LIBDIR' : os.path.normpath(bld.env['DLLDIR']),
540 'DATADIR' : os.path.normpath(bld.env['DATADIR']),
541 'CONFDIR' : os.path.normpath(bld.env['CONFDIR']),
542 'LIBS' : 'build/libs',
543 'VERSION' : str (bld.env['VERSION']),
544 'EXECUTABLE' : 'build/gtk2_ardour/ardour-' + str (bld.env['VERSION'])
547 def set_subst_dict(obj, dict):
549 setattr(obj, i, dict[i])
551 obj = bld(features = 'subst')
552 obj.source = 'ardev_common.sh.in'
553 obj.target = 'ardev_common_waf.sh'
554 obj.chmod = Utils.O755
555 obj.dict = wrapper_subst_dict
556 set_subst_dict(obj, wrapper_subst_dict)
558 obj = bld(features = 'subst')
559 obj.source = 'ardour.sh.in'
560 obj.target = 'ardour' + str (bld.env['MAJOR'])
561 obj.chmod = Utils.O755
562 obj.dict = wrapper_subst_dict
563 obj.install_path = bld.env['BINDIR']
564 set_subst_dict(obj, wrapper_subst_dict)
566 if bld.is_defined('WINDOWS_VST_SUPPORT'):
567 obj = bld(features = 'subst')
568 obj.source = '../vst/ardourvst.in'
569 obj.target = 'ardourvst' + str (bld.env['MAJOR'])
570 obj.chmod = Utils.O755
571 obj.dict = wrapper_subst_dict
572 obj.install_path = bld.env['BINDIR']
573 set_subst_dict(obj, wrapper_subst_dict)
582 if sys.platform == 'darwin':
596 # There is no acceptable monospace font available on older versions of OS X
597 # and no API on those versions to load TTF files that will work with
598 # GTK/fontconfig/pango.
600 # In addition, the ArdourMono font gets clipped for some reason on OS X
602 # Moreover, Lucida Grande just seems to work even though it is not monospace
606 'MONOSPACE' : 'Monaco',
607 'CLOCKFONT' : 'Lucida Grande',
609 else: # Linux/X11 fonts
610 basefont = '' # unspecified - use system defaults
623 'MONOSPACE' : 'ArdourMono',
624 'CLOCKFONT' : 'ArdourMono',
627 # Set up font substitution dictionary
629 for style in ['', 'BOLD', 'ITALIC']:
630 for sizename,points in iter(font_sizes.items()):
632 key = "_".join (['FONT',style,sizename])
633 fontstyle = " ".join ([basefont,style.lower(),points])
635 key = "_".join (['FONT',sizename])
636 fontstyle = " ".join ([basefont,points])
638 font_subst_dict[key] = fontstyle
641 for sizename,points in iter(font_sizes.items()):
642 key = "_".join (['FONT_SIZE',sizename])
643 font_subst_dict[key] = points
645 # various font names, eg @BOLD_MONOSPACE@
646 for font_sym,text in iter(font_names.items()):
648 font_subst_dict[key] = text
652 obj = bld(features = 'subst')
653 obj.source = [ 'clearlooks.rc.in' ]
654 obj.target = 'clearlooks.rc'
655 obj.install_path = bld.env['CONFDIR']
656 set_subst_dict(obj, font_subst_dict)
658 obj = bld(features = 'subst')
659 obj.source = [ 'default_ui_config.in' ]
660 obj.target = 'default_ui_config'
661 obj.install_path = bld.env['CONFDIR']
662 set_subst_dict(obj, font_subst_dict)
666 if sys.platform == 'darwin':
667 menus_argv = [ '-E', '-P', '-D__APPLE__', '-' ]
669 menus_argv = [ '-E', '-P' ]
671 if bld.is_defined('PTFORMAT'):
672 menus_argv += [ '-DPTFORMAT' ]
674 # always build all versions of the menu definitions
675 # so that we can try them out with different program builds.
676 for program in [ 'ardour', 'trx' ]:
677 obj = bld(features = 'command-output')
679 obj.command_is_external = True
681 obj.argv = menus_argv
682 obj.dep_vars = ['PTFORMAT', 'GTKOSX', 'WINDOWS']
683 obj.stdin = program + '.menus.in'
684 obj.stdout = program + '.menus'
685 bld.install_files (bld.env['CONFDIR'], program + '.menus')
688 freedesktop_subst_dict = {
689 'ARDOUR_EXEC' : str (bld.env['lwrcase_dirname']),
690 'ARDOUR_ICON' : str (bld.env['lwrcase_dirname']),
691 'VERSION': str (bld.env['VERSION']),
694 if bld.env['FREEDESKTOP']:
695 obj = bld(features = 'subst')
696 obj.source = 'ardour.desktop.in'
697 obj.target = str (bld.env['lwrcase_dirname']) + '.desktop'
698 obj.chmod = Utils.O644
699 obj.dict = freedesktop_subst_dict
700 set_subst_dict(obj, freedesktop_subst_dict)
702 obj = bld(features = 'subst')
703 obj.source = 'ardour-mime-info.xml'
704 obj.target = 'ardour.xml'
705 obj.chmod = Utils.O644
707 # build appdata with translations
709 appdata_i18n_xmlin(bld)
710 obj = bld(features = 'subst')
711 obj.source = 'ardour.appdata.xml.in'
712 obj.target = str (bld.env['lwrcase_dirname']) + '.appdata.xml'
713 obj.chmod = Utils.O644
714 obj.dict = freedesktop_subst_dict
715 set_subst_dict(obj, freedesktop_subst_dict)
719 # NATIVE ARDOUR BINDING FILES
720 # explicitly state the use of perl here so that it works on windows too
722 a_rule = 'perl ../tools/fmt-bindings --platform="%s" --winkey="%s" --accelmap ${SRC[0].abspath()} >${TGT}' % (sys.platform, bld.env['WINDOWS_KEY'] )
723 for b in [ 'ardour' ] :
725 target = b + '.keys',
726 source = [ b + '.keys.in', 'mixer.bindings', 'processor_box.bindings', 'step_editing.bindings', 'monitor.bindings' ],
729 obj.install_path = bld.env['CONFDIR']
731 # not modified at present
732 bld.install_files(bld.env['CONFDIR'], 'dark.colors')
735 bld.install_files(os.path.join (bld.env['DATADIR'], 'icons'), bld.path.ant_glob('icons/*.png'))
736 bld.install_files(os.path.join (bld.env['DATADIR'], 'pixmaps'), bld.path.ant_glob('pixmaps/*.xpm'))
737 bld.install_files(bld.env['DATADIR'], 'splash.png')
738 bld.install_files(bld.env['DATADIR'], 'small-splash.png')
739 bld.install_files(bld.env['DATADIR'], 'ArdourMono.ttf')
741 if bld.env['build_target'] == 'mingw':
742 # These icons need to overwrite the files already installed in the icons
743 # directory above. Do this in the external packaging scripts for now.
744 #bld.install_files(os.path.join (bld.env['DATADIR'], 'icons'), bld.path.ant_glob('icons/cursor_square/*.png'))
745 bld.install_files(os.path.join (bld.env['DATADIR'], 'icons'), 'icons/cursor_square/hotspots')
747 # Default UI configuration
748 bld.install_files(bld.env['CONFDIR'], 'default_ui_config')
750 bld.install_files(bld.env['CONFDIR'], 'dark.colors')
752 # Default export stuff
753 bld.install_files(os.path.join(bld.env['CONFDIR'], 'export'), bld.path.ant_glob('export/*.format'))
756 if bld.is_defined('ENABLE_NLS'):
757 mo_files = bld.path.ant_glob('po/*.mo')
759 lang = os.path.basename(mo.srcpath()).replace('.mo', '')
760 bld.install_as (os.path.join(os.path.normpath(bld.env['LOCALEDIR']), lang, 'LC_MESSAGES', I18N_PACKAGE + '.mo'),
764 I18N_PACKAGE = 'gtk2_ardour' + bld.env['MAJOR']
765 autowaf.build_i18n(bld, top, 'gtk2_ardour', I18N_PACKAGE, gtk2_ardour_sources,
767 appdata_i18n_pot(bld)
771 I18N_PACKAGE = 'gtk2_ardour' + bld.env['MAJOR']
772 autowaf.build_i18n_pot(bld, top, 'gtk2_ardour', I18N_PACKAGE, gtk2_ardour_sources,
774 appdata_i18n_pot(bld)
777 I18N_PACKAGE = 'gtk2_ardour' + bld.env['MAJOR']
778 autowaf.build_i18n_po(bld, top, 'gtk2_ardour', I18N_PACKAGE, gtk2_ardour_sources,
783 I18N_PACKAGE = 'gtk2_ardour' + bld.env['MAJOR']
784 autowaf.build_i18n_mo(bld, top, 'gtk2_ardour', I18N_PACKAGE, gtk2_ardour_sources,
787 def appdata_i18n_pot(bld):
788 potfile = os.path.join(bld.top_dir, 'gtk2_ardour', 'appdata',
789 'ardour.appdata.pot')
790 if bld.cmd == 'build':
791 Logs.info('Generating pot file from Ardour appdata')
792 itsfile = os.path.join(bld.top_dir, 'tools', 'as-metainfo.its')
793 adsource = os.path.join(bld.top_dir, 'gtk2_ardour',
794 'ardour.appdata.xml.in.in')
795 Logs.info('Updating ' + potfile)
796 subprocess.call(('itstool', '-i', itsfile, '-o', potfile, adsource))
797 elif bld.cmd == 'clean' and os.path.exists(potfile):
798 Logs.info('Removing Ardour appdata pot file')
801 def appdata_i18n_po(bld):
802 autowaf.build_i18n_po(bld, bld.top_dir, os.path.join(
803 'gtk2_ardour', 'appdata'), 'ardour.appdata', 'dummy', 'dummy')
805 def appdata_i18n_mo(bld):
806 autowaf.build_i18n_mo(bld, bld.top_dir, os.path.join(
807 'gtk2_ardour', 'appdata'), 'ardour.appdata', 'dummy', 'dummy')
809 def appdata_i18n_xmlin(bld):
810 adxmlinfile = os.path.join(bld.top_dir, 'gtk2_ardour',
811 'ardour.appdata.xml.in')
812 if bld.cmd == 'build':
813 itsfile = os.path.join(bld.top_dir, 'tools', 'as-metainfo.its')
814 adxmlininfile = os.path.join(bld.top_dir, 'gtk2_ardour',
815 'ardour.appdata.xml.in.in')
816 mo_glob = os.path.join(bld.top_dir, 'gtk2_ardour', 'appdata', 'po', '*.mo')
817 mo_files = glob.glob(mo_glob)
818 Logs.info('Generating ' + adxmlinfile)
819 subprocess.call(['itstool', '-i', itsfile, '-o', adxmlinfile,
820 '-j', adxmlininfile] + mo_files)
821 elif bld.cmd == 'clean' and os.path.exists(adxmlinfile):
822 Logs.info('Removing ' + adxmlinfile)
823 os.remove(adxmlinfile)