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',
129 'midi_automation_line.cc',
130 'midi_channel_dialog.cc',
131 'midi_channel_selector.cc',
132 'midi_cut_buffer.cc',
133 'midi_export_dialog.cc',
134 'midi_list_editor.cc',
135 'midi_port_dialog.cc',
136 'midi_region_view.cc',
139 'midi_streamview.cc',
142 'midi_velocity_dialog.cc',
143 'missing_file_dialog.cc',
144 'missing_plugin_dialog.cc',
146 'mixer_group_tabs.cc',
152 'monitor_section.cc',
153 'monitor_selector.cc',
155 'mono_panner_editor.cc',
158 'new_plugin_preset_dialog.cc',
159 'normalize_dialog.cc',
163 'note_select_dialog.cc',
170 'panner_interface.cc',
173 'piano_roll_header.cc',
175 'playlist_selector.cc',
177 'plugin_selector.cc',
182 'port_matrix_body.cc',
183 'port_matrix_column_labels.cc',
184 'port_matrix_component.cc',
185 'port_matrix_grid.cc',
186 'port_matrix_labels.cc',
187 'port_matrix_row_labels.cc',
189 'patch_change_dialog.cc',
190 'progress_reporter.cc',
193 'quantize_dialog.cc',
194 'rc_option_editor.cc',
196 'region_gain_line.cc',
197 'region_layering_order_editor.cc',
198 'region_selection.cc',
202 'route_group_dialog.cc',
203 'route_group_menu.cc',
204 'route_params_ui.cc',
205 'route_processor_selection.cc',
206 'route_time_axis.cc',
210 'search_path_option.cc',
211 'script_selector.cc',
213 'selection_memento.cc',
216 'session_import_dialog.cc',
217 'session_metadata_dialog.cc',
218 'session_option_editor.cc',
220 'shuttle_control.cc',
221 'soundcloud_export_selector.cc',
228 'stereo_panner_editor.cc',
230 'strip_silence_dialog.cc',
232 'tape_region_view.cc',
237 'time_axis_view_item.cc',
243 'track_selection.cc',
244 'track_view_list.cc',
245 'transform_dialog.cc',
246 'transpose_dialog.cc',
250 'visibility_group.cc',
252 # video-timeline related sources:
253 'video_image_frame.cc',
254 'add_video_dialog.cc',
255 'editor_videotimeline.cc',
258 'transcode_ffmpeg.cc',
259 'transcode_video_dialog.cc',
260 'video_server_dialog.cc',
262 'export_video_dialog.cc',
263 'export_video_infobox.cc',
264 'video_tool_paths.cc'
267 def enoify (major, minor):
268 # Code names based on
269 # https://en.wikipedia.org/wiki/Brian_Eno_discography
271 # sort Studio albums + Collaborative albums + Compilation albums by Month/Year.
272 # (no Singles, no EPs, no Video Albums, no Production)
274 return "\\n\\\"E-No\\\""
277 return "\\n\\\"No Pussyfooting\\\""
279 return "\\n\\\"Here Come the Warm Jets\\\""
281 return "\\n\\\"Taking Tiger Mountain\\\""
283 return "\\n\\\"Lady June's Linguistic Leprosy\\\""
285 return "\\n\\\"Discreet Music\\\""
287 return "\\n\\\"Another Green World\\\""
289 return "\\n\\\"Evening Star\\\""
291 return "\\n\\\"Cluster and Eno\\\""
293 return "\\n\\\"Before and After Science\\\""
297 autowaf.set_options(opt)
301 conf.load('compiler_cxx')
302 autowaf.configure(conf)
304 # TODO: Insert a sanity check for on OS X to ensure CoreAudio is present
306 autowaf.check_pkg(conf, 'fftw3f', uselib_store='FFTW3F',
308 autowaf.check_pkg(conf, 'fftw3f', uselib_store='FFTW35F',
309 atleast_version='3.3.5', mandatory=False)
310 autowaf.check_pkg(conf, 'flac', uselib_store='FLAC',
311 atleast_version='1.2.1')
312 autowaf.check_pkg(conf, 'gthread-2.0', uselib_store='GTHREAD',
313 atleast_version='2.10.1')
314 autowaf.check_pkg(conf, 'gtk+-2.0', uselib_store='GTK',
315 atleast_version='2.18')
316 autowaf.check_pkg(conf, 'gtkmm-2.4', uselib_store='GTKMM',
317 atleast_version='2.18')
318 autowaf.check_pkg(conf, 'ogg', uselib_store='OGG', atleast_version='1.1.2')
319 autowaf.check_pkg(conf, 'x11', uselib_store='X11', atleast_version='1.1', mandatory=False)
320 autowaf.check_pkg(conf, 'fontconfig', uselib_store='FONTCONFIG')
322 conf.write_config_header('gtk2ardour-config.h', remove=False)
324 bak = conf.env['define_key']
325 conf.define('VERSIONSTRING', str (conf.env['VERSION']))
326 conf.define('CODENAME', enoify(int(conf.env['MAJOR']), int(conf.env['MINOR'])))
327 conf.env['define_key'] = ['VERSIONSTRING', 'CODENAME' ]
328 conf.write_config_header('gtk2ardour-version.h')
329 conf.env['define_key'] = bak;
332 autowaf.check_header(conf, 'cxx', 'boost/shared_ptr.hpp')
333 autowaf.check_header(conf, 'cxx', 'boost/weak_ptr.hpp')
335 # Add a waf `feature' to allow compilation of things using winegcc
336 from waflib.TaskGen import feature
338 def set_winegcc(self):
339 self.env.LINK_CXX = self.env.LINK_CC = 'wineg++'
340 self.env.CC = 'winegcc'
342 def _doPyp(infileName, deps = False):
345 re_spaces = re.compile("\s+")
347 if infileName == '-':
350 fd = open(infileName)
351 inLines = fd.readlines()
357 bits = re_spaces.split(line)
358 if bits[0] == '##include':
363 # assume included file comes from same place as source file
364 incName = os.path.join (os.path.dirname (infileName), incName);
365 outStr += _doPyp(incName)
376 def include_processor(task):
377 infileName = task.inputs[0].srcpath()
378 outfileName = os.path.join(out, task.outputs[0].bldpath())
379 fdOut = open (outfileName, "w")
380 fdOut.write (_doPyp(infileName))
384 def build_color_scheme(path, prefix):
388 if re.search ('^#@color', line):
389 line.strip() # remove newline
391 if len(color_scheme):
393 color_scheme += prefix
395 color_scheme += words[1]
397 color_scheme += words[2]
403 VERSION = "%s.%s" % (bld.env['MAJOR'], bld.env['MINOR'])
404 I18N_PACKAGE = 'gtk2_ardour' + bld.env['MAJOR']
406 if bld.is_defined('WINDOWS_VST_SUPPORT') and bld.env['build_target'] != 'mingw':
407 # Windows VST support w/wine
408 # If we require VST support we build a stub main() and the FST library
409 # here using winegcc, and link it to the GTK front-end library
410 obj = bld (features = 'cxx c cxxprogram wine')
411 obj.source = ( '../libs/fst/vstwin.c', '../vst/winmain.c' )
413 # XXX do we really need to explicitly link to all of these for the wine executable?
415 obj.use = [ 'libpbd',
426 obj.target = 'ardour-' + str (bld.env['VERSION']) + '-vst.exe.so'
427 obj.includes = [ '../libs/fst', '.' ]
428 obj.linkflags = ['-mwindows', '-Wl,--export-dynamic']
429 obj.linkflags += bld.env['LDFLAGS']
430 obj.defines = ['_POSIX_SOURCE', 'USE_WS_PREFIX']
431 obj.install_path = bld.env['DLLDIR']
432 # end of the wine executable
434 # now the shared library containing the GTK GUI for ardour
435 obj = bld (features = 'cxx c cxxshlib')
436 # operate on copy to avoid adding sources twice
437 obj.source = list(gtk2_ardour_sources)
438 obj.includes = [ '../libs/fst', '.' ]
439 obj.name = 'libgtk2_ardour'
440 obj.target = 'gtk2_ardour'
441 obj.cflags = [ '-fPIC' ]
444 # just the normal executable version of the GTK GUI
445 if bld.env['build_target'] == 'mingw':
446 obj = bld (features = 'cxx c cxxprogram winres')
448 obj = bld (features = 'cxx c cxxprogram')
449 # operate on copy to avoid adding sources twice
450 obj.source = list(gtk2_ardour_sources)
451 obj.target = 'ardour-' + str (bld.env['VERSION'])
453 obj.ldflags = ['-no-undefined']
455 if bld.is_defined('WINDOWS_VST_SUPPORT'):
456 # Windows VST support mingw
457 obj.includes += [ '../libs/fst' ]
459 # at this point, "obj" refers to either the normal native executable
460 # OR the shared library built for use with wine on linux.
462 obj.use = [ 'libpbd',
473 'PACKAGE="' + I18N_PACKAGE + '"',
474 'DATA_DIR="' + os.path.normpath(bld.env['DATADIR']) + '"',
475 'CONFIG_DIR="' + os.path.normpath(bld.env['SYSCONFDIR']) + '"',
476 'LOCALEDIR="' + os.path.normpath(bld.env['LOCALEDIR']) + '"',
478 obj.install_path = bld.env['DLLDIR']
480 obj.uselib = 'UUID FLAC FONTCONFIG GLIBMM GTHREAD GTK OGG CURL DL GTKMM CANVAS FFTW3F LO TAGLIB '
482 if sys.platform == 'darwin':
483 obj.uselib += ' AUDIOUNITS OSX '
484 obj.use += ' libappleutility'
485 obj.source += [ 'cocoacarbon.mm', 'bundle_env_cocoa.cc' ]
486 elif bld.env['build_target'] == 'mingw':
487 obj.source += [ 'bundle_env_mingw.cc' ]
488 obj.source += [ 'windows_icon.rc' ]
490 obj.source += [ 'bundle_env_linux.cc' ]
492 obj.includes += ['../libs']
494 obj.use += 'libptformat'
496 if bld.env['build_target'] == 'mingw':
497 obj.linkflags += ' -mwindows'
499 if bld.is_defined('HAVE_SUIL'):
500 obj.source += [ 'lv2_plugin_ui.cc' ]
501 obj.use += [ 'SUIL' ]
503 if bld.is_defined('HAVE_FFTW35F') and bld.env['build_target'] != 'mingw':
504 bld.env['LIB_FFTW3F'] += ['fftw3f_threads']
506 if bld.is_defined('NEED_INTL'):
507 obj.linkflags += ' -lintl'
509 if bld.is_defined('WINDOWS_VST_SUPPORT'):
510 obj.source += [ 'windows_vst_plugin_ui.cc' ]
511 obj.defines += [ 'WINDOWS_VST_SUPPORT' ]
512 if bld.env['build_target'] != 'mingw':
515 if bld.is_defined('LXVST_SUPPORT'):
516 obj.source += [ 'linux_vst_gui_support.cc', 'lxvst_plugin_ui.cc' ]
517 obj.defines += [ 'LXVST_SUPPORT' ]
520 if bld.is_defined('WINDOWS_VST_SUPPORT') or bld.is_defined('LXVST_SUPPORT'):
521 obj.source += [ 'vst_plugin_ui.cc' ]
523 if bld.is_defined('PHONE_HOME'):
524 obj.defines += [ 'PHONE_HOME' ]
526 if bld.is_defined('HAVE_COREAUDIO'):
527 TaskGen.task_gen.mappings['.mm'] = TaskGen.task_gen.mappings['.cc']
528 obj.use += ' libappleutility '
530 if bld.is_defined('AUDIOUNIT_SUPPORT'):
531 obj.source += [ 'au_pluginui.mm' ]
535 wrapper_subst_dict = {
536 'INSTALL_PREFIX' : bld.env['PREFIX'],
537 'LIBDIR' : os.path.normpath(bld.env['DLLDIR']),
538 'DATADIR' : os.path.normpath(bld.env['DATADIR']),
539 'CONFDIR' : os.path.normpath(bld.env['CONFDIR']),
540 'LIBS' : 'build/libs',
541 'VERSION' : str (bld.env['VERSION']),
542 'EXECUTABLE' : 'build/gtk2_ardour/ardour-' + str (bld.env['VERSION'])
545 def set_subst_dict(obj, dict):
547 setattr(obj, i, dict[i])
549 obj = bld(features = 'subst')
550 obj.source = 'ardev_common.sh.in'
551 obj.target = 'ardev_common_waf.sh'
552 obj.chmod = Utils.O755
553 obj.dict = wrapper_subst_dict
554 set_subst_dict(obj, wrapper_subst_dict)
556 obj = bld(features = 'subst')
557 obj.source = 'ardour.sh.in'
558 obj.target = 'ardour' + 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)
564 if bld.is_defined('WINDOWS_VST_SUPPORT'):
565 obj = bld(features = 'subst')
566 obj.source = '../vst/ardourvst.in'
567 obj.target = 'ardourvst' + str (bld.env['MAJOR'])
568 obj.chmod = Utils.O755
569 obj.dict = wrapper_subst_dict
570 obj.install_path = bld.env['BINDIR']
571 set_subst_dict(obj, wrapper_subst_dict)
580 if sys.platform == 'darwin':
594 # There is no acceptable monospace font available on older versions of OS X
595 # and no API on those versions to load TTF files that will work with
596 # GTK/fontconfig/pango.
598 # In addition, the ArdourMono font gets clipped for some reason on OS X
600 # Moreover, Lucida Grande just seems to work even though it is not monospace
604 'MONOSPACE' : 'Monaco',
605 'CLOCKFONT' : 'Lucida Grande',
607 else: # Linux/X11 fonts
608 basefont = '' # unspecified - use system defaults
621 'MONOSPACE' : 'ArdourMono',
622 'CLOCKFONT' : 'ArdourMono',
625 # Set up font substitution dictionary
627 for style in ['', 'BOLD', 'ITALIC']:
628 for sizename,points in iter(font_sizes.items()):
630 key = "_".join (['FONT',style,sizename])
631 fontstyle = " ".join ([basefont,style.lower(),points])
633 key = "_".join (['FONT',sizename])
634 fontstyle = " ".join ([basefont,points])
636 font_subst_dict[key] = fontstyle
639 for sizename,points in iter(font_sizes.items()):
640 key = "_".join (['FONT_SIZE',sizename])
641 font_subst_dict[key] = points
643 # various font names, eg @BOLD_MONOSPACE@
644 for font_sym,text in iter(font_names.items()):
646 font_subst_dict[key] = text
650 obj = bld(features = 'subst')
651 obj.source = [ 'clearlooks.rc.in' ]
652 obj.target = 'clearlooks.rc'
653 obj.install_path = bld.env['CONFDIR']
654 set_subst_dict(obj, font_subst_dict)
656 obj = bld(features = 'subst')
657 obj.source = [ 'default_ui_config.in' ]
658 obj.target = 'default_ui_config'
659 obj.install_path = bld.env['CONFDIR']
660 set_subst_dict(obj, font_subst_dict)
664 if sys.platform == 'darwin':
665 menus_argv = [ '-E', '-P', '-D__APPLE__', '-' ]
667 menus_argv = [ '-E', '-P' ]
669 if bld.is_defined('PTFORMAT'):
670 menus_argv += [ '-DPTFORMAT' ]
672 # always build all versions of the menu definitions
673 # so that we can try them out with different program builds.
674 for program in [ 'ardour', 'trx' ]:
675 obj = bld(features = 'command-output')
677 obj.command_is_external = True
679 obj.argv = menus_argv
680 obj.dep_vars = ['PTFORMAT', 'GTKOSX', 'WINDOWS']
681 obj.stdin = program + '.menus.in'
682 obj.stdout = program + '.menus'
683 bld.install_files (bld.env['CONFDIR'], program + '.menus')
686 freedesktop_subst_dict = {
687 'ARDOUR_EXEC' : str (bld.env['lwrcase_dirname']),
688 'ARDOUR_ICON' : str (bld.env['lwrcase_dirname']),
689 'VERSION': str (bld.env['VERSION']),
692 if bld.env['FREEDESKTOP']:
693 obj = bld(features = 'subst')
694 obj.source = 'ardour.desktop.in'
695 obj.target = str (bld.env['lwrcase_dirname']) + '.desktop'
696 obj.chmod = Utils.O644
697 obj.dict = freedesktop_subst_dict
698 set_subst_dict(obj, freedesktop_subst_dict)
700 obj = bld(features = 'subst')
701 obj.source = 'ardour-mime-info.xml'
702 obj.target = 'ardour.xml'
703 obj.chmod = Utils.O644
705 # build appdata with translations
707 appdata_i18n_xmlin(bld)
708 obj = bld(features = 'subst')
709 obj.source = 'ardour.appdata.xml.in'
710 obj.target = str (bld.env['lwrcase_dirname']) + '.appdata.xml'
711 obj.chmod = Utils.O644
712 obj.dict = freedesktop_subst_dict
713 set_subst_dict(obj, freedesktop_subst_dict)
717 # NATIVE ARDOUR BINDING FILES
718 # explicitly state the use of perl here so that it works on windows too
720 a_rule = 'perl ../tools/fmt-bindings --platform="%s" --winkey="%s" --accelmap ${SRC} >${TGT}' % (sys.platform, bld.env['WINDOWS_KEY'] )
721 for b in [ 'ardour' ] :
723 target = b + '.keys',
724 source = b + '.keys.in',
727 obj.install_path = bld.env['CONFDIR']
729 # not modified at present
730 bld.install_files(bld.env['CONFDIR'], 'dark.colors')
733 bld.install_files(os.path.join (bld.env['DATADIR'], 'icons'), bld.path.ant_glob('icons/*.png'))
734 bld.install_files(os.path.join (bld.env['DATADIR'], 'pixmaps'), bld.path.ant_glob('pixmaps/*.xpm'))
735 bld.install_files(bld.env['DATADIR'], 'splash.png')
736 bld.install_files(bld.env['DATADIR'], 'small-splash.png')
737 bld.install_files(bld.env['DATADIR'], 'ArdourMono.ttf')
739 if bld.env['build_target'] == 'mingw':
740 # These icons need to overwrite the files already installed in the icons
741 # directory above. Do this in the external packaging scripts for now.
742 #bld.install_files(os.path.join (bld.env['DATADIR'], 'icons'), bld.path.ant_glob('icons/cursor_square/*.png'))
743 bld.install_files(os.path.join (bld.env['DATADIR'], 'icons'), 'icons/cursor_square/hotspots')
745 # Default UI configuration
746 bld.install_files(bld.env['CONFDIR'], 'default_ui_config')
748 bld.install_files(bld.env['CONFDIR'], 'dark.colors')
750 # Default export stuff
751 bld.install_files(os.path.join(bld.env['CONFDIR'], 'export'), bld.path.ant_glob('export/*.format'))
754 if bld.is_defined('ENABLE_NLS'):
755 mo_files = bld.path.ant_glob('po/*.mo')
757 lang = os.path.basename(mo.srcpath()).replace('.mo', '')
758 bld.install_as (os.path.join(os.path.normpath(bld.env['LOCALEDIR']), lang, 'LC_MESSAGES', I18N_PACKAGE + '.mo'),
762 I18N_PACKAGE = 'gtk2_ardour' + bld.env['MAJOR']
763 autowaf.build_i18n(bld, top, 'gtk2_ardour', I18N_PACKAGE, gtk2_ardour_sources,
765 appdata_i18n_pot(bld)
769 I18N_PACKAGE = 'gtk2_ardour' + bld.env['MAJOR']
770 autowaf.build_i18n_pot(bld, top, 'gtk2_ardour', I18N_PACKAGE, gtk2_ardour_sources,
772 appdata_i18n_pot(bld)
775 I18N_PACKAGE = 'gtk2_ardour' + bld.env['MAJOR']
776 autowaf.build_i18n_po(bld, top, 'gtk2_ardour', I18N_PACKAGE, gtk2_ardour_sources,
781 I18N_PACKAGE = 'gtk2_ardour' + bld.env['MAJOR']
782 autowaf.build_i18n_mo(bld, top, 'gtk2_ardour', I18N_PACKAGE, gtk2_ardour_sources,
785 def appdata_i18n_pot(bld):
786 potfile = os.path.join(bld.top_dir, 'gtk2_ardour', 'appdata',
787 'ardour.appdata.pot')
788 if bld.cmd == 'build':
789 Logs.info('Generating pot file from Ardour appdata')
790 itsfile = os.path.join(bld.top_dir, 'tools', 'as-metainfo.its')
791 adsource = os.path.join(bld.top_dir, 'gtk2_ardour',
792 'ardour.appdata.xml.in.in')
793 Logs.info('Updating ' + potfile)
794 subprocess.call(('itstool', '-i', itsfile, '-o', potfile, adsource))
795 elif bld.cmd == 'clean' and os.path.exists(potfile):
796 Logs.info('Removing Ardour appdata pot file')
799 def appdata_i18n_po(bld):
800 autowaf.build_i18n_po(bld, bld.top_dir, os.path.join(
801 'gtk2_ardour', 'appdata'), 'ardour.appdata', 'dummy', 'dummy')
803 def appdata_i18n_mo(bld):
804 autowaf.build_i18n_mo(bld, bld.top_dir, os.path.join(
805 'gtk2_ardour', 'appdata'), 'ardour.appdata', 'dummy', 'dummy')
807 def appdata_i18n_xmlin(bld):
808 adxmlinfile = os.path.join(bld.top_dir, 'gtk2_ardour',
809 'ardour.appdata.xml.in')
810 if bld.cmd == 'build':
811 itsfile = os.path.join(bld.top_dir, 'tools', 'as-metainfo.its')
812 adxmlininfile = os.path.join(bld.top_dir, 'gtk2_ardour',
813 'ardour.appdata.xml.in.in')
814 mo_glob = os.path.join(bld.top_dir, 'gtk2_ardour', 'appdata', 'po', '*.mo')
815 mo_files = glob.glob(mo_glob)
816 Logs.info('Generating ' + adxmlinfile)
817 subprocess.call(['itstool', '-i', itsfile, '-o', adxmlinfile,
818 '-j', adxmlininfile] + mo_files)
819 elif bld.cmd == 'clean' and os.path.exists(adxmlinfile):
820 Logs.info('Removing ' + adxmlinfile)
821 os.remove(adxmlinfile)