diff options
author | Stephane Letz <letz@grame.fr> | 2016-01-01 20:41:05 +0100 |
---|---|---|
committer | Stephane Letz <letz@grame.fr> | 2016-01-01 20:41:05 +0100 |
commit | 5e565e684a7454c2d9f75887ff0d98202c028107 (patch) | |
tree | 3d42555b70c8b9c71d6c0546d276d8bb18b6baa4 | |
parent | 02f74a659aeb7120dfd462a7e24c9628f28f842d (diff) | |
parent | 790243f357159388ce3b862839e82a743bdcf57b (diff) | |
download | jack2-5e565e684a7454c2d9f75887ff0d98202c028107.tar.gz |
Merge remote-tracking branch 'upstream/master'
39 files changed, 600 insertions, 468 deletions
@@ -2,6 +2,7 @@ build/ man/*.1 .lock* __pycache__ +*.pyc android/.server/ android/.client/ codeBlocks diff --git a/.wafupdaterc b/.wafupdaterc index b595a242..69f4293a 100755 --- a/.wafupdaterc +++ b/.wafupdaterc @@ -134,4 +134,5 @@ WAFLIB_STRIP_EXTRAS=" why win32_opts xcode + xcode6 " diff --git a/config.h.in b/config.h.in deleted file mode 100644 index e356790d..00000000 --- a/config.h.in +++ /dev/null @@ -1,17 +0,0 @@ -/* config.h.in. */ -#ifndef CONFIG_H -#define CONFIG_H - -/* Name of package */ -#define PACKAGE $PACKAGE - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "<jack-devel@jackaudio.org>" - -#define ADDON_DIR "$ADDON_DIR" - -#define JACK_LOCATION "$JACK_LOCATION" - -#define JACK_SVNREVISION "$JACK_SVNREVISION" - -#endif // CONFIG_H diff --git a/linux/wscript b/linux/wscript deleted file mode 100644 index 968839ba..00000000 --- a/linux/wscript +++ /dev/null @@ -1,94 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 - -from waflib import Context - -def configure(conf): - conf.define('HAVE_PPOLL', 1 ) - -def create_jack_driver_obj(bld, target, sources, uselib = None): - driver = bld(features = ['c', 'cxx', 'cxxshlib', 'cshlib']) - driver.env['cxxshlib_PATTERN'] = 'jack_%s.so' - - #driver.defines = ['HAVE_CONFIG_H','SERVER_SIDE', 'HAVE_PPOLL'] - driver.defines = ['HAVE_CONFIG_H','SERVER_SIDE', 'HAVE_PPOLL', 'HAVE_TIMERFD'] - - driver.includes = ['.', '../linux', '../posix', '../common', '../common/jack', '../dbus', '../'] - driver.target = target - driver.source = sources - driver.install_path = '${ADDON_DIR}/' - driver.use = [] - if uselib: - driver.use += uselib - return driver - -def build(bld): - if bld.env['BUILD_JACKD'] == True: - jackd = bld(features = ['cxx', 'cxxprogram']) - jackd.includes = ['../linux', '../posix', '../common/jack', '../common', '../dbus', '../'] - jackd.defines = ['HAVE_CONFIG_H','SERVER_SIDE'] - jackd.source = ['../common/Jackdmp.cpp'] - jackd.use = ['serverlib'] - if bld.env['IS_LINUX'] and bld.env['BUILD_JACKDBUS']: - jackd.source += ['../dbus/reserve.c', '../dbus/audio_reserve.c'] - jackd.use += ['PTHREAD', 'DL', 'RT', 'M', 'STDC++', 'DBUS-1'] - else: - jackd.use += ['PTHREAD', 'DL', 'RT', 'M', 'STDC++'] - jackd.target = 'jackd' - - create_jack_driver_obj(bld, 'dummy', '../common/JackDummyDriver.cpp') - - alsa_driver_src = [ - 'alsa/JackAlsaDriver.cpp', - 'alsa/alsa_rawmidi.c', - 'alsa/alsa_seqmidi.c', - 'alsa/alsa_midi_jackmp.cpp', - '../common/memops.c', - 'alsa/generic_hw.c', - 'alsa/hdsp.c', - 'alsa/alsa_driver.c', - 'alsa/hammerfall.c', - 'alsa/ice1712.c' - ] - - alsarawmidi_driver_src = ['alsarawmidi/JackALSARawMidiDriver.cpp', - 'alsarawmidi/JackALSARawMidiInputPort.cpp', - 'alsarawmidi/JackALSARawMidiOutputPort.cpp', - 'alsarawmidi/JackALSARawMidiPort.cpp', - 'alsarawmidi/JackALSARawMidiReceiveQueue.cpp', - 'alsarawmidi/JackALSARawMidiSendQueue.cpp', - 'alsarawmidi/JackALSARawMidiUtil.cpp' - ] - - ffado_driver_src = ['firewire/JackFFADODriver.cpp', - 'firewire/JackFFADOMidiInputPort.cpp', - 'firewire/JackFFADOMidiOutputPort.cpp', - 'firewire/JackFFADOMidiReceiveQueue.cpp', - 'firewire/JackFFADOMidiSendQueue.cpp' - ] - - iio_driver_src = ['iio/JackIIODriver.cpp'] - - if bld.env['BUILD_DRIVER_ALSA'] == True: - create_jack_driver_obj(bld, 'alsa', alsa_driver_src, ["ALSA"]) - create_jack_driver_obj(bld, 'alsarawmidi', alsarawmidi_driver_src, - ["ALSA"]) - - if bld.env['BUILD_DRIVER_FREEBOB'] == True: - create_jack_driver_obj(bld, 'freebob', 'freebob/JackFreebobDriver.cpp', ["LIBFREEBOB"]) - - if bld.env['BUILD_DRIVER_FFADO'] == True: - create_jack_driver_obj(bld, 'firewire', ffado_driver_src, ["LIBFFADO"]) - - if bld.env['BUILD_DRIVER_IIO'] == True: - create_jack_driver_obj(bld, 'iio', iio_driver_src, ["GTKIOSTREAM", "EIGEN3"]) - - create_jack_driver_obj(bld, 'net', '../common/JackNetDriver.cpp') - - create_jack_driver_obj(bld, 'loopback', '../common/JackLoopbackDriver.cpp') - - create_jack_driver_obj(bld, 'netone', [ '../common/JackNetOneDriver.cpp', - '../common/netjack.c', - '../common/netjack_packet.c' ], ["SAMPLERATE", "CELT"]) - - create_jack_driver_obj(bld, 'proxy', '../common/JackProxyDriver.cpp') diff --git a/macosx/wscript b/macosx/wscript deleted file mode 100644 index ba925057..00000000 --- a/macosx/wscript +++ /dev/null @@ -1,91 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 - -def create_jack_driver_obj(bld, target, sources, uselib = None): - driver = bld.new_task_gen('cxx', 'shlib') - driver.features.append('cc') - driver.env['shlib_PATTERN'] = 'jack_%s.so' - driver.defines = ['HAVE_CONFIG_H','SERVER_SIDE'] - driver.includes = ['.', '../macosx', '../posix', '../common', '../common/jack'] - driver.target = target - driver.source = sources - driver.install_path = '${ADDON_DIR}/' - driver.uselib_local = 'serverlib' - if uselib: - driver.uselib = uselib - return driver - -def create_jack_audio_driver_obj(bld, target, sources, uselib = None): - driver = bld.new_task_gen('cxx', 'shlib') - driver.features.append('cc') - driver.env['shlib_PATTERN'] = 'jack_%s.so' - driver.defines = 'HAVE_CONFIG_H' - driver.includes = ['.', '../macosx', '../posix', '../common', '../common/jack'] - driver.target = target - driver.source = sources - driver.install_path = '${ADDON_DIR}/' - driver.uselib_local = 'serverlib' - driver.env.append_value("LINKFLAGS", "-framework CoreAudio -framework CoreServices -framework AudioUnit") - if uselib: - driver.uselib = uselib - return driver - -def create_jack_midi_driver_obj(bld, target, sources, uselib = None): - driver = bld.new_task_gen('cxx', 'shlib') - driver.features.append('cc') - driver.env['shlib_PATTERN'] = 'jack_%s.so' - driver.defines = 'HAVE_CONFIG_H' - driver.includes = ['.', '../macosx', '../posix', '../common', '../common/jack'] - driver.target = target - driver.source = sources - driver.install_path = '${ADDON_DIR}/' - driver.uselib_local = 'serverlib' - driver.env.append_value("LINKFLAGS", "-framework CoreMIDI -framework CoreServices -framework AudioUnit") - if uselib: - driver.uselib = uselib - return driver - -def build(bld): - if bld.env['BUILD_JACKD'] == True: - jackd = bld.new_task_gen('cxx', 'program') - jackd.includes = ['.', '../macosx', '../posix', '../common', '../common/jack'] - jackd.defines = 'HAVE_CONFIG_H' - jackd.source = ['../common/Jackdmp.cpp'] - jackd.uselib = 'PTHREAD DL' - jackd.uselib_local = 'serverlib' - jackd.env.append_value("LINKFLAGS", "-framework CoreFoundation") - jackd.target = 'jackd' - - create_jack_driver_obj(bld, 'dummy', '../common/JackDummyDriver.cpp') - - create_jack_driver_obj(bld, 'loopback', '../common/JackLoopbackDriver.cpp') - - create_jack_audio_driver_obj(bld, 'coreaudio', 'coreaudio/JackCoreAudioDriver.cpp') - - create_jack_midi_driver_obj( - bld, - 'coremidi', - ['coremidi/JackCoreMidiInputPort.cpp', - 'coremidi/JackCoreMidiOutputPort.cpp', - 'coremidi/JackCoreMidiPhysicalInputPort.cpp', - 'coremidi/JackCoreMidiPhysicalOutputPort.cpp', - 'coremidi/JackCoreMidiVirtualInputPort.cpp', - 'coremidi/JackCoreMidiVirtualOutputPort.cpp', - 'coremidi/JackCoreMidiPort.cpp', - 'coremidi/JackCoreMidiUtil.cpp', - 'coremidi/JackCoreMidiDriver.cpp']) - - portaudio_src = [ - '../windows/JackPortAudioDriver.cpp', - '../windows/JackPortAudioDevices.cpp', - ] - - #create_jack_audio_driver_obj(bld, 'portaudio', portaudio_src) - - create_jack_driver_obj(bld, 'net', '../common/JackNetDriver.cpp') - - create_jack_driver_obj(bld, 'netone', [ '../common/JackNetOneDriver.cpp', - '../common/netjack.c', - '../common/netjack_packet.c' ], "SAMPLERATE CELT" ) - - create_jack_driver_obj(bld, 'proxy', '../common/JackProxyDriver.cpp') diff --git a/solaris/wscript b/solaris/wscript deleted file mode 100644 index e3ffc52c..00000000 --- a/solaris/wscript +++ /dev/null @@ -1,39 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 - -def create_jack_driver_obj(bld, target, sources, uselib = None): - driver = bld.new_task_gen('cxx', 'shlib') - driver.features.append('cc') - driver.env['shlib_PATTERN'] = 'jack_%s.so' - #driver.env.append_unique('CXXFLAGS', '-march=i686 -msse3 -ffast-math') - #driver.env.append_unique('CFLAGS', '-march=i686 -msse3 -ffast-math') - driver.defines = 'HAVE_CONFIG_H' - driver.includes = ['.', '..','../posix', '../common', '../common/jack'] - driver.target = target - driver.source = sources - driver.install_path = '${ADDON_DIR}/' - driver.uselib_local = 'serverlib' - if uselib: - driver.uselib = uselib - return driver - -def build(bld): - jackd = bld.new_task_gen('cxx', 'program') - jackd.includes = ['.','..', '../posix', '../common/jack', '../common'] - jackd.defines = 'HAVE_CONFIG_H' - jackd.source = ['../common/Jackdmp.cpp'] - jackd.uselib = 'PTHREAD DL' - jackd.uselib_local = 'serverlib' - jackd.target = 'jackd' - - create_jack_driver_obj(bld, 'oss', ['oss/JackOSSDriver.cpp', '../common/memops.c']) - - create_jack_driver_obj(bld, 'boomer', ['oss/JackBoomerDriver.cpp', '../common/memops.c']) - - create_jack_driver_obj(bld, 'dummy', '../common/JackDummyDriver.cpp') - - create_jack_driver_obj(bld, 'net', '../common/JackNetDriver.cpp') - - create_jack_driver_obj(bld, 'loopback', '../common/JackLoopbackDriver.cpp') - - create_jack_driver_obj(bld, 'proxy', '../common/JackProxyDriver.cpp') @@ -32,7 +32,7 @@ POSSIBILITY OF SUCH DAMAGE. import os, sys, inspect -VERSION="1.8.14" +VERSION="1.8.17" REVISION="x" GIT="x" INSTALL="x" diff --git a/waflib/Build.py b/waflib/Build.py index 154e5c8c..032e15f3 100644 --- a/waflib/Build.py +++ b/waflib/Build.py @@ -44,6 +44,10 @@ POST_LAZY = 1 POST_BOTH = 2 """Post mode: post the task generators at once, then re-check them for each group""" +PROTOCOL = -1 +if sys.platform == 'cli': + PROTOCOL = 0 + class BuildContext(Context.Context): '''executes the build''' @@ -322,7 +326,7 @@ class BuildContext(Context.Context): try: waflib.Node.pickle_lock.acquire() waflib.Node.Nod3 = self.node_class - x = cPickle.dumps(data, -1) + x = cPickle.dumps(data, PROTOCOL) finally: waflib.Node.pickle_lock.release() @@ -821,17 +825,10 @@ class inst(Task.Task): else: y = self.path.find_resource(x) if not y: - if Logs.verbose: - Logs.warn('Could not find %s immediately (may cause broken builds)' % x) - idx = self.generator.bld.get_group_idx(self) - for tg in self.generator.bld.groups[idx]: - if not isinstance(tg, inst) and id(tg) != id(self): - tg.post() - y = self.path.find_resource(x) - if y: - break + if os.path.isabs(x): + y = self.bld.root.make_node(x) else: - raise Errors.WafError('Could not find %r in %r' % (x, self.path)) + y = self.path.make_node(x) buf.append(y) self.inputs = buf @@ -1039,6 +1036,7 @@ class InstallContext(BuildContext): :param postpone: execute the task immediately to perform the installation :type postpone: bool """ + assert(dest) tsk = inst(env=env or self.env) tsk.bld = self tsk.path = cwd or self.path @@ -1075,6 +1073,7 @@ class InstallContext(BuildContext): :param postpone: execute the task immediately to perform the installation :type postpone: bool """ + assert(dest) tsk = inst(env=env or self.env) tsk.bld = self tsk.path = cwd or self.path @@ -1107,11 +1106,11 @@ class InstallContext(BuildContext): :param relative_trick: make the symlink relative (default: ``False``) :type relative_trick: bool """ - if Utils.is_win32: # symlinks *cannot* work on that platform + # TODO waf 1.9 - replace by install_as return - + assert(dest) tsk = inst(env=env or self.env) tsk.bld = self tsk.dest = dest diff --git a/waflib/Configure.py b/waflib/Configure.py index 88468d23..247173c8 100644 --- a/waflib/Configure.py +++ b/waflib/Configure.py @@ -151,14 +151,8 @@ class ConfigurationContext(Context.Context): if ver: app = "%s (%s)" % (app, ver) - now = time.ctime() - pyver = sys.hexversion - systype = sys.platform - args = " ".join(sys.argv) - wafver = Context.WAFVERSION - abi = Context.ABI - self.to_log(conf_template % vars()) - + params = {'now': time.ctime(), 'pyver': sys.hexversion, 'systype': sys.platform, 'args': " ".join(sys.argv), 'wafver': Context.WAFVERSION, 'abi': Context.ABI, 'app': app} + self.to_log(conf_template % params) self.msg('Setting top to', self.srcnode.abspath()) self.msg('Setting out to', self.bldnode.abspath()) @@ -208,17 +202,17 @@ class ConfigurationContext(Context.Context): """ if not env.PREFIX: if Options.options.prefix or Utils.is_win32: - env.PREFIX = os.path.abspath(os.path.expanduser(Options.options.prefix)) + env.PREFIX = Utils.sane_path(Options.options.prefix) else: env.PREFIX = '' if not env.BINDIR: if Options.options.bindir: - env.BINDIR = os.path.abspath(os.path.expanduser(Options.options.bindir)) + env.BINDIR = Utils.sane_path(Options.options.bindir) else: env.BINDIR = Utils.subst_vars('${PREFIX}/bin', env) if not env.LIBDIR: if Options.options.libdir: - env.LIBDIR = os.path.abspath(os.path.expanduser(Options.options.libdir)) + env.LIBDIR = Utils.sane_path(Options.options.libdir) else: env.LIBDIR = Utils.subst_vars('${PREFIX}/lib%s' % Utils.lib64(), env) @@ -347,6 +341,7 @@ def conf(f): if mandatory: raise + fun.__name__ = f.__name__ setattr(ConfigurationContext, f.__name__, fun) setattr(Build.BuildContext, f.__name__, fun) return f @@ -422,7 +417,7 @@ def find_file(self, filename, path_list=[]): """ for n in Utils.to_list(filename): for d in Utils.to_list(path_list): - p = os.path.join(d, n) + p = os.path.expanduser(os.path.join(d, n)) if os.path.exists(p): return p self.fatal('Could not find %r' % filename) @@ -529,7 +524,6 @@ def find_binary(self, filenames, exts, paths): return x return None - @conf def run_build(self, *k, **kw): """ diff --git a/waflib/Context.py b/waflib/Context.py index 70cef85c..b238636a 100644 --- a/waflib/Context.py +++ b/waflib/Context.py @@ -11,13 +11,13 @@ from waflib import Utils, Errors, Logs import waflib.Node # the following 3 constants are updated on each new release (do not touch) -HEXVERSION=0x1080e00 +HEXVERSION=0x1081100 """Constant updated on new releases""" -WAFVERSION="1.8.14" +WAFVERSION="1.8.17" """Constant updated on new releases""" -WAFREVISION="ce8234c396bb246a20ea9f51594ee051d5b378e7" +WAFREVISION="cd7579a727d1b390bf9cbf111c1b20e811370bc0" """Git revision when the waf version is updated""" ABI = 98 @@ -307,6 +307,10 @@ class Context(ctx): elif not node: if not mandatory: continue + try: + os.listdir(d) + except OSError: + raise Errors.WafError('Cannot read the folder %r' % d) raise Errors.WafError('No wscript file in directory %s' % d) def exec_command(self, cmd, **kw): @@ -610,7 +614,7 @@ class Context(ctx): doban = False for b in ban: r = b.replace("*", ".*") - if re.match(b, f): + if re.match(r, f): doban = True if not doban: f = f.replace('.py', '') diff --git a/waflib/Logs.py b/waflib/Logs.py index 8dd2af92..33fd9042 100644 --- a/waflib/Logs.py +++ b/waflib/Logs.py @@ -6,7 +6,7 @@ logging, colors, terminal width and pretty-print """ -import os, re, traceback, sys, types +import os, re, traceback, sys from waflib import Utils, ansiterm if not os.environ.get('NOSYNC', False): @@ -43,6 +43,11 @@ colors_lst = { indicator = '\r\x1b[K%s%s%s' +try: + unicode +except NameError: + unicode = None + def enable_colors(use): if use == 1: if not (sys.stderr.isatty() or sys.stdout.isatty()): @@ -150,7 +155,7 @@ class log_handler(logging.StreamHandler): def emit_override(self, record, **kw): self.terminator = getattr(record, 'terminator', '\n') stream = self.stream - if hasattr(types, "UnicodeType"): + if unicode: # python2 msg = self.formatter.format(record) fs = '%s' + self.terminator @@ -316,7 +321,7 @@ def free_logger(logger): for x in logger.handlers: x.close() logger.removeHandler(x) - except Exception as e: + except Exception: pass def pprint(col, msg, label='', sep='\n'): diff --git a/waflib/Node.py b/waflib/Node.py index b998ff26..fb3cd273 100644 --- a/waflib/Node.py +++ b/waflib/Node.py @@ -59,14 +59,11 @@ Ant patterns for files and folders to exclude while doing the recursive traversal in :py:meth:`waflib.Node.Node.ant_glob` """ -# TODO waf 1.9 -split_path = Utils.split_path_unix +# TODO remove in waf 1.9 +split_path = Utils.split_path +split_path_unix = Utils.split_path_unix split_path_cygwin = Utils.split_path_cygwin split_path_win32 = Utils.split_path_win32 -if sys.platform == 'cygwin': - split_path = split_path_cygwin -elif Utils.is_win32: - split_path = split_path_win32 class Node(object): """ @@ -152,6 +149,69 @@ class Node(object): """ Utils.writef(self.abspath(), data, flags, encoding) + def read_json(self, convert=True, encoding='utf-8'): + """ + Read and parse the contents of this node as JSON:: + + def build(bld): + bld.path.find_node('abc.json').read_json() + + Note that this by default automatically decodes unicode strings on Python2, unlike what the Python JSON module does. + + :type convert: boolean + :param convert: Prevents decoding of unicode strings on Python2 + :type encoding: string + :param encoding: The encoding of the file to read. This default to UTF8 as per the JSON standard + :rtype: object + :return: Parsed file contents + """ + import json # Python 2.6 and up + object_pairs_hook = None + if convert and sys.hexversion < 0x3000000: + try: + _type = unicode + except NameError: + _type = str + + def convert(value): + if isinstance(value, list): + return [convert(element) for element in value] + elif isinstance(value, _type): + return str(value) + else: + return value + + def object_pairs(pairs): + return dict((str(pair[0]), convert(pair[1])) for pair in pairs) + + object_pairs_hook = object_pairs + + return json.loads(self.read(encoding=encoding), object_pairs_hook=object_pairs_hook) + + def write_json(self, data, pretty=True): + """ + Writes a python object as JSON to disk. Files are always written as UTF8 as per the JSON standard:: + + def build(bld): + bld.path.find_node('xyz.json').write_json(199) + + :type data: object + :param data: The data to write to disk + :type pretty: boolean + :param pretty: Determines if the JSON will be nicely space separated + """ + import json # Python 2.6 and up + indent = 2 + separators = (',', ': ') + sort_keys = pretty + newline = os.linesep + if not pretty: + indent = None + separators = (',', ':') + newline = '' + output = json.dumps(data, indent=indent, separators=separators, sort_keys=sort_keys) + newline + self.write(output, encoding='utf-8') + def chmod(self, val): """ Change file/dir permissions:: @@ -251,7 +311,7 @@ class Node(object): cur.children = self.dict_class() else: try: - cur = cur.children[x] + cur = ch[x] continue except KeyError: pass diff --git a/waflib/Options.py b/waflib/Options.py index f11fe3e3..fe2121e3 100644 --- a/waflib/Options.py +++ b/waflib/Options.py @@ -256,7 +256,7 @@ class OptionsContext(Context.Context): commands.append(arg) if options.destdir: - options.destdir = os.path.abspath(os.path.expanduser(options.destdir)) + options.destdir = Utils.sane_path(options.destdir) if options.verbose >= 1: self.load('errcheck') diff --git a/waflib/Runner.py b/waflib/Runner.py index db3c3ed3..b3087292 100644 --- a/waflib/Runner.py +++ b/waflib/Runner.py @@ -278,6 +278,13 @@ class Parallel(object): :param tsk: task :type tsk: :py:attr:`waflib.Task.TaskBase` """ + if hasattr(tsk, 'scan') and hasattr(tsk, 'uid'): + # TODO waf 1.9 - this breaks encapsulation + key = (tsk.uid(), 'imp') + try: + del self.bld.task_sigs[key] + except KeyError: + pass if not self.bld.keep: self.stop = True self.error.append(tsk) diff --git a/waflib/Scripting.py b/waflib/Scripting.py index 832e3573..a2839a1f 100644 --- a/waflib/Scripting.py +++ b/waflib/Scripting.py @@ -46,6 +46,7 @@ def waf_entry_point(current_directory, version, wafdir): # perhaps extract 'wscript' as a constant if os.path.basename(potential_wscript) == 'wscript' and os.path.isfile(potential_wscript): # need to explicitly normalize the path, as it may contain extra '/.' + # TODO abspath? current_directory = os.path.normpath(os.path.dirname(potential_wscript)) sys.argv.pop(1) @@ -62,11 +63,14 @@ def waf_entry_point(current_directory, version, wafdir): break # if --top is provided assume the build started in the top directory - for x in sys.argv: + for i, x in enumerate(sys.argv): + # WARNING: this modifies sys.argv if x.startswith('--top='): - Context.run_dir = Context.top_dir = x[6:] + Context.run_dir = Context.top_dir = Utils.sane_path(x[6:]) + sys.argv[i] = '--top=' + Context.run_dir if x.startswith('--out='): - Context.out_dir = x[6:] + Context.out_dir = Utils.sane_path(x[6:]) + sys.argv[i] = '--out=' + Context.out_dir # try to find a lock file (if the project was configured) # at the same time, store the first wscript file seen @@ -137,7 +141,7 @@ def waf_entry_point(current_directory, version, wafdir): sys.exit(1) try: - set_main_module(os.path.join(Context.run_dir, Context.WSCRIPT_FILE)) + set_main_module(os.path.normpath(os.path.join(Context.run_dir, Context.WSCRIPT_FILE))) except Errors.WafError as e: Logs.pprint('RED', e.verbose_msg) Logs.error(str(e)) diff --git a/waflib/Task.py b/waflib/Task.py index 326ac303..b8475670 100644 --- a/waflib/Task.py +++ b/waflib/Task.py @@ -37,11 +37,14 @@ SKIP_ME = -2 RUN_ME = -3 """The task must be executed""" +# To save some memory during the build, consider discarding tsk.last_cmd in the two templates below + COMPILE_TEMPLATE_SHELL = ''' def f(tsk): env = tsk.env gen = tsk.generator bld = gen.bld + cwdx = getattr(bld, 'cwdx', bld.bldnode) # TODO single cwd value in waf 1.9 wd = getattr(tsk, 'cwd', None) p = env.get_flat tsk.last_cmd = cmd = \'\'\' %s \'\'\' % s @@ -53,6 +56,7 @@ def f(tsk): env = tsk.env gen = tsk.generator bld = gen.bld + cwdx = getattr(bld, 'cwdx', bld.bldnode) # TODO single cwd value in waf 1.9 wd = getattr(tsk, 'cwd', None) def to_list(xx): if isinstance(xx, str): return [xx] @@ -81,11 +85,10 @@ class store_task_type(type): name = name.replace('_task', '') if name != 'evil' and name != 'TaskBase': global classes - if getattr(cls, 'run_str', None): # if a string is provided, convert it to a method (f, dvars) = compile_fun(cls.run_str, cls.shell) - cls.hcode = cls.run_str + cls.hcode = Utils.h_cmd(cls.run_str) cls.orig_run_str = cls.run_str # change the name of run_str or it is impossible to subclass with a function cls.run_str = None @@ -94,10 +97,7 @@ class store_task_type(type): cls.vars.sort() elif getattr(cls, 'run', None) and not 'hcode' in cls.__dict__: # getattr(cls, 'hcode') would look in the upper classes - cls.hcode = Utils.h_fun(cls.run) - - if sys.hexversion > 0x3000000: - cls.hcode = cls.hcode.encode('iso8859-1', 'xmlcharrefreplace') + cls.hcode = Utils.h_cmd(cls.run) # be creative getattr(cls, 'register', classes)[name] = cls @@ -206,6 +206,7 @@ class TaskBase(evil): # remove the task signature immediately before it is executed # in case of failure the task will be executed again try: + # TODO waf 1.9 - this breaks encapsulation del self.generator.bld.task_sigs[self.uid()] except KeyError: pass @@ -972,17 +973,17 @@ def compile_fun_shell(line): for (var, meth) in extr: if var == 'SRC': if meth: app('tsk.inputs%s' % meth) - else: app('" ".join([a.path_from(bld.bldnode) for a in tsk.inputs])') + else: app('" ".join([a.path_from(cwdx) for a in tsk.inputs])') elif var == 'TGT': if meth: app('tsk.outputs%s' % meth) - else: app('" ".join([a.path_from(bld.bldnode) for a in tsk.outputs])') + else: app('" ".join([a.path_from(cwdx) for a in tsk.outputs])') elif meth: if meth.startswith(':'): m = meth[1:] if m == 'SRC': - m = '[a.path_from(bld.bldnode) for a in tsk.inputs]' + m = '[a.path_from(cwdx) for a in tsk.inputs]' elif m == 'TGT': - m = '[a.path_from(bld.bldnode) for a in tsk.outputs]' + m = '[a.path_from(cwdx) for a in tsk.outputs]' elif m[:3] not in ('tsk', 'gen', 'bld'): dvars.extend([var, meth[1:]]) m = '%r' % m @@ -1027,17 +1028,17 @@ def compile_fun_noshell(line): (var, meth) = extr[x] if var == 'SRC': if meth: app('lst.append(tsk.inputs%s)' % meth) - else: app("lst.extend([a.path_from(bld.bldnode) for a in tsk.inputs])") + else: app("lst.extend([a.path_from(cwdx) for a in tsk.inputs])") elif var == 'TGT': if meth: app('lst.append(tsk.outputs%s)' % meth) - else: app("lst.extend([a.path_from(bld.bldnode) for a in tsk.outputs])") + else: app("lst.extend([a.path_from(cwdx) for a in tsk.outputs])") elif meth: if meth.startswith(':'): m = meth[1:] if m == 'SRC': - m = '[a.path_from(bld.bldnode) for a in tsk.inputs]' + m = '[a.path_from(cwdx) for a in tsk.inputs]' elif m == 'TGT': - m = '[a.path_from(bld.bldnode) for a in tsk.outputs]' + m = '[a.path_from(cwdx) for a in tsk.outputs]' elif m[:3] not in ('tsk', 'gen', 'bld'): dvars.extend([var, m]) m = '%r' % m @@ -1074,9 +1075,27 @@ def compile_fun(line, shell=False): The reserved keywords *TGT* and *SRC* represent the task input and output nodes """ - if line.find('<') > 0 or line.find('>') > 0 or line.find('&&') > 0: - shell = True - + if isinstance(line, str): + if line.find('<') > 0 or line.find('>') > 0 or line.find('&&') > 0: + shell = True + else: + dvars_lst = [] + funs_lst = [] + for x in line: + if isinstance(x, str): + fun, dvars = compile_fun(x, shell) + dvars_lst += dvars + funs_lst.append(fun) + else: + # assume a function to let through + funs_lst.append(x) + def composed_fun(task): + for x in funs_lst: + ret = x(task) + if ret: + return ret + return None + return composed_fun, dvars if shell: return compile_fun_shell(line) else: @@ -1111,7 +1130,7 @@ def task_factory(name, func=None, vars=None, color='GREEN', ext_in=[], ext_out=[ 'scan': scan, } - if isinstance(func, str): + if isinstance(func, str) or isinstance(func, tuple): params['run_str'] = func else: params['run'] = func diff --git a/waflib/TaskGen.py b/waflib/TaskGen.py index 44aa25d5..b897e077 100644 --- a/waflib/TaskGen.py +++ b/waflib/TaskGen.py @@ -564,7 +564,15 @@ def process_rule(self): except KeyError: pass if not cls: - cls = Task.task_factory(name, self.rule, + + rule = self.rule + if hasattr(self, 'chmod'): + def chmod_fun(tsk): + for x in tsk.outputs: + os.chmod(x.abspath(), self.chmod) + rule = (self.rule, chmod_fun) + + cls = Task.task_factory(name, rule, getattr(self, 'vars', []), shell=getattr(self, 'shell', True), color=getattr(self, 'color', 'BLUE'), scan = getattr(self, 'scan', None)) @@ -614,7 +622,7 @@ def process_rule(self): x.parent.mkdir() # if a node was given, create the required folders tsk.outputs.append(x) if getattr(self, 'install_path', None): - self.bld.install_files(self.install_path, tsk.outputs) + self.bld.install_files(self.install_path, tsk.outputs, chmod=getattr(self, 'chmod', Utils.O644)) if getattr(self, 'source', None): tsk.inputs = self.to_nodes(self.source) @@ -669,24 +677,34 @@ class subst_pc(Task.Task): in the substitution changes. """ + def force_permissions(self): + "Private for the time being, we will probably refactor this into run_str=[run1,chmod]" + if getattr(self.generator, 'chmod', None): + for x in self.outputs: + os.chmod(x.abspath(), self.generator.chmod) + def run(self): "Substitutes variables in a .in file" if getattr(self.generator, 'is_copy', None): - self.outputs[0].write(self.inputs[0].read('rb'), 'wb') - if getattr(self.generator, 'chmod', None): - os.chmod(self.outputs[0].abspath(), self.generator.chmod) + for i, x in enumerate(self.outputs): + x.write(self.inputs[i].read('rb'), 'wb') + self.force_permissions() return None if getattr(self.generator, 'fun', None): - return self.generator.fun(self) + ret = self.generator.fun(self) + if not ret: + self.force_permissions() + return ret code = self.inputs[0].read(encoding=getattr(self.generator, 'encoding', 'ISO8859-1')) if getattr(self.generator, 'subst_fun', None): code = self.generator.subst_fun(self, code) if code is not None: self.outputs[0].write(code, encoding=getattr(self.generator, 'encoding', 'ISO8859-1')) - return + self.force_permissions() + return None # replace all % by %% to prevent errors by % signs code = code.replace('%', '%%') @@ -722,8 +740,7 @@ class subst_pc(Task.Task): try: delattr(self, 'cache_sig') except AttributeError: pass - if getattr(self.generator, 'chmod', None): - os.chmod(self.outputs[0].abspath(), self.generator.chmod) + self.force_permissions() def sig_vars(self): """ @@ -816,7 +833,7 @@ def process_subst(self): b = y if not a: - raise Errors.WafError('cound not find %r for %r' % (x, self)) + raise Errors.WafError('could not find %r for %r' % (x, self)) has_constraints = False tsk = self.create_task('subst', a, b) diff --git a/waflib/Tools/c_aliases.py b/waflib/Tools/c_aliases.py index 4bb6352e..0747abf5 100644 --- a/waflib/Tools/c_aliases.py +++ b/waflib/Tools/c_aliases.py @@ -4,8 +4,7 @@ "base for all c/c++ programs and libraries" -import os, sys, re -from waflib import Utils, Build, Errors +from waflib import Utils, Errors from waflib.Configure import conf def get_extensions(lst): @@ -49,7 +48,7 @@ def sniff_features(**kw): feats.append('cxx') break - if 'c' in exts or 'vala' in exts: + if 'c' in exts or 'vala' in exts or 'gs' in exts: feats.append('c') for x in 'f f90 F F90 for FOR'.split(): @@ -71,7 +70,7 @@ def sniff_features(**kw): feats.append(x + type) will_link = True if not will_link and not kw.get('features', []): - raise Errors.WafError('Cannot link from %r, try passing eg: features="cprogram"?' % kw) + raise Errors.WafError('Cannot link from %r, try passing eg: features="c cprogram"?' % kw) return feats def set_features(kw, _type): diff --git a/waflib/Tools/c_config.py b/waflib/Tools/c_config.py index 14243cd8..f114dffb 100644 --- a/waflib/Tools/c_config.py +++ b/waflib/Tools/c_config.py @@ -6,7 +6,7 @@ C/C++/D configuration helpers """ -import os, re, shlex, sys +import os, re, shlex from waflib import Build, Utils, Task, Options, Logs, Errors, Runner from waflib.TaskGen import after_method, feature from waflib.Configure import conf @@ -288,11 +288,11 @@ def exec_cfg(self, kw): """ path = Utils.to_list(kw['path']) - + env = self.env.env or None def define_it(): pkgname = kw.get('uselib_store', kw['package'].upper()) if kw.get('global_define'): - # compatibility + # compatibility, replace by pkgname in WAF 1.9? self.define(self.have_define(kw['package']), 1, False) else: self.env.append_unique('DEFINES_%s' % pkgname, "%s=1" % self.have_define(pkgname)) @@ -301,7 +301,7 @@ def exec_cfg(self, kw): # pkg-config version if 'atleast_pkgconfig_version' in kw: cmd = path + ['--atleast-pkgconfig-version=%s' % kw['atleast_pkgconfig_version']] - self.cmd_and_log(cmd) + self.cmd_and_log(cmd, env=env) if not 'okmsg' in kw: kw['okmsg'] = 'yes' return @@ -310,7 +310,7 @@ def exec_cfg(self, kw): for x in cfg_ver: y = x.replace('-', '_') if y in kw: - self.cmd_and_log(path + ['--%s=%s' % (x, kw[y]), kw['package']]) + self.cmd_and_log(path + ['--%s=%s' % (x, kw[y]), kw['package']], env=env) if not 'okmsg' in kw: kw['okmsg'] = 'yes' define_it() @@ -318,7 +318,7 @@ def exec_cfg(self, kw): # retrieving the version of a module if 'modversion' in kw: - version = self.cmd_and_log(path + ['--modversion', kw['modversion']]).strip() + version = self.cmd_and_log(path + ['--modversion', kw['modversion']], env=env).strip() self.define('%s_VERSION' % Utils.quote_define_name(kw.get('uselib_store', kw['modversion'])), version) return version @@ -342,19 +342,19 @@ def exec_cfg(self, kw): # retrieving variables of a module if 'variables' in kw: - env = kw.get('env', self.env) + v = kw.get('env', self.env) uselib = kw.get('uselib_store', kw['package'].upper()) vars = Utils.to_list(kw['variables']) for v in vars: - val = self.cmd_and_log(lst + ['--variable=' + v]).strip() + val = self.cmd_and_log(lst + ['--variable=' + v], env=env).strip() var = '%s_%s' % (uselib, v) - env[var] = val + v[var] = val if not 'okmsg' in kw: kw['okmsg'] = 'yes' return # so we assume the command-line will output flags to be parsed afterwards - ret = self.cmd_and_log(lst) + ret = self.cmd_and_log(lst, env=env) if not 'okmsg' in kw: kw['okmsg'] = 'yes' @@ -482,7 +482,10 @@ def validate_c(self, kw): kw['type'] = 'cprogram' if not 'features' in kw: - kw['features'] = [kw['compile_mode'], kw['type']] # "cprogram c" + if not 'header_name' in kw or kw.get('link_header_test', True): + kw['features'] = [kw['compile_mode'], kw['type']] # "c ccprogram" + else: + kw['features'] = [kw['compile_mode']] else: kw['features'] = Utils.to_list(kw['features']) @@ -604,6 +607,11 @@ def validate_c(self, kw): if self.env[INCKEYS]: kw['code'] = '\n'.join(['#include <%s>' % x for x in self.env[INCKEYS]]) + '\n' + kw['code'] + # in case defines lead to very long command-lines + if kw.get('merge_config_header', False) or env.merge_config_header: + kw['code'] = '%s\n\n%s' % (self.get_config_header(), kw['code']) + env.DEFINES = [] # modify the copy + if not kw.get('success'): kw['success'] = None if 'define_name' in kw: @@ -626,7 +634,7 @@ def post_check(self, *k, **kw): is_success = (kw['success'] == 0) if 'define_name' in kw: - # TODO simplify? + # TODO simplify! if 'header_name' in kw or 'function_name' in kw or 'type_name' in kw or 'fragment' in kw: if kw['execute'] and kw.get('define_ret', None) and isinstance(is_success, str): self.define(kw['define_name'], is_success, quote=kw.get('quote', 1)) @@ -635,6 +643,10 @@ def post_check(self, *k, **kw): else: self.define_cond(kw['define_name'], is_success) + # consistency with check_cfg + if kw.get('global_define', None): + self.env[kw['define_name']] = is_success + if 'header_name' in kw: if kw.get('auto_add_header_name', False): self.env.append_value(INCKEYS, Utils.to_list(kw['header_name'])) diff --git a/waflib/Tools/c_osx.py b/waflib/Tools/c_osx.py index 2b3c6474..4337cc68 100644 --- a/waflib/Tools/c_osx.py +++ b/waflib/Tools/c_osx.py @@ -6,8 +6,8 @@ MacOSX related tools """ -import os, shutil, sys, platform -from waflib import TaskGen, Task, Build, Options, Utils, Errors +import os, shutil, platform +from waflib import Task, Utils, Errors from waflib.TaskGen import taskgen_method, feature, after_method, before_method app_info = ''' @@ -48,7 +48,6 @@ def create_bundle_dirs(self, name, out): """ Create bundle folders, used by :py:func:`create_task_macplist` and :py:func:`create_task_macapp` """ - bld = self.bld dir = out.parent.find_or_declare(name) dir.mkdir() macos = dir.find_or_declare(['Contents', 'MacOS']) @@ -102,7 +101,7 @@ def create_task_macapp(self): inst_to = getattr(self, 'install_path', '/Applications') + '/%s/Resources' % name for node in self.to_nodes(self.mac_files): relpath = node.path_from(mac_files_root or node.parent) - tsk = self.create_task('macapp', node, res_dir.make_node(relpath)) + self.create_task('macapp', node, res_dir.make_node(relpath)) self.bld.install_as(os.path.join(inst_to, relpath), node) if getattr(self, 'mac_resources', None): @@ -121,7 +120,7 @@ def create_task_macapp(self): nodes = [node] for node in nodes: rel = node.path_from(parent) - tsk = self.create_task('macapp', node, res_dir.make_node(rel)) + self.create_task('macapp', node, res_dir.make_node(rel)) self.bld.install_as(inst_to + '/%s' % rel, node) if getattr(self.bld, 'is_install', None): diff --git a/waflib/Tools/c_tests.py b/waflib/Tools/c_tests.py index 2888828d..3b37f54c 100644 --- a/waflib/Tools/c_tests.py +++ b/waflib/Tools/c_tests.py @@ -9,7 +9,6 @@ Various configuration tests. from waflib import Task from waflib.Configure import conf from waflib.TaskGen import feature, before_method, after_method -import sys LIB_CODE = ''' #ifdef _MSC_VER diff --git a/waflib/Tools/ccroot.py b/waflib/Tools/ccroot.py index 363d18d1..7fb53bba 100644 --- a/waflib/Tools/ccroot.py +++ b/waflib/Tools/ccroot.py @@ -25,8 +25,8 @@ USELIB_VARS['cxx'] = set(['INCLUDES', 'FRAMEWORKPATH', 'DEFINES', 'CPPFLAGS USELIB_VARS['d'] = set(['INCLUDES', 'DFLAGS']) USELIB_VARS['includes'] = set(['INCLUDES', 'FRAMEWORKPATH', 'ARCH']) -USELIB_VARS['cprogram'] = USELIB_VARS['cxxprogram'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS', 'FRAMEWORK', 'FRAMEWORKPATH', 'ARCH']) -USELIB_VARS['cshlib'] = USELIB_VARS['cxxshlib'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS', 'FRAMEWORK', 'FRAMEWORKPATH', 'ARCH']) +USELIB_VARS['cprogram'] = USELIB_VARS['cxxprogram'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS', 'FRAMEWORK', 'FRAMEWORKPATH', 'ARCH', 'LDFLAGS']) +USELIB_VARS['cshlib'] = USELIB_VARS['cxxshlib'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS', 'FRAMEWORK', 'FRAMEWORKPATH', 'ARCH', 'LDFLAGS']) USELIB_VARS['cstlib'] = USELIB_VARS['cxxstlib'] = set(['ARFLAGS', 'LINKDEPS']) USELIB_VARS['dprogram'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS']) @@ -158,7 +158,10 @@ class link_task(Task.Task): if len(nums) >= 2: pattern += '.%s' % nums[1] - tmp = folder + os.sep + pattern % name + if folder: + tmp = folder + os.sep + pattern % name + else: + tmp = pattern % name target = self.generator.path.find_or_declare(tmp) self.set_outputs(target) diff --git a/waflib/Tools/clang.py b/waflib/Tools/clang.py index 0740e00b..2259c5df 100644 --- a/waflib/Tools/clang.py +++ b/waflib/Tools/clang.py @@ -6,7 +6,6 @@ Detect the Clang C compiler """ -import os, sys from waflib.Tools import ccroot, ar, gcc from waflib.Configure import conf diff --git a/waflib/Tools/clangxx.py b/waflib/Tools/clangxx.py index b52fc352..b539b287 100644 --- a/waflib/Tools/clangxx.py +++ b/waflib/Tools/clangxx.py @@ -6,7 +6,6 @@ Detect the Clang++ C++ compiler """ -import os, sys from waflib.Tools import ccroot, ar, gxx from waflib.Configure import conf diff --git a/waflib/Tools/compiler_c.py b/waflib/Tools/compiler_c.py index 69c808f2..7d4e22ca 100644 --- a/waflib/Tools/compiler_c.py +++ b/waflib/Tools/compiler_c.py @@ -30,9 +30,9 @@ Not all compilers need to have a specific tool. For example, the clang compilers $ CC=clang waf configure """ -import os, sys, imp, types, re +import re from waflib.Tools import ccroot -from waflib import Utils, Configure +from waflib import Utils from waflib.Logs import debug c_compiler = { diff --git a/waflib/Tools/compiler_cxx.py b/waflib/Tools/compiler_cxx.py index 4b15b9e3..6f0ea9ea 100644 --- a/waflib/Tools/compiler_cxx.py +++ b/waflib/Tools/compiler_cxx.py @@ -31,9 +31,9 @@ Not all compilers need to have a specific tool. For example, the clang compilers """ -import os, sys, imp, types, re +import re from waflib.Tools import ccroot -from waflib import Utils, Configure +from waflib import Utils from waflib.Logs import debug cxx_compiler = { diff --git a/waflib/Tools/errcheck.py b/waflib/Tools/errcheck.py index 14ce28fb..1f548aca 100644 --- a/waflib/Tools/errcheck.py +++ b/waflib/Tools/errcheck.py @@ -22,6 +22,7 @@ typos = { meths_typos = ['__call__', 'program', 'shlib', 'stlib', 'objects'] +import sys from waflib import Logs, Build, Node, Task, TaskGen, ConfigSet, Errors, Utils import waflib.Tools.ccroot @@ -84,6 +85,9 @@ def check_invalid_constraints(self): # the build scripts have been read, so we can check for invalid after/before attributes on task classes for cls in list(Task.classes.values()): + if sys.hexversion > 0x3000000 and issubclass(cls, Task.Task) and isinstance(cls.hcode, str): + raise Errors.WafError('Class %r has hcode value %r of type <str>, expecting <bytes> (use Utils.h_cmd() ?)' % (cls, cls.hcode)) + for x in ('before', 'after'): for y in Utils.to_list(getattr(cls, x, [])): if not Task.classes.get(y, None): @@ -103,7 +107,6 @@ def replace(m): if x in kw: if x == 'iscopy' and 'subst' in getattr(self, 'features', ''): continue - err = True Logs.error('Fix the typo %r -> %r on %r' % (x, typos[x], ret)) return ret setattr(Build.BuildContext, m, call) diff --git a/waflib/Tools/gcc.py b/waflib/Tools/gcc.py index 741a2e3f..0b897c7d 100644 --- a/waflib/Tools/gcc.py +++ b/waflib/Tools/gcc.py @@ -8,8 +8,6 @@ gcc/llvm detection. """ -import os, sys -from waflib import Configure, Options, Utils from waflib.Tools import ccroot, ar from waflib.Configure import conf diff --git a/waflib/Tools/gxx.py b/waflib/Tools/gxx.py index 4c89273b..9cf52070 100644 --- a/waflib/Tools/gxx.py +++ b/waflib/Tools/gxx.py @@ -8,8 +8,6 @@ g++/llvm detection. """ -import os, sys -from waflib import Configure, Options, Utils from waflib.Tools import ccroot, ar from waflib.Configure import conf diff --git a/waflib/Tools/icc.py b/waflib/Tools/icc.py index c50d4995..f3395030 100644 --- a/waflib/Tools/icc.py +++ b/waflib/Tools/icc.py @@ -7,7 +7,7 @@ Detect the Intel C compiler """ -import os, sys +import sys from waflib.Tools import ccroot, ar, gcc from waflib.Configure import conf diff --git a/waflib/Tools/icpc.py b/waflib/Tools/icpc.py index ec1320ed..03603d44 100644 --- a/waflib/Tools/icpc.py +++ b/waflib/Tools/icpc.py @@ -6,7 +6,7 @@ Detect the Intel C++ compiler """ -import os, sys +import sys from waflib.Tools import ccroot, ar, gxx from waflib.Configure import conf diff --git a/waflib/Tools/irixcc.py b/waflib/Tools/irixcc.py index be90eee0..55eb70be 100644 --- a/waflib/Tools/irixcc.py +++ b/waflib/Tools/irixcc.py @@ -6,8 +6,6 @@ compiler definition for irix/MIPSpro cc compiler based on suncc.py from waf """ -import os -from waflib import Utils from waflib.Tools import ccroot, ar from waflib.Configure import conf diff --git a/waflib/Tools/msvc.py b/waflib/Tools/msvc.py index c220f3f9..d98432e0 100644 --- a/waflib/Tools/msvc.py +++ b/waflib/Tools/msvc.py @@ -194,10 +194,14 @@ echo LIB=%%LIB%%;%%LIBPATH%% try: try: conf.cmd_and_log(cxx + ['/help'], env=env) + except UnicodeError: + st = Utils.ex_stack() + if conf.logger: + conf.logger.error(st) + conf.fatal('msvc: Unicode error - check the code page?') except Exception as e: - debug('msvc: get_msvc_version: %r %r %r -> failure' % (compiler, version, target)) - debug(str(e)) - conf.fatal('msvc: cannot run the compiler (in get_msvc_version)') + debug('msvc: get_msvc_version: %r %r %r -> failure %s' % (compiler, version, target, str(e))) + conf.fatal('msvc: cannot run the compiler in get_msvc_version (run with -v to display errors)') else: debug('msvc: get_msvc_version: %r %r %r -> OK', compiler, version, target) finally: @@ -235,7 +239,7 @@ def gather_wsdk_versions(conf, versions): path,type = Utils.winreg.QueryValueEx(msvc_version,'InstallationFolder') except WindowsError: continue - if os.path.isfile(os.path.join(path, 'bin', 'SetEnv.cmd')): + if path and os.path.isfile(os.path.join(path, 'bin', 'SetEnv.cmd')): targets = [] for target,arch in all_msvc_platforms: try: @@ -328,8 +332,8 @@ def get_compiler_env(conf, compiler, version, bat_target, bat, select=None): """ Gets the compiler environment variables as a tuple. Evaluation is eager by default. If set to lazy with ``--msvc_lazy_autodetect`` or ``env.MSVC_LAZY_AUTODETECT`` - the environment is evaluated when the tuple is destructured or iterated. This means - destructuring can throw :py:class:`conf.errors.ConfigurationError`. + the environment is evaluated when the tuple is destructured or iterated. This means + destructuring can throw :py:class:`conf.errors.ConfigurationError`. :param conf: configuration context to use to eventually get the version environment :param compiler: compiler name @@ -350,26 +354,26 @@ def get_compiler_env(conf, compiler, version, bat_target, bat, select=None): class lazytup(object): """ A tuple that evaluates its elements from a function when iterated or destructured. - + :param fn: thunk to evaluate the tuple on demand :param lazy: whether to delay evaluation or evaluate in the constructor :param default: optional default for :py:func:`repr` if it should not evaluate """ - def __init__(self, fn, lazy=True, default=None): + def __init__(self, fn, lazy=True, default=None): self.fn = fn self.default = default if not lazy: self.evaluate() - def __len__(self): + def __len__(self): self.evaluate() - return len(self.value) - def __iter__(self): + return len(self.value) + def __iter__(self): self.evaluate() - for i, v in enumerate(self.value): - yield v - def __getitem__(self, i): + for i, v in enumerate(self.value): + yield v + def __getitem__(self, i): self.evaluate() - return self.value[i] + return self.value[i] def __repr__(self): if hasattr(self, 'value'): return repr(self.value) @@ -594,9 +598,9 @@ def gather_intel_composer_versions(conf, versions): if (r'if exist "%VS110COMNTOOLS%..\IDE\VSWinExpress.exe"' in Utils.readf(compilervars_arch) and not os.path.exists(vs_express_path) and not os.path.exists(dev_env_path)): Logs.warn(('The Intel compilervar_arch.bat only checks for one Visual Studio SKU ' - '(VSWinExpress.exe) but it does not seem to be installed at %r. ' - 'The intel command line set up will fail to configure unless the file %r' - 'is patched. See: %s') % (vs_express_path, compilervars_arch, patch_url)) + '(VSWinExpress.exe) but it does not seem to be installed at %r. ' + 'The intel command line set up will fail to configure unless the file %r' + 'is patched. See: %s') % (vs_express_path, compilervars_arch, patch_url)) except WindowsError: pass major = version[0:2] @@ -833,9 +837,6 @@ def find_msvc(conf): v.MSVC_MANIFEST = (compiler == 'msvc' and version >= 8) or (compiler == 'wsdk' and version >= 6) or (compiler == 'intel' and version >= 11) # compiler - cxx = None - if v['CXX']: cxx = v['CXX'] - elif 'CXX' in conf.environ: cxx = conf.environ['CXX'] cxx = conf.find_program(compiler_name, var='CXX', path_list=path) # before setting anything, check if the compiler is really msvc diff --git a/waflib/Utils.py b/waflib/Utils.py index 25f91c70..3d981ac7 100644 --- a/waflib/Utils.py +++ b/waflib/Utils.py @@ -409,10 +409,25 @@ def split_path_win32(path): return ret return re.split(re_sp, path) +msysroot = None +def split_path_msys(path): + if (path.startswith('/') or path.startswith('\\')) and not path.startswith('//') and not path.startswith('\\\\'): + # msys paths can be in the form /usr/bin + global msysroot + if not msysroot: + # msys has python 2.7 or 3, so we can use this + msysroot = subprocess.check_output(['cygpath', '-w', '/']).decode(sys.stdout.encoding or 'iso8859-1') + msysroot = msysroot.strip() + path = os.path.normpath(msysroot + os.sep + path) + return split_path_win32(path) + if sys.platform == 'cygwin': split_path = split_path_cygwin elif is_win32: - split_path = split_path_win32 + if os.environ.get('MSYSTEM', None): + split_path = split_path_msys + else: + split_path = split_path_win32 else: split_path = split_path_unix @@ -441,6 +456,7 @@ def check_dir(path): def check_exe(name, env=None): """ Ensure that a program exists + :type name: string :param name: name or path to program :return: path of the program or None @@ -523,6 +539,25 @@ def h_fun(fun): pass return h +def h_cmd(ins): + """ + Task command hashes are calculated by calling this function. The inputs can be + strings, functions, tuples/lists containing strings/functions + """ + # this function is not meant to be particularly fast + if isinstance(ins, str): + # a command is either a string + ret = ins + elif isinstance(ins, list) or isinstance(ins, tuple): + # or a list of functions/strings + ret = str([h_cmd(x) for x in ins]) + else: + # or just a python function + ret = str(h_fun(ins)) + if sys.hexversion > 0x3000000: + ret = ret.encode('iso8859-1', 'xmlcharrefreplace') + return ret + reg_subst = re.compile(r"(\\\\)|(\$\$)|\$\{([^}]+)\}") def subst_vars(expr, params): """ @@ -545,6 +580,8 @@ def subst_vars(expr, params): return params.get_flat(m.group(3)) except AttributeError: return params[m.group(3)] + # if you get a TypeError, it means that 'expr' is not a string... + # Utils.subst_vars(None, env) will not work return reg_subst.sub(repl_var, expr) def destos_to_binfmt(key): @@ -595,6 +632,9 @@ def unversioned_sys_platform(): return 'darwin' if s == 'win32' or s == 'os2': return s + if s == 'cli' and os.name == 'nt': + # ironpython is only on windows as far as we know + return 'win32' return re.split('\d+$', s)[0] def nada(*k, **kw): @@ -709,6 +749,7 @@ def run_once(fun): cache[k] = ret return ret wrap.__cache__ = cache + wrap.__name__ = fun.__name__ return wrap def get_registry_app_path(key, filename): @@ -730,3 +771,7 @@ def lib64(): return '64' return '' +def sane_path(p): + # private function for the time being! + return os.path.abspath(os.path.expanduser(p)) + diff --git a/waflib/extras/build_logs.py b/waflib/extras/build_logs.py index 9c7c9cd6..9209ec33 100644 --- a/waflib/extras/build_logs.py +++ b/waflib/extras/build_logs.py @@ -10,7 +10,7 @@ A system for recording all outputs to a log file. Just add the following to your """ import atexit, sys, time, os, shutil, threading -from waflib import Logs, Context +from waflib import ansiterm, Logs, Context # adding the logs under the build/ directory will clash with the clean/ command try: @@ -68,8 +68,12 @@ def init(ctx): # sys.stdout has already been replaced, so __stdout__ will be faster #sys.stdout = log_to_file(sys.stdout, fileobj, filename) #sys.stderr = log_to_file(sys.stderr, fileobj, filename) - sys.stdout = log_to_file(sys.__stdout__, fileobj, filename) - sys.stderr = log_to_file(sys.__stderr__, fileobj, filename) + def wrap(stream): + if stream.isatty(): + return ansiterm.AnsiTerm(stream) + return stream + sys.stdout = log_to_file(wrap(sys.__stdout__), fileobj, filename) + sys.stderr = log_to_file(wrap(sys.__stderr__), fileobj, filename) # now mess with the logging module... for x in Logs.log.handlers: diff --git a/waflib/extras/c_bgxlc.py b/waflib/extras/c_bgxlc.py index 89a7ec16..6e3eaf7b 100644 --- a/waflib/extras/c_bgxlc.py +++ b/waflib/extras/c_bgxlc.py @@ -6,7 +6,6 @@ IBM XL Compiler for Blue Gene """ -import os from waflib.Tools import ccroot,ar from waflib.Configure import conf diff --git a/waflib/extras/c_nec.py b/waflib/extras/c_nec.py index 04b6aae6..87e0c055 100644 --- a/waflib/extras/c_nec.py +++ b/waflib/extras/c_nec.py @@ -6,7 +6,6 @@ NEC SX Compiler for SX vector systems """ -import os import re from waflib import Utils from waflib.Tools import ccroot,ar diff --git a/windows/wscript b/windows/wscript deleted file mode 100644 index 944a80de..00000000 --- a/windows/wscript +++ /dev/null @@ -1,69 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 - -def create_jack_driver_obj(bld, target, sources, uselib = None): - driver = bld(features = ['c', 'cxx', 'cxxshlib', 'cshlib']) - driver.env['cxxshlib_PATTERN'] = 'jack_%s.dll' - driver.defines = ['HAVE_CONFIG_H','SERVER_SIDE'] - driver.includes = ['.', '..' , '../windows', '../common', '../common/jack'] - driver.target = target - driver.source = sources - driver.install_path = '${ADDON_DIR}/' - driver.use = ['serverlib'] - if uselib: - driver.use += uselib - return driver - -def build(bld): - if bld.env['BUILD_JACKD'] == True: - jackd = bld(features = ['cxx', 'cxxprogram']) - jackd.includes = ['..', '../windows', '../common/jack', '../common', '../dbus'] - jackd.defines = ['HAVE_CONFIG_H','SERVER_SIDE'] - jackd.source = ['../common/Jackdmp.cpp'] - jackd.install_path = '${BINDIR}' - jackd.use = ['serverlib'] - jackd.target = 'jackd' - - create_jack_driver_obj(bld, 'dummy', '../common/JackDummyDriver.cpp') - - winmme_driver_src = [ - 'winmme/JackWinMMEDriver.cpp', - 'winmme/JackWinMMEInputPort.cpp', - 'winmme/JackWinMMEOutputPort.cpp', - 'winmme/JackWinMMEPort.cpp', - ] - - if bld.env['BUILD_DRIVER_WINMME'] == True: - winmme_driver = bld(features = ['c', 'cxx', 'cxxshlib', 'cshlib']) - winmme_driver.env['cxxshlib_PATTERN'] = 'jack_%s.dll' - winmme_driver.defines = ['HAVE_CONFIG_H','SERVER_SIDE'] - winmme_driver.includes = ['.', '..' , '../windows', '../common', '../common/jack'] - winmme_driver.target = 'winmme' - winmme_driver.source = winmme_driver_src - winmme_driver.install_path = '${ADDON_DIR}/' - winmme_driver.use = ['serverlib', 'WINMME'] - - portaudio_driver_src = [ - 'portaudio/JackPortAudioDevices.cpp', - 'portaudio/JackPortAudioDriver.cpp', - ] - - if bld.env['BUILD_DRIVER_PORTAUDIO'] == True: - portaudio_driver = bld(features = ['c', 'cxx', 'cxxshlib', 'cshlib']) - portaudio_driver.env['cxxshlib_PATTERN'] = 'jack_%s.dll' - portaudio_driver.defines = ['HAVE_CONFIG_H','SERVER_SIDE'] - portaudio_driver.includes = ['.', '..' , '../windows', '../common', '../common/jack'] - portaudio_driver.target = 'portaudio' - portaudio_driver.source = portaudio_driver_src - portaudio_driver.install_path = '${ADDON_DIR}/' - portaudio_driver.use = ['serverlib', 'PORTAUDIO' ] - - create_jack_driver_obj(bld, 'net', '../common/JackNetDriver.cpp') - - create_jack_driver_obj(bld, 'loopback', '../common/JackLoopbackDriver.cpp') - - create_jack_driver_obj(bld, 'netone', [ '../common/JackNetOneDriver.cpp', - '../common/netjack.c', - '../common/netjack_packet.c' ], ["SAMPLERATE", "CELT"] ) - - create_jack_driver_obj(bld, 'proxy', '../common/JackProxyDriver.cpp') @@ -187,10 +187,23 @@ class AutoOption: """ all_found = True + # Use-variables that should be used when checking libraries, headers and + # programs. The list will be populated when looking for packages. + use = [] + + # check for packages + for package,uselib_store,atleast_version in self.packages: + try: + conf.check_cfg(package=package, uselib_store=uselib_store, atleast_version=atleast_version, args='--cflags --libs') + use.append(uselib_store) + except conf.errors.ConfigurationError: + all_found = False + self.packages_not_found.append([package,atleast_version]) + # check for libraries for lib,uselib_store in self.libs: try: - conf.check_cc(lib=lib, uselib_store=uselib_store) + conf.check_cc(lib=lib, uselib_store=uselib_store, use=use) except conf.errors.ConfigurationError: all_found = False self.libs_not_found.append(lib) @@ -198,23 +211,15 @@ class AutoOption: # check for headers for header in self.headers: try: - conf.check_cc(header_name=header) + conf.check_cc(header_name=header, use=use) except conf.errors.ConfigurationError: all_found = False self.headers_not_found.append(header) - # check for packages - for package,uselib_store,atleast_version in self.packages: - try: - conf.check_cfg(package=package, uselib_store=uselib_store, atleast_version=atleast_version, args='--cflags --libs') - except conf.errors.ConfigurationError: - all_found = False - self.packages_not_found.append([package,atleast_version]) - # check for programs for program,var in self.programs: try: - conf.find_program(program, var=var) + conf.find_program(program, var=var, use=use) except conf.errors.ConfigurationError: all_found = False self.programs_not_found.append(program) @@ -480,9 +485,14 @@ def configure(conf): # configure all auto options configure_auto_options(conf) + # Check for functions. + conf.check_cc( + function_name='ppoll', + header_name=['poll.h', 'signal.h'], + defines=['_GNU_SOURCE'], + mandatory=False) + conf.recurse('common') - if conf.env['IS_LINUX']: - conf.recurse('linux') if Options.options.dbus: conf.recurse('dbus') if conf.env['BUILD_JACKDBUS'] != True: @@ -663,6 +673,271 @@ def init(ctx): cmd = name + '_' + lib32 variant = lib32 +def obj_add_includes(bld, obj): + if bld.env['BUILD_JACKDBUS']: + obj.includes += ['dbus'] + + if bld.env['IS_LINUX']: + obj.includes += ['linux', 'posix'] + + if bld.env['IS_MACOSX']: + obj.includes += ['macosx', 'posix'] + + if bld.env['IS_SUN']: + obj.includes += ['posix', 'solaris'] + + if bld.env['IS_WINDOWS']: + obj.includes += ['windows'] + +# FIXME: Is SERVER_SIDE needed? +def build_jackd(bld): + jackd = bld( + features = ['cxx', 'cxxprogram'], + defines = ['HAVE_CONFIG_H','SERVER_SIDE'], + includes = ['.', 'common', 'common/jack'], + target = 'jackd', + source = ['common/Jackdmp.cpp'], + use = ['serverlib']) + + if bld.env['BUILD_JACKDBUS']: + jackd.source += ['dbus/audio_reserve.c', 'dbus/reserve.c'] + jackd.use += ['DBUS-1'] + + if bld.env['IS_LINUX']: + jackd.use += ['DL', 'M', 'PTHREAD', 'RT', 'STDC++'] + + if bld.env['IS_MACOSX']: + bld.framework = ['CoreFoundation'] + jackd.use += ['DL', 'PTHREAD'] + + if bld.env['IS_SUN']: + jackd.use += ['DL', 'PTHREAD'] + + obj_add_includes(bld, jackd) + + return jackd + +# FIXME: Is SERVER_SIDE needed? +def create_driver_obj(bld, **kw): + driver = bld( + features = ['c', 'cshlib', 'cxx', 'cxxshlib'], + defines = ['HAVE_CONFIG_H', 'SERVER_SIDE'], + includes = ['.', 'common', 'common/jack'], + install_path = '${ADDON_DIR}/', + **kw) + + if bld.env['IS_WINDOWS']: + driver.env['cxxshlib_PATTERN'] = 'jack_%s.dll' + else: + driver.env['cxxshlib_PATTERN'] = 'jack_%s.so' + + obj_add_includes(bld, driver) + + return driver + +def build_drivers(bld): + # Non-hardware driver sources. Lexically sorted. + dummy_src = [ + 'common/JackDummyDriver.cpp' + ] + + loopback_src = [ + 'common/JackLoopbackDriver.cpp' + ] + + net_src = [ + 'common/JackNetDriver.cpp' + ] + + netone_src = [ + 'common/JackNetOneDriver.cpp', + 'common/netjack.c', + 'common/netjack_packet.c' + ] + + proxy_src = [ + 'common/JackProxyDriver.cpp' + ] + + # Hardware driver sources. Lexically sorted. + alsa_src = [ + 'common/memops.c', + 'linux/alsa/JackAlsaDriver.cpp', + 'linux/alsa/alsa_rawmidi.c', + 'linux/alsa/alsa_seqmidi.c', + 'linux/alsa/alsa_midi_jackmp.cpp', + 'linux/alsa/generic_hw.c', + 'linux/alsa/hdsp.c', + 'linux/alsa/alsa_driver.c', + 'linux/alsa/hammerfall.c', + 'linux/alsa/ice1712.c' + ] + + alsarawmidi_src = [ + 'linux/alsarawmidi/JackALSARawMidiDriver.cpp', + 'linux/alsarawmidi/JackALSARawMidiInputPort.cpp', + 'linux/alsarawmidi/JackALSARawMidiOutputPort.cpp', + 'linux/alsarawmidi/JackALSARawMidiPort.cpp', + 'linux/alsarawmidi/JackALSARawMidiReceiveQueue.cpp', + 'linux/alsarawmidi/JackALSARawMidiSendQueue.cpp', + 'linux/alsarawmidi/JackALSARawMidiUtil.cpp' + ] + + boomer_src = [ + 'common/memops.c', + 'solaris/oss/JackBoomerDriver.cpp' + ] + + coreaudio_src = [ + 'macosx/coreaudio/JackCoreAudioDriver.cpp' + ] + + coremidi_src = [ + 'macosx/coremidi/JackCoreMidiInputPort.cpp', + 'macosx/coremidi/JackCoreMidiOutputPort.cpp', + 'macosx/coremidi/JackCoreMidiPhysicalInputPort.cpp', + 'macosx/coremidi/JackCoreMidiPhysicalOutputPort.cpp', + 'macosx/coremidi/JackCoreMidiVirtualInputPort.cpp', + 'macosx/coremidi/JackCoreMidiVirtualOutputPort.cpp', + 'macosx/coremidi/JackCoreMidiPort.cpp', + 'macosx/coremidi/JackCoreMidiUtil.cpp', + 'macosx/coremidi/JackCoreMidiDriver.cpp' + ] + + ffado_src = [ + 'linux/firewire/JackFFADODriver.cpp', + 'linux/firewire/JackFFADOMidiInputPort.cpp', + 'linux/firewire/JackFFADOMidiOutputPort.cpp', + 'linux/firewire/JackFFADOMidiReceiveQueue.cpp', + 'linux/firewire/JackFFADOMidiSendQueue.cpp' + ] + + freebob_src = [ + 'linux/freebob/JackFreebobDriver.cpp' + ] + + iio_driver_src = [ + 'linux/iio/JackIIODriver.cpp' + ] + + oss_src = [ + 'common/memops.c', + 'solaris/oss/JackOSSDriver.cpp' + ] + + portaudio_src = [ + 'windows/portaudio/JackPortAudioDevices.cpp', + 'windows/portaudio/JackPortAudioDriver.cpp', + ] + + winmme_driver_src = [ + 'windows/winmme/JackWinMMEDriver.cpp', + 'windows/winmme/JackWinMMEInputPort.cpp', + 'windows/winmme/JackWinMMEOutputPort.cpp', + 'windows/winmme/JackWinMMEPort.cpp', + ] + + # Create non-hardware driver objects. Lexically sorted. + create_driver_obj( + bld, + target = 'dummy', + source = dummy_src) + + create_driver_obj( + bld, + target = 'loopback', + source = loopback_src) + + create_driver_obj( + bld, + target = 'net', + source = net_src) + + create_driver_obj( + bld, + target = 'netone', + source = netone_src, + use = ['SAMPLERATE', 'CELT']) + + create_driver_obj( + bld, + target = 'proxy', + source = proxy_src) + + # Create hardware driver objects. Lexically sorted after the conditional, + # e.g. BUILD_DRIVER_ALSA. + if bld.env['BUILD_DRIVER_ALSA']: + create_driver_obj( + bld, + target = 'alsa', + source = alsa_src, + use = ['ALSA']) + create_driver_obj( + bld, + target = 'alsarawmidi', + source = alsarawmidi_src, + use = ['ALSA']) + + if bld.env['BUILD_DRIVER_FREEBOB']: + create_driver_obj( + bld, + target = 'freebob', + source = freebob_src, + use = ['LIBFREEBOB']) + + if bld.env['BUILD_DRIVER_FFADO']: + create_driver_obj( + bld, + target = 'firewire', + source = ffado_src, + use = ['LIBFFADO']) + + if bld.env['BUILD_DRIVER_IIO']: + create_driver_obj( + bld, + target = 'iio', + source = iio_src, + use = ['GTKIOSTREAM', 'EIGEN3']) + + if bld.env['BUILD_DRIVER_PORTAUDIO']: + create_driver_obj( + bld, + target = 'portaudio', + source = portaudio_src, + use = ['serverlib', 'PORTAUDIO']) # FIXME: Is serverlib needed here? + + if bld.env['BUILD_DRIVER_WINMME']: + create_driver_obj( + bld, + target = 'winmme', + source = winmme_src, + use = ['serverlib', 'WINMME']) # FIXME: Is serverlib needed here? + + if bld.env['IS_MACOSX']: + create_driver_obj( + bld, + target = 'coreaudio', + source = coreaudio_src, + use = ['serverlib'], # FIXME: Is this needed? + framework = ['AudioUnit', 'CoreAudio', 'CoreServices']) + + create_driver_obj( + bld, + target = 'coremidi', + source = coremidi_src, + use = ['serverlib'], # FIXME: Is this needed? + framework = ['AudioUnit', 'CoreMIDI', 'CoreServices']) + + if bld.env['IS_SUN']: + create_driver_obj( + bld, + target = 'boomer', + source = boomer_src) + create_driver_obj( + bld, + target = 'oss', + source = oss_src) + def build(bld): if not bld.variant: out2 = out @@ -701,8 +976,12 @@ def build(bld): target = [bld.path.find_or_declare('svnversion.h')] ) + if bld.env['BUILD_JACKD']: + build_jackd(bld) + + build_drivers(bld) + if bld.env['IS_LINUX']: - bld.recurse('linux') bld.recurse('example-clients') bld.recurse('tests') bld.recurse('man') @@ -710,21 +989,18 @@ def build(bld): bld.recurse('dbus') if bld.env['IS_MACOSX']: - bld.recurse('macosx') bld.recurse('example-clients') bld.recurse('tests') if bld.env['BUILD_JACKDBUS'] == True: bld.recurse('dbus') if bld.env['IS_SUN']: - bld.recurse('solaris') bld.recurse('example-clients') bld.recurse('tests') if bld.env['BUILD_JACKDBUS'] == True: bld.recurse('dbus') if bld.env['IS_WINDOWS']: - bld.recurse('windows') bld.recurse('example-clients') #bld.recurse('tests') |