gui: update full view name on view name change. Fix for #105
[ladish.git] / wscript
blobf43477bc3cc68d71cf0014913f8a20d66c844579
1 #! /usr/bin/env python
2 # encoding: utf-8
4 import os
5 import Options
6 import Utils
7 import shutil
8 import re
10 APPNAME='ladish'
11 VERSION='0.3-rc'
12 DBUS_NAME_BASE = 'org.ladish'
13 RELEASE = False
15 # these variables are mandatory ('/' are converted automatically)
16 srcdir = '.'
17 blddir = 'build'
19 def display_msg(conf, msg="", status = None, color = None):
20 if status:
21 conf.check_message_1(msg)
22 conf.check_message_2(status, color)
23 else:
24 Utils.pprint('NORMAL', msg)
26 def display_raw_text(conf, text, color = 'NORMAL'):
27 Utils.pprint(color, text, sep = '')
29 def display_line(conf, text, color = 'NORMAL'):
30 Utils.pprint(color, text, sep = os.linesep)
32 def yesno(bool):
33 if bool:
34 return "yes"
35 else:
36 return "no"
38 def set_options(opt):
39 opt.tool_options('compiler_cc')
40 opt.tool_options('compiler_cxx')
41 opt.tool_options('boost')
42 opt.add_option('--enable-pkg-config-dbus-service-dir', action='store_true', default=False, help='force D-Bus service install dir to be one returned by pkg-config')
43 opt.add_option('--enable-liblash', action='store_true', default=False, help='Build LASH compatibility library')
44 opt.add_option('--debug', action='store_true', default=False, dest='debug', help="Build debuggable binaries")
45 opt.add_option('--doxygen', action='store_true', default=False, help='Enable build of doxygen documentation')
46 opt.add_option('--distnodeps', action='store_true', default=False, help="When creating distribution tarball, don't package git submodules")
48 def add_cflag(conf, flag):
49 conf.env.append_unique('CXXFLAGS', flag)
50 conf.env.append_unique('CCFLAGS', flag)
52 def add_linkflag(conf, flag):
53 conf.env.append_unique('LINKFLAGS', flag)
55 def check_gcc_optimizations_enabled(flags):
56 gcc_optimizations_enabled = False
57 for flag in flags:
58 if len(flag) < 2 or flag[0] != '-' or flag[1] != 'O':
59 continue
60 if len(flag) == 2:
61 gcc_optimizations_enabled = True;
62 else:
63 gcc_optimizations_enabled = flag[2] != '0';
64 return gcc_optimizations_enabled
66 def configure(conf):
67 conf.check_tool('compiler_cc')
68 conf.check_tool('compiler_cxx')
69 conf.check_tool('boost')
70 #conf.check_tool('ParallelDebug')
72 conf.check_cfg(
73 package = 'jack',
74 mandatory = True,
75 errmsg = "not installed, see http://jackaudio.org/",
76 args = '--cflags --libs')
78 conf.check_cfg(
79 package = 'dbus-1',
80 atleast_version = '1.0.0',
81 mandatory = True,
82 errmsg = "not installed, see http://dbus.freedesktop.org/",
83 args = '--cflags --libs')
85 dbus_dir = conf.check_cfg(package='dbus-1', args='--variable=session_bus_services_dir', msg="Retrieving D-Bus services dir")
86 if not dbus_dir:
87 return
89 dbus_dir = dbus_dir.strip()
90 conf.env['DBUS_SERVICES_DIR_REAL'] = dbus_dir
92 if Options.options.enable_pkg_config_dbus_service_dir:
93 conf.env['DBUS_SERVICES_DIR'] = dbus_dir
94 else:
95 conf.env['DBUS_SERVICES_DIR'] = os.path.join(os.path.normpath(conf.env['PREFIX']), 'share', 'dbus-1', 'services')
97 conf.env['LIBDIR'] = os.path.join(os.path.normpath(conf.env['PREFIX']), 'lib')
99 conf.env['BUILD_LIBLASH'] = Options.options.enable_liblash
100 conf.env['BUILD_DOXYGEN_DOCS'] = Options.options.doxygen
102 conf.check_cfg(
103 package = 'uuid',
104 mandatory = True,
105 errmsg = "not installed, see http://e2fsprogs.sourceforge.net/",
106 args = '--cflags --libs')
108 conf.check(
109 header_name='expat.h',
110 mandatory = True,
111 errmsg = "not installed, see http://expat.sourceforge.net/")
113 conf.env['LIB_EXPAT'] = ['expat']
115 build_gui = True
117 if build_gui and not conf.check_cfg(
118 package = 'glib-2.0',
119 mandatory = False,
120 errmsg = "not installed, see http://www.gtk.org/",
121 args = '--cflags --libs'):
122 build_gui = False
124 if build_gui and not conf.check_cfg(
125 package = 'dbus-glib-1',
126 mandatory = False,
127 errmsg = "not installed, see http://dbus.freedesktop.org/",
128 args = '--cflags --libs'):
129 build_gui = False
131 if build_gui and not conf.check_cfg(
132 package = 'gtk+-2.0',
133 mandatory = False,
134 atleast_version = '2.20.0',
135 errmsg = "not installed, see http://www.gtk.org/",
136 args = '--cflags --libs'):
137 build_gui = False
139 if build_gui and not conf.check_cfg(
140 package = 'flowcanvas',
141 mandatory = False,
142 atleast_version = '0.6.4',
143 errmsg = "not installed, see http://drobilla.net/software/flowcanvas/",
144 args = '--cflags --libs'):
145 build_gui = False
147 if build_gui:
148 # We need the boost headers package (e.g. libboost-dev)
149 # shared_ptr.hpp and weak_ptr.hpp
150 build_gui = conf.check_boost(errmsg="not found, see http://boost.org/")
152 conf.env['BUILD_GLADISH'] = build_gui
154 conf.env['BUILD_WERROR'] = not RELEASE
155 if conf.env['BUILD_WERROR']:
156 add_cflag(conf, '-Wall')
157 add_cflag(conf, '-Werror')
158 # for pre gcc-4.4, enable optimizations so use of uninitialized variables gets detected
159 try:
160 is_gcc = conf.env['CC_NAME'] == 'gcc'
161 if is_gcc:
162 gcc_ver = []
163 for n in conf.env['CC_VERSION']:
164 gcc_ver.append(int(n))
165 if gcc_ver[0] < 4 or gcc_ver[1] < 4:
166 #print "optimize force enable is required"
167 if not check_gcc_optimizations_enabled(conf.env['CCFLAGS']):
168 if Options.options.debug:
169 print "C optimization must be forced in order to enable -Wuninitialized"
170 print "However this will not be made because debug compilation is enabled"
171 else:
172 print "C optimization forced in order to enable -Wuninitialized"
173 conf.env.append_unique('CCFLAGS', "-O")
174 except:
175 pass
177 conf.env['BUILD_DEBUG'] = Options.options.debug
178 if conf.env['BUILD_DEBUG']:
179 add_cflag(conf, '-g')
180 add_cflag(conf, '-O0')
181 add_linkflag(conf, '-g')
183 conf.define('DATA_DIR', os.path.normpath(os.path.join(conf.env['PREFIX'], 'share', APPNAME)))
184 conf.define('PACKAGE_VERSION', VERSION)
185 conf.define('DBUS_NAME_BASE', DBUS_NAME_BASE)
186 conf.define('DBUS_BASE_PATH', '/' + DBUS_NAME_BASE.replace('.', '/'))
187 conf.define('BASE_NAME', APPNAME)
188 conf.define('_GNU_SOURCE', 1)
189 conf.write_config_header('config.h')
191 display_msg(conf)
193 display_msg(conf, "==================")
194 version_msg = APPNAME + "-" + VERSION
196 if os.access('version.h', os.R_OK):
197 data = file('version.h').read()
198 m = re.match(r'^#define GIT_VERSION "([^"]*)"$', data)
199 if m != None:
200 version_msg += " exported from " + m.group(1)
201 elif os.access('.git', os.R_OK):
202 version_msg += " git revision will checked and eventually updated during build"
204 display_msg(conf, version_msg)
206 display_msg(conf)
207 display_msg(conf, "Install prefix", conf.env['PREFIX'], 'CYAN')
209 display_msg(conf, 'Build gladish', yesno(conf.env['BUILD_GLADISH']))
210 display_msg(conf, 'Build liblash', yesno(Options.options.enable_liblash))
211 display_msg(conf, 'Treat warnings as errors', yesno(conf.env['BUILD_WERROR']))
212 display_msg(conf, 'Debuggable binaries', yesno(conf.env['BUILD_DEBUG']))
213 display_msg(conf, 'Build doxygen documentation', yesno(conf.env['BUILD_DOXYGEN_DOCS']))
215 if conf.env['DBUS_SERVICES_DIR'] != conf.env['DBUS_SERVICES_DIR_REAL']:
216 display_msg(conf)
217 display_line(conf, "WARNING: D-Bus session services directory as reported by pkg-config is", 'RED')
218 display_raw_text(conf, "WARNING:", 'RED')
219 display_line(conf, conf.env['DBUS_SERVICES_DIR_REAL'], 'CYAN')
220 display_line(conf, 'WARNING: but service file will be installed in', 'RED')
221 display_raw_text(conf, "WARNING:", 'RED')
222 display_line(conf, conf.env['DBUS_SERVICES_DIR'], 'CYAN')
223 display_line(conf, 'WARNING: You may need to adjust your D-Bus configuration after installing ladish', 'RED')
224 display_line(conf, 'WARNING: You can override dbus service install directory', 'RED')
225 display_line(conf, 'WARNING: with --enable-pkg-config-dbus-service-dir option to this script', 'RED')
227 display_msg(conf, 'C compiler flags', repr(conf.env['CCFLAGS']))
228 display_msg(conf, 'C++ compiler flags', repr(conf.env['CXXFLAGS']))
230 if not conf.env['BUILD_GLADISH']:
231 display_msg(conf)
232 display_line(conf, "WARNING: The GUI frontend will not built", 'RED')
234 display_msg(conf)
236 def build(bld):
237 daemon = bld.new_task_gen('cc', 'program')
238 daemon.target = 'ladishd'
239 daemon.includes = "build/default" # XXX config.h version.h and other generated files
240 daemon.uselib = 'DBUS-1 UUID EXPAT'
241 daemon.ver_header = 'version.h'
242 daemon.env.append_value("LINKFLAGS", ["-lutil", "-ldl", "-Wl,-E"])
244 daemon.source = [
245 'catdup.c',
248 for source in [
249 'main.c',
250 'loader.c',
251 'log.c',
252 'dirhelpers.c',
253 'sigsegv.c',
254 'proctitle.c',
255 'appdb.c',
256 'procfs.c',
257 'control.c',
258 'studio.c',
259 'graph.c',
260 'client.c',
261 'port.c',
262 'virtualizer.c',
263 'dict.c',
264 'graph_dict.c',
265 'escape.c',
266 'studio_jack_conf.c',
267 'save.c',
268 'load.c',
269 'cmd_load_studio.c',
270 'cmd_new_studio.c',
271 'cmd_rename_studio.c',
272 'cmd_save_studio.c',
273 'cmd_start_studio.c',
274 'cmd_stop_studio.c',
275 'cmd_unload_studio.c',
276 'cmd_new_app.c',
277 'cmd_change_app_state.c',
278 'cmd_remove_app.c',
279 'cmd_create_room.c',
280 'cmd_delete_room.c',
281 'cmd_save_project.c',
282 'cmd_unload_project.c',
283 'cmd_load_project.c',
284 'cmd_exit.c',
285 'cqueue.c',
286 'app_supervisor.c',
287 'room.c',
288 'room_save.c',
289 'room_load.c',
291 daemon.source.append(os.path.join("daemon", source))
293 for source in [
294 'jack_proxy.c',
295 'graph_proxy.c',
296 'a2j_proxy.c',
297 "jmcore_proxy.c",
298 "notify_proxy.c",
300 daemon.source.append(os.path.join("proxies", source))
302 for source in [
303 'signal.c',
304 'method.c',
305 'error.c',
306 'object_path.c',
307 'interface.c',
308 'helpers.c',
310 daemon.source.append(os.path.join("dbus", source))
312 for source in [
313 'time.c',
315 daemon.source.append(os.path.join("common", source))
317 # process dbus.service.in -> ladish.service
318 import misc
319 obj = bld.new_task_gen('subst')
320 obj.source = os.path.join('daemon', 'dbus.service.in')
321 obj.target = DBUS_NAME_BASE + '.service'
322 obj.dict = {'dbus_object_path': DBUS_NAME_BASE,
323 'daemon_bin_path': os.path.join(bld.env['PREFIX'], 'bin', daemon.target)}
324 obj.install_path = bld.env['DBUS_SERVICES_DIR'] + os.path.sep
325 obj.fun = misc.subst_func
327 #####################################################
328 # jmcore
329 jmcore = bld.new_task_gen('cc', 'program')
330 jmcore.target = 'jmcore'
331 jmcore.includes = "build/default" # XXX config.h version.h and other generated files
332 jmcore.uselib = 'DBUS-1 JACK'
333 jmcore.defines = ['LOG_OUTPUT_STDOUT']
334 jmcore.source = ['jmcore.c']
336 for source in [
337 #'signal.c',
338 'method.c',
339 'error.c',
340 'object_path.c',
341 'interface.c',
342 'helpers.c',
344 jmcore.source.append(os.path.join("dbus", source))
346 if bld.env['BUILD_LIBLASH']:
347 liblash = bld.new_task_gen('cc', 'shlib')
348 liblash.includes = "build/default" # XXX config.h version.h and other generated files
349 liblash.uselib = 'DBUS-1'
350 liblash.target = 'lash'
351 liblash.vnum = "1.1.1"
352 liblash.defines = ['LOG_OUTPUT_STDOUT']
353 liblash.source = [os.path.join("lash_compat", "liblash", 'lash.c')]
355 bld.install_files('${PREFIX}/include/lash', 'lash_compat/liblash/lash/*.h')
357 # process lash-1.0.pc.in -> lash-1.0.pc
358 obj = bld.new_task_gen('subst')
359 obj.source = [os.path.join("lash_compat", 'lash-1.0.pc.in')]
360 obj.target = 'lash-1.0.pc'
361 obj.dict = {'prefix': bld.env['PREFIX'],
362 'exec_prefix': bld.env['PREFIX'],
363 'libdir': bld.env['LIBDIR'],
364 'includedir': os.path.normpath(bld.env['PREFIX'] + '/include'),
366 obj.install_path = '${LIBDIR}/pkgconfig/'
367 obj.fun = misc.subst_func
369 obj = bld.new_task_gen('subst')
370 obj.source = os.path.join('daemon', 'dbus.service.in')
371 obj.target = DBUS_NAME_BASE + '.jmcore.service'
372 obj.dict = {'dbus_object_path': DBUS_NAME_BASE + ".jmcore",
373 'daemon_bin_path': os.path.join(bld.env['PREFIX'], 'bin', jmcore.target)}
374 obj.install_path = bld.env['DBUS_SERVICES_DIR'] + os.path.sep
375 obj.fun = misc.subst_func
377 #####################################################
378 # pylash
380 # pkgpyexec_LTLIBRARIES = _lash.la
381 # INCLUDES = $(PYTHON_INCLUDES)
382 # _lash_la_LDFLAGS = -module -avoid-version ../liblash/liblash.la
383 # _lash_la_SOURCES = lash.c lash.h lash_wrap.c
384 # pkgpyexec_SCRIPTS = lash.py
385 # CLEANFILES = lash_wrap.c lash.py lash.pyc zynjacku.defs
386 # EXTRA_DIST = test.py lash.i lash.py
387 # lash_wrap.c lash.py: lash.i lash.h
388 # swig -o lash_wrap.c -I$(top_srcdir) -python $(top_srcdir)/$(subdir)/lash.i
390 #####################################################
391 # gladish
392 if bld.env['BUILD_GLADISH']:
393 gladish = bld.new_task_gen('cxx', 'program')
394 gladish.features.append('cc')
395 gladish.target = 'gladish'
396 gladish.defines = ['LOG_OUTPUT_STDOUT']
397 gladish.includes = "build/default" # XXX config.h version.h and other generated files
398 gladish.uselib = 'DBUS-1 DBUS-GLIB-1 FLOWCANVAS'
400 gladish.source = [
401 'catdup.c',
404 for source in [
405 'main.c',
406 'load_project_dialog.c',
407 'save_project_dialog.c',
408 'world_tree.c',
409 'graph_view.c',
410 'canvas.cpp',
411 'graph_canvas.c',
412 'gtk_builder.c',
413 'ask_dialog.c',
414 'create_room_dialog.c',
415 'menu.c',
416 'about.c',
417 'dbus.c',
418 'studio.c',
419 'studio_list.c',
420 'dialogs.c',
421 'jack.c',
422 'control.c',
423 'pixbuf.c',
424 'room.c',
425 'statusbar.c',
426 'action.c',
428 gladish.source.append(os.path.join("gui", source))
430 for source in [
431 'jack_proxy.c',
432 'graph_proxy.c',
433 'studio_proxy.c',
434 'control_proxy.c',
435 'app_supervisor_proxy.c',
436 "room_proxy.c",
438 gladish.source.append(os.path.join("proxies", source))
440 for source in [
441 'method.c',
442 'helpers.c',
444 gladish.source.append(os.path.join("dbus", source))
446 # GtkBuilder UI definitions (XML)
447 bld.install_files(bld.env['DATA_DIR'], 'gui/gladish.ui')
449 bld.install_files('${PREFIX}/bin', 'ladish_control', chmod=0755)
451 # 'Desktop' file (menu entry, icon, etc)
452 bld.install_files('${PREFIX}/share/applications/', 'gui/gladish.desktop', chmod=0644)
454 # Icons
455 icon_sizes = ['16x16', '22x22', '24x24', '32x32', '48x48', '256x256']
456 for icon_size in icon_sizes:
457 bld.path.ant_glob('art/' + icon_size + '/apps/*.png')
458 bld.install_files('${PREFIX}/share/icons/hicolor/' + icon_size + '/apps/', 'art/' + icon_size + '/apps/gladish.png')
460 status_images = []
461 for status in ["down", "unloaded", "started", "stopped", "warning", "error"]:
462 status_images.append("art/status_" + status + ".png")
464 bld.install_files(bld.env['DATA_DIR'], status_images)
465 bld.install_files(bld.env['DATA_DIR'], "art/ladish-logo-128x128.png")
466 bld.install_files(bld.env['DATA_DIR'], ["COPYING", "AUTHORS", "README", "NEWS"])
468 if bld.env['BUILD_DOXYGEN_DOCS'] == True:
469 html_docs_source_dir = "build/default/html"
470 if Options.commands['clean']:
471 if os.access(html_docs_source_dir, os.R_OK):
472 Utils.pprint('CYAN', "Removing doxygen generated documentation...")
473 shutil.rmtree(html_docs_source_dir)
474 Utils.pprint('CYAN', "Removing doxygen generated documentation done.")
475 elif Options.commands['build']:
476 if not os.access(html_docs_source_dir, os.R_OK):
477 os.popen("doxygen").read()
478 else:
479 Utils.pprint('CYAN', "doxygen documentation already built.")
481 def get_tags_dirs():
482 source_root = os.path.dirname(Utils.g_module.root_path)
483 if 'relpath' in os.path.__all__:
484 source_root = os.path.relpath(source_root)
485 paths = source_root
486 paths += " " + os.path.join(source_root, "common")
487 paths += " " + os.path.join(source_root, "dbus")
488 paths += " " + os.path.join(source_root, "proxies")
489 paths += " " + os.path.join(source_root, "daemon")
490 paths += " " + os.path.join(source_root, "gui")
491 paths += " " + os.path.join(source_root, "example-apps")
492 paths += " " + os.path.join(source_root, "lib")
493 paths += " " + os.path.join(source_root, "lash_compat", "liblash")
494 paths += " " + os.path.join(source_root, "lash_compat", "liblash", "lash")
495 return paths
497 def gtags(ctx):
498 '''build tag files for GNU global'''
499 cmd = "find %s -mindepth 1 -maxdepth 1 -name '*.[ch]' -print | gtags --statistics -f -" % get_tags_dirs()
500 #print("Running: %s" % cmd)
501 os.system(cmd)
503 def etags(ctx):
504 '''build TAGS file using etags'''
505 cmd = "find %s -mindepth 1 -maxdepth 1 -name '*.[ch]' -print | etags -" % get_tags_dirs()
506 #print("Running: %s" % cmd)
507 os.system(cmd)
508 os.system("stat -c '%y' TAGS")
510 def dist_hook():
511 #print repr(Options.options)
512 if Options.options.distnodeps:
513 shutil.rmtree('laditools')
514 shutil.rmtree('flowcanvas')
515 shutil.rmtree('jack2')
516 shutil.rmtree('a2jmidid')
517 nodist_files = ['.gitmodules', 'GTAGS', 'GRTAGS', 'GPATH', 'GSYMS'] # waf does not ignore these file
518 for nodist_file in nodist_files:
519 os.remove(nodist_file)
520 shutil.copy('../build/default/version.h', "./")
522 import commands
523 from Constants import RUN_ME
524 from TaskGen import feature, after
525 import Task, Utils
527 @feature('cc')
528 @after('apply_core')
529 def process_git(self):
530 if getattr(self, 'ver_header', None):
531 tsk = self.create_task('git_ver')
532 tsk.set_outputs(self.path.find_or_declare(self.ver_header))
534 # needs some help with implicit dependencies
535 # http://code.google.com/p/waf/issues/detail?id=732
536 tg = self.bld.name_to_obj('ladishd', self.env)
537 if id(tg) != id(self):
538 tg.post()
539 for x in tg.tasks:
540 if x.inputs and x.inputs[0].name == 'main.c' and x.inputs[0].parent.name == 'daemon':
541 x.set_run_after(tsk)
543 def git_ver(self):
544 header = self.outputs[0].abspath(self.env)
545 if os.access('../version.h', os.R_OK):
546 shutil.copy('../version.h', header)
547 data = file(header).read()
548 m = re.match(r'^#define GIT_VERSION "([^"]*)"$', data)
549 if m != None:
550 self.ver = m.group(1)
551 Utils.pprint('BLUE', "tarball from git revision " + self.ver)
552 else:
553 self.ver = "tarball"
554 return
556 if os.access('../.git', os.R_OK):
557 self.ver = commands.getoutput("LANG= git rev-parse HEAD").splitlines()[0]
558 if commands.getoutput("LANG= git diff-index --name-only HEAD").splitlines():
559 self.ver += "-dirty"
561 Utils.pprint('BLUE', "git revision " + self.ver)
562 else:
563 self.ver = "unknown"
565 fi = open(header, 'w')
566 fi.write('#define GIT_VERSION "%s"\n' % self.ver)
567 fi.close()
569 cls = Task.task_type_from_func('git_ver', vars=[], func=git_ver, color='BLUE')
571 def always(self):
572 return RUN_ME
573 cls.runnable_status = always
575 def post_run(self):
576 sg = Utils.h_list(self.ver)
577 node = self.outputs[0]
578 variant = node.variant(self.env)
579 self.generator.bld.node_sigs[variant][node.id] = sg
580 cls.post_run = post_run
582 import Runner
584 old_refill = Runner.Parallel.refill_task_list
585 def refill_task_list(self):
586 old_refill(self)
587 self.outstanding.sort(cmp=lambda a, b: cmp(b.__class__.__name__, a.__class__.__name__))
588 Runner.Parallel.refill_task_list = refill_task_list