daemon: ignore duplicate jack-stopped signal
[ladish.git] / wscript
blobfff1a3b3962a926d12b50fe33ef32d0c29c98f77
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'
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 if RELEASE:
45 opt.add_option('--debug', action='store_true', default=False, dest='debug', help="Build debuggable binaries")
46 opt.add_option('--doxygen', action='store_true', default=False, help='Enable build of doxygen documentation')
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 configure(conf):
56 conf.check_tool('compiler_cc')
57 conf.check_tool('compiler_cxx')
58 conf.check_tool('boost')
60 conf.check_cfg(
61 package = 'jack',
62 mandatory = True,
63 errmsg = "not installed, see http://jackaudio.org/",
64 args = '--cflags --libs')
66 conf.check_cfg(
67 package = 'dbus-1',
68 atleast_version = '1.0.0',
69 mandatory = True,
70 errmsg = "not installed, see http://dbus.freedesktop.org/",
71 args = '--cflags --libs')
73 dbus_dir = conf.check_cfg(package='dbus-1', args='--variable=session_bus_services_dir', msg="Retrieving D-Bus services dir")
74 if not dbus_dir:
75 return
77 dbus_dir = dbus_dir.strip()
78 conf.env['DBUS_SERVICES_DIR_REAL'] = dbus_dir
80 if Options.options.enable_pkg_config_dbus_service_dir:
81 conf.env['DBUS_SERVICES_DIR'] = dbus_dir
82 else:
83 conf.env['DBUS_SERVICES_DIR'] = os.path.join(os.path.normpath(conf.env['PREFIX']), 'share', 'dbus-1', 'services')
85 conf.env['BUILD_LIBLASH'] = Options.options.enable_liblash
86 conf.env['BUILD_DOXYGEN_DOCS'] = Options.options.doxygen
88 conf.check_cfg(
89 package = 'uuid',
90 mandatory = True,
91 errmsg = "not installed, see http://e2fsprogs.sourceforge.net/",
92 args = '--cflags --libs')
94 conf.check(
95 header_name='expat.h',
96 mandatory = True,
97 errmsg = "not installed, see http://expat.sourceforge.net/")
99 conf.env['LIB_EXPAT'] = ['expat']
101 build_gui = True
103 if build_gui and not conf.check_cfg(
104 package = 'glib-2.0',
105 mandatory = False,
106 errmsg = "not installed, see http://www.gtk.org/",
107 args = '--cflags --libs'):
108 build_gui = False
110 if build_gui and not conf.check_cfg(
111 package = 'dbus-glib-1',
112 mandatory = False,
113 errmsg = "not installed, see http://dbus.freedesktop.org/",
114 args = '--cflags --libs'):
115 build_gui = False
117 if build_gui and not conf.check_cfg(
118 package = 'gtk+-2.0',
119 mandatory = False,
120 atleast_version = '2.16.0',
121 errmsg = "not installed, see http://www.gtk.org/",
122 args = '--cflags --libs'):
123 build_gui = False
125 if build_gui and not conf.check_cfg(
126 package = 'flowcanvas',
127 mandatory = False,
128 atleast_version = '0.6.0',
129 errmsg = "not installed, see http://drobilla.net/software/flowcanvas/",
130 args = '--cflags --libs'):
131 build_gui = False
133 if build_gui:
134 # We need the boost headers package (e.g. libboost-dev)
135 # shared_ptr.hpp and weak_ptr.hpp
136 build_gui = conf.check_boost(errmsg="not found, see http://boost.org/")
138 conf.env['BUILD_GLADISH'] = build_gui
140 conf.env['BUILD_WERROR'] = not RELEASE
141 if conf.env['BUILD_WERROR']:
142 add_cflag(conf, '-Wall')
143 add_cflag(conf, '-Werror')
145 conf.env['BUILD_DEBUG'] = not RELEASE or Options.options.debug
146 if conf.env['BUILD_DEBUG']:
147 add_cflag(conf, '-g')
148 add_linkflag(conf, '-g')
150 conf.define('DATA_DIR', os.path.normpath(os.path.join(conf.env['PREFIX'], 'share', APPNAME)))
151 conf.define('PACKAGE_VERSION', VERSION)
152 conf.define('DBUS_NAME_BASE', DBUS_NAME_BASE)
153 conf.define('DBUS_BASE_PATH', '/' + DBUS_NAME_BASE.replace('.', '/'))
154 conf.define('BASE_NAME', APPNAME)
155 conf.define('_GNU_SOURCE', 1)
156 conf.write_config_header('config.h')
158 display_msg(conf)
160 display_msg(conf, "==================")
161 version_msg = APPNAME + "-" + VERSION
163 if os.access('version.h', os.R_OK):
164 data = file('version.h').read()
165 m = re.match(r'^#define GIT_VERSION "([^"]*)"$', data)
166 if m != None:
167 version_msg += " exported from " + m.group(1)
168 elif os.access('.git', os.R_OK):
169 version_msg += " git revision will checked and eventually updated during build"
171 display_msg(conf, version_msg)
173 display_msg(conf)
174 display_msg(conf, "Install prefix", conf.env['PREFIX'], 'CYAN')
176 display_msg(conf, 'Build gladish', yesno(conf.env['BUILD_GLADISH']))
177 display_msg(conf, 'Build liblash', yesno(Options.options.enable_liblash))
178 display_msg(conf, 'Treat warnings as errors', yesno(conf.env['BUILD_WERROR']))
179 display_msg(conf, 'Debuggable binaries', yesno(conf.env['BUILD_DEBUG']))
180 display_msg(conf, 'Build doxygen documentation', yesno(conf.env['BUILD_DOXYGEN_DOCS']))
182 if conf.env['DBUS_SERVICES_DIR'] != conf.env['DBUS_SERVICES_DIR_REAL']:
183 display_msg(conf)
184 display_line(conf, "WARNING: D-Bus session services directory as reported by pkg-config is", 'RED')
185 display_raw_text(conf, "WARNING:", 'RED')
186 display_line(conf, conf.env['DBUS_SERVICES_DIR_REAL'], 'CYAN')
187 display_line(conf, 'WARNING: but service file will be installed in', 'RED')
188 display_raw_text(conf, "WARNING:", 'RED')
189 display_line(conf, conf.env['DBUS_SERVICES_DIR'], 'CYAN')
190 display_line(conf, 'WARNING: You may need to adjust your D-Bus configuration after installing ladish', 'RED')
191 display_line(conf, 'WARNING: You can override dbus service install directory', 'RED')
192 display_line(conf, 'WARNING: with --enable-pkg-config-dbus-service-dir option to this script', 'RED')
194 display_msg(conf)
196 def build(bld):
197 daemon = bld.new_task_gen('cc', 'program')
198 daemon.target = 'ladishd'
199 daemon.includes = "build/default" # XXX config.h version.h and other generated files
200 daemon.uselib = 'DBUS-1 UUID EXPAT'
201 daemon.ver_header = 'version.h'
202 daemon.env.append_value("LINKFLAGS", ["-lutil", "-ldl", "-Wl,-E"])
204 daemon.source = [
205 'catdup.c',
208 for source in [
209 'main.c',
210 'loader.c',
211 'log.c',
212 'dirhelpers.c',
213 'sigsegv.c',
214 'proctitle.c',
215 'appdb.c',
216 'procfs.c',
217 'control.c',
218 'studio.c',
219 'graph.c',
220 'client.c',
221 'port.c',
222 'virtualizer.c',
223 'dict.c',
224 'graph_dict.c',
225 'escape.c',
226 'studio_jack_conf.c',
227 'cmd_load_studio.c',
228 'cmd_new_studio.c',
229 'cmd_rename_studio.c',
230 'cmd_save_studio.c',
231 'cmd_start_studio.c',
232 'cmd_stop_studio.c',
233 'cmd_unload_studio.c',
234 'cmd_new_app.c',
235 'cmd_change_app_state.c',
236 'cmd_create_room.c',
237 'cmd_delete_room.c',
238 'cmd_exit.c',
239 'cqueue.c',
240 'app_supervisor.c',
241 'room.c',
243 daemon.source.append(os.path.join("daemon", source))
245 for source in [
246 'jack_proxy.c',
247 'graph_proxy.c',
248 'a2j_proxy.c',
249 "jmcore_proxy.c",
250 "notify_proxy.c",
252 daemon.source.append(os.path.join("proxies", source))
254 for source in [
255 'signal.c',
256 'method.c',
257 'error.c',
258 'object_path.c',
259 'interface.c',
260 'helpers.c',
262 daemon.source.append(os.path.join("dbus", source))
264 for source in [
265 'time.c',
267 daemon.source.append(os.path.join("common", source))
269 # process dbus.service.in -> ladish.service
270 import misc
271 obj = bld.new_task_gen('subst')
272 obj.source = os.path.join('daemon', 'dbus.service.in')
273 obj.target = DBUS_NAME_BASE + '.service'
274 obj.dict = {'dbus_object_path': DBUS_NAME_BASE,
275 'daemon_bin_path': os.path.join(bld.env['PREFIX'], 'bin', daemon.target)}
276 obj.install_path = bld.env['DBUS_SERVICES_DIR'] + os.path.sep
277 obj.fun = misc.subst_func
279 #####################################################
280 # jmcore
281 jmcore = bld.new_task_gen('cc', 'program')
282 jmcore.target = 'jmcore'
283 jmcore.includes = "build/default" # XXX config.h version.h and other generated files
284 jmcore.uselib = 'DBUS-1 JACK'
285 jmcore.defines = ['LOG_OUTPUT_STDOUT']
286 jmcore.source = ['jmcore.c']
288 for source in [
289 #'signal.c',
290 'method.c',
291 'error.c',
292 'object_path.c',
293 'interface.c',
294 'helpers.c',
296 jmcore.source.append(os.path.join("dbus", source))
298 if bld.env['BUILD_LIBLASH']:
299 liblash = bld.new_task_gen('cc', 'shlib')
300 liblash.includes = "build/default" # XXX config.h version.h and other generated files
301 liblash.uselib = 'DBUS-1'
302 liblash.target = 'lash'
303 liblash.vnum = "1.1.1"
304 liblash.defines = ['LOG_OUTPUT_STDOUT']
305 liblash.source = [os.path.join("lash_compat", "liblash", 'lash.c')]
307 obj = bld.new_task_gen('subst')
308 obj.source = os.path.join('daemon', 'dbus.service.in')
309 obj.target = DBUS_NAME_BASE + '.jmcore.service'
310 obj.dict = {'dbus_object_path': DBUS_NAME_BASE + ".jmcore",
311 'daemon_bin_path': os.path.join(bld.env['PREFIX'], 'bin', jmcore.target)}
312 obj.install_path = bld.env['DBUS_SERVICES_DIR'] + os.path.sep
313 obj.fun = misc.subst_func
315 #####################################################
316 # pylash
318 # pkgpyexec_LTLIBRARIES = _lash.la
319 # INCLUDES = $(PYTHON_INCLUDES)
320 # _lash_la_LDFLAGS = -module -avoid-version ../liblash/liblash.la
321 # _lash_la_SOURCES = lash.c lash.h lash_wrap.c
322 # pkgpyexec_SCRIPTS = lash.py
323 # CLEANFILES = lash_wrap.c lash.py lash.pyc zynjacku.defs
324 # EXTRA_DIST = test.py lash.i lash.py
325 # lash_wrap.c lash.py: lash.i lash.h
326 # swig -o lash_wrap.c -I$(top_srcdir) -python $(top_srcdir)/$(subdir)/lash.i
328 #####################################################
329 # gladish
330 if bld.env['BUILD_GLADISH']:
331 gladish = bld.new_task_gen('cxx', 'program')
332 gladish.features.append('cc')
333 gladish.target = 'gladish'
334 gladish.defines = ['LOG_OUTPUT_STDOUT']
335 gladish.includes = "build/default" # XXX config.h version.h and other generated files
336 gladish.uselib = 'DBUS-1 DBUS-GLIB-1 FLOWCANVAS'
338 gladish.source = [
339 'catdup.c',
342 for source in [
343 'main.c',
344 #'lash_client.cpp',
345 #'lash_proxy.cpp',
346 #'load_projects_dialog.cpp',
347 #'project.cpp',
348 'world_tree.c',
349 'graph_view.c',
350 #'project_properties.cpp',
351 #'session.cpp',
352 'canvas.cpp',
353 'graph_canvas.c',
354 'gtk_builder.c',
355 'ask_dialog.c',
356 'create_room_dialog.c',
357 'menu.c',
359 gladish.source.append(os.path.join("gui", source))
361 for source in [
362 'jack_proxy.c',
363 'graph_proxy.c',
364 'studio_proxy.c',
365 'control_proxy.c',
366 'app_supervisor_proxy.c',
368 gladish.source.append(os.path.join("proxies", source))
370 for source in [
371 'method.c',
372 'helpers.c',
374 gladish.source.append(os.path.join("dbus", source))
376 # GtkBuilder UI definitions (XML)
377 bld.install_files(bld.env['DATA_DIR'], 'gui/gladish.ui')
379 bld.install_files('${PREFIX}/bin', 'ladish_control', chmod=0755)
381 # 'Desktop' file (menu entry, icon, etc)
382 #obj = bld.create_obj('subst')
383 #obj.source = 'patchage.desktop.in'
384 #obj.target = 'patchage.desktop'
385 #obj.dict = {
386 # 'BINDIR' : bld.env()['BINDIR'],
387 # 'APP_INSTALL_NAME' : bld.env()['APP_INSTALL_NAME'],
388 # 'APP_HUMAN_NAME' : bld.env()['APP_HUMAN_NAME'],
390 #install_as(os.path.normpath(bld.env()['DATADIR'] + 'applications/'), bld.env()['APP_INSTALL_NAME'] + '.desktop', 'build/default/patchage.desktop')
392 # Icons
394 # Installation layout (with /usr prefix)
395 # /usr/bin/patchage
396 # /usr/share/applications/patchage.desktop
397 # /usr/share/icons/hicolor/16x16/apps/patchage.png
398 # /usr/share/icons/hicolor/22x22/apps/patchage.png
399 # /usr/share/icons/hicolor/24x24/apps/patchage.png
400 # /usr/share/icons/hicolor/32x32/apps/patchage.png
401 # /usr/share/icons/hicolor/48x48/apps/patchage.png
402 # /usr/share/icons/hicolor/scalable/apps/patchage.svg
403 # /usr/share/patchage/patchage.glade
405 # icon cache is updated using:
406 # gtk-update-icon-cache -f -t $(datadir)/icons/hicolor
408 # Dave disabled this, ask why before removing this
409 #install_as(os.path.normpath(bld.env()['PREFIX'] + '/share/icons/hicolor/scalable/apps/'), bld.env()['APP_INSTALL_NAME'] + '.svg', 'icons/scalable/patchage.svg')
411 #icon_sizes = ['16x16', '22x22', '24x24', '32x32', '48x48']
412 #for icon_size in icon_sizes:
413 # install_as(os.path.normpath(bld.env()['DATADIR'] + '/icons/hicolor/' + icon_size + '/apps/'), bld.env()['APP_INSTALL_NAME'] + '.png', 'icons/' + icon_size + '/patchage.png')
415 status_images = []
416 for status in ["down", "unloaded", "started", "stopped", "warning", "error"]:
417 status_images.append("art/status_" + status + ".png")
419 bld.install_files(bld.env['DATA_DIR'], status_images)
420 bld.install_files(bld.env['DATA_DIR'], "art/ladish-logo-128x128.png")
421 bld.install_files(bld.env['DATA_DIR'], ["COPYING", "AUTHORS", "README", "NEWS"])
423 if bld.env['BUILD_DOXYGEN_DOCS'] == True:
424 html_docs_source_dir = "build/default/html"
425 if Options.commands['clean']:
426 if os.access(html_docs_source_dir, os.R_OK):
427 Utils.pprint('CYAN', "Removing doxygen generated documentation...")
428 shutil.rmtree(html_docs_source_dir)
429 Utils.pprint('CYAN', "Removing doxygen generated documentation done.")
430 elif Options.commands['build']:
431 if not os.access(html_docs_source_dir, os.R_OK):
432 os.popen("doxygen").read()
433 else:
434 Utils.pprint('CYAN', "doxygen documentation already built.")
436 def dist_hook():
437 shutil.copy('../build/default/version.h', "./")
439 import commands
440 from Constants import RUN_ME
441 from TaskGen import feature, after
442 import Task, Utils
444 @feature('cc')
445 @after('apply_core')
446 def process_git(self):
447 if getattr(self, 'ver_header', None):
448 tsk = self.create_task('git_ver')
449 tsk.set_outputs(self.path.find_or_declare(self.ver_header))
451 def git_ver(self):
452 header = self.outputs[0].abspath(self.env)
453 if os.access('../version.h', os.R_OK):
454 shutil.copy('../version.h', header)
455 data = file(header).read()
456 m = re.match(r'^#define GIT_VERSION "([^"]*)"$', data)
457 if m != None:
458 self.ver = m.group(1)
459 Utils.pprint('BLUE', "tarball from git revision " + self.ver)
460 else:
461 self.ver = "tarball"
462 return
464 if os.access('../.git', os.R_OK):
465 self.ver = commands.getoutput("LANG= git rev-parse HEAD").splitlines()[0]
466 if commands.getoutput("LANG= git diff-index --name-only HEAD").splitlines():
467 self.ver += "-dirty"
469 Utils.pprint('BLUE', "git revision " + self.ver)
470 else:
471 self.ver = "unknown"
473 fi = open(header, 'w')
474 fi.write('#define GIT_VERSION "%s"\n' % self.ver)
475 fi.close()
477 cls = Task.task_type_from_func('git_ver', vars=[], func=git_ver, color='BLUE', before='cc')
479 def always(self):
480 return RUN_ME
481 cls.runnable_status = always
483 def post_run(self):
484 sg = Utils.h_list(self.ver)
485 node = self.outputs[0]
486 variant = node.variant(self.env)
487 self.generator.bld.node_sigs[variant][node.id] = sg
488 cls.post_run = post_run