From 41c7b2dcf88500e47a87e9a707e85f970769eb93 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Mon, 6 Apr 2015 17:55:40 +0200 Subject: [PATCH 0001/1763] docs --- ChangeLog | 5 +++++ waflib/Context.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 851ea06a0c..cef2e7e72a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,12 @@ NEW IN WAF 1.8.8 ---------------- * Fixed a regression in Fortran builds #1546 +* Fixed a regression in the libdir installation path on 32-bit ubuntu #1552 +* Process -Bstatic and -Bdynamic in parse_flags (pkg-config tools) +* Fortran compiler detection to cover the sxf03 as well as the sxf90 +* Jython detection enhancements * Doxygen tool enhancements +* Moved the project to Github/waf.io and updated the documentation NEW IN WAF 1.8.7 ---------------- diff --git a/waflib/Context.py b/waflib/Context.py index 974df0c7a7..cb32408cec 100644 --- a/waflib/Context.py +++ b/waflib/Context.py @@ -17,7 +17,7 @@ WAFVERSION="1.8.8" """Constant updated on new releases""" -WAFREVISION="cca30e91f4e1796b6a9c204b1604ac52315fad56" +WAFREVISION="8ac4646d0966fe22f8ae8955c7e9b9d56ae8288e" """Git revision when the waf version is updated""" ABI = 98 From d46bc99b2260ac55b408e8acd301ee104d74f129 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Wed, 8 Apr 2015 19:11:49 +0200 Subject: [PATCH 0002/1763] No more ftp.waf.io --- docs/book/download.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/book/download.txt b/docs/book/download.txt index c4f04d03fa..d019d5d6e9 100644 --- a/docs/book/download.txt +++ b/docs/book/download.txt @@ -11,7 +11,7 @@ The Waf binary is a python script which does not require any installation whatso [source,shishell] --------------- -$ wget http://ftp.waf.io/pub/release/waf-1.8.8 +$ wget https://waf.io/waf-1.8.8 $ mv waf-1.8.8 waf $ python waf --version waf 1.8.8 (54dc13ba5f51bfe2ae277451ec5ac1d0a91c7aaf) @@ -33,7 +33,7 @@ Building Waf requires a Python interpreter having a version number in the range [source,shishell] --------------- -$ wget http://ftp.waf.io/pub/release/waf-1.8.8.tar.bz2 +$ wget https://waf.io/waf-1.8.8.tar.bz2 $ tar xjvf waf-1.8.8.tar.bz2 $ cd waf-1.8.8 $ python waf-light From 0c0e0388a01bc04b766dcd89e72e8693adecd5db Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Wed, 8 Apr 2015 23:32:53 +0200 Subject: [PATCH 0003/1763] More accurate rpath parsing in parse_flags --- waflib/Tools/c_config.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/waflib/Tools/c_config.py b/waflib/Tools/c_config.py index f989a4ade5..7294eb9e12 100755 --- a/waflib/Tools/c_config.py +++ b/waflib/Tools/c_config.py @@ -7,7 +7,7 @@ """ import os, re, shlex, sys -from waflib import Build, Utils, Task, Options, Logs, Errors, ConfigSet, Runner +from waflib import Build, Utils, Task, Options, Logs, Errors, Runner from waflib.TaskGen import after_method, feature from waflib.Configure import conf @@ -175,8 +175,10 @@ def configure(conf): appu('FRAMEWORK_' + uselib, [lst.pop(0)]) elif x.startswith('-F'): appu('FRAMEWORKPATH_' + uselib, [x[2:]]) - elif x == '-Wl,-rpath': - app('RPATH_' + uselib, lst.pop(0)) + elif x == '-Wl,-rpath' or x == '-Wl,-R': + app('RPATH_' + uselib, lst.pop(0).lstrip('-Wl,')) + elif x.startswith('-Wl,-R,'): + app('RPATH_' + uselib, x[7:]) elif x.startswith('-Wl,-R'): app('RPATH_' + uselib, x[6:]) elif x.startswith('-Wl,-rpath,'): From ba7295d555b911af1bf3fcb137284747fa1a7382 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sat, 11 Apr 2015 10:51:19 +0200 Subject: [PATCH 0004/1763] xsubpp misconfiguration on redhat systems --- waflib/Tools/perl.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/waflib/Tools/perl.py b/waflib/Tools/perl.py index cc645261dc..dc852dfe96 100644 --- a/waflib/Tools/perl.py +++ b/waflib/Tools/perl.py @@ -63,7 +63,6 @@ def check_perl_version(self, minver=None): minver is supposed to be a tuple """ res = True - if minver: cver = '.'.join(map(str,minver)) else: @@ -75,11 +74,10 @@ def check_perl_version(self, minver=None): if not perl: perl = self.find_program('perl', var='PERL') - if not perl: self.end_msg("Perl not found", color="YELLOW") return False - + self.env['PERL'] = perl version = self.cmd_and_log(self.env.PERL + ["-e", 'printf \"%vd\", $^V']) @@ -141,9 +139,14 @@ def cfg_lst(cfg): env['LINKFLAGS_PERLEXT'] = cfg_lst('$Config{lddlflags}') env['INCLUDES_PERLEXT'] = cfg_lst('$Config{archlib}/CORE') env['CFLAGS_PERLEXT'] = cfg_lst('$Config{ccflags} $Config{cccdlflags}') - env['XSUBPP'] = cfg_lst('$Config{privlib}/ExtUtils/xsubpp$Config{exe_ext}') + env['XSUBPP'] = xsubpp = cfg_lst('$Config{privlib}/ExtUtils/xsubpp$Config{exe_ext}') env['EXTUTILS_TYPEMAP'] = cfg_lst('$Config{privlib}/ExtUtils/typemap') + if len(xsubpp) == 1 and not os.path.isfile(xsubpp[0]): + # oh Fedora + env.XSUBPP = [] + self.find_program('xsubpp') + if not getattr(Options.options, 'perlarchdir', None): env['ARCHDIR_PERL'] = cfg_str('$Config{sitearch}') else: From c53a6f9e0766ec74de9b2e78517b924c50eb9825 Mon Sep 17 00:00:00 2001 From: Daniel Svensson Date: Sat, 11 Apr 2015 13:17:21 +0200 Subject: [PATCH 0005/1763] Find xsubpp in order, privlib, vendorlib and path. --- waflib/Tools/perl.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/waflib/Tools/perl.py b/waflib/Tools/perl.py index dc852dfe96..89946021f2 100644 --- a/waflib/Tools/perl.py +++ b/waflib/Tools/perl.py @@ -135,17 +135,18 @@ def cfg_str(cfg): return self.cmd_and_log(cmd_perl_config(cfg)) def cfg_lst(cfg): return Utils.to_list(cfg_str(cfg)) + def find_xsubpp(): + for var in ('privlib', 'vendorlib'): + xsubpp = cfg_lst('$Config{%s}/ExtUtils/xsubpp$Config{exe_ext}' % var) + if xsubpp and os.path.isfile(xsubpp[0]): + return xsubpp + return self.find_program('xsubpp') env['LINKFLAGS_PERLEXT'] = cfg_lst('$Config{lddlflags}') env['INCLUDES_PERLEXT'] = cfg_lst('$Config{archlib}/CORE') env['CFLAGS_PERLEXT'] = cfg_lst('$Config{ccflags} $Config{cccdlflags}') - env['XSUBPP'] = xsubpp = cfg_lst('$Config{privlib}/ExtUtils/xsubpp$Config{exe_ext}') env['EXTUTILS_TYPEMAP'] = cfg_lst('$Config{privlib}/ExtUtils/typemap') - - if len(xsubpp) == 1 and not os.path.isfile(xsubpp[0]): - # oh Fedora - env.XSUBPP = [] - self.find_program('xsubpp') + env['XSUBPP'] = find_xsubpp() if not getattr(Options.options, 'perlarchdir', None): env['ARCHDIR_PERL'] = cfg_str('$Config{sitearch}') @@ -160,4 +161,3 @@ def options(opt): """ opt.add_option('--with-perl-binary', type='string', dest='perlbinary', help = 'Specify alternate perl binary', default=None) opt.add_option('--with-perl-archdir', type='string', dest='perlarchdir', help = 'Specify directory where to install arch specific files', default=None) - From 588f809ffa4dd514ea90bdcd0341d9baf508784f Mon Sep 17 00:00:00 2001 From: Daniel Svensson Date: Sat, 11 Apr 2015 15:38:44 +0200 Subject: [PATCH 0006/1763] Use same prefix convention for python as with ruby and perl. Should /usr/local/.../site-packages not be in sys.path in some platform, a user would pass --pythondir, and --pythonarchdir to waf when compiling, or modify sys.path. This makes waf work more predictable, as when passing --prefix parameter to the build, everything will be installed under this directory. --- waflib/Tools/python.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/waflib/Tools/python.py b/waflib/Tools/python.py index 33530dd311..f183d324c1 100644 --- a/waflib/Tools/python.py +++ b/waflib/Tools/python.py @@ -461,7 +461,7 @@ def check_python_version(conf, minver=None): "get_python_lib(standard_lib=0) or ''"]) else: python_LIBDEST = None - (pydir,) = conf.get_python_variables( ["get_python_lib(standard_lib=0) or ''"]) + (pydir,) = conf.get_python_variables( ["get_python_lib(standard_lib=0, prefix='%s') or ''" % conf.env['PREFIX']]) if python_LIBDEST is None: if conf.env['LIBDIR']: python_LIBDEST = os.path.join(conf.env['LIBDIR'], "python" + pyver) @@ -476,7 +476,7 @@ def check_python_version(conf, minver=None): pyarchdir = conf.environ['PYTHONARCHDIR'] else: # Finally, try to guess - (pyarchdir, ) = conf.get_python_variables( ["get_python_lib(plat_specific=1, standard_lib=0) or ''"]) + (pyarchdir, ) = conf.get_python_variables( ["get_python_lib(plat_specific=1, standard_lib=0, prefix='%s') or ''" % conf.env['PREFIX']]) if not pyarchdir: pyarchdir = pydir From 924f8bbce893de3b1c13cbecc846ec5376d538a8 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Wed, 22 Apr 2015 21:34:45 +0200 Subject: [PATCH 0007/1763] Inserting LDFLAGS at the end of the command-line causes less overhead than expected, and LINKFLAGS can still be used for flags in the beginning of the line --- waflib/Tools/c.py | 4 ++-- waflib/Tools/c_config.py | 8 ++++---- waflib/Tools/cxx.py | 4 ++-- waflib/Tools/fc.py | 10 ++++------ waflib/Tools/fc_config.py | 5 +++-- 5 files changed, 15 insertions(+), 16 deletions(-) diff --git a/waflib/Tools/c.py b/waflib/Tools/c.py index b97eee15d9..0b06a7fa59 100644 --- a/waflib/Tools/c.py +++ b/waflib/Tools/c.py @@ -4,7 +4,7 @@ "Base for c programs/libraries" -from waflib import TaskGen, Task, Utils +from waflib import TaskGen, Task from waflib.Tools import c_preproc from waflib.Tools.ccroot import link_task, stlink_task @@ -24,7 +24,7 @@ class c(Task.Task): class cprogram(link_task): "Link object files into a c program" - run_str = '${LINK_CC} ${LINKFLAGS} ${CCLNK_SRC_F}${SRC} ${CCLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${FRAMEWORK_ST:FRAMEWORK} ${ARCH_ST:ARCH} ${STLIB_MARKER} ${STLIBPATH_ST:STLIBPATH} ${STLIB_ST:STLIB} ${SHLIB_MARKER} ${LIBPATH_ST:LIBPATH} ${LIB_ST:LIB}' + run_str = '${LINK_CC} ${LINKFLAGS} ${CCLNK_SRC_F}${SRC} ${CCLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${FRAMEWORK_ST:FRAMEWORK} ${ARCH_ST:ARCH} ${STLIB_MARKER} ${STLIBPATH_ST:STLIBPATH} ${STLIB_ST:STLIB} ${SHLIB_MARKER} ${LIBPATH_ST:LIBPATH} ${LIB_ST:LIB} ${LDFLAGS}' ext_out = ['.bin'] vars = ['LINKDEPS'] inst_to = '${BINDIR}' diff --git a/waflib/Tools/c_config.py b/waflib/Tools/c_config.py index 7294eb9e12..e9c22204f4 100755 --- a/waflib/Tools/c_config.py +++ b/waflib/Tools/c_config.py @@ -929,7 +929,7 @@ def get_config_header(self, defines=True, headers=False, define_prefix=''): @conf def cc_add_flags(conf): """ - Read the CFLAGS/CPPFLAGS from os.environ and add to conf.env.CFLAGS + Add CFLAGS / CPPFLAGS from os.environ to conf.env """ conf.add_os_flags('CPPFLAGS', 'CFLAGS') conf.add_os_flags('CFLAGS') @@ -937,7 +937,7 @@ def cc_add_flags(conf): @conf def cxx_add_flags(conf): """ - Read the CXXFLAGS/CPPFLAGS and add to conf.env.CXXFLAGS + Add CXXFLAGS / CPPFLAGS from os.environ to conf.env """ conf.add_os_flags('CPPFLAGS', 'CXXFLAGS') conf.add_os_flags('CXXFLAGS') @@ -945,10 +945,10 @@ def cxx_add_flags(conf): @conf def link_add_flags(conf): """ - Read the LINKFLAGS/LDFLAGS and add to conf.env.LDFLAGS + Add LINKFLAGS / LDFLAGS from os.environ to conf.env """ conf.add_os_flags('LINKFLAGS') - conf.add_os_flags('LDFLAGS', 'LINKFLAGS') + conf.add_os_flags('LDFLAGS') @conf def cc_load_tools(conf): diff --git a/waflib/Tools/cxx.py b/waflib/Tools/cxx.py index 9e1777d46e..311c1e5297 100644 --- a/waflib/Tools/cxx.py +++ b/waflib/Tools/cxx.py @@ -4,7 +4,7 @@ "Base for c++ programs and libraries" -from waflib import TaskGen, Task, Utils +from waflib import TaskGen, Task from waflib.Tools import c_preproc from waflib.Tools.ccroot import link_task, stlink_task @@ -25,7 +25,7 @@ class cxx(Task.Task): class cxxprogram(link_task): "Link object files into a c++ program" - run_str = '${LINK_CXX} ${LINKFLAGS} ${CXXLNK_SRC_F}${SRC} ${CXXLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${FRAMEWORK_ST:FRAMEWORK} ${ARCH_ST:ARCH} ${STLIB_MARKER} ${STLIBPATH_ST:STLIBPATH} ${STLIB_ST:STLIB} ${SHLIB_MARKER} ${LIBPATH_ST:LIBPATH} ${LIB_ST:LIB}' + run_str = '${LINK_CXX} ${LINKFLAGS} ${CXXLNK_SRC_F}${SRC} ${CXXLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${FRAMEWORK_ST:FRAMEWORK} ${ARCH_ST:ARCH} ${STLIB_MARKER} ${STLIBPATH_ST:STLIBPATH} ${STLIB_ST:STLIB} ${SHLIB_MARKER} ${LIBPATH_ST:LIBPATH} ${LIB_ST:LIB} ${LDFLAGS}' vars = ['LINKDEPS'] ext_out = ['.bin'] inst_to = '${BINDIR}' diff --git a/waflib/Tools/fc.py b/waflib/Tools/fc.py index 829b335a2a..15010e0f68 100644 --- a/waflib/Tools/fc.py +++ b/waflib/Tools/fc.py @@ -7,11 +7,9 @@ fortran support """ -import re - -from waflib import Utils, Task, TaskGen, Logs +from waflib import Utils, Task, Logs from waflib.Tools import ccroot, fc_config, fc_scan -from waflib.TaskGen import feature, before_method, after_method, extension +from waflib.TaskGen import feature, extension from waflib.Configure import conf ccroot.USELIB_VARS['fc'] = set(['FCFLAGS', 'DEFINES', 'INCLUDES']) @@ -152,7 +150,7 @@ def runnable_status(self): class fcprogram(ccroot.link_task): """Link fortran programs""" color = 'YELLOW' - run_str = '${FC} ${LINKFLAGS} ${FCLNK_SRC_F}${SRC} ${FCLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FCSTLIB_MARKER} ${FCSTLIBPATH_ST:STLIBPATH} ${FCSTLIB_ST:STLIB} ${FCSHLIB_MARKER} ${FCLIBPATH_ST:LIBPATH} ${FCLIB_ST:LIB}' + run_str = '${FC} ${LINKFLAGS} ${FCLNK_SRC_F}${SRC} ${FCLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FCSTLIB_MARKER} ${FCSTLIBPATH_ST:STLIBPATH} ${FCSTLIB_ST:STLIB} ${FCSHLIB_MARKER} ${FCLIBPATH_ST:LIBPATH} ${FCLIB_ST:LIB} ${LDFLAGS}' inst_to = '${BINDIR}' class fcshlib(fcprogram): @@ -183,7 +181,7 @@ def exec_command(self, cmd, **kw): kw['output'] = 0 try: (bld.out, bld.err) = bld.cmd_and_log(cmd, **kw) - except Exception as e: + except Exception: return -1 if bld.out: diff --git a/waflib/Tools/fc_config.py b/waflib/Tools/fc_config.py index d8c9ac9339..76a547a546 100644 --- a/waflib/Tools/fc_config.py +++ b/waflib/Tools/fc_config.py @@ -49,10 +49,11 @@ def fc_flags(conf): @conf def fc_add_flags(conf): """ - FCFLAGS? + Add FCFLAGS / LDFLAGS / LINKFLAGS from os.environ to conf.env """ conf.add_os_flags('FCFLAGS') - conf.add_os_flags('LDFLAGS', 'LINKFLAGS') + conf.add_os_flags('LINKFLAGS') + conf.add_os_flags('LDFLAGS') @conf def check_fortran(self, *k, **kw): From b807733cad31a4e14dd88dd5619d7ab513835408 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sun, 26 Apr 2015 12:18:15 +0200 Subject: [PATCH 0008/1763] docs --- ChangeLog | 6 ++++++ TODO | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index cef2e7e72a..242e9f4401 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +NEW IN WAF 1.8.9 +---------------- +* VS 2013 supports cross-compiling for x86 and arm from amd64 +* Perl detection enhancements on Redhat systems +* More accurate rpath parsing in check_cfg + NEW IN WAF 1.8.8 ---------------- * Fixed a regression in Fortran builds #1546 diff --git a/TODO b/TODO index aa7e2b9aed..94d56e8ffa 100644 --- a/TODO +++ b/TODO @@ -6,7 +6,7 @@ Waf 1.9 * Remove the split functions from Utils * Ensure _cache.py are valid python files * Include the tool 'nobuild' by default -* Support for linkflags/cflags at the end of commands +* cflags in the beginning / cppflags at the end Waf 1.8.x --------- From ffd6c6011337fc632b22d3c351e2a23970fe5d68 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sun, 26 Apr 2015 16:52:45 +0200 Subject: [PATCH 0009/1763] docs --- docs/book/configuration.txt | 4 ++-- docs/book/cprog.txt | 36 +++++++++++++++++++----------------- docs/book/download.txt | 26 +++++++++++++------------- docs/book/waf.txt | 2 +- docs/sphinx/conf.py | 11 ++++++++--- waflib/Tools/intltool.py | 4 ++-- 6 files changed, 45 insertions(+), 38 deletions(-) diff --git a/docs/book/configuration.txt b/docs/book/configuration.txt index 390c8cc9ca..93ff960810 100644 --- a/docs/book/configuration.txt +++ b/docs/book/configuration.txt @@ -178,7 +178,7 @@ out = 'build' def configure(ctx): ctx.find_program('touch', var='TOUCH') - ctx.check_waf_version(mini='1.8.8') + ctx.check_waf_version(mini='1.8.9') ctx.find_file('fstab', ['/opt', '/etc']) --------------- @@ -394,7 +394,7 @@ Checking for program some_app : not found $ cat build/config.log <2> # project configured on Tue Jul 13 19:15:04 2010 by -# waf 1.8.8 (abi 98, python 20605f0 on linux2) +# waf 1.8.9 (abi 98, python 20605f0 on linux2) # using /home/waf/bin/waf configure # Checking for program some_app diff --git a/docs/book/cprog.txt b/docs/book/cprog.txt index f9c7babab0..0948b0ce7e 100644 --- a/docs/book/cprog.txt +++ b/docs/book/cprog.txt @@ -568,29 +568,31 @@ waf_config_files = ['/compilation/waf/demos/adv/build/config.h'] ==== Advanced tests -The methods 'conf.check' create a build context and a task generator internally. This means that the attributes 'includes', 'defines', 'cxxflags' may be used (not all shown here). Advanced tests may be created by passing feature arguments: +The methods 'conf.check' create a build context and a task generator internally. This means that the attributes 'includes', 'defines', 'cxxflags' may be used (not all shown here). Yet some tests can be require several targets at once. In order to faciliate this, a custom build function can be passed directly, for example: -// cprog_cfg_advanced [source,python] --------------- -from waflib.TaskGen import feature, before_method +def build(bld): + lib_node = bld.srcnode.make_node('libdir/iotest.c') + lib_node.parent.mkdir() + lib_node.write('#include \nint lib_func(void) { FILE *f = fopen("foo", "r");}\n', 'w') + bld(features='c cshlib', source=[lib_node], linkflags=['-g3'], target='mylib') +conf.check(build_fun=build, msg='Custom test') +--------------- -@feature('special_test') -@before_method('process_source') -def my_special_test(self): - self.bld(rule='touch ${TGT}', target='foo') <1> - self.bld(rule='cp ${SRC} ${TGT}', source='foo', target='bar') - self.source = [] <2> +As a result, tests can also be written for other programming languages and compilers. Here is for example a custom test for LaTeX packages: -def configure(conf): - conf.check_cc(features='special_test', msg='my test!') <3> +[source,python] +--------------- +def build_latex_test(bld): + def write_tex(tsk): + tsk.outputs[0].write(r'''\documentclass[a4paper,12pt]{article} \usepackage{ucs} \begin{document} test \end{document} ''') + bld(rule=write_tex, target='main.tex') + bld(features='tex', type='pdflatex', source='main.tex', prompt=0) +conf.test(build_fun=build_latex_test, msg='Checking for UCS', okmsg='ok', errmsg='ucs.sty is missing install latex-extras') --------------- -<1> Create a task generator from another task generator -<2> Disable the compilation of +test.c+ by setting no source files -<3> Use the feature special_test - -==== Creating configuration headers +==== Configuration headers Adding lots of command-line define values increases the size of the command-line and makes it harder to review the flags when errors occur. Besides that, the defines passed on the command-line may fail unexpectedly with different compilers and command execution contexts. For example, define values containing quotes may be misinterpreted in Visual Studio response files. It is therefore a best practice to use configuration headers whenever possible. @@ -683,7 +685,7 @@ The outputs are written in the build directory into the file 'config.log': [source,shishell] ------------------ # project configured on Tue Aug 31 17:30:21 2010 by -# waf 1.8.8 (abi 98, python 20605f0 on linux2) +# waf 1.8.9 (abi 98, python 20605f0 on linux2) # using /home/waf/bin/waf configure # --- diff --git a/docs/book/download.txt b/docs/book/download.txt index d019d5d6e9..2636e318b2 100644 --- a/docs/book/download.txt +++ b/docs/book/download.txt @@ -11,10 +11,10 @@ The Waf binary is a python script which does not require any installation whatso [source,shishell] --------------- -$ wget https://waf.io/waf-1.8.8 -$ mv waf-1.8.8 waf +$ wget https://waf.io/waf-1.8.9 +$ mv waf-1.8.9 waf $ python waf --version -waf 1.8.8 (54dc13ba5f51bfe2ae277451ec5ac1d0a91c7aaf) +waf 1.8.9 (54dc13ba5f51bfe2ae277451ec5ac1d0a91c7aaf) --------------- The +waf+ file has its own library compressed in a binary stream in the same file. Upon execution, the library is uncompressed in a hidden folder in the current directory. The folder will be re-created if removed. This scheme enables different Waf versions to be executed from the same folders: @@ -22,7 +22,7 @@ The +waf+ file has its own library compressed in a binary stream in the same fil [source,shishell] --------------- $ ls -ld .waf* -.waf-1.8.8-2c924e3f453eb715218b9cc852291170 +.waf-1.8.9-2c924e3f453eb715218b9cc852291170 --------------- NOTE: The binary file requires http://docs.python.org/library/bz2.html[bzip2] compression support, which may be unavailable in some self-compiled cPython installations. @@ -33,18 +33,18 @@ Building Waf requires a Python interpreter having a version number in the range [source,shishell] --------------- -$ wget https://waf.io/waf-1.8.8.tar.bz2 -$ tar xjvf waf-1.8.8.tar.bz2 -$ cd waf-1.8.8 +$ wget https://waf.io/waf-1.8.9.tar.bz2 +$ tar xjvf waf-1.8.9.tar.bz2 +$ cd waf-1.8.9 $ python waf-light Configuring the project 'build' finished successfully (0.001s) Checking for program python : /usr/bin/python Checking for python version : (2, 6, 5, 'final', 0) 'configure' finished successfully (0.176s) -Waf: Entering directory `/waf-1.8.8/build' +Waf: Entering directory `/waf-1.8.9/build' [1/1] create_waf: -> waf -Waf: Leaving directory `/waf-1.8.8/build' +Waf: Leaving directory `/waf-1.8.9/build' 'build' finished successfully (2.050s) --------------- @@ -86,7 +86,7 @@ The following will create a custom waf file which will import and execute 'foo' $ python waf-light --make-waf --tools=compat15,$PWD/aba.py --prelude=$'\tfrom waflib.extras import aba\n\taba.foo()' $ ./waf --help -This is Waf 1.8.8 +This is Waf 1.8.9 [...] --------------- @@ -112,7 +112,7 @@ On unix-like systems, it is usually much more convenient to set the executable p --------------- $ chmod 755 waf $ ./waf --version -waf 1.8.8 (54dc13ba5f51bfe2ae277451ec5ac1d0a91c7aaf) +waf 1.8.9 (54dc13ba5f51bfe2ae277451ec5ac1d0a91c7aaf) --------------- If the command-line interpreter supports aliases, it is recommended to set the alias once: @@ -121,7 +121,7 @@ If the command-line interpreter supports aliases, it is recommended to set the a --------------- $ alias waf=$PWD/waf $ waf --version -waf 1.8.8 (54dc13ba5f51bfe2ae277451ec5ac1d0a91c7aaf) +waf 1.8.9 (54dc13ba5f51bfe2ae277451ec5ac1d0a91c7aaf) --------------- Or, the execution path may be modified to point at the location of the waf binary: @@ -130,7 +130,7 @@ Or, the execution path may be modified to point at the location of the waf binar --------------- $ export PATH=$PWD:$PATH $ waf --version -waf 1.8.8 (54dc13ba5f51bfe2ae277451ec5ac1d0a91c7aaf) +waf 1.8.9 (54dc13ba5f51bfe2ae277451ec5ac1d0a91c7aaf) --------------- In the next sections of the book, we assume that either an alias or the execution path have been set in a way that +waf+ may be called directly. diff --git a/docs/book/waf.txt b/docs/book/waf.txt index 1549b0a728..94bddd6fa6 100644 --- a/docs/book/waf.txt +++ b/docs/book/waf.txt @@ -9,7 +9,7 @@ The Waf Book [preface] == Introduction -Copyright (C) 2010-2011 Thomas Nagy +Copyright (C) 2010-2015 Thomas Nagy Copies of this book may be redistributed, verbatim, and for non-commercial purposes. The license for this book is diff --git a/docs/sphinx/conf.py b/docs/sphinx/conf.py index 8c47195d3c..f2639e7bd8 100644 --- a/docs/sphinx/conf.py +++ b/docs/sphinx/conf.py @@ -11,7 +11,7 @@ # All configuration values have a default; values that are commented out # serve to show the default. -import sys, os +import sys, os, re # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the @@ -348,9 +348,14 @@ def configure(ctx): # built documents. # # The short X.Y version. -version = '1.8.8' +#version = '1.8.9' # The full version, including alpha/beta/rc tags. -release = '1.8.8' +#release = version +# +with open('../../waflib/Context.py', 'r') as f: + txt = f.read() + m = re.compile('WAFVERSION=[\'"]([^\'"]+)', re.M).search(txt) + version = release = m.group(1) # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/waflib/Tools/intltool.py b/waflib/Tools/intltool.py index 3ea9f4461e..fa8e2af5fc 100644 --- a/waflib/Tools/intltool.py +++ b/waflib/Tools/intltool.py @@ -75,8 +75,8 @@ def build(bld): :param source: source files to process :type source: list of string :param style: the intltool-merge mode of operation, can be one of the following values: - ``ba``, ``desktop``, ``keys``, ``quoted``, ``quotedxml``, ``rfc822deb``, ``schemas`` and ``xml``. - See the ``intltool-merge`` man page for more information about supported modes of operation. + ``ba``, ``desktop``, ``keys``, ``quoted``, ``quotedxml``, ``rfc822deb``, ``schemas`` and ``xml``. + See the ``intltool-merge`` man page for more information about supported modes of operation. :type style: string :param flags: compilation flags ("-quc" by default) :type flags: list of string From 6c7eb129aff603feaeed0b8c6a30bcd1a4bd8a82 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sun, 26 Apr 2015 17:09:01 +0200 Subject: [PATCH 0010/1763] docs: update the version number automatically --- docs/book/configuration.txt | 4 ++-- docs/book/cprog.txt | 2 +- docs/book/download.txt | 26 +++++++++++++------------- docs/book/waf.txt | 32 ++++++++++++++++---------------- docs/book/wscript | 16 ++++++++++++---- 5 files changed, 44 insertions(+), 36 deletions(-) diff --git a/docs/book/configuration.txt b/docs/book/configuration.txt index 93ff960810..8453d7d74e 100644 --- a/docs/book/configuration.txt +++ b/docs/book/configuration.txt @@ -178,7 +178,7 @@ out = 'build' def configure(ctx): ctx.find_program('touch', var='TOUCH') - ctx.check_waf_version(mini='1.8.9') + ctx.check_waf_version(mini='{version}') ctx.find_file('fstab', ['/opt', '/etc']) --------------- @@ -394,7 +394,7 @@ Checking for program some_app : not found $ cat build/config.log <2> # project configured on Tue Jul 13 19:15:04 2010 by -# waf 1.8.9 (abi 98, python 20605f0 on linux2) +# waf {version} (abi 98, python 20605f0 on linux2) # using /home/waf/bin/waf configure # Checking for program some_app diff --git a/docs/book/cprog.txt b/docs/book/cprog.txt index 0948b0ce7e..c663e07747 100644 --- a/docs/book/cprog.txt +++ b/docs/book/cprog.txt @@ -685,7 +685,7 @@ The outputs are written in the build directory into the file 'config.log': [source,shishell] ------------------ # project configured on Tue Aug 31 17:30:21 2010 by -# waf 1.8.9 (abi 98, python 20605f0 on linux2) +# waf {version} (abi 98, python 20605f0 on linux2) # using /home/waf/bin/waf configure # --- diff --git a/docs/book/download.txt b/docs/book/download.txt index 2636e318b2..6bf535ec54 100644 --- a/docs/book/download.txt +++ b/docs/book/download.txt @@ -11,10 +11,10 @@ The Waf binary is a python script which does not require any installation whatso [source,shishell] --------------- -$ wget https://waf.io/waf-1.8.9 -$ mv waf-1.8.9 waf +$ wget https://waf.io/waf-{version} +$ mv waf-{version} waf $ python waf --version -waf 1.8.9 (54dc13ba5f51bfe2ae277451ec5ac1d0a91c7aaf) +waf {version} (54dc13ba5f51bfe2ae277451ec5ac1d0a91c7aaf) --------------- The +waf+ file has its own library compressed in a binary stream in the same file. Upon execution, the library is uncompressed in a hidden folder in the current directory. The folder will be re-created if removed. This scheme enables different Waf versions to be executed from the same folders: @@ -22,7 +22,7 @@ The +waf+ file has its own library compressed in a binary stream in the same fil [source,shishell] --------------- $ ls -ld .waf* -.waf-1.8.9-2c924e3f453eb715218b9cc852291170 +.waf-{version}-2c924e3f453eb715218b9cc852291170 --------------- NOTE: The binary file requires http://docs.python.org/library/bz2.html[bzip2] compression support, which may be unavailable in some self-compiled cPython installations. @@ -33,18 +33,18 @@ Building Waf requires a Python interpreter having a version number in the range [source,shishell] --------------- -$ wget https://waf.io/waf-1.8.9.tar.bz2 -$ tar xjvf waf-1.8.9.tar.bz2 -$ cd waf-1.8.9 +$ wget https://waf.io/waf-{version}.tar.bz2 +$ tar xjvf waf-{version}.tar.bz2 +$ cd waf-{version} $ python waf-light Configuring the project 'build' finished successfully (0.001s) Checking for program python : /usr/bin/python Checking for python version : (2, 6, 5, 'final', 0) 'configure' finished successfully (0.176s) -Waf: Entering directory `/waf-1.8.9/build' +Waf: Entering directory `/waf-{version}/build' [1/1] create_waf: -> waf -Waf: Leaving directory `/waf-1.8.9/build' +Waf: Leaving directory `/waf-{version}/build' 'build' finished successfully (2.050s) --------------- @@ -86,7 +86,7 @@ The following will create a custom waf file which will import and execute 'foo' $ python waf-light --make-waf --tools=compat15,$PWD/aba.py --prelude=$'\tfrom waflib.extras import aba\n\taba.foo()' $ ./waf --help -This is Waf 1.8.9 +This is Waf {version} [...] --------------- @@ -112,7 +112,7 @@ On unix-like systems, it is usually much more convenient to set the executable p --------------- $ chmod 755 waf $ ./waf --version -waf 1.8.9 (54dc13ba5f51bfe2ae277451ec5ac1d0a91c7aaf) +waf {version} (54dc13ba5f51bfe2ae277451ec5ac1d0a91c7aaf) --------------- If the command-line interpreter supports aliases, it is recommended to set the alias once: @@ -121,7 +121,7 @@ If the command-line interpreter supports aliases, it is recommended to set the a --------------- $ alias waf=$PWD/waf $ waf --version -waf 1.8.9 (54dc13ba5f51bfe2ae277451ec5ac1d0a91c7aaf) +waf {version} (54dc13ba5f51bfe2ae277451ec5ac1d0a91c7aaf) --------------- Or, the execution path may be modified to point at the location of the waf binary: @@ -130,7 +130,7 @@ Or, the execution path may be modified to point at the location of the waf binar --------------- $ export PATH=$PWD:$PATH $ waf --version -waf 1.8.9 (54dc13ba5f51bfe2ae277451ec5ac1d0a91c7aaf) +waf {version} (54dc13ba5f51bfe2ae277451ec5ac1d0a91c7aaf) --------------- In the next sections of the book, we assume that either an alias or the execution path have been set in a way that +waf+ may be called directly. diff --git a/docs/book/waf.txt b/docs/book/waf.txt index 94bddd6fa6..f588735005 100644 --- a/docs/book/waf.txt +++ b/docs/book/waf.txt @@ -35,20 +35,20 @@ The chapters are ordered by difficulty, starting from the basic use of Waf and P :numbered: -include::download.txt[] -include::execution.txt[] -include::configuration.txt[] -include::build.txt[] -include::nodes.txt[] -include::advbuild.txt[] -include::tasks.txt[] -include::make_like_rules.txt[] -include::chains.txt[] -include::task_generators.txt[] -include::cprog.txt[] -include::scenarios.txt[] -include::development.txt[] -include::architecture.txt[] -include::conclusion.txt[] -include::glossary.txt[] +include::download_.txt[] +include::execution_.txt[] +include::configuration_.txt[] +include::build_.txt[] +include::nodes_.txt[] +include::advbuild_.txt[] +include::tasks_.txt[] +include::make_like_rules_.txt[] +include::chains_.txt[] +include::task_generators_.txt[] +include::cprog_.txt[] +include::scenarios_.txt[] +include::development_.txt[] +include::architecture_.txt[] +include::conclusion_.txt[] +include::glossary_.txt[] diff --git a/docs/book/wscript b/docs/book/wscript index efe012b190..d71699ab49 100644 --- a/docs/book/wscript +++ b/docs/book/wscript @@ -132,15 +132,23 @@ def build(bld): for x in 'shishell.lang symbols.lang default.style lang.map waf.css'.split(): bld(features='subst', source=x, target=x, is_copy=True) + + + with open('../../waflib/Context.py', 'r') as f: + version = re.compile('WAFVERSION=[\'"]([^\'"]+)', re.M).search(f.read()).group(1) + def sfun(tsk, text): + return text.replace('{version}', version) + for x in bld.path.ant_glob('*.txt'): + bld(features='subst', source=x, target=x.change_ext('_.txt'), subst_fun=sfun) + bld.add_group() # separator, the documents may require any of the pictures from above bld(rule='${ADOC} -a icons=true -a stylesheet=${SRC[1].abspath()} -a iconsdir=. -a toc -d book -o ${TGT} ${SRC[0].abspath()}', - source='waf.txt waf.css', target='index.html', scan=ascii_doc_scan) + source='waf_.txt waf.css', target='index.html', scan=ascii_doc_scan) - bld(rule='${A2X} -L -a toc --icons-dir=. --icons -D ${gen.path.get_bld().abspath()} \ - -d book -f pdf --dblatex-opts "-s ${SRC[1].abspath()} -p ${SRC[2].abspath()}" ${SRC[0].bldpath()}', + bld(rule='${A2X} -L -a toc --icons-dir=. --icons -d book -f pdf --dblatex-opts "-s ${SRC[1].abspath()} -p ${SRC[2].abspath()} -o ${TGT}" ${SRC[0].bldpath()}', shell=True, - source='waf.txt asciidoc-dblatex.sty asciidoc-dblatex.xsl', target='waf.pdf', scan=ascii_doc_scan) + source='waf_.txt asciidoc-dblatex.sty asciidoc-dblatex.xsl', target='waf.pdf', scan=ascii_doc_scan) #bld(rule='ln -sf single.html index.html', shell=True) From 0da5029e356f1d29b29786a5c55a079ff73832c7 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sun, 26 Apr 2015 18:03:45 +0200 Subject: [PATCH 0011/1763] No more dia for diagrams --- docs/book/wscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/book/wscript b/docs/book/wscript index d71699ab49..8d06f3b9f9 100644 --- a/docs/book/wscript +++ b/docs/book/wscript @@ -91,7 +91,7 @@ def options(opt): def configure(conf): conf.find_program('a2x', var='A2X') conf.find_program('asciidoc', var='ADOC') - conf.find_program('dia', var='DIA') + #conf.find_program('dia', var='DIA') conf.find_program('convert', var='CONVERT') conf.find_program('source-highlight', var='SOURCE_HIGHLIGHT') conf.find_program('dot') From 9cafbf7580770318793a06a88af1e860b4980ae4 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sun, 26 Apr 2015 18:23:21 +0200 Subject: [PATCH 0012/1763] docs --- docs/book/conftest.dia | 867 ----------------------- docs/book/tasks_overview.dia | 690 ------------------ docs/book/waf-activity.dia | 1300 ---------------------------------- 3 files changed, 2857 deletions(-) delete mode 100644 docs/book/conftest.dia delete mode 100644 docs/book/tasks_overview.dia delete mode 100644 docs/book/waf-activity.dia diff --git a/docs/book/conftest.dia b/docs/book/conftest.dia deleted file mode 100644 index 6bbd2dea1b..0000000000 --- a/docs/book/conftest.dia +++ /dev/null @@ -1,867 +0,0 @@ - - - - - - - - - - - - - #A4# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Get one method# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Execute the test# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Error handler# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Failure# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #no# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #More tests -to execute?# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Success# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Fatal error# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Recoverable -error# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Start# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #End# - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/book/tasks_overview.dia b/docs/book/tasks_overview.dia deleted file mode 100644 index d38390f612..0000000000 --- a/docs/book/tasks_overview.dia +++ /dev/null @@ -1,690 +0,0 @@ - - - - - - - - - - - - - #A4# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Execute the build functions -from user scripts# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Have the task generators -generate the tasks# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Set the build order -on the tasks# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Execute -the tasks# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Save the BuildContext -data to the cache# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Start# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #End# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Read the BuildContext -data from the cache# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/book/waf-activity.dia b/docs/book/waf-activity.dia deleted file mode 100644 index d30cbb19b8..0000000000 --- a/docs/book/waf-activity.dia +++ /dev/null @@ -1,1300 +0,0 @@ - - - - - - - - - - - - - #A4# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Call the function "options"# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Load user scripts# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Parse the -command-line options# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Failure?# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Unpack the waf library# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #The waf library -is present?# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Execute the command# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #More commands -to process?# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #yes# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #no# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Command is -'configure', -or the project -is configured# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Error: configure -the project# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #no# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #yes# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #yes# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #no# - - - - - - - - - - - - - - - - - - - - - - - - From e230700c0a00872655dbd44dd3f9376284a9d503 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sun, 26 Apr 2015 20:36:48 +0200 Subject: [PATCH 0013/1763] Cache pictures in the repository --- docs/book/semd_cache/_build_overview.pdf | Bin 0 -> 9497 bytes docs/book/semd_cache/_build_overview.svg | 417 ++ docs/book/semd_cache/_classes.pdf | Bin 0 -> 18358 bytes docs/book/semd_cache/_classes.svg | 3376 +++++++++++++++ docs/book/semd_cache/_classes_build.pdf | Bin 0 -> 18734 bytes docs/book/semd_cache/_classes_build.svg | 3673 +++++++++++++++++ docs/book/semd_cache/_posting.pdf | Bin 0 -> 10238 bytes docs/book/semd_cache/_posting.svg | 702 ++++ docs/book/semd_cache/_prodcons.pdf | Bin 0 -> 12359 bytes docs/book/semd_cache/_prodcons.svg | 1802 ++++++++ docs/book/semd_cache/_source.pdf | Bin 0 -> 9489 bytes docs/book/semd_cache/_source.svg | 523 +++ docs/book/semd_cache/_task_run.pdf | Bin 0 -> 10724 bytes docs/book/semd_cache/_task_run.svg | 640 +++ docs/book/semd_cache/_task_signature.pdf | Bin 0 -> 10209 bytes docs/book/semd_cache/_task_signature.png | Bin 0 -> 41540 bytes docs/book/semd_cache/_task_signature.svg | 886 ++++ docs/book/semd_cache/_tasks_actors.pdf | Bin 0 -> 8621 bytes docs/book/semd_cache/_tasks_actors.svg | 279 ++ docs/book/semd_cache/_waflib.pdf | Bin 0 -> 10000 bytes docs/book/semd_cache/_waflib.svg | 625 +++ .../semd_cache/width1100_classes_build.png | Bin 0 -> 76509 bytes .../book/semd_cache/width250_tasks_actors.png | Bin 0 -> 11191 bytes .../semd_cache/width450_build_overview.png | Bin 0 -> 27439 bytes docs/book/semd_cache/width450_source.png | Bin 0 -> 22558 bytes docs/book/semd_cache/width450_waflib.png | Bin 0 -> 26534 bytes docs/book/semd_cache/width520_posting.png | Bin 0 -> 40929 bytes docs/book/semd_cache/width610_task_run.png | Bin 0 -> 27702 bytes docs/book/semd_cache/width850_classes.png | Bin 0 -> 90950 bytes docs/book/semd_cache/width900_prodcons.png | Bin 0 -> 91827 bytes docs/book/semd_wrapper.py | 35 + docs/book/wscript | 10 +- 32 files changed, 12962 insertions(+), 6 deletions(-) create mode 100644 docs/book/semd_cache/_build_overview.pdf create mode 100644 docs/book/semd_cache/_build_overview.svg create mode 100644 docs/book/semd_cache/_classes.pdf create mode 100644 docs/book/semd_cache/_classes.svg create mode 100644 docs/book/semd_cache/_classes_build.pdf create mode 100644 docs/book/semd_cache/_classes_build.svg create mode 100644 docs/book/semd_cache/_posting.pdf create mode 100644 docs/book/semd_cache/_posting.svg create mode 100644 docs/book/semd_cache/_prodcons.pdf create mode 100644 docs/book/semd_cache/_prodcons.svg create mode 100644 docs/book/semd_cache/_source.pdf create mode 100644 docs/book/semd_cache/_source.svg create mode 100644 docs/book/semd_cache/_task_run.pdf create mode 100644 docs/book/semd_cache/_task_run.svg create mode 100644 docs/book/semd_cache/_task_signature.pdf create mode 100644 docs/book/semd_cache/_task_signature.png create mode 100644 docs/book/semd_cache/_task_signature.svg create mode 100644 docs/book/semd_cache/_tasks_actors.pdf create mode 100644 docs/book/semd_cache/_tasks_actors.svg create mode 100644 docs/book/semd_cache/_waflib.pdf create mode 100644 docs/book/semd_cache/_waflib.svg create mode 100644 docs/book/semd_cache/width1100_classes_build.png create mode 100644 docs/book/semd_cache/width250_tasks_actors.png create mode 100644 docs/book/semd_cache/width450_build_overview.png create mode 100644 docs/book/semd_cache/width450_source.png create mode 100644 docs/book/semd_cache/width450_waflib.png create mode 100644 docs/book/semd_cache/width520_posting.png create mode 100644 docs/book/semd_cache/width610_task_run.png create mode 100644 docs/book/semd_cache/width850_classes.png create mode 100644 docs/book/semd_cache/width900_prodcons.png create mode 100755 docs/book/semd_wrapper.py diff --git a/docs/book/semd_cache/_build_overview.pdf b/docs/book/semd_cache/_build_overview.pdf new file mode 100644 index 0000000000000000000000000000000000000000..1cd410019f92028f1962ad24af835cb239b2d954 GIT binary patch literal 9497 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 + +Semantik diagram +Generated with Qt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Read the BuildContext +data from cache + + + + + + + + + + + + + +Call the build functions +(user scripts) + + + + + + + + + + + + + +Have task generators +create tasks (post) + + + + + + + + + + + + + +Set the build order on +the tasks + + + + + + + + + + + + + +Execute the tasks that +need to + + + + + + + + + + + + + +Cache the BuildContext +data + + + + + + + + + +Start + + + + + + + + + + + + diff --git a/docs/book/semd_cache/_classes.pdf b/docs/book/semd_cache/_classes.pdf new file mode 100644 index 0000000000000000000000000000000000000000..0764986bb83d97fc39d8a21572f949668c1197eb GIT binary patch literal 18358 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 literal 0 HcmV?d00001 diff --git a/docs/book/semd_cache/_classes.svg b/docs/book/semd_cache/_classes.svg new file mode 100644 index 0000000000..7a277895ee --- /dev/null +++ b/docs/book/semd_cache/_classes.svg @@ -0,0 +1,3376 @@ + + +Semantik diagram +Generated with Qt + + + + + + + + + + + + + + + + + + + + + +UninstallContext + + + + + + + + + + + + + + + + + + + + + + + + + + + + +«metaclass» + + + + + + + + + + + + + + + +store_context + + + + + + + + + + + + + + + + +classes: List<Class> + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + + +create_context(name: String): Context + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Context + + + + + + + + + + + + + + + + +root: Node + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +path: Node + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +logger: logging.Logger + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +node_class: Class + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +cmd: String + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +fun: String + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + + +execute() : void + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +recurse(dirs: List<Node>) + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Node + + + + + + + + + + + + + + + + +ctx: Context + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +name: string + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +parent: Node + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +sig: long + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +children: Map<String, Node> + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + + +abspath(): String + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +make_node(path): Node + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +find_node(path): Node + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +search_node(path): Node + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +find_resource(path): Node + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +find_or_declare(path): Node + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +BuildContext + + + + + + + + + + + + + + + + +env: ConfigSet + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +srcnode: Node + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +bldnode: Node + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +groups: List<task_gen> + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + + +store(filename): void + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +load(filename): void + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +install_files(): void + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +install_as(): void + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +symlink_as(): void + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +get_tgen_by_name(name: String): task_gen + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +add_group(): void + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +load_envs(): void + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +ConfigurationContext + + + + + + + + + + + + + + + + +env: Configset + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +srcnode: Node + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +bldnode: Node + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + + +find_program(String): String + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +ConfigSet + + + + + + + + + + + + + + + + +parent: ConfigSet + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +table: dict + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + + +derive(): ConfigSet + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +store(filename): void + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +load(filename): void + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +append_value(var: String, val: String) + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +append_unique(var: String, val: String) + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +prepend_value(var: String, val: String) + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +ListContext + + + + + + + + + + + + + + + + + + + + + + + + + + + + +CleanContext + + + + + + + + + + + + + + + + + + + + + + + + + + + + +StepContext + + + + + + + + + + + + + + + + + + + + + + + + + + + + +InstallContext + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +parent + + + + + + + + + + + + +children + + + + + + + + + + + + +root + + + + + + + + + + + + diff --git a/docs/book/semd_cache/_classes_build.pdf b/docs/book/semd_cache/_classes_build.pdf new file mode 100644 index 0000000000000000000000000000000000000000..a313b1594430df1c83cdfcfd26f5ddd7c1a4e5bc GIT binary patch literal 18734 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 + +Semantik diagram +Generated with Qt + + + + + + + + + + + + + + + + + + + + + +BuildContext + + + + + + + + + + + + + + + + +env: ConfigSet + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +srcnode: Node + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +bldnode: Node + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +groups: List<task_gen> + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + + +store(filename): void + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +load(filename): void + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +install_files(): void + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +install_as(): void + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +symlink_as(): void + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +get_tgen_by_name(name: String): task_gen + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +add_group(): void + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +load_envs(): void + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Parallel + + + + + + + + + + + + + + + + +numjobs: int + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +frozen: List<TaskBase> + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +outstanding: List<TaskBase> + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +out: Queue + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +ready: queue + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + + +get_next_task(): TaskBase + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +task_gen + + + + + + + + + + + + + + + + +env: ConfigSet + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +tasks: List<TaskBase> + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +name: String + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + + +post(): void + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +create_task(cls: String): TaskBase + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +«metaclass» + + + + + + + + + + + + + + + +store_task__type + + + + + + + + + + + + + + + + + + + + + + + + + + + + +TaskBase + + + + + + + + + + + + + + + + +env: ConfigSet + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +classes: Map<String, Class> + + + + + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + + +run(): int + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +runnable_status(): int + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +post_run(): void + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +uid(): int + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +TaskConsumer + + + + + + + + + + + + + + + + +run: void + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +ConfigSet + + + + + + + + + + + + + + + + +parent: ConfigSet + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +table: dict + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + + +derive(): ConfigSet + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +store(filename): void + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +load(filename): void + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +append_value(var: String, val: String) + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +append_unique(var: String, val: String) + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +prepend_value(var: String, val: String) + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Task + + + + + + + + + + + + + + + + +inputs: List<Node> + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +outputs: List<Node> + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +run_after: List<TaskBase> + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +hasrun: int + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + + +uid(): int + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +signature(): int + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Node + + + + + + + + + + + + + + + + +ctx: Context + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +name: string + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +parent: Node + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +sig: long + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +children: Map<String, Node> + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + + +abspath(): String + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +make_node(path): Node + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +find_node(path): Node + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +search_node(path): Node + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + +find_resource(path): Node + + + + + + + + + + + + + + + ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Use + + + + + + + + + + + + +Use + + + + + + + + + + + + diff --git a/docs/book/semd_cache/_posting.pdf b/docs/book/semd_cache/_posting.pdf new file mode 100644 index 0000000000000000000000000000000000000000..dbbc67d157c3d8b2e9e96ba3050f836cdd88f0ab GIT binary patch literal 10238 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 literal 0 HcmV?d00001 diff --git a/docs/book/semd_cache/_posting.svg b/docs/book/semd_cache/_posting.svg new file mode 100644 index 0000000000..d2ea20aa85 --- /dev/null +++ b/docs/book/semd_cache/_posting.svg @@ -0,0 +1,702 @@ + + +Semantik diagram +Generated with Qt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Pop one method +name from +self.meths + + + + + + + + + + + + + +Execute the method + + + + + + + + + + + + + +Take a task generator +instance which is not +"posted" + + + + + + + + + + + + + +Turn self.features into a +list, and add '*' + + + + + + + + + + + + + +Add all the corresponding +feature methods to +self.meths + + + + + + + + + + + + + +Perform a topological +sort on self.meths using +the precendence +constraints + + + + + + + + + +End + + + + + + + + + + + + +Yes + + + + + + + + + + + + +No + + + + + + + + + + + + +Are there task +generators to +process? + + + + + + + + + + + + +No + + + + + + + + + + + + +More methods to +execute in +self.meths? + + + + + + + + + + + + +Yes + + + + + + + + + + + + +Start + + + + + + + + + + + + diff --git a/docs/book/semd_cache/_prodcons.pdf b/docs/book/semd_cache/_prodcons.pdf new file mode 100644 index 0000000000000000000000000000000000000000..04e3a3577d9e92757de6fd6a95e0189743995fc6 GIT binary patch literal 12359 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 + +Semantik diagram +Generated with Qt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Get a group of task from the build +context (list "outstanding") + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Move tasks from +"frozen" to +"outstanding" + + + + + + + + + + + + + +Wait for one task +from queue "out" + + + + + + + + + + + + + +Get a task from +"outstanding" + + + + + + + + + + + + + +Get a task from +the queue "out" + + + + + + + + + + + + + +Add task to +"frozen" + + + + + + + + + + + + + +Add task to +"ready" + + + + + + + + + + + + + +Execute the task + + + + + + + + + + + + + +Notify the +producer to stop +the build + + + + + + + + + + + + + +Put the task +into the queue +"out" + + + + + + + + + +N consumers +(Runner.TaskConsumer) + + + + + + + + + + + + +1 Producer +(Runner.Parallel) + + + + + + + + + + + + +Build complete + + + + + + + + + + + + +Yes + + + + + + + + + + + + +No + + + + + + + + + + + + +Waiting tasks (list +outstanding) or tasks +being processed? + + + + + + + + + + + + +Are there tasks in the +list "frozen"? + + + + + + + + + + + + +Yes + + + + + + + + + + + + +No + + + + + + + + + + + + +No + + + + + + + + + + + + +Yes + + + + + + + + + + + + +Are there tasks +being processed? + + + + + + + + + + + + +Are there waiting +tasks in the list +"outstanding"? + + + + + + + + + + + + +No + + + + + + + + + + + + +No + + + + + + + + + + + + +Yes + + + + + + + + + + + + +Are there enough +tasks in the queue +"ready"? + + + + + + + + + + + + +Task +status? + + + + + + + + + + + + +Ask +later + + + + + + + + + + + + +Execute + + + + + + + + + + + + +Skip + + + + + + + + + + + + +Wait for one +task from the +queue "ready" + + + + + + + + + + + + +Error + + + + + + + + + + + + +Ok + + + + + + + + + + + + +No more task +to process + + + + + + + + + + + + +Task +obtained + + + + + + + + + + + + diff --git a/docs/book/semd_cache/_source.pdf b/docs/book/semd_cache/_source.pdf new file mode 100644 index 0000000000000000000000000000000000000000..1cf044cb81f18154b2966053f5f49daadcf8ad2f GIT binary patch literal 9489 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 literal 0 HcmV?d00001 diff --git a/docs/book/semd_cache/_source.svg b/docs/book/semd_cache/_source.svg new file mode 100644 index 0000000000..1c840e4fda --- /dev/null +++ b/docs/book/semd_cache/_source.svg @@ -0,0 +1,523 @@ + + +Semantik diagram +Generated with Qt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +No + + + + + + + + + + + + +Yes + + + + + + + + + + + + +No + + + + + + + + + + + + +Yes + + + + + + + + + + + + + + + + + + + + + + + + + +More entries in +self.source? + + + + + + + + + + + + + + + + +Create a corresponding +Node object + + + + + + + + + + + + + +No mapping, raise an +error + + + + + + + + + +Is there an +extension +mapping? + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Execute the extension +mapping function on the +node + + + + + + + + + +End + + + + + + + + + + + + diff --git a/docs/book/semd_cache/_task_run.pdf b/docs/book/semd_cache/_task_run.pdf new file mode 100644 index 0000000000000000000000000000000000000000..0c61977e91f0020427bbf8ad2348393c29ff2798 GIT binary patch literal 10724 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 literal 0 HcmV?d00001 diff --git a/docs/book/semd_cache/_task_run.svg b/docs/book/semd_cache/_task_run.svg new file mode 100644 index 0000000000..b17dd04c23 --- /dev/null +++ b/docs/book/semd_cache/_task_run.svg @@ -0,0 +1,640 @@ + + +Semantik diagram +Generated with Qt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +SUCCESS + + + + + + + + + + + + + + + + +Compute the task status +(runnable_status) + + + + + + + + + + + + + +Execute the task (run) + + + + + + + + + + + + + +Perform additional +verifications +(post_run) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +ASK_LATER + + + + + + + + + + + + +RUN_ME + + + + + + + + + + + + +SKIP_ME + + + + + + + + + + + + +CRASHED: +non-zero +exit status + + + + + + + + + + + + +EXCEPTION: +Python error + + + + + + + + + + + + +? + + + + + + + + + + + + +MISSING: no files + + + + + + + + + + + + diff --git a/docs/book/semd_cache/_task_signature.pdf b/docs/book/semd_cache/_task_signature.pdf new file mode 100644 index 0000000000000000000000000000000000000000..fb5dc55fe8ad3584f941046821eca81c86814f0f GIT binary patch literal 10209 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 IZDq3m1I9*$HUIzs literal 0 HcmV?d00001 diff --git a/docs/book/semd_cache/_task_signature.png b/docs/book/semd_cache/_task_signature.png new file mode 100644 index 0000000000000000000000000000000000000000..b47dd5a2aacf57b586f173faa12ce1ea688a78aa GIT binary patch literal 41540 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�HzTYyJ26~KSJI@zUw`~h;eeQ!w}Kgx6Gxe; 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 literal 0 HcmV?d00001 diff --git a/docs/book/semd_cache/_task_signature.svg b/docs/book/semd_cache/_task_signature.svg new file mode 100644 index 0000000000..2f7f22d6cf --- /dev/null +++ b/docs/book/semd_cache/_task_signature.svg @@ -0,0 +1,886 @@ + + +Semantik diagram +Generated with Qt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Compute the task +identifier (method "uid") + + + + + + + + + + + + + +Compute the task hash +(method "signature") + + + + + + + + + + + + + +Execute the task + + + + + + + + + + + + + +Associate the hash to the +task uid + + + + + + + + + + + + + +Associate the output +nodes with the task hash + + + + + + + + + +Is a previous +signature +associated with +the uid? + + + + + + + + + + + + +Do the current +and previous +hashes match? + + + + + + + + + + + + +Are the output +nodes +associated with +the same hash? + + + + + + + + + + + + +Yes + + + + + + + + + + + + +Yes + + + + + + + + + + + + +Yes + + + + + + + + + + + + +Yes + + + + + + + + + + + + +No + + + + + + + + + + + + +No + + + + + + + + + + + + +No + + + + + + + + + + + + +Has the task been +successfully +executed? + + + + + + + + + + + + +No + + + + + + + + + + + + +End + + + + + + + + + + + + diff --git a/docs/book/semd_cache/_tasks_actors.pdf b/docs/book/semd_cache/_tasks_actors.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2742f94abdf2c07b950bac12273b8562b1d8540a GIT binary patch literal 8621 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 BpS=J8 literal 0 HcmV?d00001 diff --git a/docs/book/semd_cache/_tasks_actors.svg b/docs/book/semd_cache/_tasks_actors.svg new file mode 100644 index 0000000000..8135945c42 --- /dev/null +++ b/docs/book/semd_cache/_tasks_actors.svg @@ -0,0 +1,279 @@ + + +Semantik diagram +Generated with Qt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +BuildContext + + + + + + + + + + + + + +Task +Producer + + + + + + + + + + + + + +Task +Consumer 1 + + + + + + + + + + + + + +Task +Consumer n + + + + + + + + + +Get tasks to +process + + + + + + + + + + + + +Process +tasks + + + + + + + + + + + + +Process +tasks + + + + + + + + + + + + diff --git a/docs/book/semd_cache/_waflib.pdf b/docs/book/semd_cache/_waflib.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c22565effa5b339afd5b995c5788e9b2a8400b42 GIT binary patch literal 10000 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 literal 0 HcmV?d00001 diff --git a/docs/book/semd_cache/_waflib.svg b/docs/book/semd_cache/_waflib.svg new file mode 100644 index 0000000000..763cd9026a --- /dev/null +++ b/docs/book/semd_cache/_waflib.svg @@ -0,0 +1,625 @@ + + +Semantik diagram +Generated with Qt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Does the environment +variable "WAFDIR" point +to a folder containing +"waflib"? + + + + + + + + + + + + +Does the "waf" folder +contain "waflib"? + + + + + + + + + + + + +Was the .waf-version +folder extracted from +the "waf" script? + + + + + + + + + + + + +Is the local "waflib" +folder usable? + + + + + + + + + + + + +Yes + + + + + + + + + + + + +Yes + + + + + + + + + + + + +Yes + + + + + + + + + + + + +Yes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Unpack the stream +contained in "waf" + + + + + + + + + + + + + +No waflib directory, +raise an error + + + + + + + + + diff --git a/docs/book/semd_cache/width1100_classes_build.png b/docs/book/semd_cache/width1100_classes_build.png new file mode 100644 index 0000000000000000000000000000000000000000..a0556f2b1d5616b291486b9defba44af7258cd4a GIT binary patch literal 76509 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

}W4VV`FYU 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 literal 0 HcmV?d00001 diff --git a/docs/book/semd_cache/width250_tasks_actors.png b/docs/book/semd_cache/width250_tasks_actors.png new file mode 100644 index 0000000000000000000000000000000000000000..66e10be3f999c23b6be03bb4ab379a75dc35742c GIT binary patch literal 11191 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 literal 0 HcmV?d00001 diff --git a/docs/book/semd_cache/width450_build_overview.png b/docs/book/semd_cache/width450_build_overview.png new file mode 100644 index 0000000000000000000000000000000000000000..684af7de26a104de795e40766b359d5f9247cb2c GIT binary patch literal 27439 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ðVQ^5&Jx> zV{Rw`qf2Joz;(ZC$K~iTBJdYG#@W6n9_^L^PT55$83NY851dMqO=@p4{L)P?Y+S;) zy3Jp5B+OrfWtiMnh_SMCaT&U_)2g2%#xXH8EYD^xn}+ov>k{Wr7e73ULE>O0IOTa~RwZO6!e7-)FSs9l10y4#o^ z2zURO{tB#j-|B1#!qh@;x07Z+8U56JJgMBwSZF0M0&SL-gt1}k7>~q#1KVp^>+ry% zgUV3qJLbYJpvXUrqn$7$$GdlHg2+~trb^S=EcT*UK{R~VcX|-YT!(+}B)?~BDsJ^& z66{|pOU*Ux98r;lJ|FwMVIS^Al$;Yx`YAbwvxy(?Rd|wG(&u!wM=kaaHr**JIQUm^ znQ4&*SG>k3^FfRJqslX-&z`Zo?ce@0+}&xs&@$F!`RZAwstl+|AwXS90cERWyE$aG zLvYvK=bl@;5@!61_Q%FeSY5Lot_FvtDZSQ0oF9HcfV$s!aP4o7pxfKi5Vb{$(cwuY zYcDAdTn_sjC=^;Y?}G*z9v=RBAAtY&NPNgHqHG?H&r$F(_M?guhoQ}W3jKHp^*O98 zZM+_~5L>~>ewcoEMBov4>+CfhH@-G<>+P7EopVyoZwu3M{j^Tqxhdr5iBYuoz7>;= zS$Em%;=!$xtqx~`J@Xc9-0j|yJpW|9)}b8<(_e0O+wqom%2*V=UC>mInwbc(ftms( zaid{_bUvr1h8z)53iFSpB_D?@(n>7wOKA^i&URS1`ICIZ^&0u6 z&VunoHM_>SFrQ`YuQy2wbQlBr=#7vvu;eSnD=Ee+&BV_r#!Zi!ghk+g6psABOKhFf z*yzHHXEr?_D;qvt*gr538Ul{cbWC1PwKD|@bOj|PQ9w0Np@|YHR6z9YIXbeXchwl5 zJh5v1$8Pbxxc)i{CENT0UvRIsg&?M9W#)~(T#^K_9s`a9$iM1WsnC!c8Of7iC>uFp z8({;{1aNTOvx-t!t)?Z&vL;C=DLfr#H3dhaV|r~rv{h6n&_nx{sN+O-B;b8T*%|Z) z^d;}_;Ln!W$2%LNFU(wcg=ZpOT@s3amV+bzAOQ~~;VV_9+1Sj<24?%FhI)qj#`?gq zv_#Og^x#{o)OE;+WM}^a#azq6!UDj5Z2tSV(?pb!2Rc2U$IW&V zRt7FLbulPJqS;{W?T(P2t=0*m_OkiWIvb8uqmlHa#KdiIJy{lzzA!envMS#Ta5n|Y zD^*4#1Y|KghlhlOgkA@8teW)&$i7U70^I)&53PU_34nh5`-eq9P`0;Oqx00V{ENfo zjHsxNRcr9i49v|-{?7?aME}Ak&)8NZ5|Gb1$Bu38R*NGFV4;l<>lo7@c?Sj2nq@U z!3hfsT7SrFg^q8T`V83@oL8CnE;nZ;;Q1czZ$VKU>!-pkH5C;MtgM0v_+0ke^~;{O z*IOCqXWuzo_5{H7tpz0|ADIo2IKQzF5fPD+3eqKre@3ULF9)y*Y3UIlu>qT_-TOo6 zHR&Ke|KaHsV9V!8sMeY)0zDC3Jw2c*W5ASjLuqGsy1#D@e%H{zp{_pv^Cud9UG{8lc%bG<1G( zA%p<1WvofIBdgY)H#_90sF9tW5P!&V2j1U+|1P7Tqk}ECw}Z@JXpiJDsI)=AQi6uWNAqUF<$Eq zX2C5zMv91t0L35xI3K8OSciHPKiNkU)UkLSphFyGJXNIl0v^fuh$dx73&2`H^DUQJ zI9<<-(`qUXe4a}K%dlH6`~}b+Y5sdZG+a>L2+Ryu?tK1`%KG|9F!GU+OG`@bP6p_K z{zuVXd>!Lc*AZr7X7;*0s0XSefbYZS?)>=Rfq@YN`jM)N3J<8)13+!Oyo#da0Kbwn+A`u3KZh%4xooZDMs5{fq(eV)l%#8UB4OhKUB)6A`^;K2l4tVnf9C)uX z7gtZOO-xKcieH0HnF7<*&Fyk;hMt8*VdlWJ_-TN7u5w7_$~i2Cu%QCGJTra;&jWJ* hO5oK0<>v$H%Z=D~y79sDK!fR-sG!uhGRSwI{{`H;PoDq) literal 0 HcmV?d00001 diff --git a/docs/book/semd_cache/width450_source.png b/docs/book/semd_cache/width450_source.png new file mode 100644 index 0000000000000000000000000000000000000000..3fc7cd4921f670f8977780feaf64aec9c78e6bf9 GIT binary patch literal 22558 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 literal 0 HcmV?d00001 diff --git a/docs/book/semd_cache/width450_waflib.png b/docs/book/semd_cache/width450_waflib.png new file mode 100644 index 0000000000000000000000000000000000000000..e17baeb7f2311d4fb52702ba781433f0a9b1f806 GIT binary patch literal 26534 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 literal 0 HcmV?d00001 diff --git a/docs/book/semd_cache/width520_posting.png b/docs/book/semd_cache/width520_posting.png new file mode 100644 index 0000000000000000000000000000000000000000..92d4c3fe6167566af59a72d8be23e5c0dd3ed2a9 GIT binary patch literal 40929 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ġ$jp>I3&Qwl}$-a<#&nf zZvXW*jF3krN4__NP?~r(CZ>s_-d9Xry~$(6TL5we<@~_D8F&5yPZ&4sv3CV!JU?Or zVg&_~`#aUGUpO8|DTi@HWTftj;CK$}3nngFp#F~^qg@t^V3B~Ml%Aef4~<0sf5IbI z`xrDdMLs?Qp;j5FGL0>+r;qRP9=o&kv;XN=0z}iRLyXWjLww@fhTX!IPdzCFc=*$9}V}W8@%b?*@q8Sn=?u2 z?vB#mU_tIOrVvxsSuD`+qWM5RU?wiqy|^V_UUuBQ=i=fbal7gN_m7;a?L89QT#MO^ zhJS;B`T4L$ zQhyln5+Wlj?ep^*p2XijRDcrMyA-xMF3xFXneRqKq2i0wCJBK2pAEsCy!k?7m7y~= zGhw#(4)X8p?Cj8z=AVP{^&Wi#1E-_;lB}#w&-q(S+>9FYiizSq_KIHQlEht(@p&mp zIgQ?O|Jn>nk!@|_13ODYHAfx8v#NtKm_(#Y?Iyd?b|G(i_{S|`N*+XbU)#NL3OqbK z6BCoJ1I)y(B4rr>Ede38Cz-LSDV?3I>2rtz9UZE$J$DO+;(Nd3ZamOPv_1a$oN|l zz2HVp(pVkfWH*f38hreBP=;E3U@|Bf*4A3y3ezg_l~m^XDJi@{vQt3T0_02b+U~=* z@pI~JPDEL)Sr5{S$E{z4e%*MFKvdHO^vQe%N`ZvBQDUE5b#-NV8XH(FR6?7*a{~;F z7^UImTg*g-JT*t@Y&Du^kGeHPP_SvJV6jfjwQ zlY$YPSoK38>Avtofw;XpX?qz?;lY~Q+!=!SDFE>$N)va{90<##f5#t=uNvY(Kp5k8 z>Bm8HEC6I`g4=ix^eRB4vv|k9HW1wY|9U_}wSNP_>MNY#>{7C2DW|NwQf+c^?{LuU z;SL-ZRk+S_X>e#LMZoKg@JBMTC!p>C03Khp8?9P3c4v7{Q&U4j6&~C>Z;)X5c4vR~ zN3y*kL6vy8KCxnS`0*pXxf$}|?CxTRkl*swJ_;U{W(xY?TE z2~yA-L5w0LCB=U0?Eggs6AR1g^sE8f3y$Oxv@FmiaWvG|%fvIDU4YEvk=?aab-~$b zI37DVCMKn2$m`(tY+E5$hR*i`xplB0jz*r;|S@=L_{r$6avOBuhWv zyfwG509z;C$?%e~u|7C9_t)1O3_~L$(Nv=c_oPT808)+1O6v3MbU(S|b|XQKCLHil zI3zI8#=-7?Vb*6GLk&AYfq`cW^=Fqa&#%Z7yO$9(BJOuJwfn7sxKutj+q&NF?z_9Y znmc<4dufy?!P%JD*u^HNu#4})!X1;7A4ooY_`qx9eFtvJaHvuU76S__H~?i9XYTSC zq%VsE{~ftir2wD{CYgr}RoLVH8W9doM_~E?hHrDqya0X-8HZU#Osp|sqb@onWhoGy zirsSYpNY%MGoPQ1$HTQn9!^vA<>e)Vc58HOtkO4{{A!?Zgjd4|l`PR`j4vU;H4DC< zw@?3*++YzLdqnxQtRyBnGBPqcG9or2B03^AR_^=v$(b2tB_+$J+t-HyAfQ&Oec;7+ zQBhxlChc`L1?Eo$O{=Va$QBcB~dj&sW|1$JpaZ+8JA?9NHx zdccae_SEG54#jL1^}&JVMfvyHT}rQKXpfmIWXQ>&MmL*TV-L@ZkXsOXyu(6m)FwD$j*-c`@h>r#HFdbKEN^BUtYUy`CN(uBCu^_-1C!Ez z{J6?H)Hkf8sIbAS*=RpU9vnDPT _t`_Pc*!Nt}kef>hBqzOp2nbZ$S4ilNHvVof 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 Yv!dv_BDVK{ej=owD@YWIzk2sS0Blmi^8f$< literal 0 HcmV?d00001 diff --git a/docs/book/semd_cache/width850_classes.png b/docs/book/semd_cache/width850_classes.png new file mode 100644 index 0000000000000000000000000000000000000000..d962ecce4043cccb2d67336159b02444dfbeba47 GIT binary patch literal 90950 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 literal 0 HcmV?d00001 diff --git a/docs/book/semd_cache/width900_prodcons.png b/docs/book/semd_cache/width900_prodcons.png new file mode 100644 index 0000000000000000000000000000000000000000..212a3bfd7d379e872d9c2a37cc24ed7ec15cd34a GIT binary patch literal 91827 zcmeFZbyQSe-#0u45=tlt(xQ~4f`GJ+Gz=wOBhuYnDj*Hg-Q5yHhtl0Oq;z-ZJe%Kj zUH7xreLw#_>wVYz$2)7mFfg1sd!N0(@rmOnD=mtRMS=x^K(NKdgybQRdtTs+7~?MZ z&G?AfK6tuk0~J@mz`&TAm-!1`Vp@u++CU&UwBTP*clJIlA3`9{A>u+G6dV(_W*ju| zPf_T5GS9Ss@C)g^N|7RZo>pNzI#%%okwcF4F2B{=WvsB!Wxm^LSfH8|Gf|I7p07JJ*e)l-|gFP=wIDA)RrR<2B!dl#H2La z{`14$36$;j>>+_4{vUcC)Zu|ZzH+JQ>FIs>@PJNkB~G4#YVAjZRwG^gKeWODNlWM#e4zDm(E%Uw)8SqavAb|X((bCd-_3Bk|!OF^t{d|*mFgY*h zM==Pb@R>6>ww9QLL|0#5kxXw-PY*gS#alZ*@F$8eImlO{g~dfhxSG5qZMbH=Ga`5K z4#e>IXW(5(ovea_0?H>^=!IPPgL{xY&i7!N_r8aO;KuhB8R*H#^wVNLfc!Q4stZ2e zyGXN^gqV0VJ1aI;wOFe@j)wxw5N;ctcQ0FeL#Z@lqHiDBvh?zwKG8h!D-Bj)fQgI0Vp(C71Xt17xkids5(X=DB0!v= z^-6`TL%xb1eGMooVhL!?lYtQiWaj5z#__tHY{iOEJNJq}ASvfaTqTgWJ97&z}!=aC>`unCpvq8ZnVMEnG_4A3olg-c71FBp7JCnAB^Ij$+waSc*V+xOZ`Sc{D5w6|=WL*FF_0QW`5M zDLF+2WY-D~4GrnC#b!z4+t>u4F3(r(HpjX$N|zax?w?{k!SW`bliA->XlYI4%LdU|8SI8`>MhSe;Y-4TsC-GUVkZ$vFnZcWuH zYcUs#>cKCxKBdYgyt8`o;>Fb@V)I2PJu7Q}Yb(vmm(3vROiw2iF%bqN3%Ct6)TeuU zdzYg52{kQSYiek$g~;bd#3$`6Z^Jx57&~j^bw^KrK5vl1hiT^IIwoGTH4#MPgPosv$!W|X%(>)rKYA* zP*Ctu$ZR(h6fj{@DMcwAHR=&YMJ+EcGZ8YfvmXwmQm*qTDh|=fu(`TjV^H1P+yTMH z3y+J7>q33h&1hBXLp>F-_m9EBL1KRAqa96Nuw>cU*c94%6-2c$sFaH|VtEaMeSAcv z&4Y`AS*X1FSMzbIjvisj^OmODmwOvNv((<`fk5hLYV0-%@$f7^qugOnkB*M=@-h%u zNK<=7#mIwn1vS0ThGH1nWyg`;U}n?kp&fmiwP<(mM0a1G_9g!MRia#^H9S0=f4-F~ zMlWv;MZwQK(`w>+_0?5W?jJu&+XUZ?$BX!{%f6+4DEzH(DjaejS_aY@c2s!yCwY0O z!^bg_-RB!3+JQkq(M(#l7e_{P2CHFVVM*Wa*u5>X*A*Q$444GhA|;nutJHQc<=f~e z7Gkaxxn(|6Yc^G5cM(X;!^5M@0yiITsQ2;l$;@2Nlq5pObr+VQo z7rwanq{i&|?tyi0yD_r93U?Ka4Fa>-I#)HJ_>BHW_1r&6gleEi5cv z>ZF6vDxRsBEuF-`#8h5dnz!0O;-;2j1;Sjtu7LroYH19fyn+e=k%LQXS0p$QA-%ef z+w_6y;o(I^Md4-aR4rXy49}m-4r`4BZ}|$nfTc6%fw1_V9pnY|D$BtPaeNNNiBi4I z8aopgwBv$;f-S+%zb}sGo;60njmYJ)0IbH5_I7A~!#H>Lb-TecXa=&wL9($7LEgf~b zEGr1WANW00n4%Ct$8E6q2pI!#31oS(bUuH69@+4$I5#hk+AD|La`0_wx>30>2bg@r z7a+kY3aATXoa>%h!iXuTyqf0=;3#HQlzgg>PdlYYLUDTUJ#?HQL8&-Cr=g`z#3UJq z@kowby7AMYcn=OetZO-B0|L>TRPSPNNNk3Clsra!zV#ozIJ$v?S0*ORjkHfuwo}Hb6t%MIXH8owkLj=X({|hw^ z+)_|h{zPDRp6mevQA9fP$B)oi)L*wyF$EQs2|iJ5Fa#KO=i1cfe6x@sJQnALpE1AcM;rCpl!ROB)CzX|zDM8V|XSeZt zn1OS6>*wbuE+Ydk)5jkE27#1A*FeUH81Cz`A=d`ev9PdWa58fD&ac*oH`S6eg>!Op zo)KRdiHlt5f9l9`>|ty?-WqVVl~$}2IRm>^Ov z_x+LQ`{QJP;p}!kw8xeR+0fd{JT0|6G%NCc8f= zm!)ZIZRxFclOr#$3n=drrpdUtDkSvjolO8n#`x&`3#1p}wJ^ zgDrmjtMkg5@oK|XxjT|9(fRz!$*yb#qPQrq`@TX@47ueR&#Nr=<>N+~P40~&^jL*)_{{HeNr)ZS35g%&?>K$G#J zVK`U|QBnH3hHFQS;&E>|^3}>dC@dCx9+*G%_yBp|{Q@rnA~^)5tI8Fh7h zJNDDQGNLiDvAHvx;3}W(;|EJi69^w~o|@~gu)Dcc7^jw%Jshliceq*5qoJuuUT+YR zp8k?5!=ur?y1H6lU;jVF&Vzr79pd^US5Pw6Roj5#UmBGztEQHhpD$^UhR7*`6`p)9 zEGXdEmW-^fZbe;R9fIhtCyzXM%J|&{4HRo43HT2s1FU;BJ1nTE)0t&v9DWPAaQ&IA zxd#IM|4!)4%*>;+_w&t^%z7_Ak$TKnR$@VzANw@FVr4B>ZTeCoB_;I;JBR>FSW$5~ z<%1`O+2;IU=U}JbY|G3{{qx3@`t3%7`1qiQw0HORUN0Q>-*q`DK=P;B|ByhKd{S3a&E;o7T*{N? zMMlzqyf!4E#Z2d=qN294yv(tXfN}pjPLYc35h&c4LpI1?8^y(cW}dyXy0ip#>cDkk z9@n4kNyMkAf~>gXj8`{2f6bpl)Y7CAd1&gd9;GEFCLZ9p{{8&{4of=f-p9`ic#RL8 z*dlt^Ql`>xKshd(V`a4>QrsgYH}XrH%JTuv!NJLw%`#NIji{U^3zz zvV{c2GDshw$)xcjAUf2+Y4sBIIt6LtQ?|4q>Yz-8iSzB-^2*A}($dLV3;0_0%NqM_ z5tPmwvx}pS;%xJoih2+YpFVxs9!&la6SD+?$Q;k2;5&0$o*WSt7S6kqGZPJV9Djdg zLxa0#ALi|zxw10OE4I*lnP5TspKJO({_l9>Jx&e|>~ooM?1LT-Y_ec=-~vL}^6Yv|jh`KVTrz zHor}qteT~^gH6KL)uv~AkCPu!YKblng@s+7?&9|L7pDjN`E@RJ!jIR<3uNhQ9Cj)2 z@We1m{zoAMx||d;9xe`!nOcjv9%6RTFHH{&yk=sW?&vVwig|;Eb`DCYWRHFC%uE_8 z-S$3BIk~cxzE~YSy+Vz6wa7`g$IuOrA`)9^4662EitD}fkhiUeQE4e?&ZmhErEKhx zl%QvyqvXrc_s;#4mB8&b*RBUY4{Yi!wZAB(TjUd5uEYLa* zuk?c27HjWxm-tysQqqpb>gCoExutue!|#kXm?e?mT%kJWFxMaK!u9oaWb<63I;epf z1orp$DdAk7 zr6&hdG|%x)%FD^UIa&+}zOp6o5dE4L6B7fv4i1wM+^?WP-Tcj-&iup;y~mcI5X-Hy z%a#C?PZs32sK?03(faU9(O|<1fJmL}%+&T01GI(l2LNeOIF*&hLHRD=bRe`{33oe= zY;5#k_W=-+8Wkw9WMA^}@zK(XAg($>U+T044wkDu2h|t>0Er+RO-)Sz1}IRY0GI;> z#q1S82g{XiQLB-G;bBtHTMed*nh?%b+q5?|rGd>RC5#3cxVXh?WM%9!C}z?C=Hdg+ z;XS{MjLfG`pOym-K~2MDKK+cxmcHy317nLhqJX?lFEi-BIbTh_bLS42N-%`c(NTbV zY4hAdKmP!3B-o^!TV0WiV3Xe00k|0K9^-3p8Z=ByTPwZsY_UwQUk|jk{aCjIpGf-8 zjAZ`$^&0$gV&d%YA5YK#OZnV`3`~BGp@5{YfcnDi;%MITU5C&eNZfaOXOZ3M>cgGd z-7ekIaf^T8#d321r-6K`$AiUDe%P}H>Lv^-&{r@Pf(`}p)gGW`k?VLP&9C{vOUP>x zlTP{?;oCpWs#t6-MobcCg#-q=UY%Ll*&&qF?&S#66C9koDl04hgE=vPfCk2hgM%Z5 zez!0jn(FKC|AhzZ_%#B*9HLyT#c%odw~XL*i|unTR2m*0wdZ(DYURG`?;&xdNwP9LJAOnWk<989QrpT=QBl11TZSu+;GvPrw$*_qzn!cK=r z5DNxEVU9&X+Cq}#et5NYYhPk*431EI41W$euYFGfcX%2-Xj%dTANi+Em{veje|9ei zwhTX~lS#bV+(@o8pMAUV?1W^2Rk@?LKnlhz)m!i`igRW3z_^A)7(?!yT}&>+UjBVO zgLsOu-gAc7PDy52R@CmYHFjgpm=gXoVXaB0#K*5HmAT!It=2czBO)=pGhfKXs?g)D zmmKZDr3oG~eE0N3KOsFruJtQ?H-R>yZZ5qW`{DJ@qdjqpC@rEi$(};)l`%3K6Pt=} z?m;;wlv>*Xm;Q|T*2s;?1mispw_~)zL*qQHOEtw;93{VOZK)Tqv~z#e2`OkXjOeY; zUh<~aNDS`IxKq{(+W!6hjo}Rkcc@s)yyY|0`0M`)bI8|_xVfpYKn4OVsBdua7=>gC zy?Z*rgO+t$zPS3g=m`6x!n+wq`-zF#^VD{Rxb70oBVLOjb$^1FwxP(Iv(OotsAIb zbX=I+sAg`9Cbl5!0mA`D?1DZ*OmjvjY^soG;@_EU zQpS;py{jm zZ`eV>t4IleN%{wz+m+KsN`QJDAPcLjt8;zi-}&0qjE zPKd~`-~Cc@Hkj@M5Oa=77(g!E0m|I<@uwIyDB7W^zw}cl_2Wh5<)2Vxq@;Ys1A{*N zA*gb)IJk?SGz~v+8wrpihzsxzIxok@A3C5ArZmmVmT386wU#4usyTP`0w2w6b7;!t zaF_7`j&lgektyeOPx;e{SX$g)>-sh%-FQztgu`N?7~(Kkq5!izOR>F!Lw{%I&GH#0 zI=T-a#)RDYM_XGtUV8HCZH)N(S{bY32ehI$3U(~+`=4KV&QVf(F{%9e**uR2y?^%) zUGtCFn3$!dm8$CM>%Ha>FFZtVgEYi=YUw}ZM=|0Qpc^b2zfx=r`bXMx<>cga+J8KT z0+eYBDcAMqbhqKse!)(UCv*W6$HlafwQ)>HKk<1J6&#`UT>t-m`y zuX+6uyxMC%+h2?gMuWsPPlX1ywXvwx3BlnO>tQsuY!Vo+SXdgIHY*AXnWMW4i;8Hy zdg6IkWqY(i$OBdRo$JdWGVU&rf)E^%lHCBkOuF3W8r8no+S*!dmwCs-Ek`g~JXaeV z+nuNg~a_aNpVI-%fP@-JSYkkL=)W|j{hkL78K*Yw^f*xU3|JF9wqeR4Lkd=^P;M% zsx%9yngyZ4dZ}HR%|?RNU5HxfSaKkicT*sp3~1=OzLZ$oIDth*NJ!{~=YfK#tE&SD z^nme+9~(P6F1hpUwz49P+W~d+_;~S$%Y(hOrL`p?4DAvXKyjd*qm7Mm#>JW0LX1t+ z)TeTGW`>5ke*ga6+8T-XMO%BYx@>irPNvSy^=%?OR17qV>s^3%h{MT?4VMF1>%u34 zB!m!TrT3cy7vY1AsEho(QfpBDdHn>bzVYUQ{jDuERm<;z6nzfPcr$J7$0O{%H_t}c zb2MvD?A~^NDN%TcG`)^{x|Zwv@7V-!w?Zwr77Ti+|E3xShlkTIzZktp^);{1U(U;u zfT3q{=Fw)Rr>D!(^8g;}s`dd$nzW-A@X!81L5aK;TDnW+9UVr8tE|33L5k`@z4|UL zE~Lby*w~m(D9=;j7mw@j{-g!u3IM*20_E&-Jj!5l!vg~YLqi8cnE_ruLE7u-VKOi< zfPw>HhqR}|SDp9%{wY-F!lZiewC6|Nf3yG(9)M!j<7ywBYH7Z?1<*bzQK!iY42tSb|E=4SUNwumkA}9sxqg1( zczJ%&(%wEUS9a6ODcnoW>tHt5Fw;M7uo6i8FYMn7kDNRa1b>`|nCp|R7NZBuRafKx={kYBK1TWwHJ~+p$lL{$k z+~ZVP`iS8(kE21K%Tr3j@gnjvDl7IXc;Kb!BIO*O|Hb7hX;`*DY?I5R71dUYA)UF=RFuIqj5YpdUD0&PW1+b1DKnw2+G$8$rh7R(w|f8&=K zBVuzVx#9ms9G5@42N>$9N1gO_e-{@?Nl2VeD$8Dku64)=z9D^-=w~i~k{|E*I_MUt zQ63utz*zV5<>)#0+M83GRa;wIfs3`5HCKN;(XTJ-YxR#eLIkd4xvl=Bc|R0+MA@Ks zm<1B_4{xuLYXvJ4MJ4L9olSD=$)#v=gDh+<$6aeEzV}Gimb!aP{8_ou{LNFJYFrZ{ zW676AuOMFu>mTEyHN`L1f4etF`tIjCy;xg#AZuIDELp9*9fk`SA?nK7Z6}R;lB75! zfzu3xmy*@~WC0ry)f}Gie9%M%1=XYAb%5EXqGo1>(S{q*e60Zr5;-B!nJw(%seTMgk@U$y)71)vJXEqt;HbJU^&>4=j>11GJuGqbSni5$PN zrJdZM)GI>{XTdyHXB^fsRmFp1H2^$TXFMw5OskCJGhAsgSEP9*5=2t{`Ns8wDsq#r z&GM!Lu2Um(J+U4j!xPB=Yr|KAc3k1GD>j~YW!vH?_-(cG$ykvvI%2jUub@0ZdS=>m zO05k02(Ecq_=d_+KL#~EX;y|TT0ge28kCH8q2YuWwyLSKNyv>bW~<9f{=V0 z9t2}QG&x#9EQ~8DFn6HX1{Lj;hs_0yzkHFmDPdfeDmwD$j%LkXb)Bg;ISq=hBxF)q zTUdBP$XSt+l44bRdHnahQATUZN&9+NwLO^5V{R-H=H&Mi??rf5GBrOVNnaC54SJiP5-)^I+m$VFtOXarV^FU6iev88o^P`)DBx^7mVpSvd(5b+cEy z^hW#T%Y^Til-5BtV)xf#bEFDP=f$mQ1&h6sm7%Y4z-dH=+0vnKqXSr@ z&@AS5CnzYdn@XEj+=(~a+i)g%O(9seCS|+Xs(9>_k3i+jMu*HL)LQmsSs>2c`E%cd zZ~p$~nK6|2iB9GzA)$Q4ixpWZMUHT!etbCnthVM*s~n{6jOSeTl6uT74jKAd(cb? zjkjKRgGO=t7=Dy*-Ce#F(+~yqLa2t7^Dd=u^%a}@`MR429<+`5yva*PLrvwRcf#Tr zd9j=c1qC8fJ^Kl?qJIjtXJ6_W;3j8Y^6kxK{O&5l)T=&Lag#P9|7@s+)5>or zf#Rw_xckcIt!%iP?nz_lMbF3<_OQKD_tW5=Z7gg5F;wYD+aHFVp=-^DxHY!+&QWpK ztp)QR+i;i`AFg1-=aJ2eR(#{#b029V{qBctmza>+49!t<^|jWsmq!;h>>ST6ipX4g z;aQ*Vo`C~{Loju)$oCmqf!9I94%N2S;Pud8Vg6#uKjYgCs?HMGvT%1ij}zI6tEuQS zao#)UxIX^OL`CiT$DoZ&2P!t5dC5z3wR<2ObY{tPD02yUFFEKOCYP%~f|~OHxYPOh zxx>N&29?(A?7svM3TkR`p{c2#g3jN8@Co2;z*|gK7S|7i%F_4r_HF~rh|whP!F$k0 zTFUN-F+^Gq5A)a8$$yeRLYg`+_g}QjcnHfyY^=!Vz6C0bzP_=^i>Cp4lGI^=kBR~U zOg?=0R$tHW)0~f5|a_?i0A8=49vSS?liLF$hsWHpNNvjN-U^)udM+6hd3 zXA2c+_V(3D3)`x6@Q{R&S?Js#5yC#A+%mfu2ALVI)PK# z-s`8;2X-u*GyCmP4H92eJsA{ zyB>z{3JOlk7(in~Y?cm;owrNKSS-4?_z&$xc-|pRuzYolYPK%9$NOg8pG7~ZHrFT| z==SgSs6xyPjq&j&X6Gp3K~GqC%jb^{Dp<^fG8bOmTRB0Mvr>8Kn3t|hqrVz=5)Aot%BRdp{2;ivV@4>p{R>YM!s2c zt;OXz0;lif`;&PCf$$B(fu69k7y37maErG`aRQQscCgdFsmI7Rq}FioyQr*goWAOl zsX`yCSMXv|_@V!fs@rTDnULP?N#UH87pGb+T6Ev}TQ~$3QHhG{-lZoWMR82O z;Mw&DXvcT7humb+a&m)bR*Ms+*F!_4KwDutUG9fhYB>MBs)`pNHhdKQ9UW)C{}AD- zEw8TjCvfYG=8YbSj>Z9e(hhw9VWO-zPMh4H{93y%F|i)-<3O(xA3udFnBy@fVRqHl z)^_*X-*D|_W3wB8aRMfzrm9L`*D_lwk>qh|3Eko(!lW!c4TKob*r_m$T^w(^JV4t& zze1L!gC1IF{Cua@f=)VSf}LIrfxH+u{hcYl+Br;@-YjB{va$O}cdAHfFBs7c;XmgWXxRQCe6MpV7gR$ga2kXI)tvW>s>{#9CE zu0@<=Y>%zYS10xV<~StsO%m<FZX15f|(_Uj3=pWMlnr z!TwI#j%OMxrSRiV5Amb>r0cSs$m=vo9s1K!{gjf zAu1{g6$4TLYa1J&!c>3yWbb|mBLMb>8ni4sM zM)zHPeE}PL`&@&oTP@T|-mdew>rzQprX(TIa7}h1s{vN^`gh}wP0pn0wTUrSia?S< znnz)-N3tR8`lDxjjz@VGU<5#qdb}~Z$uafjEhoUn0^!mQ!6z5be`gg&3aIz@ge{I= zI^mYXe^u6}GhegkyYCKuBH%FFYto{;Uv*x!R&q=^E1gN zkkl~ST(ug{I?eux8c#2KRUlAO^sO_<>1L}On0ls^-d4~A*a?a?C`?(ih z#k}M$`+CW-t|IG=WoO=!={-&=FJTqisxCO`sq9(&;z_HEV&o7_a`8(qF~-bFmg#M- zx=N{w1#C{E%s{**&Vgc86~#>VnW{JvD_C@}s>fcYNzGv~{`joRGKbe^bOC88Xd$Yx_T0)c&9#HIPoeSB(sT*gj4R7^;P>B15y+^(+g zZA^q7JUxi(%_IM=tp3Ria{R#{jrT_DkS9O+2p7A-b;0gZbaM=0GCrEG4AfE7K&iLI zF)R1d%axnX_Sg#+aMDw5WWrn+q2$YOd~`hRs)-%+=)2GTjyzo=)ULJohgbYWVX;r? zc=?r6Q&jBwGCsX3dV<+9e<(^COOnOk(b4&Ll-x6xhR&z^6Q}yCT<|xY)gU&uH&T)v z9d2Qw7_Sx|_FX$#tyP`!U-KvM@@nzfS3@1%6*lBdw@$wF;w>~DJ5|WW&J!xts9?nkYbNa4DDQ^aIx%_cW)2-jQ zcIQipR>@7CF;~pSN|!_ZdQ(c$hojorJV3K$D6-B9L`mdFEOQWP6JZKxv@tGm#7A~7 z9~Y>$e;A!#FUwAE|FKh7w{uLi@K0pa#XkuFtSN<{J0P*I2U0%*oNj)8{_*3-c6|3W ze12N(DvL8@H*mpUgvG?fJ~}H83GzJtJ~Ld|J5xzx9HODbZ#YuhHJi&)U+;n3-+Vp( zhNp&SGlcc<$U%83D>Qe$qeENASt^qtBD=AjQPl4GdwuXO4{y^;sHn2Rc1dfZOO=l_ zISIvU*oRkqE{yMyX(#5%wf#L^rZ+q5&KEVsb1U&#YFdewi-SX+WyeToub+MV)3}8w z!B~X`M~{)3PW8rs>E$70$rNvc?XvKtej&W2~Q)3MaY<8O8Ax;SPi5!x4wMY$F~ zS9AFrLr#)%((}s>_P&FD1%nEd0_MS!wPt++?2KjSgN26&ci!V0nVAgVa{J>&iS5DH zl-DA8Doi`Wyk~8_>i^>QU;gm0K3aRj<-m1;Ff=hC4HY{Y6s5d5TcrBmOyt>sJI6{A>xG*QUY`Axbk`5LpCTOGDf5u@Z!1Cg%`;AV-uCv4Dtmb)* zA~U7OmE1@{&glajDKW7#%MSExndEh1f(%)DSGT(U_BI~gT0Y0U&ng`Q0Qt%>8*6S( zPvYP}ll1|@qhON5^}g=S4pf#s-I0Z;#Ci82>&R09c;|)iD`9&78taXyw*iRtDQ0Z! ztW;np01s0$v*zYz0MC8=j#!7!mb8ubDBAlW)3JgC4Xgx}W>YJR+X(B{gV}nZQ36;%w{ig);gcamz#QP1FOJspb8qX0 zwNL@K6Wfsq83#?(xdH6WvEAX%6)!m)=C|U=YhYA-d{@aHH?hFUfGjfr8o>tOhv@3+ zqMdmO;IjOYNoSE%oZ_u$Gftqj(4lp2*f^?-1Ny3U;!KYQ+oQbPfs2(O^ z%r7ksGb`|5SVTVxY^V!r^Nr9>H7Hm5$a?LcG??X+BnQz)R2Yb)3jabNt`Eve1T8L( z%ea#b>#h8LElmHBTc6!5r=&d3RZv6eM(pg4p3glzV2iB_=6I%# zCGo+5N$xlySOWHtK$t#q950zGpC?r|AK(#PxdjmiY!8dBoNd5<2h58|n)5@}`;fOG zV<$a^`6c$-aT%f^QSiQBrbm~?$`O?L%l}i+P zo@$u2pjmGVvjI+mVD;+s=8p*|^>uvBR`)TTJ?iA}gq@?CozlSNWbc=mLGxJKG#Yj! zIMQepEc^6&pJ$v1@}8MGJqT>32pM)xZ-f3MpyhaQ&yeEwJlRI11sGVO-`dfV;N!D@ z{{0nDl{n-)Zv_Md7#P43$x99D$T$FG1!yPEoLVut!k?Ja`gPMBDH90m@i_xl?^FIw zct#IfLyACWgRGFJP^M67DiMhey?Y8(nK zx6*iZWFBO{Vl65LM-Dp*Ov|C`j76?j_uBbF_LQ1myXj2VI^05*KzO_~dH~>B3n;|8 z+I2W9h)z0TKzsdYXV~R%h50B?&Y}UyzG{kWIFDvF5EbTduhY_CG1?eBKR;Y8Lv8{0 z5SO{RTqc%WtKZrj=-l*#_2|+(K!0|jADHTw`b&z8+wfaSuAIA4YPjen0#zA<7v?PJ zHhKoz=6MHDl;ET{SK;E6V}l3v-I%0V+qUal3K89OOk)KwIQP3LvzQ8#xk#9;H{}=^ z`I}{(MlG#el-0QOKwVNgPGd262iGs{#Q>BkptR)@iizef!=sc@fx zhcEbGeQI1zCJ2rBkz6--rTHwl@&u2{T#co}W`Y|zUt&_0ZcrlE!Q$SZrwd)fmng?s zLg5`v_g~A?#$0e^Xvd=C&c&;#$)QI41{_Rcl>00AFY9SqM&5@n@td2-8q(FLmVH*< zIBxypkIIAnPp<__v_vMr)a~snIEdb+(K9eJ_jU{n5yoVN87Yy2C>-w5U%TLIm@M;T@O*8*&_J{o%gN5{ z>4J6V_f!)Kx@;r|zBM~=akkyFnauy{_ia&TCNRe4>~_6M1i zmh&1VHamP(QDnv`HHWx4lfQ)nu#AKTj!p%4Ep&}@a+k>uPb^S6g`NTRzogzyy2z8i zF^zp%e}W?9uC9z$lAt^CBe_!b2;xXTDY!8L%gDtj({_lr3_W5)|Qyf949#)(36wBMHTvC=OUCUhbfC`NnJNNsi-2L^Q-*6i?iIBwez zrJiCb8B2eYNUxCC6FK48va31wsxzGjxx!#uZn=1#8Us!nrX7HhEZn z_NSfjx?lm8V!o%WTqf+Ggf*t~HZI&EH}i2lPl_}8J+i-pM0WLk$6HvM4aSpT`ng70 z_ih#JI%~Frh+Ko7%0`vSlB;*FuV)H`6#nE}xn(MrCOk^=MpWC-wci3yc!UAVOS27C zDdj-{^_nj6f0B<~^8bAyf(C)>4_DyX!q%2T8NRQQhKB3mm>Hn@SfVBSYXvNJ5BYNJ;rQdev7Z@HkY79 zdEhbk#6Rr_`>2@;c+%sbRqKs{N< zXoF}=*nps+z7EXVGMkfK(46GaVcdnOTQE&~<@jNwu$zn1Waap?uMGSZTD?Cr6xl9% zNj3RrHb~?YeYN;VC)dXJ=G08@UB^*^Mp0Lhqpw;a%XMnq2hmQJuzh zjzU1=ilFaV1`8e^Dvy%%uv~mRV=78X^zo&qd-Bl^KlLxDf}Dn|v9^g^gnExll#IpA zUy-51xLKA5A`f&?=Si3Vk`V?KU>wd>y=}*fGlRI3l@p>> z-(!fo{0y~Z6tBi?Z+gq+DXRUvs^n4N1ZY(OLP2wTIxGB)hMPk_@T@;Chn|p={|Iy{ z*4J~Z&_cH$`nY`jlw<4SF2wMmvk0Q+_g<#x0?_t&dkf34%|$C|NadiVoBg}I*{#|uQ>&7y_qZ+X(5HI zP5Py%j43ad^;o-|0zPKT!yiTBZbwzfyTe6AZm#aLR{A-IM4+*pOFV0v{BW&)e&_(3 z60kr;<XJ!5_Q|G6)6Q>5Z~#}W{eIp)l?k;i zxRqB?*~(f|-^>gqRavF^@79K70V?vc3fFLqJh3E-ngQSa!s+Hx5ZUfd0r~ ztcMu5uvc~9C9~H+EgD9_e_`Aek;U7#QlfXcB4wqv){|-+eeY?c--=t^1*}^rQ$Dvg zdrExg)S}5crMtO-bbnN~@iQwEdY-Tf4ng-f&R0z6SQgBWhPkT$5ALb|(tS_2_B(7w z^>#fz2gJDPTthujFduJ@o$OqHx#EBR{JpaB={2qvf4($uODWk0z&m^f7LREu=qmDw zi-{USfxQ~&eQ|!QBRc2i8kH*Psahr{_4{Y*5m?#o*T*BpjYW!p`n#CoJ`Rzz?&+EJ zK#g{;4gCC>N);4KzK(t5TIb%rn<~7R_4q$pfMG#-Lac5fW@p<5q$8R=r}F7{5P5#b zKj2Td-~mYa!4jsnlhbM+3Eieqp?-hD;+F+0>-OCvQSDg6n|2dI>uPquH8t^jCl9Tt^KJSU)w+SvY$`0psFUC{uLpgH%OJ)H2v-qNqJ~*}Z zqL&vJZ^$upR(ik(Od73@`~36+=ImSBeJUCT&ZCM-+s{0=THgTy>hyuTVwpp6;lIEe z-sgVSXqm%CLd>0;-S4g!QT7e zt^kwT#>N|)i!M9u0l-_PRO@;nf*u_V)XcC!$2H%9MczJ6;cnUP;!7Pt)Ye0w!u+cL zU6%SGUD)U@9rv9k55Pl2;7uP|*SJNck`Du8f6ZNKfc-EY2<%PV7 z0|Iuv5eD~Yu!8GBXA9n_>2H3F%ysoaVP3*=MfuA@s5}4q!pvKie zV*$8DZ0xy|Q{=t7ca1ZfK$iVd5|itw0N#Z5;6YYqCQyJ$0)G>@s{>FALuLuUI*5w| z2?MZ+!*cIG0mYO{`cT1QdkD~*&(%4xzkM5V3to(T1ov_nFeV4)_Q^>eTG|Jl^dsQz z1?R5rK%gcrF0S}=w#`KvIPpeCM#jd*0KYUc60vSMOL!~!SIY)+(5dF;kI(Udp;XZI zY+!smdfoS{HZ*mwzwxGSZ~XkK>FUe{m&vq;*{mm#KcNNs#_7hFb@bP2AcsQMhVtU* z=*IrCq@vbMCdJf;`g?>4Q~uN`{8AXn%V6<)!D3N5p)$4lOM+X!@NHhxp}ENpU|8qEB^ucL-~1>!IP{Ij2=}Xa}(D_9gKLq)t?hrALSc7j2VWs*t;t z8=RcHa`QQ1Tlsubpge4_>0-Nmh76oHkzpa>bom=79GX8?{Fx_b3=`ZK<2@tLX{Gx5 zVl21s?d`?HJX>kH)27SU8N+GOwcn2J>2sfrT=Jp*Oq(?_6^YA^3J|CYSXWU4PB?Ju zjsbutf!-j35|I>maO;K5HY)jG_+qoN;M#HFxhB76);%L^+M;J=_Qz_~Wciy$#6aEs zb!?@@4R=t^l2?+^6C}z3b73o}&B1^xKgslujA&uI@(cc-WHE!N5TNVH5EqRAj z|MHv8ja93z19(la|2YW2VQKmJ>XfvBYZ#oyCbB8z+wQT;DY;oYS}zPh?yOvmH5WnZ zdg2n!$F9!H6Wis~C)T20LgFy#R&yCdH$qx#={ zN48igI9w2z%}alkm%qLBqSA>X8f59EU@*7Bl=)s+=Hj9#WyX!@I(dRj*%6Z`G^26W zxlD&v_Bv44YSldVJ0k${DH|HSl75i&&%#jz0in`z9*Tgw9rkinn$I}v0mSoG6WW1J z`KTJtRC);huy*5s$FZ6>Z-${R(oQZo?J^P_mRD3a`CKV%ddtT7fDOthg z*~OlAZdWaRCgVdBfLPKVfrtm&ZE5r+{n+(BED^ac28~e4?foz-sqCR@9dzmNxuS zh)CA_tZ$@0KAWZV>4~=R;2|w?88pCusoOqvONR04NSDAu3)UtPQ2mCJ;*gJ*}hg*X+cJpW5dj(Q7QB6KCC$ zo6JF1jGsAn)uwI8&%QXAnSDUA5asdiWg4lM(}@53U@;VAo51*~$pX&W59oWWi8U5` zBNc^@*ruk!!bnIKxTOd*e1GhX-dPEElCp_B$F#GIABL_;Gii-eU+e zL<@}}cnO%(E6x*o+Tma0g`X77w3;<+v?@vx<}U`iOH*GK}Jul_u zmDxNlSb2p(g{tX!iHFZ_vr;&H+v`Ku(v|Cqgwog;wPMj@UVxu;=+xq0yPtvTjh9b| zfsoZm`JIEdvq)8OOu)LLfkM2z5VjhZ`}19ez270>@`_q6(u4mp7#LYFEy*Nj=>rOd zJR_3S%XUX2%;T?;>dqe-t(y=ac-+S0K_b`gAY$-ANEO4vI?nyUQ}g0e8r5I(;fjgs zmV#_8>d)1t!&D~2qXAm#0s;zh3QD(bi+p(T<^0OpJotr=IeOyku}6gKU%cLs7tXcE ziMHbOC~*U(M91p&Rpu+^`)M9r^^Ft#GBRW_BaXlR1bDH_5iVI6qg)RAV^3G1Uo*_v zH=kKKXO-ZO2WC5GDhMK_ta$|m**MGHsYA5Be(H&zksN2+sU)Y{q_cAlYcpLRXcb#-=TUMc~a&Pd+%kj4EZ37#=Vw zsPQt7f3-{Vh3Av(_QD7dta$U zBC>NoshXK-57mWEDo)pz+LphmWF|zP8lC7U`J}4$O|^DC4wXjJu$_PM_CN2vR#9C& z;meK{I1lJC;E^n@tyP(;rY90b2&UZ&!6!pULP0@kB=?`3oa{1O+Su6G=C;zBnR3pO zNE+#vw#Gnq6FfLL1lD2&m6%l@*L;2l^-+OU+T8ESJ z{^f;YOeAdO!?k_RdJ+es&)^*};ALKMQU{1_&Ktb%Pdh<7`Wl$Q(lbR#Ns;l|*j})! zueaxq&hSe>9Dt{lSA+Q(9Pw08RkuIFE=Y2j=yW2&w54^XWb`t4HR4? z3{_>BBc@%eF+`ftM=3FtWMz}|S7q#5J&y&PimEiLCAo>5KQC}r zxSvgFQwxgW>uFn(Z@-h&bUeLs=D;RKR}{fN3;dwK^HXlx8igm$W~C=#b#)c+GGplX zxfntH2-;Lhaq(fhXXdd|6zTm&_}6cyDlIjYmB$0Is8uRd{R`DSE)D%3MeL;@$?hhh z5fC?^;AToKG+n8fbIDyw1yc^4Wa}=4ahJ(oEiCLt=;X_1^!Oo>WHe}tu^BB%T@maw zbZ0LW5Aqr?TSYMS@mLxBGYlaZq1+U;zQ?;xweRjA!nWd>$t;(6+iir^zMI?ahtHon z^sYSS^_0dIs}*k5^rmZPpZ=fRBe?_U`7K;t@*E z$N-nMfgIVa`ys*mG%A~y9{u)K;=in59TLX%W+ArEty;)-c+&q-f?I8 zl+mMiFPfa?nx@uiS7&#=g$6qhpgbxn(ZM-41FZz%uEzr6(K{YwwaLlS z=V?c(%BrSs=n=SZU>`ge{xZBHeL$u@Drz*cKvjTL`gaO0ZItTog_fs*?~p(g7cZFh z*7J%}XGBa@mE+M%-PYeR+S=idc|jU&Yak@2I0^&O@}gc6yL;>J-}&{ge`S$J$Tgh3 zyhoyEW?^J8sjLwl6Fck+n+ADuxRW}RG$V&!i*$%}FE2%0od3b%%?^qq9Ol6xk)zE2 zJ-29I@uoj(BM)!&aG?wUEDa5jfhIj4DI6Api}3>_5|pMHa>K_R{HDJ8Tp3^2;}6vQ z9wb=kC0|kGQstHmR$)72wg6{C_I?a+k7!r9;rJidQpO*CG6)7a z@bLe{DdSZg(QcbA>siHQqP%ri_mL_uV~-1OqyIY;pxnE9bBYIrgn$CYpmbcd(!yMe zIvMG!bl;4Uva02Htur*s<%QgV{HZ{fR#H*vU$YZ$xz97HC@Wh^cLNbVBpKqSr)Oaq zZEPfkBQ($w^dR8D#z;Zbs2Z$z=f<7`Cqt*$iRb#~moE?GsIW-n)YLAXU8NKkTMG)_ zSBo`@qwn=nEa@%!@!uUDe#N`GmXO|l zdTy3b5cs3z?(Nt*>)f33j*5HIu7#G()Xf&0YzCcHES^ziEAb(v4l$Fl%T{}>y(jZQ z-$^oROSX`Yw?9wr)Gsf~re&cx?r+5&#g{rCSujraR9XI5$n<>u^{rC3Y5S6m?mrKI zRDueF?pWxSS&l4kwS)iE1OcY*La}b!Wv#>3NV~A}+~LM(B%SI=dER?blg^L#kjcd# z4r}=!l<5N{0I;bpwnb&5WaK3iXl%i!YiDkDN4!{RZyB|1dioB@;?|a~ znOQLU$E;x%Q5&1RI2KEl3jx_GkK9|~M_t>qv+RyI+~br{N%B7y_UH`WWa9eyx(F@a z+&s2wkH+?{FRia<5sQ|EJYH%V+8qz9swSAUX{2vp<0HSnzA7z;(wuzxq~_r0 z6j5Zi!}g72({mSY1&97f?oqpnH^1o3M2noK98Z@k5-Phx&rVMsnhL!aiO^G-z32V% z{<@Srx30r>AfM{Bny!I4)gR>g!`O^vtg+&gpRr>Z3ZIwfsn&kqdVk;VpdfF#P`{u1 zs$y)QpO-XJ5Jips*^kh|-2NiXhI-?{Opxw@JfJ|OJdig<@1I9@z`Ht-Re`1lfS@;3 z{=I}ywg_X{%_sUuyn&`PzqI5Vm9J609=g8*H&UPue7N#jXhYmsTQhzmj4-sY>ts4| zQRaG_s6Z$XC;W{vzP6d(>|izdm-qde619#Oduh%5r!y+Ox1iA2u}{zT63-qS?^k~R z-t3vVnk_8KQ>RhqatMAV{%FJ%W|bi-zh^7*B4R=)c|Y+y8)H?)T8U_5j~{PvbUsTZjtTBiGJ5%LqI5sAo_(+s;b3FqxSI-=@8#V>&wY)=cl z{p)NdA8M0%@z9sPZn>j%$~wv{>ieC6uJq5qoGBC(K4_$l#fdzM>mxSR_*0?^u z&nryvM26xCR7xN81c~j5;iauO78({7asLMsRVub?=)C+o&$(=%`n$wd3(-^{fw71> zha=eO0Q!oao1INTN3HtZiX=i*9MB&y{E17e!^kitcj ze8zW-oBtVQ^~}P9_9QK0>Y^rA30GcmwB1DSA#)x&?~8{4t$mLB8-c`(T}62T8DX9M z&q+xO)v9ccHpj=t#$cNM{vC!`bY_1|x<~%|V2rSQuv6tdevs_GK2ui{8Y+44%NvOV zBj5!9Y&9=1UJD2v+7lzFd?^a8gkJ-f%Q^q$w=&SGkD4c$DcGTKz+)L(&d{+ zn(HC{vMfn9m=wt?ho|xx;M%*`El~1OY_YA(`gb6a_(^AxT3EwNK>f6RAE^)J{9F6V=(*fj~3|Ho%YjD6p=_s1B|v!`1&&r@Rqi@hw@~UlvUal zG0m;4b~4^a0fN4>GspMxWfs^oE-f+{b!a4`^aOu&*f@{K^Ftw$lYI^%JCyqiXNRVI zekhm6vz|Agj4GzvZONp!K&|XOe}|-v3&Qryyfoc{ojkZ%#U>oI^)k*Pg2_`m=L zOQ8vT>q6B^jn}m?r3T&c8S{@gNyD5D#;jW~`1sPYFV9Wo_m7UQwkn$n(8-NN;8HVd z7@rp{mXmScn5xUDS%EiSl<849lP_Cy_0;^lAhKe_Z!k~2mQYcUZj8xxG;-XP9S<*` zz3h`PX=?R0;_66{y+Ln_^=F`+71+P5-(Fu*QtbBSFaWxP(dbui=7HE-ziwT&Ar8sg zb|kW?E^m%AxQ3ROW*Azs_@KWFqIXAieb;B=gWfedUK+}wVf${;@m%4m!tpc(P}M8l zJGa{oNR1w6Ua}hZM-xA8RCAB7xmVjD^~SR6AbZ&VxbUJ}Pz94U)3KqyZm2#G3FLuu z#c=t+QEmal4j&&@4i4b1TwR`zPNGwgGOb%+ATZ7MByhmC6jYXZmE=)fs7X&94kzs0 z_IvkNvc%(ncUIb&n|lv=+0an`b&Q{Ch1u@zq5Lcw!YctbJb4X{2P9=WrzJi<`~(E1 zV9=G9heL=dtF9h$%>aVs-Z&P=t%;-qc-p0Gja6cB?%E6JgJsFIC5(w#WYIudOU?s{zn+j|5HodjLtjOD@)oYMliR$E#t_SKL1zw|KD7Lx)vkH z2CmVuF(oeW-I*7Nz>=G{VwKGlt8zbgXo@RigwDH+8XzUOa!8mAHpgD;w#{>E*1HMt zy}PyZc&R)bMn-T5P2_aXEGP&;7k&ReTr}gv+yM+lJLUzzU!lxz@D!oU8J6TvS*^4z zEDAI4oc_M?^F>Jd)>$47$8ll2yQyV(xMzfxm36G6BcKaBXqP=MhokB}JOC|8_RFg* z^~!y)7n^Fs%#?gzOzXD!(2f0_OXMGzya77rvgSl6Lvq_n&;L!M7@60Q)ZpcHi|g9) zII-@SxS3A1VhUunOm;Hw-reH;B>bXPy-qurFR#+&CSer%fkbMoF_@2=jCO9+gvy=pSYMf2v~XB zVM*Pg_m|u189943+k2Bc$&VTE{7hABQJTKJ{KHZz+4ttAr^$YRNv`(8>YcR+xtf_7 zO9O<~GjxUP>$vUpn3m#0`SX^rw9x>_c%Jm)ndYhKKrBgZ% zB5oLzqoQD?4&JQuaPVT0b14CEV14>1NmHefj*|A(^8S0uC!*4ii{$T{9`4_J#mV!$ zIxj6ZAjeuh!slHU0Rt*3o}d`{;LJ?@7Uw4$IjO$vs2EMh-%dXrdC zFzwqa)^jhpJNJqFlGTrd0x=^ycb_kEG6@lpgT9AXg{x494Gizch)Fnq1@2r^7q#>5 z4l{2ya+hG}{m^dH%A0QiC$9TyJ+J6Vct5BIeEd9!LL)rESmE;I{224^)&8orp(*Bb zWZ-WLHDC^ZNa_9FZ-{HpfW5K6EKi%Ym!uMuPchv1ZG+N2-6i4c*?rmihnYi?>NuU> zCkQ&<=MO#3)gf3)C?ENFYUwT3PrD?K6`|kIE%CT6KN~}MZw4Ewi^|Qd_WWRTw8)Yh zsxkZh+X!wlyVlp6N@cS>!)N9;Bk5!$nm(vYIJ=cSDF`|q7x~~bVK}@qt-U4?@PdZu!5AEFL!+cv(wi=RR=0 zaNuk_mC$%eUNGk#tAvksTH=|Y`1PkDGC6%YE>S3pVUL-(P|8G|>v8JQmT5?5fjLl0 zJ32ZziO}31jjk5WR#)$9EvEQSa(D83W!?)um^?kMCLSrMz23RX!g~xm0kIMMh+8La zk40YOC{fLR6HV76EO{ecBRF^5z$-<0t?VI=QszoXffv!C_v$=AbAy_nG%P(Uqg?Cy zReNu**KA52O|Bxg$8 z2ea@tirz;l6lo0OM_|b-Dq2qc_|=u?A6j{Qak_6}ViMc;03iuQAj<4#dQ01-H@c{M zWY}@xN=X;@yV{&tTF#o=nW7S%{m={wYn{NG~C5zxo(<)O{C0Wz>hWD+8;pYC__$9&a({y)S-oMQ`reSc@VL2(=mo~b!BlKS}YYJ=A# zI7Ik20i?Jwl!K`uOB!ay`VMv^kD%1-sYO@sUi~a+gchOq5auAV-64-u);6< z4;P@Yyd>DBvirdw0IR?-Op3;Nmo&#z5eFJ^?VA><@bjaq3m#56pD!^nG4q)BFuU~KDp0DY zAtC8+ZH?_(g1$tct@(>^dNki_HQLJPwjj1A-smb7W^7j@6jW3XlQ?6<$Ri^6>S}8% z%%-U@0=`khm<4Kip89OiYZGKi#H_Du7jZ^{;?9VIfJ9D4W{;Hef#=v;1oN1X(%~6` zIP^24fyFOHXK1Gk=taq_Y0`1ob$^?WI~m#DoexTX?axzO@Ixh*ApKg{s(xwFisB;$ zPWNOVQSLlw0QLcqCp9uD;86ktyd8U8#2I4pgS)ri zsi{qcXZ4nqmp|q;Ha3>Y8ES5R@qd>pf!nM;Qm|L6&!*ti-z3J3j*BzZ)=p82=~{YY zMdPNZufOE;<&X3Ja^-H7I|71K)T8j=)|P@353&G$wQ?J>#9&gNz@Q-FW^Sf8Z+hC> ze_B?m{BJ87`6`zC-YI+3FTjcPV2x2>WCYjm-uI;6}JeuP`z43@5lyw&06P$wKb7v=r*=hZd}CNZOi|&?r5ZY zi|pG7P<@mCY*NpYATrAttEuU?_*`GY!%IO$a5I0yZV!7A2S&KuwTg~gD0u9Pt6^!h zg@v=84UIE1T&MPXUr6|*_v^Rt?bXCGNqCXCG5N9v>+0NNxkYd64P6emIyBg=Ckxws zZE?zHco3LI{=RhuCoKjB1|l+$!AVrRuh4qb@j7GE`)Q{MA)*p7jYTYpl7|tKk#}Cj zS<2-xfFE>x;EN|n!=X!^I`)63stS=1LvfjGT0iV;H%bt43}OhOaB)w&{8-UjWVb6V zYM?SgAgUZ29+n@JE@L4i#jA5(@cWTV#p%YtD@;>ZZN0Gl=MTCMx`2PGQV29JYj&Ou z$D^^Amlv;SXol_bF5LOZ!=D`M;AYmtxB6#!IWZ!_et$W{%lrQH59jCLz{}|t7;9PM zNBmK=vrT|J94iT*4!d&Xc_}p&)fA_4!`txy`pw@x4bO=0nG0FJraQ8t;RxOWvc%@5 z+uo2!n6S@wDkJXGM?&BOVO*E=LIp?;8VVI!bG%d$vERNO9BrvObC**A8y(hG7iUcn zC9$wT{5y$Tvs>xuqm|*VDA*`0At9n{5g*xp7gwal@MYbdL~j@3$lU46QT3eov37wL z`zZbG4~O~4kPI+sO#t}alD*mN4D3%@-beED|Ni_by3TH`x|S%@gy)NW*meok9p}dUXZ+R&?|E;ZU z;67d4-j*cAn4VT5`fJgf_!d0GbB5Li8<1D0^Wyx^kIcikxa#*jOyoxf2F`Y~nA5yJ z!d0?4UGwr;a_CvH=zGzUlG1NY1oUN|V{{}HvZ zzUtamoo$T7fL5+)UrNr6*G_+NtUSuZ=WrqjPhLBW*H@uh+L(-< zx<+9%DY&goH>hshJ9+>zGyuTdCl1y+Yd-PM_v^NqV)eu`n=a=oqvmjGH~PT9F_fz? zs+9Kequ{-J!&Fb{%dQtSdCk=F7ehr4SGNMSk$OTM#4uakjP(sl_u{a`HY7B>r`*pR zS&V+$hO+;NdQg-!?MnH(2xVst$9*k3v&lFKDLU{a&mAf5miJ$vKWBBKuNL?#*&?r? zQ0?;LsdGJ|Hm=|GXOELR3Dbv)IMwe}yM!PTBrT|EJeUtj)%*+MPPa7A$ zU@4iJhF0!4q9%GVzp^qUai=%#k1J2w`ozyI%oH{iyGz$VJ>dB$^n%jC_$A*R2H$Lk zYHa5>m;QGyi})3u$BmduOBfW&G;DSM)V?#ujW}7Q)G^D7>o>QZkbd5=`!eYrmrBro zaHp(Twfi4<|5BoRX(1?w1fj^ zK72lW#Ugg(qx%RMurR9py^E`$He;iiq2BRFMLH)N8);FIXAk9csnJ3bzaU>6vWDXE z^tKnhPILR?=Ypg@8uf0-y%w(@cPNrXI|SUA<&x zWR8nc{QBe?P?eVM&!U5Qd4?!W46-F1)lV4X*e#!hiRNl@i*$>2Q}$4cxI_n|mpGQT zoHx_cFf#k6zAqfEt(A*TlJD#2`#Ci5L%|a3V_@UcM03UAmuR_U!<3SPgNe2$0{V2A z8meq6b`0qxK2$ytEzV>HZxU=-)t)nEdSo4I3Phw*{hf4^eXr}zj%Aq`k*NDKSsMv2 zmZ4<8R;)nG&W@6*ZT32!rf0-kf2QQRod%y3D~YA`j}&f| zx}DkpLdk>xc#_>6L{xlMBPnEuPll;&Uyt5^hsF=K=T~FyOSZj2q2_N1+&vMeKl#z~ zkC23-5C%szczmsQ*uzG4E!{kr3b1YaoWPYTqvTAxE~EXZ=$oR$n{_&$zMToOSJg4y{Bl(`qW*Gs8tL`jNQZC+hSDIL@enF9x+$fvME5C*Q& z`+J2m637+3%^TZlHajg%dW@=rsZ%|Hxx|AX&|#!c2(52i zz}|OWTG1^GzW$5MiPtUGG4r&zCR4>=$w>N(Y}xLC$#X`*#>1C2Q7vN*GYGfvEMdwF*WxySKvBNYd;Hn_w1 zBI7*6+lqdMR{)0Rs-??W(>2FTrAe+JWOUo*T{^fI!r!v6TOZGQi-gI;%?ccl-VFJH z$B%nnlo5(>oWeHt%Uu$OnlXiy{a z@aT=WTWG5;SMFRe)YX>8;*aO9-pf=VM@pf*wU2D;L>?(f`mV*hE8wN()1iS8UL^g@ zWk68>#a z?pp*usfgrzQx60Wk9t@US=#KY?6PoEk%yn22ZWCnsk5m8nzp8OE1vfL+=|JoUt+o(3&ksZ5SxjZKU#d*YOydqt@k%f40I>TYIxM$v?Kws&twlA(tEO*ZxP@eEE!l=x6`Z1B~er7-CY3ie?v=UlBFH zz8$8tEQy3~j?A1xk%54*b+$~Op5$GMn{v_W@CzF6RU{PDT&=>2ALiuI5_fEUY2088?G z7Qu#0o+L`sGU_!KU1@SqT!E{kVy;(W?de{&vp=Szzvp#CmHNu?tQkcQodA+CX8G|| zT}~~()xyDaYr}mc68_9DPgnx;fa_qI?~+}T9hV8$|_}G#M+38j3g%`TUuPCa0E0$Mn(o-MwabE zv(McYuNOB921Q)IItd9F%#3U3iLD9Cv|&BQ7DhYDgId2VYXWB+ViY`}c0 zAd2Od+c$|U$ylbfILrFe^X&%J?~|6;_pTZAsY6wR(Z9-xQ2ENkv5i^%W0936w8l;Q zOe5Zv%v9GLm zY#dyWY2x|&NeJiW(~PKo|vVjX9gD7ETSIZ}{|;=yw@2 z-Ha6{iye9lIc49rmzK))HxzvO0++hLt=`-$A5v%v3pMP-f@_n2Rtm#$q53&veU927 zIBU8iK;yeHQkP`;YhgE2>;Xikfh2^jiVcK?;25dev@kk2NKH*m!02LEu-u!(9U9F% zI5P6NsU!Net$~tKLa7KoQEsO&p$yRlXA?k3^k)f9Tf2o#5Xnk9oU}dd30s z2EM`Y!1^!DGgOqdpwaD-ID3=hB;8GNV`Ecu*1FD?E|Drpb@zlXpZaHAx|{W)gDS&o z8iLMnIbEs}XKc0OWupO`s-A5C#0i(v_Q|AS1xk386I<1(ealS+cVVh?eqN9Bfa(zS zKu{9TV7#UFlWOqx@ZhLAR-M-V=G(ZQE1nVKzoHcH9fbIMW*cmGZ{5lKHQ;Xh>BW|T z!$}n`gI+s~#aCD7+pDWar$x%@)LkelN zfmMCB9F-RjQqt23N6n$HEkO>OW5(vX-sl)ecRQJf>B^L;5on_}HWn^-v_HZ?@2BnM zbqSX#l>Eux%if5nQ#j?b{r%E3*l4T7PM6yRa=F#alixJ4mw1^G^GckX0$OwoBL_Q1 z5&O<3C9hS(m9*VmBZ6icG}{QSxt%Hf=utQt=z79BOt#L2_V@PSb>ZRvh_KV3bXV1k zyF2x`e6q4R^;q=R@L!>u-|-eY_PZ_-Y4@L3>lql#HyA9mf*f_cd}RI?qqJ*e$VIo* zIbr(FzQ1|K!@Xs?d0C9!7YTpAoEjl2AJm)MSX+Y?zbDX?ff<60hu5J~oC(ny@Tr0J zZOUFIiHKcic^$R3k(!pa-*7#B=Dal#LETXF5B&o_WF$+HxYvRRll&$tuPnH?O}21q zYO1K=Y@l%fqnH0Nul=yulb0_IsZAk;#EZwu&W@&?&d9(vMGEp~oKJQvsTDmM9JcWP zA&z7fOH-PLdCU75re?`JdecBHplgUKN#{H~aU2TqkgqiBFMyi@UZ1DCZNv~VJ&KHo z(AU%B6os6b1iSMdbszLF;ouqqHhqmEwz0iEJ3U=*Z6E{w?)#d~ zTU()QUw1>Stiiap0z*ZgzTZ`hJ{hTzTU8->g@q$_NQ82Lg}|p*%A{@I{hu^xgDcCV!59x@JW1=G{hftPW!&2ujH*B#e3qoboUG+YVK zk_hA{1;H{TJ&=c2UH|m@v%A3gwuXb1H9P;5azQabj2yC9K*svc`~LeE^WcpPZiv9S zV4j{BAK#j&0;$zk;q>bDY_>5!{tS!&{#bhL`NIWAKey>3X;gyM_3g@@_~@mTjamGJ z(XX+wz~eiF8$Nuw`~utOcb`}2zvd?1=B}u$ivtqX_%se4-HhMwhXZy}50Q*Izfs0M zN~HvMX&6As!#jZTH2jiYt1a=BZAE#f*A%O@Wq+_ff5GRy;Sb@$FJ4L}4%s~+?1Akf ztlz<@@tfn^OQF$x<^8p^+xY#`T-Ko7LE8+qanyw}(MH5}gNgjRM}bV$!`1$#wl*9R z{wzk=H1=gn-}VA8;b&$xKkDl0++wiY-7kTg435j&uzR609bvZ9)}BlDx&xo)1x80k z5DtswIJ?={cY{{VQRT6Mu&_LZLX~1SkcEO++!}VD^0Ng&K|xWKU}SBfqM`yTVHG7M z3jf??tq9FwKjQw>svw*qCA-U$gkPG+=1zHj(fx*Nd7j~i2kUMU2JhLd=lP-2FD$e$ zGFq*&U4aImi#&}1Pw<&mc8+24Zk+i86;zdn55q|c?hobT9IJcye#f{T?=H%-Me`?j z^zEQO#gOPmLlJt0e*4ZH)!a(S1&9v;Y7qqOfHUg^Sp0h7eD)wHah*#UpKMfh$S1T- zi|RS6_td(M+^X2h%g-Nzb1w{7cHzaa0e?^a&qpH&~k~1wsD)RvZzxx%{8sppx4kSpTms4 za{OmhuTsq%1H(k;enWG)AKe7g1Jmq&ju09Xbo-&j=Gi9IM2~o6J_CM z&lLrZfxDSyWo2;JcT2TaQi@IkF2_T|D^}aNqnPoqxmV0y#^;->8Knw#KLM4OQ&!H& z%F5ccZ2HXRB_hG)B{Jw`gdnE1PGKncZnDgtZxKGp)z#(Sob1eP zZo*wSAu&fk}mT4PiYCEEW2`y&EBE@Q9C$i0$s8773IT z#9g1ac%QLG>H`DhX^d||^nG%LR;T?@Ntsd^+rWL%uSDd}eKx1fc2}l#aU)}5`TEJa zMo+$p=9UiFZmJi|k{gD#^HaB>?T`IK<+SbIVqb_G{<=OYIrx}Y&_L|;4sRaWu<}}! zL*dA_hT&roerm*)<#~XP0j_Mh=f)@Ng6Nq&0R1%F`~ZUak)lrO)mcK)5rYS=pTW-%ObG(xxNOq$ZBsBo3Q(5o&EI_sDV5iD zcziW>CMrFg)UOz5b%NIKHcP+t5^vBF_bA(K-5hR)ekYD0g$TiJq?vU03xkx(<* z+L8M#OZa^dz2hJg%XML_ll`PmOAwBtoE+r1w9htNaU{;Jqy>4z)s-usu2y`y^Zq&e z{ID|u55cXDRYSAsYR%SQq9z+#J|q|ix0ix&7!A9jj){A%q_Id$5gzDc?$@rp#UX1D z?jJU9VKjlXoY(a9Ms-)FuiqFRoi@%+jqvYkzpsfTnzFa|_N|LamP21=G2Ch9i7-dS zEn^mn9Ih6l!}#>~GQx`d^h;y~c4J@7(58to>fpCs*-eb4t^;P~68U~)*th`I_4YE( z&Fme5&UET##)>Ok!kvC-?tDb1?^AYssSCp~f?D(c|J$4dr>iM16I`xD`jL}3(C$D4`0ZCr3(A;>6{C%+`44b%={xdDLT@K1a`|Q*?qCt$VhAt%GnPhx~J@U0ly}c zQ>xPRt>3{86`!}gB#7;XUAet}Szi^9(f=o)pk#oTVARLZW$tu!M!?_D9Mx2g4<)5t z`J4n36p(6d>IWMApytdHd%*4V=V!gUYureaW)y9KMqRGH>6?c!V#a%Elo4nR)zvNw zt*9CrZ{2F^z!_U{@I$$9oaKgJ`<`4!Ncb`S@cN)$s`;$|F_2g6iRUPZj*!5Rs?W^e zoZ?2#!7F^4gf&YX?|INsPnlO=@tsBWbhvu{;_J1^h=#A@%+B^c19J6`@#!N+ZH37IP?)Kc`t*F{C*5oxeQg~1g#imypX-oAYcI1oH} zP4ey;`X8(tiqqGxpvYY8-pCEmRs#55!60*<=RcEcHkLe)?V%_+J6Gvc0+7D9yzcrl z4*BkFPLBvgjsL>UTgg6&SJ?BVC%-;jebR7`@C7CWsn~UZY{Z*76rDFmk`cb>-&^dA z!D|9loUoJx+0o#E;ju>h1_8a%_?p_Oya!hijl*D$iE(*e=zewwUrc7OsB}cFfkdl+ ztUQ(uDB1_UKJex}i=B*FuJ4e=#8USE&7}R}>hcN6w>_rkl=aqV_|Ig81r2_mM`1qZ zg^s2E&qf_p?y} zevHT3Mk8lCpGdkM^Zvb}eS7BIPVKnS&0e?C2vVMj36%|rLYt$qtbqdqG-YX$>}34a zkeD}(a4BjGrbTT)DQ#u*g~_(y{PMg|!~K z=lKb*-rku)=Oy#K!1D@fk)JmaIZQxCTd_=-G5sN_-i@;zIL6?(T}akH@)>&?l6wOt zUhRn53zIDHq4ShS7(D#&#DV&SbRh ze6Hy(jAJNGx9^-o;B9kjD>lhcjbbmP^{GsbLHNDf~b2Q_^JHCjb|H23qn7Y?iy z|AE%eSNnB6uCA!ih;RBKw)LQ}@R$Cc`&*R-XJ^!^wQeNc0ZdvtN!25G37d=!1^TJ4 zYI-PS%5x3UM({4BG-lb;ZU)z^xsBl5^_2yRZ`EHr=s#lLqKjd%S<3ZB4t|9qZ$DE! zf@faBxY84UJ-ZeYH)dbJSnYgPzpR%Egf8{UzftL)*9FSy{)~E z@);+vf3l~2?=ccGG&a8JdRxBk?b$r^)iE{oM^7DGQ?IG6b>H_(IqHuM{BKSG2OHb4 zyz>9T3ecWgTr|@+54oxN03kwp$eTA606kAkOpLq%GkNmx0B+V?+RnH1F`%uwFm3=! z{^Vp+w+4M3SOg)R`Y+(@%5RX52$)VD}ISRVH%H9+?Lp`W2N}9T{8rn zU2|RJvL35_RgH6%}2dbwE)*meD<8=WFCESlqSK@N1dI&ZSl(l_zZ6w0_FmAhu!ORdK}_fb>MUmMKKD;jjE zu$Uqj3!mY%Z%}ZK9#sR8WH{|#hdbWqQ&qT{l=&B@V>aUcgG4^TXm}i2yh9~pDob%$ z+v;33$}!ne6mWKfoa-brC8hu39x`O3FJbNN@52uGqi5%wBYMH5^Ol!4;vyC}`x+S; z^<~q&u^6Mb`uV|jrRNPBZeL_hRR}JE{+Hm~%(S#7E&4*u20!$(fBD=HoDJs8P$LbN zIehy5WdyWu4C0|Y@_!y)mt?1=_InZ=Pg(ud;oe^C6MPdL6QB>tjpYAFQ80J1`|C|b z1)P-fm{`8NAY%ts#C@1WOAR49)okdUG{qC3jl)p++()BUSX5Y8N;9cxZmK~Ooaw*) zb6BEgWZH$s-!5m8W$}?u^qf3eFLpBIUmXaL^Hy;CZ0e7}z@@kOAt3N{b=kPP8}=#S zKnp^VXm~9Yi!x z>NSVNv9MT-Dap(CHU$1!5$-l`MxgN4E0d^k*dDL4&GN6AgaF^;tw|x$Fc^tEE{wZZ zlb^wA2W~$PkWRjnW;Qf%2MF6a>N@|ZdFy%UYWf-VHd2aujU(9S50=KY`5kV6KV}FzWXK;_IjWW!&F$*8!AlfE zbCY@6qh9lfi1kma&87C?Iw)9-^W2m5|1q*r;L|J`DYjpDqbVprxyzM7ntnZKuzT*CfKEY|eU1DIE`a?cX@%nI7Uz1ytHj03V%Nay~PR?NcJgVt# ztZhu$K&pv@h=_PfCFqHDCUh9^lprX} zt?n}HxzJNi+z`n;lLc%#&6DlC70-ka)2 z4;lam3_G+yTI;qfV|NUpwy9|)&{%GJeb+sAc=U1s6bg&B6N{CP^S1Aj)7vjT5VJBU z(-o2MV76@yR%NjSxkgmB_yrAvv`^nCX1#r}?af<6FqiGac}GW_StduW0_XL2ZFh%} zb7XSKB+f9=j2o$(o{34P9>Xy)D>^1&K`nd9jRtStkq3)QfE2_`}bz6W+0z2&b>`5IK|J=o<_4c&g2Yc zb#-+iqCS<9mxsMKt$Hm4w~S~v`H}c2(NqG{nohO)+b^xZ(>MZhuBGTk=g=~)qWE2$ zn!sMAuP-~j>@Eq!%|+5^lFR_-r2V_{(0W=A}~m!wco<4qs@0qMlN`5(^wN0(pvE(j`q zN;D3u69R+MAJ`uw`Or!@1O}x+)M)50El2@9<$xrX$Zt;=qs2(Wa2*d-j78R69qGOx`NWWUK1!VAHz_S%E6tF0<8$vZA7uc{!2OIk%?TLW?zFKN!%X-u6US1QE%i7Ev75y@z!|7Hl)y^VJ>X9 zT!qKRcCPG0KFWO*{16FSn~kqg5k>WwSjbi^M&f_TUriO%D!C83|uDM`jIw!lQd5tG;>Q|Kq6vPx^5Gu@Zo!s@8v09Pmf~ zk1zEp_7VK!iE5z6s*v&PPS6a`m7D zpJ)W|H_lm!i3OvghAe_t#DYx~>^}hl0h>nBFunAwni8dx83?+BMe##lpb!s&_z&PQ zz#@IVPzMR5^{=nXW^{InVg#h`O%*`GGbp?J`;E^`;W)lRrG>-ElLiD;s5=(>%i>5W z0IHkKR){ACaCu(UdTKRjdR#d#etPVWcI}5_!y2E$cfU9OweDeV1fM@jPjBzat`j)H zd~y6?JlMLZSj2y$#*U7ww5WGEWq@QJ_|3PVr(lfkYJTBM8KEA`e7wq_(Y^y8pSbMAFd_jahum%mMcPkh%H<8Nj4*Glx5f zpy8MN=fuqR2X8q?Mgxi{uw);EB)H`ef+l~ow)enbOprJ}-fv_1m&F;tpQ@yGE=Lh2 z4AT2B%ZK-PPkVtyT%6g-HH`QaAAfyyH9I;OE`yl{PtVzU_jLkDvCcv~zES?mre|fr z2?OcPs=z|5^StKL5dM$sGCMgrrO6M1{h*C!h?%MrIwqW~932|c!aZtGtpq^szk4*- z%>SW!=B&xOoAHxc&o>7^=xtQgPh)8Wo;aXN!BJa)4IHo@1FyR}I%43qSbew=?dJ!g zJc!k?*4HP~a5mLj1hpq@PcGfu!3o{m%nY4(vcjB>f@XDXd$hahvKQGC*6k4Vad|Qr z+yCwzs3Re68xy@xh%5g8+YaRyat${X4Rx{Hq->WdTg4E;J9y2)(z~=w8Kqf;;eQQt zK#*tjGddO~rof4Y1_gbX#0BT`FWr{TrYND`t-pG z0`({)cwHG2)Lcxrdu|Ttc{2cl)Q46oPZ0VdLGpxvur;{ap9X6&YV4q(z(ANIGj0O1 z|EZq{$~fuW#&JzENE7_FKl4*C{W>)Q3XwD}Q0)5U3*Y72ind7Wz@(gki} zk@|>>d*qfEcg)WIR-r!HTxQF(Ff=4K1gnnYWdT6JfXh34^jlxkK|gC$I{i`0#)5&R zmig{vDEGnT>hv{#&{SyvL{Hx+$JI%0^-29$6AIt0=96zkd|b@8q_axPUWV0o|4nDv zx-eztUG;~io#h+N=rID$!`Ty;KCW2NPBa)~r|qRQyQW%f%x$+zmrux_iK@JFjV$0* zJWU`MIcIH2acrEMbtaIgo!)#|{>RDa1Y_D5whfqt}Cw?3hsk4{4m05cTydj1!akkyq*_5|5SZ4&Pz^RZi*3b!}j{LUzd zKaC3U^QXEJ#r?7Pd9Ux3%-670n7m^KLn$BlJc z7Hvfo!)^_|G-lGODX9 zz`jK*IU-y1^QnvH4YL7Ar)u|o>z=mRGMhjy>2kI=b2we1i(G~Ru$sYzMMYR#HrCec zSZ^#9K>-0!@nFOV8)U?a_wVubUVstq)on9g#*#E|&AsC083rFTanAQtkSn96j~b{> z3{_oMOKA?x%w97+Yn}igig}tmn9MUUy+Oo}Pm9lOj{-s7JI}gMkT;E_NIBtE(SuuD zQ`-P&OWI&VgEoO@qwqkzC&(f92_5(M=Cy4jX0#sUR+Z z{37}5#oCV_pL$E1Y$OvHV6PCrBdh7@-_v3%RnYxpxYFk<6=*UR|1r)NfNw1#4SNp7 z4MT&4h0RJmzD|!x;j>U!gQa3~8ZiYU5p0gQ7%l1u#87F)KH5H-FvQRh#84V0y55Wq zX8K!E9SLKNv|AdMT?)8d!)t|V5^4$I8Fq`Ke{RPeK$ek=zkYc6=`5bk7kWAK1aTbN&7w|cUI$s@_{dheb2(5EFz ziCjGa@5i&%{pQqcMB(mD(HWF7qy|)P^-8mQL1lqFq4Yy}U3%_0 zPEvXmyubWw`qdzsK)i4fd|hW#miE@}urA+4C_{Oa1JpTbFPb#y4PCd}=HXeub`O$~ zP8JCS7TmY8vPE$lrUbgW4S8=s+MAP7Yx$5WEI@3~t<9&kLMGfQ`O?9DjBAX6ZfnH( z44)rDohH5TdH%Y6Ge3G{+3PS-w}~Q%GgaquB?G)5AeB9qREnDzIXe2WOYsVa>}- zr4uaUh3(}YqCd^@xArP)UM3LV9bV9qu{{>jj=^qYk>w++t7O$q@lC0GHpO(-zPh>s z&@9Qw_wB?$0|KxM`m02Yuma~-TS;DUH$$C`O=Z&B$p{pvB&G;$8NeW@jS0~@X9dRj z#gA9r@%PxT-3k9_GQ}sTN70Z&FaTa8Jj>d6XjpC-de;)>>f&=V!dCJ7ZmC<6OiyQg zFvHF$)8tnms)~{lGb`H)@UcIqtG8;HQ3xW^a$1{pun-eb*0A|Czqisyz4Ldv_>!34 z+SJ7bS>(G+F3>*Xa}$w_B*H*Li~jj@*u1I@_r=%RuVr=WYHGiq)HJ@h^0Xbnk!$zQ zZJJ?)_jWPAEs7?rawLuBW@yC={mk-K6jx+u84V^aL7mu1mx}JemM>ZiRU?F4@l7Bp zYhZwH$qCjnHm&of1N@vo)9u>Qtz-)HC-1gK3xYU zpillO=Hi+G=FsvA#-Xk?REKM;(>LSLP~Q#DLD$`zfqwRBBVqf+XwBflit8qLYVFaI zWb)XoM(kU}5V`}Y%)yPt+h1|Aq}P!U(FkqYh{)i%yV(*1A}6(3(>PS%;lK;gD;|RY zu_FuuPVo>{Q;{dA$=%O$I{XGq^@vPdI6^gZ^DQ7czZcot-FjHqyHA}qbM0!Kosa*0NrP@oNVHc-aDgZhPuCy|KNbj`#pdZJ*i8+Kl-f(0_}Q7 z>V8eO$yy2{EVu}ZMi^-O(b{mSQI9or8_rf?M7h2Og`98u44z+B3 zA4&Qe8Y{n8$AEAlSQ{o)$UpKh1VaGi%;qK`KawN|Qvy2vWfyD_y-0s;pW4Va<-IjQ zz(lYdC@&~04r{bhCx3T2S=Gi7EtYD|Vbge-T3;7}EU(*W)7~N*X>p-{u;d^uA@Y;) ze!$HB-hbjE)BlT$i$0LG01b9nk!*f_W2vIIZeHNVM9)CJZDj4DMsbICQh7zfcHxhcBex{ zTK3KC<~2hLTdHX3TyZlE$WX$e_IFf7Jr8oQ4d_R>`d~+9i$O2D5T)N6D6B?w-{aUP z&7DMm-K|Oc&n6a59MtImTcmGsMjg!QP!XHX%`=W!B65|jZF>|2R9n+nDzTPmU^e7s z4cB+p7h{6S^n$`Z<9#Fk@zLEu^6~Z+snLSRlVT)`GmXH;#7mmtSa@DVd@aFmi25FX zxP$XHBtD>XJ~ilgZv63GpfD`sYkj{=CFv3BFuuw%ZP#!85I=;P&YCX z0NUquWy||d;f=F-WNF~g(@?k+DSRpSH=G==1Y*R-8uf%6{SLbOcJp@v44=DK|D@my*V0-if;UnYN~eqa(9m4S0rWBO9)2GJI8+#fr_yQh`v!Q0;1$pBD}_{!kLWvf>%D z{gY5Qq@Xff0T*WVq%(B~446f^z|6DLaGY=BUn1g_d+G5O-eKlsu77a@mVetBxuMG3 z^oYEC!d4#Uq%)O~N#DMS*qi%kqY=~4Qln$K@XRBSa9|IWwqZTTmfwV3QTRo!kHSvM zaeXNEEgN}TAZL#MR_JZ-_p{aPIEz1jVUVTPe4k)HER{3P&M0bRbJGmF7;02ik`vFU z+XUD43NCk(98o$l$KOaQKC7dGeJ#&4W%jd96dTMUHdFq|Wy=XiaKc|cG@h?E62iUR zKxEAJ3Zxt4WI$sm$QaYvdPLMvQyp;zTJI9Rk8PBDGIywHiYQHvDNBh!CytQC>#wff z!6Z>yRgK-reC%jbIq}77_RGPYZqaD`X(_wU>lRUigOr*rNq!T;C&Sv+mdZC`9ez(f zObql*UaQduI~m6X!!Xfun9>Z4*l)ziWsr_PBM3=SR-NnEu=#yh@uCVfQbequyG)%Pli*K3g}vMe~dz|_UgTx-WB zKxr`L#!WFBO(X+_QtYG0Q+J;;B?DVDopz6|wm~-&+MpH>WTTqIvuFOMFm&x(3>)7_ zsQ46EI&IguL*vF^OF|XdjF+=03|jO6 z%=qt8!_os2b~k#0ATA6J+t?v@mSZ!GIDE8Sr#oH10MCIa0f)7kvom{SujuCpB4?ke zwY~3DW6NG)wT{)*j@1vtb{oN(j-*-cLueUnd`xnjm)w=BVUMVM-e-HAvLo<%sm4c+ z7j+Xc?GhL7KgoYU&r9@@t4YMWrxcbB+^hWD+|-GVQ>1O-YEbS{Eru|b#BP>c2@(;# zVsj?^iaoDuWqAGza(4LR~_Y9qU_%Aymfe`-4%-^axl{4V?f zy*BMUA)Ry4Y5al$LvR6GR29ct(52n2CXzV-b$n74rM2m0Mz%$9)%M*MQ|k|T-y5S0 zDpON?RCg1$Y2}D2n6IcJq*>eyoSl7gf)tecBU+O2SwA8Z64W=GkS^q%Con3jFWA*4 z)yPxSPUu);D_!2!SjtT)`hWX-aYO$YIV2`7;^?U-fuj2k%FHjIsvn#yrwJ^kaerp0 zf1swbNFk6){`5UyZLo_z?bFdx46;uZDXlv(L1a+Jc8&oAY)}_QTpT&N1KFXPnlA^^~W?#!t^gonc!7(|ie5jFAeYE(@m_?Qf)cXu&|>V! zvGDH$6`A15nI|&;i+TSQf$ka{efsl!xiMJ>=6C zi9G*Pfr!h*)KR$K;fQZ{k3EQ&pI=~Lam3{Y6YubMD-l?JIjZXFE}uWwL+&{-b6}i_ z3kqm}@!Qi`^YjNy9}fub&M%Nk_}e>7J!jf$Ufdq<(%7R!C`bZ+Ajv>~a1V}~=k;1l zt7)#s`fCu);WWxGi`5lJ9Us-3ZlDay&`!1tpuAq3|G}jl>ueBfwcpH-#5r=n-}R0} zt%I)H0k6?(x1GVagoTw0RYPNlXou~t*GT5CT7Z(H@b2!+>qMQfi-6+2Wc;KTyK+;8 zily#1$5nmXEV8vjKYeK34?`B8>?b*wyEgQ^1$|xNh*vc zO3g1&r9*CR#qtoz=;eIraS@s*u4^u%VEJALr*i$wlRx5Jn^gIyn;%B1ugL<=8sHWf ziziHM&O_m3dv4x6O#8{%J#L05g?&?amXZKEg-LQARKT8v>J@CXL{7~}D`*BkE_nNw z`q|lMI%J0eAe%bR&!8mfe?*+N0a0nOSh6W0sI079e~MUqLcWTTNK=AGtTLva*YlxHhAJ6yBvjbTHkZ<2<_C<-_l z_+io{yN=GNB86|UBH~H7C{l)hfh9DvZb|mGfK~17&_x3ca6ry6H(S7b{;Zz>9=to3 z@YJ;t#@V`;GmVhbBWiHj=!=D=Wxf09+SOcw5;c&KGrK=Ps%G1ra_^u;3(?cPirRM} zCX1HNaG@?j2LUH3ZRWce>=HGyrh$eZDruB}&1cFGX_LaM_n!bT5MiI^kIsTp6{jC1 zv0?F(bcht?kAU%^$u3jGHynSizf!dYWJLFc`=B-X^c+hP9d#6)@EYxNS{9+NJ47oL zmZkodkt3~;>|_WVUXYxWsDAFj#(^Ju_3?s3gc_=^;;K{1C@HyB3sg}p-1JdH3rp@2 zA^V&$xkJBE)qD`?rgFkXC?t!-j$bPYd+OG%iL3)thzkhX8Ina7I#fe#i-xHI5V2_%iBLXGX2?yNfXy4 zu8a{PXaAz$eK=;efCGP|)vPEldN_kY_nn+n#BwM)S9kmH5pwDikxQ~3e0w#-72SqIbO+!yDlB6Q!d56}6r>({<((G#t*y5CH; z4?*7W-|HG8v~mtv|IE%_%M*N{_X2oJZxnZUcf#32Cn@=~+Pf$>(V@v5Idu@vM{Zoe zq6eAlX;qKRUq?QwqJiMjr%!yE(V6wDle9=)6Y;{KZujpI^&At2v&(pu7BYvrf}E~9 za=@OtL!W%?qX-*4ik%^!h5Kka*@p&NS!3%|C0HkSH8w^}9ksS|^Exm1^kEI9sWFqa zlhZ@Ezdq#)E?RWl@-J2p0VP^WR0L%HSBuC?m=eocRAkXb1x1XzGGypK*f1&+b>7xQ z9-5$v;0EP(o2kV0jk~3m(U-|7_KkCuKBlRu>SH`H_E#z%9+IE2o`;yC%Z82_Fd=;9 z6w8aLduV`v(oqqg6yM!$&6x$UiueA=|VEs{T^t`1Vcs76k$kaWEm z=dny$0JV=PCm6XSx!4^Hj&5iNf;ED}1%#BUQZ|uyQim<_!?Ay??sUMEog6({>Q{BO zns>m+HWfMfcd={`bHP}?UoJ}t7Xzbn9g7`Zo*J_i0ZCR$s;|G_0}cC%lpd& z;Tn%Pg?MgpcxL3{bDR4qEYt;v!G47*U}1%)>A>mh{tdq1nBaOE_Zky^it5hsK5zIK zpagOW?Z+0BGQk%2xaGFq(<$`d)Mc|a|B^G+C1)NhA$23d-Y1ujZdG?)8M9{z+p|+Q zLq9R!{CKhSniZqrCV)`(3WxJajuiO+;J(KzaRHj273)3G-+wLC*^d~O!;oMS5bQSq z6qKHwx%tneB*&u%IDP#^x8o%SgX*YG76lm@z4Fgl!M$=xW3OP_E7p7K^%%=CS7uL5 z5J-S=1rWah@|)5aR6tzR)Z7f{^Q3b-qLYxb-c|+c+!PUc*@@juW9ww>lnyMzj6e{#eRzJhq<_Ik&gB&_*BNtbq=V1MV3zGGJT= zxX)38Ou$jKukTZZ7Cd~Vru;VrVNp%U=ygP+?crVB0UaYX|2b!3ZnsqANC%F}fr01e z0mGv3!M6eN9drKP5>4+^RkAcRXKsiu$2ccN5Qd1V*_o<@WDQL+j>q&hxj^$w7HPnz z*6{o5hb72G_{7uD^3L!84gD|^OAVU@g4GW5>oBKLGaGfcL@#*QQF=8qnPsEpKE6trAR&spzL;|YszY5}U3+`h0i%Dh21FIo zIN8_$+Zg(Kinb(Nl4%Z@$jL@%gUNn z@gR2>w_TUX!H}rw>l1pPWM*ZNh*&08IcaEMrzx}nMaq=A)tjW{n;UoOgjhgwil_T| zyhvc#Wlk0Vl&1GaY)h^UlcmV_jO@?0@BNYWXW8s_Z_d5STrxZ-M@NBli|-NuIQiy7 z!BlM-qUm-2J}EBF(Wi{LeV+!m)6>rh^EUI< zZ`mcAcyl;;8D0x5zpd*cYZ-BGrHd+*N-bpMDdc|_O zA7A)tr5dhrK`=xt0|rq0KN0qFJ*|GU5*kQ0A5AQ*nubn(LrwuXcmOI`y|OY2M^i-! zppMtTuB)$4Z2$Bj;O@$0baGM*0chcp2Hbf2fQhIS*jDt43IqE4rCnY5Q(DQKoRI!& zih)UbQj)g4LTO{8gec4YL5n(irb+=YYtPHgQ`b=cnSfNUSK8VN1s+pgVC4FDem>FU zU~SFV-hO!VOI2m1&)rx}Mh=+)0PO>O=3|olvI_>JSPX>&O7J=P`Uc5w@i&ovvuXc{ z(QuvpQnUBw57Tle6##-HU)}zJ*$9<;EDj&Yzhc1^L72O&o8|<9@`GOg@bkwYp0i)R zlN+mP$;rDQhsa^dx&)y49C+r4XhO|1hpKd$jt#u4PvumZ%wA?TwR_1@Q%`e>qrd3} zjX6UMC3?)# zkejEq_(EWDgXB}WjVAk)r#Yuh(Qg46AYa0Qpg|$tcdBW>v^vC_qtUTu!$5SZOc;(VwB@*OIs4h%>$0@-){ixIQPkw$t5D-w9DD3b*fSz@0#&5>sz0qrdzl(HbR|+Go(0Y%3<-H7je6|;vEYd6k#32snqP4I3 zO%F47Wmmck*rAk)>8w^~8xo`d*i0zkJUTobB=iBm%JZ_4GqqXTC|>~O1;9~9!ROA* z%gY17@7=pcRFSvvu@X7*xPq<4#bFBhUW2K?v7uvgy0i#9&HTft!?vc! zL!{WD;qpA&#*ysTd+a!6$4v10C?Csbyc`G0=6AzPeOTLpS@Gi^0CP|A!A^P7(zl4p z%BnrOVcqp%2d*&bvE+}!6#DugQ-^i1FMwR!UZ?y>KKoh$S)jCm;jIJnt#1Drph@%t zQHGJQIRZ8L@Cidb@GldZdxU;Tadup6w1a7B+pg{5wK+%`hMcZ;Qg%$qKj$+gaXSvz z2a)37#CeA6c226vh7Me4t@F;iXgT^wf1UC3zjj^2P_Tcr8E-!3#tzbq_}906M(>%# zI44kaYP60rD$&mFaee@{`>EKhN}GYSax72_EZw5+fsAGxd7j8W_~`EbbKcZ z^m=b9$h;P@Ld({+hX=>4y5V}eyTKjeOS0p+0&Q86ZPet~d5V3LBxm1*@-`Ex2vtp> z>^47Ta{xRaU-dtwqG~;G`15fpYol6@$W{%MCiOhxfzp=80^~}(1HynR^=R;5D zhk!ThRNl2(DqB>soOgd<8aY8%zUZk%7gE1(cmyl7zovz|c1VMXi8+fM)SN29Z(`Tn z-rd$~Px96XAtb=vAIT&M?d{N8@Hn7~um{mDj5E{GfLa$KF9Z6|u)@lc3X)B>ahUk4`EcbM7nZuN+`I9`)r;-udk_1_28cJHR_^aN7<5U+Xc>&HZwO*uU~ z()B*?+cunSCfmvDw*0Rwj>#MGeE>M~m6h6oe2lqDv-A6%ow7)O&1@Wu2ww=bl`4PR zW7PS(z2~-B$x(_Qrx?0XOn+EE|3Bj;a&}fH@zLz2ZKB5cq5FcFhl?Az2enqYJl7t# z5y4b@ev9pxmo^bMpji)~H`un$hIfbayVFj?aE~T}UDzaQiMs4V)>oyu?OY=dTtn8w zAW%}Ef!$1sGZ>`V85%{&K zxjBH^zC2TS1p~ti8a5~Qfrf%td4EtvKtCboW7BFiQwOR~1(K+!-D1e*4Mz@f|4m?i zL7C%&cBbiRscDbpj8Tq$uyjqk5P~RjzbDV2v{AU1#4cwL-=@? zVy_d%iIXHp5^GlGzn|V^>?rhS7=Q+;X{q16Xa77?x_HCjn+&8IA5Q%DpN9GI1RzSf zzub=3a*{}p0MvZ~yS*tA7$!DFV>f`?AXKz7-E9e=czSy8gFBT~?x`3#U_0Vu}8 zBAXSI&gE8dgx$S88T&Bc1BrowUR+#aVqz?1TDjqxhLCl3b_OsuCMN3urwceC`0`iD z+#f|yR40J4AZH4L^w*JX3kwS;?o=QirmwHxUoZ4QN?MwenYrs&^+zXj*uW+bD*(Vi zY3p|0+jWqh0%1rk`k#L777QL{5d&dg+Zf*k`wP-D(2Pw?AR&1PlSZ45q+i~gngCuu zW%Fi6@!6?<45YfhU^CY^%=94KvemKzcKA`psMwTqJ=2lk)l-aD`i;HOo8 zRLfU@a$>;qiWi?XaI)B?fAM;`GV?2!(Ze-9e)8$*X^}Ss%wQr=0s4P&O&p2m{raz8 zT|i*K(|r&yJbELD0c;d#^UYV9?f2Rtfzttqf|Bg)n51|sYirN7F6n?#fX{4hX`vrv zU}a;&#KdxYXzd*9FYs%@0Z!HhMOBki9Bb?Anq}JjE`>-U)SR5tPC(3}etvL}o{eq& z-z^gG-2<5@pjLqlw!5brSQ-o_t_GpX$jIo_e-el<6w8VNwd^qTG(RFj;qd`Yr0CJR zv%{c#P6E`<($cp(6(-;>k;4bVPC)*OH2}=)QY_5P&@ta2ko;_HOiAGr`3j}vnI<)JeWZNhNv!E%@q)KB znoJ_S&2`$5JQcc^NwoZy55v85_q@r01#1$(05rK?TF-_u?+&rCvJPjoeX=wSFiNaC9|d(kXG)cM&GPLz z4)Cd02I{XPt4Lg|(F&g?`=Xa2*ZlD^;t0U+DSsp#pq7CDqlTs?S-|w|y(GZ8Dwtcn(0*~$S_{FB1L}_(mR`>7C7%vECCZ!pD4WZ}D>s(ZW_9w#tc2k^}je(eQ-2XwNAUTBsGzu9fAFyU1-yj#rDwIh~O*OTcQ3dMvTiBpz zL?8iP!vN0vFI5j)mXIVM!R#%3j)URrB!a(kf578I!87-F9-m~guFO9#k5b?TiJFd% zOqLQk8^GVI#KeZngTh;q=x!=@y0PWBm*le@SskI8P6_ap0YR6jr!~ zub%lU&J^IPdLoOdMUU-+q5Q8ZUl9o2`$9Jpwpwq;t@o7=`pc~hUA&#!SJaOUL@5yG zHFl<&mKBJu&+KnH7>Le>bCJ-Ix_ddH%Bmvu57$^8+pxTiP9!+|TMZ?RjboipuWf=A zMrT_1ZjS%?Bi)zU%{5=*%-{{pm)~RO0CUEevcL}7!WeYmal(wN5K%)lo%TNM;u0Bu z7C*W_L&gVOjJKVAreA>am}z-op~|!?GNlk{>}eUz+uhc1Rzhd2)3lbJ2aqSs&r#zI9@g|-yJIKrmp^YX9{EaDo~`s?cA5dLZLLJ**~-RWJt;8zMY@vCqsiAoYb$b zUy=e|PbBnyg}*=cLY5}`RX5Ync3y$NrAW+o&-ri|!M||bMO1rWVZJ!>uQnq$E2*_v zb>9FqgS%Sgf%P{QxyXPqR?(@VOk^~2@j z1$fl2(V>(E6OqzTdv5{Cb-&^Y_*&@NWFxZap81Rx@8xSSog|I<{(ug~_ifcmN*Y}= zV^gKr(_x>9c57W*fii~4F07KG!~K$Ph5+!>AiN?ym>bCV5{)SMO=IEYWce0LJqR(p zpwQ%(I>~P*+uwo9@h)`^f6bA7LpdJrF(I~x7n{h*XC=3r4!YW%#BCmMxv)Oc4Vhwp zm`YGFkpQAFK3)x;`A3=O@U2A} zEJ?*L+h2zuE54hrTkf^k1xjAp^p^mJ^uQYiL=b^8LvCBF3266~1K(J?1x7YsfaA;= zqYNW9)XxDvk5 zTZ<*YrdHTM0_&qdjn=>Y&qxk9br+Y*yE-Ym7lCDMRNPU&0gk_#?DnY1A@V&>VHwlC z_ltyqG>(aN*PS%i!BQu!#tz+e0<7(VmuMZ#Z-GtR$&-ZOqxwBZP`SsWrVz!vE8spV zygp)Gez86$#DSGHtqAU49I5dE_cabfg&3F{I4 z?H(tCgVni5iCA^g6XEVU`%OzP4QK4N zU3lI3?=t;7o!_Ye@d6lN*c%l^qnbxeORJE`yb2zkGX+V3XSmqp(pMpaxRv(Y#>*XB z$&Bwa|MM;vfYJ@_+)3%`(b3W3)e7}9Y-XMSwJ(&`_w%kQTfy9;clMG5*xjE$7x#bQ zDL$wRz=D88e7VJoYB_EL77WI-4v`V)!?0H_cMg1H$(AKVad5%u=!;58eGd)}-Y}}; z=SBoblASB~S6JdmwT*|tGQhx5D8Ug(zbWTPNN4OjIXX6YoSSnUsJ{ij`0Af;x|NYB zT)d_3GoZgGoPfa773e^L4DB!pAW@x-#>!yauY&t(VL3s0~K#=hq<0GK4{N(xg z=)w2DSOCafbxMlvqaz?#$;u7@dTEWX%$G^XF`!HR9vK=M8Xg9{p^@Yj-~tFp=YTh= zYM>1$KsZ&v7&9n6#zQRA#-A()&{uw|SwHp+xJ-M2+X_>H@Ix8qkHwy0#pLKNIe1}Z zAHc6*ZsgK>20*JAWWazV`$ZmHZlMIY=aXdI_0K7H2KZE=lyAnEFiJQ}?%F_;8nEXj zBqE6Tb(Zh|{b;B169+$x5IkT&B`_JT8TRqvJYRmi_kiWm2UN_liHM+U-AL5Wezny! z+^mQ~O~A&iySv+4pbgL*mm0i<%M4mTu4B3sRUoRYrUpDb-@?DN$3=pHNkaou`)Xhg z{=GcGh-o>X8%Rij&K71uOo1t{=v2ovJskrkc4(df*Sn{1>+LYR?c4X= zzyGdisZ^jlK1sNx9lolFu*@)h+EL6=HypFn;iZMx8?N}KOmYf@c``k;s5D3CAXztnx#6w{=#8<_CZ*>;VF+JWyUVvjS(Ew8YuShC(vVu76GwxP^k>3wPh9+ z(K($Arzr^<8Uk$eY`qpSaRwgSKm3r<;WDtwVRR(5wShGB#!q=4rSGnC%MIao5c6^+ zYQO>oBXAg)WCkGo{KxNcoD49S|371rhk`r*{f9>;!-kGkTo4RUh_^nv6o!HbDjK_h z_xzB(LkvX6N&9e2FXRv0QoqXwfK6glnueMh^$qLa+Exf5K%b$BfF>X^GT?6kuf2D@ zxFlVlnCbt^Z|wxG2%_<__@CDk_!=DpW$ch)c_x%Qkk-V?JWZH2Ne}RIJ*c1a!pR=8 zYO4B||Jm*eX#ypRB)P3LzAS|2=N!n`f%5hEmjFNoKOYH(P#-J}#ikMa4P{?P2-&x* z!|PM+M&sKr*s}cG+=*hOHLl+nUW3&NzJ!8-duu}X&`%zpGgGOwcF=;GCT8d2YI9sS ze?(xVs$=8+KZMH-cyLLdzdmq1-!tJB57bkD|0)YP={=G?4`%fBU}~;W*|P*N7}#c% zK0dG(VGQ9)0Tq{jQf-DB6>~p~8XfO}b;ut5JD7FA#A%eL8 zF%p`IxV^Um^=Hn@g=F$`COUdSX2eeN5MVpqvW%8U?<)f( z9Y!ZZ03th^3kE1&@!M{I7>zrTp-@ymp~E1J9r$q@6aB?U+|xTxODzpOc9;px`!rAu zffgf2g&YlFxz6s@-gd?a{xT!?c8yY@$IS2g1zM?p5znm@oVDa6L;%*3nwOrEmp-q# z_(~i=%diuYV$-Sk+ls$u0FXn1wvwQlhqkzmUJuUs>*putkCi9P{L9|I)Eu0mq6wE5 zTLVj?UO<^6oc=8+A{)eQ^y*OiyT&_MQ+$3FT`>tGfD>heHyj$EEkCfUb)ND5C<52E zHr{RnK(69&6gVgbk_bcE*Hwt}4bWEFS6B(}^alpko{?Ar&O>HnV$VRFow*WCub+gh zwdUaThqPEA4}&ZSS#c=43tPt}*qQ`M1RJIs&&|!O{H4(%cc1&IC9L4^lDPtw-L~S- zx5IYM%EJBdk!kb{K{16Y1`@4VNzkCEc!aF_ldeM~*vl{%R`iAm?C{=e3c9Jkz7dOm zx6fn{WuAC^kVrO;_6y}yY5y`UaXaBe%hA)V>0Ys%FY%y|RQq0@?%-7LO6b7N1!7X1 zC6funa04#KqQL9zr>*HqU%+;XA_Ki6KpFF}AW?jNf{DTykX22_#nn3)oZLokU4nkL z236#uiTuuMG>7!j64p|7M5T1D{TuYQdnpf~ox71!PfZu(YgX0duxa88?mfr82^nB? zb4r_{TL)>88U1Z6;n0w$uM1#YXT~_^t1h3K5^}bCo>r zE?@k_CSxEex;wXdv&UV&)s=3O0(!K6f8093-#!DTQU4D0EjwDZL_}i;O%38z)AMm? z2IsW6-L5VV-{B?gBGHM1Wk+!9Xy^h)j?mtp`~Y~#OK(2*Q=2%rB6$yg`4f|!sC>Za zHzT^UDnzv%+7bIU-g{o$whKUkG~T`x zsVT+ws5X0TgCF>)B2vP_?R|O~U~o2*>7?pZnpPj~0Lone$&~lvTz3*olJOwAqvvDL z)S@Y*FZ;WVZM|nRi&A;t@8eg2rJIn$-(glB-QXjP&6J^Aew1*?`AC2A9;Aa#bJcbx zZzx8NH;hM!aSrF3>mnh<9v0-UKM#Rz#m~el4nOvEOSlVQ*j0_k*On<9>5*C9>T(;K zxyqClq&bfGaTZ$t4JS?%L!hB%_v+_~kRk;cYE^uz}A- zpCBYpT}kN=bC?_@fY?6MKYY(Q>#YbZ+0h$@LpzvlZ@Ubg#?R%7=V}#x0-#QEGX8VR zH#CxeX?=@NKQgDP9b#c*4+um;A6_l})6>zqYLksjIim%iWqlTW78(xUhks)TS;)Sn zT1Rac@;9Ikpm_b?lMQCtl`56HZ`DEAFUe7#P2=j(IFJ#hXcJqhn0L8|?7RqfVg04S z%@Hu1ol9jpHOYQ&%Pt-wXEC0>=o$DQ{7YeIYTc5H3m~-s_7WhZADVt0RO{(SL<}a0 zv5s{G$*bqRP2>Lb2RHaf<&Tc$H3?Ec14)veo9)F>{|__$u)*d6kV}oWcJ?ywM1BWo z-hntVwProAWWGF%+dgi*(t@BhFUK3ZV#gC=!dLvJ~T9YP3Js+ z7=^c9=T!J32y<6%U~XP_|lYM7~w>0KlC z7mMuEu-=(Ya^Y4yOHpz(D!h?I(>3gK-d625#XJWP*O@>XbD{+txDx(7QF4xZTEezZ z$AVXSUn-Ix@7EwU@0ciJ5Riv1=2}jc0wvon47fXu96bR`qp8Aa$5lZ?jCA$&0#B){ z(|QL+yxMQoEeMyz=y*nJ($jXj?DRWq(327cBsCA?pWQ;UCi z=LuK(QAM4`_9zqx23*xyE%c~Zx4$Zo!K{NuZVt@2w?VEo7`6LDVT0P?o-%X1fYc=r zX8<(}-LV)x87AUTu^ba6ktA-%UU5#lz|%`e?a6P~<|QuDpsYruxN^^hnaJx~w`#Sp z5m#;BCl@zLtkz!7561@Bw z5Sn|gHpR)&As*JcfQ!NaM9h$p;~ntNSV83vc=^E9tdB4HsvMj*YwovGCrL6;!4mj> za_7;wckfhey0S&uTP&(;X0xLz|N6!m7JzAhEgQ(!W86r?qwgJ9L0&*eY!IT5$kiC_ z@3;S?cXS@Bd0ilxg$tMV2dMf0R$rCf0;dPncp_L6+#}%kGtr3Y##k!(&ZV`VdRa3v znq>K(>$6v&#ssQ5jE1eCP{#Mq$a9#cw18y3n@S~7;Aq53R#ZUF@`gzX_ zea+J6tB~0e60r6?{}><4~;Jdxs>{5NR<;W8lm-ci(7#tNaqJl!}=~>w!%i_e$|LN<&YH z)PtIzEoXQz(OLRz2(*^u!ejtuSXSb{G^JYcUS~Mw~8D zQm$?Z&++T>q8CB7xq4K;F`HMFo}=mTc{v(0UMJPCdBUm9v?FB5cMZ$p-$K{i%jU>p z!4}hJbejWNz>jlT*yeXq=IQ_LEWSA7i%>IubR5pimGtF1s|2S)YsbCpL^M& z2xivpg$z+#Te&P#hq^g5x9rPRbGD1Hp75C z(nk8OsyYeq0634SwY+++ZIXD;-82`giDLIiW2m z%J$MI_w&-IS&q+V4VA3FsRdb`@0o{%6H3$>T*fTQpZdSjwe8~BBw(Fy^OfNqu?7^1 zMK|z-7c^e|9?7v8$>}u4vAc?DR^6MY&#!>EAlK-8W&;t(k~l`DTD{cX(5BXR3Xu!ewA85<*05d~X-Pj4wLXGgg_UpKwlBsru!K-v`N;x)9xh@(X}* zR$An3>G7lecyh+l2w{z_2Z&tLpefeTu27wRMPp$ro+OcRw&`}&H7z_d3XALVRrW)| zn1Cr<4#@Aph+B|0quDOCN{{0AishE@t*`UsApK9A@r$C#U@#|*md-9zY`G9u&yFlg z!$bw?$O{_k4*_7j4rYv|@Z_j(NLMY;PTKJcZZ{tgy$#v(3Kx5IW9E6ZZ3wJ?h_6}C zv01r3mYf(*mbS&$`k7A{k^$n6`&xnYK@{uSoJ7Hjc2wG-9R`6=GfRHFq zL|R4>^Y;lQ!~2;%Lcs?`rb}ntYU7aOt~VIET$S%ZktozF{=Zo4cMr9O2Mc2M))DCy z3PuKwRiw-uQyoXmuK0^oj2~Intk^}qXZ80D(5~cd?BMN#M!okn`CY;$BROkDFhg*m zm?Qp#rW!?~7nFpl?z^24;4C=;WH&dj<7&updh?S<64EnpyEBVg`Mu;NntI5Qfwx+s zrkKT8axyxgGL3hL81jYhVh~5i#ir*EOapo{$0TBX^K*hws{t~FK8s^tJzluwfF7kG znKfgM#BZc(xiHT1?D&Vk!t!{@CD4X+YI4#zW@%*MQI(+E?Y&8vkQnH8Vg5KkO64U4 z4VInJX(Ihvh|vllAWpJR`tVnLld`@7a`XPObxer=TA9Ilf4yc0R9vlkkGz@sDFhN- z$)Y7uYl1XJ6us)@WA~N6WPm!gs`?rwg;xrIuU9FrbC*lSLBdc~{lx7ww-oqVgBV4} zMUB3YNWf+EgvLKPe!TEe)|CNysp=srnRk(EHdKoA!&@3^+QG$@THB5?1QLL_X@Q@U z*;?Sy))(;Ztl9o3{%!3pDjxf4s0j?IGuNBEu1lL$EzKbJ*V<1rtn!e{Y2^E5VwCus z!8gmUX`R_%EM|#^%-foonaS^U1rU-Tn)a-?eQHc}e{Y0Pj}~NfWA_m?#yk8;*#VXKmi-3+l(-FlR9j=?ELo;so|)Rq ztofgY#J<<#!%z?L^@jOYolG^KMUy$jkLP_rx5BktX(Dsrxfig*XdviYb-VqitW5Ga z6_Tko%|WO93dGIDzkty-w*~)Sf!-LcIbz^&OR;0KH^yf{tkh)x-;qEH0As1@&YwJ! z?a6*I_|n=+vsCQ4GxhvscQ|!Eqw6!5kTTZ%-~Z;S)RgLnkp9;`1cFWNMcZX{O~($N z{693a37S0rpCb}8Wwgv6js5bxxY~U^iSFt4`~N=Z;nrr=OxwtV2*2n3#p99ce}}VV z00L-R1pC=r|B5iG^S`BbEIl4;#WtVA z`Ti)?y}c4|f0wVQo~IY_>q5a;k~o%l)@x*S3XA!e6HU4lKb{HlG5}^;8gT_oASlQ% zD8oji6dgw1=P9~A-gn)Ww~?XHBk?qyi`?W;8|9YsW5CoS3U4-1jctE}@*h39ovk0} zY97hmxW+Wc!mij{)*h?t>of4LZR}_n7%Yu?14E+1LLG}|g2DduEteU<=bi$w08dX( zOvGHcxo=G1)YSj{6K%lrK*-X~hf31qIXu)XsAnTYgneV|8SS&&jvzGY2~$>8jU~cC zctu0g4-X#%M$RQp%p4qiUTY&<4oe?Bu5OOTdKb2j*lIYYM=fYrezS96;j6~?D4ALQ z4hb+W2xktM3J2}sD3+qEwtahLuJo`Lql_mKJbPxPPE}@Y$6wH8tzyrGzS&HJ_isr8 zzKeAm8{oC6{b9mJka-pFt?c^69$v!MG{ArW4Qe{&0ts7A5h-fSpf*S->Nt?6lO*?l^X3f?4-ZpE2dW6rLuJP= zfkvDpp`oGO!oh(Tff=e6F-pYW2S=dR2E^le-YWno>;J{rTSrwDweO;vMpU{xq`SLQ zy1P52K^jy*8l|MWJEc*P?rxCo?!J@nJHK(xx%Z#Dhr_W2Veh@xTx-7X^F9H>2+}iu zxle|X{@(2KFd<{5CMwbLT|C-&zewM#1`>cqu@yRp+ul|B4 z0vM0O?{AiyF!r|h?QCqY2yph-*V)ZN^!Uxk0o?>lSU>tONg_&0Nl{T#<6z-nVdG$1 zo{Z<7xzgr)d5z1_cIe;sO^+YW3u)hvjZc@9l$o+6!^^8BR`W&l?TzJz0)wK~bLgzg z|dGV6(PZdwHHl@41q;B!wU?9*`*_x~42GEt8Y+wug;Ir=}8a z(f6cjXlQ;2`T#7pAv|2xQnR4AcsC4#8chtiJL$DrlZBe4#m6@SQ%IDUWQUVz55(&a z&yG(Iw_xs9*oyIu=c=!>uBPVnkFngprl((5I}JPhqfBOhu0+cz$?b2C za#K=*-07Sg@_WM-@W#1Da3P~!U>uJYCgEij^mx*V0<_Z~e1})XLxJtp`A7nN2>jjs z6`Vn{+t^9~V~7a=%|XX>L%5wS4)h*9x)0EVx4$Qwlkh2Jdp8(&w!wS*f20xpqvj{k0- zr+#;}a=W{*0SGg=1dk;);K3zS0cflTZ)WR(mo@+M65y=d`hubFDlWwr+&3Zl`5Lk= zHBsf|trM`2Kuh+YRgF$h`ntCBU}i@m=xe>w@-w&z?!`3&teTX>6ipof0xv%IFP0Sj5e^*UC>vm z{)bLdJ7uIU?R2!riyZ-cZ;F%ITMounxJJUje2_9Ofv@tH1^V$~`3Td4M?YQ?FNz8_mzU{rm$Z&AM zz?)j0iu-ImUhMIVyfB137SP8pSl$3r$T#qvePgdk++5toXSl6(=85!8O-%ub@Y^>P zPbMi7PQjfN;2VPSiZ?kaRT?n!{x4wus>kjY3Sduw5e8B_%~)_5uuGLz+OLnFM;8C& z{15fIrdZ8jmJrBeWY5tIxshNy;jUu?KtbPnV^XMA3FCbxa;Eahm34*Z}xpa zTbWB2@&hg)ec%T{1~s@a6Fm9OKrgzJvg6jAxw1DoiTOo&wEZzCC`j*W6`iVW!%s`9Fg+s)L&*$m@1aNN;CbNTQV5&d6umJ8C0r>a^4KW(xFH-^V2qa7c z2Hs0c24|z4ofPlhN%-&f0*3s{w;+dyQ>9uQ_(S94s%&dpTOMHP^A@~g2C7bEVC8)b zzR8xUTVwtn4A1$uVZaPg{l6qpONSaqqtRK`+~bvw6)9TIJh);HLozZlVq)TP3VABm z(JaxK3WGQ`DHj-U(6hh+TwF9?q}v4_S*t=HWRu%H$Ab}zA8a%n6V3hXciE9>)ze6%|-=g#R&CaY6~Ea8*kwR z;Gfj&K+Oda`RV>RU+=#EuwZ5MzxT-gB)w4os4HI;B8Bu)NlHQ@B9Lvf4x-(KDS1B? zTxYH0^LreC)0nTMotK|aNks*O9y-xFP^5=|qjbOIcrEm5JurzFUiv z!KVHLbvZ^6XHG0FCLjtMq~}*uWEWTTas9j4n;HNH*jQqoDnS4HaJca0xz;noS%K1k zkeD>;d+Zl8!H#9)6-MxtieG;MRb*TXPORGgR#2S-_>_i?|^q?4&`pJmf?9fu( z!S{3tU^4+jP+YvnH>pGX?t2^S>$w-BVD|u8XZD_4oh;noI{lY;udOZ3dW*3fNx-q4 zP!~Y``bjQ{xofH8apM%@H9vc0dxmcFycE&bE2*Opb@b>!aR=0kfGJo)==KS>m1v5r zezg1&6ezmp0G~6172CdhREv&w6o|@rL7q>&NIQpmj9wq2u815%VtgW^tQ;(ZA=SRC z=0&xjZ-&DxSnQ;b_Y$J&(OFuRhT?Z9L;@dK0)1m--h~U|4_MYl@TSe?Rzm{6e%+KH zuP!RG?%(L+Axs?D^z!m@SZF7Lpf(ARlaY;0PlpUy?(gk&{p|)HnNELmdz)FCC19!f z(l(mYtXp0^vLG*S@O3JETptLkN|x_#I>!M{r^ibzEdu0!y1Fo=1#GgdV}4(IE^>g0j^19unK?ZJYH zLonjC9Lf;1Q7tth*$2M94x#b>5jRairkLX{)wQ**PEOkOwphByxDZqvoNEv`KO_Zb zv+nzFVe)(YHlu^51-UA{$~jd?1x09V1u9J@gVQw?BXuBZISL#we2R z*idlv*DefD=v<#>RtO1u-rW4&F+i{{bAW8nVg6F$4k@rbb*LSSd^fH6O2!1i9+1Vk#XNAR^Arr{^~~ zfc%Mvhv(8n2&tl@+XJ3uZp}n7J^KrV*S+7sxeE!|s10~-b6yWYvgz96w0mg2MS_Ly ziZA4YVa1I+2j^g6mK1Tk#j`Rk&0bIMZk#egDNSH==RfuHPbJ{s+q1L3KXd`lbD8+a#w);dav z1X9x7j=CrDN9ISrt|2(4#b*d~kkj$tSt`Kk+o~su3(ce)ab9P*ZRJ4O=e~^=jgvr=OUp z^?Ou=9fuAg_(95;0+?EIAns(t93lc-SV8s2L4=lfsH&@rPsqo5_j}7x7IS>I(Tm@q zqk3xws>7Bq7CRK^K&J{3Kf%JoZ)|NeH?`c}-GHz(*_SiI?EPH3eTs%QunX0pu45KLWg|eHH%p`S(-s z$f2&Do-?Vh)yF##+WW1iVWgSPd>JSaBXWoY?;)MK4a6W z^80D34`>1BX>D(>T|XR8d37)b+@2V88qiA0=|yx|a(+A446m$Y#{PVI;pBL{d%875 z0P@*Ds@&Di(M)#Rc11dWYg-F6q}Lqjo6H+rzPh%;p1`LLID}BJn`^n78XG(9oUC?5 zV84I&JtVZw)93VQrBJY> zh^n-elfQR3mf)#iMNwfv5dD-pj2c?$&Go+_gy*@t$KS`$H>>ak4~w5J)jTVNnkHjq z|EyMP#7sHDO#JMwWc>Nuti)KW|9EdZ${>@k3O;R#j~~aMM(6cLePGJ!$w>g82Oyb2 zP?qe0f}exvYqxa^dv1BrmUix!J3uP^jDXA`D?l^k1-0we932fPaj}W-$>Ju`S$2N) zGq=zqR|-uTcsdz+h)zV^+}QeFxI~qkZWpko^VhRivy|jWkf9>xJ=H0*g4|7=<7TUR zmGT2^_8CIEVc8F|r>DF4Wo69;ch)D+N5ZIr#-oly?3!}oPmgWSXY)UyML51j#Z5h) z$5>$1$a-zI)uK40mydZ=E2lj%$^F90QQBnl>MwPZtSnRFH62Tu8b>N-*jGc2>C_Tb z4pzSs5~8J!>g%KTBFVgXlKd`nLfIqqiFA%OvNi2k!iiSv#}!j;ppN=Pf{b!v`uEb0 zbpMbhRxGgSYSl^O`h}?86}AnmIp2_Ae826=4;Qx(W2H!^ERD4)Wcl*oc-!1X{(h^+ zp6pmIqD(9?A-=PZesv>(G(kp@PFz*f&<__8cD&m<`&#&MZ>19G!22ewqIS-K!7}H0 zGABU_5fLP?bJe*K9?N55lGa!Dj>qhG9qT#FpFi7D$MY+LxprxNabhsgFw#-@Zy~+? z{Yd!SSHRo=2pLkMU!M_4)C5JvZN}|0S811pR?7K*K!g0dEeGU;EB?lbTA|G^Oe8ow z?t#cs+hD1L5<3*8eBWfdUHi52>`wv%k?~4s_uuo7^EqF1n{M>#3{fCaUl1|b*RQ&4NP?A|#*0X+C(FB%}kkvXzxbka<+YSB< zQ*^N-+fp-+h7A3ehZ@13+#Ji9(BpJ-RjV;3L7j_&0>Hdgg1t_H6(pw8)6rFFGoj)nMZUz90!EtY7ws2N<9+k)cT)zuX+LdUqYxPPV;u3+L+ zEoaHPt#4vML}i=)a1}{&+b?qX&Q?7=BA|x--5j9sH)@m0mPjzPayLYeEik@`6s_J@ zTtAu33Z?*81RP|xc0=Z(Z79)W3%Y{kug{U=y7&GbhBwOo(@y_68aqOV@6GhY3|3`? zIAoSf*n7Q+M$d}ASevhD;o(Wt4-vk4w?8!p~~!D?ut)Cgy7HWZ{E)?&nw zGQ%%GTThyRl$1XT{3lwXbQxA{td^U;%NvweeXd-J#U2yXm5moW=S!FvY!sgjXe(hM zgm;e{(*vbLyBuUn94*J=?G)b7kgw*CmxUBc_IG+z2@3aqYjwn{7SPqiX#O3xyXu;n zbTyou&F3KYFk89kH-t1LpE7)m-*XNA4dK@=)4e8pAV_bf+v4OU90rYwyn@Y?Vn-O0@#9VWh0WHd-BhMZ z5#cj$_&Wi(R}Km>px9CR!D0d|;+K3|KuRZlI3-=%uxJzzgLqw`FG4}-U3agbf0>XL$0aiq3J)%ivjY?dRC?6n$Bnu z7`$63C`LH0dic#NGBHInyGd7Oi-ij<3%a924?Pd2`|6pFY#$8LXsOI0f$ji%4lJsB z6Va(VYJ&)YH}`8U<-B(#4ikH)3hE;C1e&BiC)~~lW2a@iurSI=<`ZsEt zTsf16<(KZKJ37Ay|?llMGuS z{;$h4`xHn~i)ijO^&lDx2^szq2EUrmXm=+D;U>5YbW}K3#YaRksbx&{CURXn|J+^e z5_#TVZPIIDMsZfUT3F<#Fu#()sNNc}NT^}H)-bE$!`fV_=%{OjR{8}6(Qo0|+{VV< zPI|cSm|5kwf`U|iWC#PqgPB3kmx7v9P{g z@z=ouCLj3r&BV@1P6>eR1QcXvXNRz{!vbvV&-@_o(T#bs^X&6^urC=!`Xwuw#nj&+ zRwYloF&cM4Kf=|PM|oVr0Jci?Qf9?Y42eF-fVR)z=R^YwoX5SUTu;_f(jFfz>u&^k+Ua-9KspV z1ahfU5*EKom^xUj?D^f*hpAi&a%he<ct5JN}I6z_e6A7=rPx?7BN-lgyno z?=>!DMwm7Bkrl*bhYnQq>?n|5>nD{YEf_3K9eOy_%@LRB>?nW9Su+9)Q&eQsP1O%_ zx`Im6`5S6I>NcEZ9SJ+w-CP1@m=qg^r#**-Fke#!PLGxbQUCjD{`refrLX_FY(P>% zrk=5-+&b1N{@zao00+fMuC5Lb58HF;$;sIP1sgz*Bd~*4ntV_=XMxhSu6V-N*Ds+W z*@=hnGHOctkyAW>AP}&*b!$FW$Hig9bxn>l*wJ4jRAMHCU%vMaQbW+@{lVRjr48hf!;+y_ z41!`g-xCirLx1magfDQ(O!i{|@_R#d{pRUMgSM8Us#M89_ux z$RugxOWW56o+BM-_eGW_V>+H%V4* zP{4v26n%J8x_~pAn`%)~Qc`X0`O5Yac9;YRq)_Q|05(uW{2sOdx>A+HDqL~GzlNUf z)}m}K@s>I`-bEYTy0F%WH?)E+w%CP6Ma17=*^*)x!kGjG z;y6Gl?yU-O_!@?JSE;yo5gUSFf16V=_lUh%b{t zbL49z@AJEQbvg}O{h2jm+e9L@6^C@_B3>|cY|<#-xazENL;^0&3!tSjY~8sq3aG!n zXms6<-g}+@M9c9|qfSA~YjgKNtLIpz+S4d4q7{eyw<_3m>iU^o<(#kd`Fo%UX*uE> zcnZen#3&6qMrndlOCoHfFIoL5ukLESFKyk1@)Wz>a~e21ON7QOegV}bw8^oR2 z?8m3aF+uMO3C4s9g{i*ApvjA3H#}5GmFLPb7~s1djQUS>zukFHdvbL(JvO!ry!boU zgX)k#!i~hauS(8OO_xIuk)ujPeJnTqTQg&tlq~0;S*$R_YdqXT>-4mVeo>J`4_A7aei5>^744* z`d<*t6tW-?|5%z~R6DLLLp=rn!l23dn;Bh^gq^E}w|A4fLX!)#6QuU5Y2D#SfH&xO__u|@ z-^Kqx=k#B{-LbRsG^&`-i2LJo>B3ge(T(P$z)^?v{YlP%-)13SoO?vt=sx>&g5VWG zPBgc;I%>Y#>7E!T+qfI1!V8HwHx%WXdqw~)k8+giZ&5=-0~mtl@JMJl@w9@02%qAI z<;H4TjY*Ut!**X@AQgLwUgtSk`tA(mSs(}zXa!F``a1ZfMyIIsnb!aW)62{K>S){o zM8axt>v9p$7SpP2$UUv_?1O5H@)bqHCT``WVi+C$3JbYOORF`xV``HBux}3Pp~m$)KC{;p5E0+SfEH|`8rRy#v^0zw z^TF7@$1d{IO>u54WFw)EE&E${9*2i&zzzLJ^~Csa+PB~Mg4`^|dl2H#4k|bL1gYt% z8Afw#ou9S(t}Z%6Vp#7h{w{A-MR=u+msUGN0!P0(drJT*+n+YAdveoVCN2PhoUT&9 z!`*YAS$q;96=rtOiUg87fV?s9)d(D$b3v`u^-7mRGdSZRAW9V4Qv1Nr3VZT|3OOR0&y z=ppalnNNzP58exuVY2$y+h?Ikne8!3x>XKR8fJ!Q&z0N=#RVIS90fUn_wAe2Esl>S zHjYgHUKP6O{Sz+02@?ay5U&|-XR_g($me67og)fl7R~=(%)~b?MNQQ(H{FpFqn=B6 z2qsH-gMp!grCB&>@8r>{*BsoITS_%={XMB8yBAuoxB;)OAmJona@pXv6X`umUMU^K0$B$WpnM&$+R5bW- z(4zkZ@<$cw0YC^CQb4zbG*D8bLCYzZs6kX@d7V-}sVOOG(C!kf_;daAqu>1nF|P~e z9#s8Gy=!4+CW&r#iRBcSJb(Vp12#5*Wq%?CtG&Okuc1DFMpH(C0Xqgy(DwJIU~8;@ zmYs`>0`IKHGYOdBD{-fGh5-)dOii-f>TTB_UmSHrI9>o$a!tTj7UVsHg|NE4?YZqw zktdL+lZu=+tE6BCI^YsoJc#kSIUGa;f|?NS#8Z~v#tR9Q;i_`2wXoc*Kd%!%RI-0s z=#6AER}FxOBrB&~H~pI*V`kNgANYZ1UsIi39+!|DMf)Gjy}Pf5r{iy$B6~gCt%E)Z zWU}O!I);i39(GK9Rw@}H3+euZf&Fae`N7hz`}M_JC8d~Tc1zB`pYK5XR*-rN$OFQ8 zhv6#u0K@^vt;fOW^3>2!^apO+Ng8VELO!n|yS^IR`biKadHPWx{R0971phHHRbXvRoeSM-Nx=7;g{I zPN&94U-7Nw7ND}S z1n9YZxbpe_Z^ai|}Y6>btJ4a4*IF*3kz`%V`>FRg|saHwytgcOwco zpD75e{NuqV_jph&k|4Vb=`+s&h%@K{fdC#bQ~Y|Oi8zT=+)tW$(1USFt}|CejwiYC zz(s}ah7bAIo1)e*tob-LrvRY3m#+4+;%Mjn)0T#c;c3TfC0V4#yLXQvJt8@{EbQm8 zvJ$5iU#b7eVE(uHy!=n|sb>8_&hAD8fYDK-R2~z#vvYH8UguKoy6bDE!^1@U<~2xw zMDQ;bRSjR^-CYfP{C`FpCCN+0%m1Gt#n^XTf+uZ9$Kx#J90-IEdHd+7qO_2ogEZ?o z@JTGY3Op)0Ei5gCe6GsS)+^~T$F<2c1CEAKv-;Y2Ml7%X%KjfRgI^VpjEo+~ah`r-D$&&o=Me{DOK@gAZbSn!$TL zB8M#`$}zRo#gLT$x7D@yKqNU&vFR{0)p0f$iA!1V*RKd>_ro~{&k7=<((&!W|{(Ybi#$!oIu-h4Ib31~t|GxgrUFvYW_%HL%}dII?~+(>diO14F~W@CF(AXhvzNg_j^*h{F2!MS9NH1fb2%HO2Ac1Wr<);GX^oFJMx2 zkm#w#D7&-p?JF@?Y6kUn_t}n=3+rl=n*q$8FYu+y`1BZ>BaGFWj?0=uyeZ;E_|%-0 ze!Sv4c|a@T@14?2XgzgQMQH7s2$L|d2?|v}h8kkmcPP?9#ymTR8VG90w(ypbvpgze z@zm|<;4*ru-n|x~L<$07jxweH8MK+ae6KdTa6d=7Nm2k@6S3W!J9iVwB(-Bbjv2m< zPFcltxnfVZ+ay|AGxO2jUS8>fJ`KFMg(hbZDz4aF#QYRMU$t@eoyyhvlt??1yGXv=e9FJl_6ZDC z>Cj$x4Gs#h6R44QfgDq^gv~s*d9U%YTyV8eu+t?5%K0a!r1t;YNN9~wf`;&X9KDqB zE>fV?ip^BBwwB1zNzNkvZj`@Sz!q^XyWAlI4Vm>By$th)Kww2(RFgj%q$M-Htshjd zns1r&RqXFtW6?Zhz*2eN|1Q$40q#+5%_Lbp@qv$s^lLTm)Pdc&GWcieFevec6^EyO zo0JnVlw>63l?iaCTi93`>i^=*QMvfqtl;@J0KWmSX+SOT=@T?ZcKs(nPy!{tEnUep zVrZw=x05xmKeZ2kTJx0N16yKwb*UWGbb)!S8s3!!u5p1j?+=qdk&=0{SEKhn=;;Me z3V{KP>WAV$=J@!8xZZb2!3T4|$-%qjXvzEL<|Zqjejfp>ro>*bnlAfq@;gh2=x8^} zU(W-BlDveo2amOAI0UenX2!XQQFO!0b4ae`-r7~1B=vaQRjCb~ZJyWX`&b*> zwd#D6guDcS$Va6FhL3?nxQ-Ylw!(>UZNgS2|Diq$T*9rh>{QABHCJ&zpbL31eGo_~1@D z__F>ltPqd4_wM$N`F`&)0gH-)*w9PUJ((Cv?0b(6Zj1YYmS%h`jYd-=5@beSy3EFu6v(@NEvFCn zn`1=D?A=dN?|EJBv5b4wwDB*EFCYA5ZF5K~w`1?#UnA~%92jPbmCZv}@j^>Av$ZkZ zH@C1fLwYIqYMg6;<29K|7{FkP3f`%N9T}u+z#6YVl(*F9S~v^MEGBAF(ZE2od9_Jj z%F-71+qK^SYn)+i%c4# z>|`d)jxG5EdM*Z)=1kCPJslP&nm#Ap`K^BNmWg=TTu>s0t$rFXGNOUK#pcl1c{cpa z5i5+opWX>J4OyztHr=F4(F5{pX8w4kdad`5uo2M@e9qJmE9{k6o@s( z|H50-pb=1-t+=`Uz8mJZqC*0I`=x#cA5#qSYmEh%(s+E78PJ%L?>4R0XvvlH`f)rW zr^}?V3Z)tcY8^nv$d2(mm}Rx-#~kXOIP-eEy6hsrNhC=@NwAjd{GBf3D(w2wIm=ydT&l{JFn^QV@cQoo*sbD67Zr1 zK8DH3P5zJG3euC~yslT3uOdtug0REC;dNdAWSXg*A(Ld)F9@xJ=JWQDjeORcP!S=G z`qlrVE7j_Fna?vbyL$DwC(*bH7dDVLwP5(sofq3gW zT8HJQwgFQILPq|Zrv05?$bo~4X z4MDDaa8>fr3pV_el7({2*wZ(v|xjEsze zL?B>$dJC80meqUXM{-2r?Sp2hFQr3x#Z!9gy}K=@Ruamxx3_S+ihez| z6kOB+d+~lel$k%##&gHQH75}=?0DI)|GZC?*Ge&0ouQG7Z8uc~Ft>ekME>t=H|apu zxdOttZIzZp>wD~kqx5ELxnmG^4g48LT`RfZjIzsyIWGn6M*AJk8H z9{&1NQu&OKaGRT+%qlB{PWVP5;m=vs#1v-I-%TzraamIWM6v-6EI|>{SUyxPSHqLW zSdjNC!5qd>&9*l?Q10jHDVUQ%mLS7LW#T+b(h>+!X8MLC3k$@!+V5^rGcRb#$|ITa z1YJ1TL(9vTLM-3Ed_?}Pp4?QsskQ+m!Ml!yXKNNN#JsscQ%vX}k-d=Y>{SvwuBU3t zbx?>93wWO#x!Bt3+JeE&tI&u}Gv|+sp40v8BSr5&s~vOd90^?#(pQg9O)%1~kt2$6 z=HTKHv@|t)I9$v9&6{FkDq+ihihuc7j^UM|nQ}vmd>%&)>zZ#K-Hkh*yF>+%Zf^m9 z^5uoY3SS;pQ`p~R0I#5+_@gcy;wM~O+@0NB8$Q&xpXpSTglAIv$W^k4gX@R@xAj3C z+Mns z%1#SEsiO&Gu$@Ab+_}CKYA} z^hJNVG6(wx2VnnkURoa^krP8AeDYBsN&*g?WE!*Xm_7ckpMEIy@igJ!M}PE^DaVNU zoBrpW{z&;DpUUO%*zB%B063`&wbIv71YB2#3!orTvZ3R8VGrT4`>U@MyQ}5Uczob8 zOB5HJ-};Ar$~`hy`Wy0*@agLIKGlR2@Zp3BCJK}S?yrV`7dR$kX-*E4QIpHo!5m;Y9r9o!f(9y!}GE+1xng3rQ46c>do|2?r4c zEVPYYWI9jtG3E-g;C``$%E6+&l=Pdk=ebLobj5(1lkC#c{X|AR;C73@RubE{>wwEM zZoziP-fwXRxDLS#ie|yOaXnh=xk)|KE%$MD%*YbN4u3x?XDrL`pt`q?Epd^*9DcDE z5aIBU$aMn|0*UBKOiH3hexJYj5n9wWTa+}Gt7kSW_g?;L_as8P(_pS?F4FKSZeIlk z<}<*&p1=SGpojov2h4vj5L4RL#_MkH$+?bs=SsOgnGmVgy(M+L9*3!x2RffT^x{A5 zVsry{@ty0wKTjc|v0|2E+j(iSUX-?Rx2v^l)*tZI)O9sqAatev_hwFKvdcZx;5quM zeoP@@YK?21D5TdEI z9k=F3?WB(d+LEgd&+spl`%5oC6|Og*%08}Rwv9r<<%bFZYy(|>FaC_c&b8`%%1`A< znjkIy=irj(#wl{$%$TrZOd99p^wiy1HbHQiDRC&EZ7M*1#TUH-DZQ$Og^oYk2ga8p zzYP;(V59OlWQ`a7CGXp$_=%*`<%|5>|4k196{i(Ry|W(dJNAc6rTMNoIFj5>dI0dJ zvabMRjB9Ao%*3j@*E}WzgT>9|d4AFG|KOrQAlYc^7hk`g<{q*X!&pOkF|?SfNZ98{!?4J*3mkpQxL4kgh4IHfh-Ab?)PV|2<_3(JQH1ll#LRW5VIX%P}9Vpj$P0rjR zqRW&JpMX;>C(jVYe|dqs;+&XX8U>d=?WwM0M=gik()e{qhtnj^N6QKT9+!_ZST8JT zO!TlxFvA9$0x|(tne9E`qJ!jCE5o#xkq<&fMuyxr!wPD%-)0zG)X~Gvu~nhc4^9T- zn?+t%f+a6G3J|OV09tCLj5Ho+Q)}xYK(wgSQ3GIxL~eBIvxVl`KoT@86a?g(kqpgW zbfqVCyg3ZvGCS2q51!3#;kTXtJ(6x|_UX5&tzxh#3*XLAE)5_GuCekZ6hR_7!5TPx z95pwT@e$@usSgXcE_FwM7(4x-ldd0C`?Xs24rvS!B>nbQ_hoBUHycunU`4SJo|dON zYTH^E;Y-h1S-}h*9a80H^dpwp)UryLs-W!ElE=;}7X+|gt&|o+4$qMV8ZYXOdoxO; zY#>em+S&v%M3=ouPa9FkrRL53eLHjWyyDoGBGT{f>ZrwO{`=dwD~^hV+|uD_JQn}S zuVWgeB+v1S?S4K7v(@aDgHBFPARBA0(K#2WJ35!P^4Ka!I(*2Tjm`$@v|`#9FM_*F z=Dp_8E=~Z6aEEoaP@aaVZ`;%v7m%Y08`4VSwa5{_-*n8((Y~p9)fC%h5-^Ma$!k>% zI6uh!!~RXyJg*jWH@S)@@^dJWD9(zH_Vp1=OX91)U2ytXL1?rRQtD7J zqO8!5jyMMX)TUvgRo_gMU^TYfqOIY7-`@{zgI^?b@1hTE6brMd|1dKNww>qbQ+b}c z5MmxEaZ*M|qC+54@nSis6ez zZGA&Z&VaaO?@fsW!GOu@F9VxL%WW-cg^EC0rdMVB;$ustkdmk2IHdDqdZyS+pa6h#gS(bM^z(Qg z{<=|=$P(ER=kDLQ8dw+&4bzKJYJcvSNme;_4~_<7LU53^Oq#4`4(@R>i;+oF*#iFPlhUiP2 z5)@BEw;L5aS778UVyax_aS3bq`daDM8odqZCl|4ODB;z;jC&5sOtHGnS5mtcG9UlEz>uIWPBb^*#DtFfgb1@QU2A@fTd7>akzv7sj}(6 z+LYd&T6jO$KVgOd7egpibGl|5rd&J;$XRxLNHVq1U}Mb3z{mIA9wvhP0(TL-$b$aH z*Pswp2p5ZyB7R#ceN93CjL+}1rc@~b1#!|6A%J}mpipygxXo6XfWiz&7*nF*UK)WB z96>&JJ%erOm@;d6fbDYqM_WV0&(Dv65jQ!h-YA6(z>TmR0(?D-)%P|w@^-dc zTZb6<&9I*UG@T%uuS}DIi~(&Up0$6eSKtu!RmJ^zCwsH7`z;bNtG$G47hI4vJdM;o zOhlI{3vN?WqH7iLV=Ggb zxw@g@t=X|~LBj>+rL*e(Dt_|2$*Rf`kv-m@)pd0y)#}L{zr2Xjikyd1slW3@e(Iqh zSJCnE3R9;mE{c@_n>`l#g)|j?QeU30f3?1$iHQk_nUE}8m|s|!ou3B|=-_X3MA>j6 zanjh3bIBORm1YJhuUC{{MB#uyBQ+H~vMua=akJbe4Vs>^nE(ZU8-U!mc6W=bX~<$TqnW+kx~DBdw`uTE82Irx zc+5Zka~kT(XCg$lI-KXczbbZrriWD}P>w9gsZ;-Vxa6?W+qK@~=;UOLg5S)B98|}a zmfpg{?+ImWXk*jY6LVT?#r*bls?Z0*MLDP-4t%gy;Sgu}%=X7ATp06eBzxgknG zVdmC~&`=efk@(Ru^Yyo4qPBVGz{wpKBt=tC3Ql zIHq!!rd?TGox|eHoDdmE6oIU~!C?g%@>QSsTWl;)Hg#Io0*i7}Q!}h9K=QimGq>JETnZNzXzNxX*E9CQJm|nng zA)YQcq3<7=oRW#bE%fCDE-o(tM`JFx#Rxcz0^&^D|EY9SCq<2w$$KAH2!w96bM|!+ zK|#N>J40~>jhv1iZntPD9@cbBtqK(}D5RoZy|xcoCEfegN8gU>C$6RVu)mYc=RT=g z*lx1$4jgtG>%9htn0BtoCP*&ZeS-$_#lvm-NT$*2S2~-UQ%rnp!&1yv<8Hc=BM!lIU=8ymV3S?PxtH;)lmX~Pi`%w}mR_h0q&C-#)Td;!a0;81 z5)La^<+m!*Kj@#GddW_PYfywtHL)P2;W=ocf=zyG+!n)A8WVFvz{lhAdSxV5MyiBy z-%rP!&E~@gTcX^4zo&=0{)B*UGLy~7TGXR)s*A7GR8)SOPcu&1s;kT3Me?chIlEsv zyFE0>ijk}2<|uafdNFfz=Ql9j-p-j;SCNT=%TC6%#$~SLwid^*$$N9Rjk<8!=oZ>A!wR1{MiaeSs1_v=&0bevkW1RViI5)V^U>(?1WN{Y=_7L&zT0;Yg72j59jUCHNQp~I$<82~EKi-E<{{LS zMi8eWP^ASySW;4o-N4G;XNC~49^8>neX?*JXt*7Ty`COGZozf0xmvOM!@u9WL0KS? z8Cbo*Q$)!ZeCwlvK$7KC(jJ&UfBUmqCG7hV8RF!0GC84kc`c6mj++}UW`>hJw=`Om z9E}y%CNUAYtLs)u%F^3AuZB(3nRQ`tF{4kOo2!9^g)}$Ov^sWZIB(2;6x+>mYE$5F$@KuU26p!5oJyp>reqNb8dDCk{R0;lGXjQVU{{%*9u5iVr6dFrPt@9W}p(8P;w7eG#iCR$YdDqB@%BuY>JuWU@ zaaZTMa_+qkA1po9vHgVY?Nu@|hJ8b|pY?xzMT>9~Plv8$WUzzD)Bm}@Uy}v@BL#)M zm>4i1Sp6a5&5DbAN{_4maV$TZ*DoBT(}P8uvkO=dU^6ZJ&4`JeNU>@#**mVZq1p^&+=YlXkW0|4eY7~aJ;8!^sj zDMZUl5MLqXcZ%ZGmqxlU9^G#F@$)@^uh949(YfNKGY5!9sL}}BfO6;j;^^?=Y#tpw z;0EFa@%x`{vIqgg)efmxN)_c%7W|b|5hh|Ts|;oO8V74vx%;6l^Xj!#q=;u9`wbsz zhjlP0SKAQd`q42kSXggVng6*Qrw2`h66dpfYHHDf%I!2wb zxXgx;x^=4NBqJn5Sn&78@-nhjm7|SK|MAX!cND2VpZuT?#bz_|gF{*JYe-1?0|sSA z!~WzU{%ty-{uS2SJLG&8sAz%w0DC?qwZX(>>eHuh?q4F%iC?JD<7(8qd~JBYa}u{U zf{97Wm&yJ-`^Uo03jlZAMBKV9va)i&a`HDi5vBIC7oXkM=H?#Zmfb~|Z_j=UBGrnD z9{cpdm`9U?dDr8&jD^MY=9HzPjF4|r3K2)3`3qydL`zUi{`qt4JAPN2*mS8;8T6*; z6D@tGM*U?`NXSY3)ikG_IRI?cOig#Ap8MUthq}1)A|ym8KE66FvmS^9^1lcBzB+%z zeW}zT@Vu$%`jLBj_Ym)Xdx-LA%1|#9DBlNWd@Y!TCC24WCl&|+htmm-YQ5O#vBEKe z8#jt?W5ngo;fPCc!c*a!MR%4YCF#~W2L0LNJUe0Qf@yk7PZ1lxc)k8J) zPScV6`I3*W-(fSbJ3HL@c%aYQeD!KNS zOrv-kv60s{Hf6G?W@ulWZus`0$f>I4rn+`KeV_(g=A=&y*T%R$1ej7^}B; zP_XFR>>MQuJbj~-$8~nRBg_`LLPxh45<+Fbss;h7XboRqd`il8c^hF7Z?kD9z#q$z z&3bt_#p1yyY6+}Om6as$FKHL&M9lUkr-O7>>5m_HXqCl!){5lM{d}Wh*{6zr{J=)D zfBzm}wU|HWt&Ldttf;j+A}0R+JrpE2J2al*b8g1+342H<&Fk#2=M;fL?gDI= zIY1cF9?9Ux##VX*(HXy{q|i7x!r`f2w&qPE74~+ZpX4M%nfp^R+;85B95@(3?(!Sz@l$U zJ$jIqccaO`9fmLGt=YivaHY-0yODgP(e+$dG^qh^K5~XeYg*I!aLt-mF=z=a!bTcsI zv;}V>es)d8i=OW$c#(+$p&R38w}`ibu=m1w>#HsCCX4k6@6=Ei0|h66Uqh+U(FV%X zEQOfpXi)sq*4f`cNh>NU^7p@2@eLyjL`TtY28{?|fpmRRXeu8clD|Lw4`pJXR|os> z0R*sS|MUr2%p}BEd*8pMQt~}9s7JujQHCD(XhoifOG63!9*UCO4#Qf30<9cR^B+`N zdOF(nLgg=k7#UE-)2IBF^7~3=N=nTtUlieucXYIAivH;b$NlOXMP#T&Rx57#8fOz@ z_V1omq@~^3-^XL(d-`A}x^rJ9Q8QPIw8Yhw2O%JGyV!EcJ)T>i*U7FrIRX0A7K0%dd$5Klq^*xw?k4lw__# zWuJ-Vu3V?!S5?Ri=O{~L8tQ_A84{;nC+P{yca*&Yiepvl$j~v18_s`c>vVv zWJt$r8;TG7Ur^oj>mYstQA7m2CV-zCb)H+#O1%uGE%6~1l4>6<^y4r~P*?9nL5QY5 zC{+IX>)pl%@10wOG|g2`ZtfBl*|lK)7X zd0>sJE_AH-Gx6E6^zP&tNTCYsM z@aeAN=+dI|ojX>s=)!jUgtZZ79zeN&3QWyMK`m1jLsQ_8-I&qJfvEVD-xflIw9hRRQk~G%Q`t0a>KW051KD7EKFhq zAH4kRx3lMxFtR3wu@rY!t3-O?uvt4(eDw2|d*s#EsX}M&TBU)aphyx3JI*ExQAx*j zc668w(B0f1diz>ykjP9jFF*f$IrTC;e9_B`^5Qh$ImZ@{>t)&Z?ug3dT9n?{NhZusF7dZQ>}-?RFeJ zezG(=R%x?!Nf?{AGh+4U_aiN5Hp{)gD$UJ*{ctx@)?{jrruFaNFTfUToYS11zF1Ds zsCLk(u`}<8sI*GR)Rh)&{enE>d~uN56{}A~6w9DmA}_B($H2qmaJ4T#c)Zi?;IJM} zhgn&1>`!>`%b%d`;NT!XpU>3vvj^6bCojD*Uf;#T$j_yRdO#8`tC)a*RD~Fso_Fth zEq3O%>MtFJ$4gr()B}Rb*{5pk<)F9art$j5#<=%)HZ0@9lqc5~+RPe$Paf=#c0_F8 zq0$f8oXxsRaoaM2mHN@dL~5qa>~MoywIdD#V@@J6(CKXB@rMt8;8FYY#qZzKMKTbH zp{@*f1!)E`(a`vRMGfi5F*14xRkSWw7d;mjw+8^4Wo>DF5YL{M2{LToD5~S*A!K%` z*AWqvl8R@wGB>v}R$ZBS2eHuwIiq8zI?)9IU|eR~fIJo*i#!<)7bhnTk%oqPF*D0l zleSbS&_HQbnDbF_XR2yysHl*Kh#DIYj;w%YS!rqU6A$3-07cp_BFK7re}Q4N+LqrL zA;zc#d_$uXext_h&aPV2IQ`XJH+p{{g}!F$z>vgIETG5Zw>90~T|5Kwv)#ubJT7td zdR^QhA%#qJNTC@>rGprfOeAftXXSGkl0ElQD?<#TYIGly$GCE6-=^&4r=Qnz1uR&hw^|X==?ioDO{{P5W_(3aP99j?S91G5z=Ot@%GK7_rBuUL*?v zIk*Xg$8Ua~{q4Eu5e(A9+*C`SYioJQpVHC!nM#U^+5x`ef}e>z8tv9~@w&5X(yo}w zSk1{^i$8%8(*xKw*ys=>K~%VY=v?^sNS|x>&Vr6p?vEeAJxglJ%9l1fkIA3%@m-!C ztT9;EB_Rd-*XUQf-dyZx$KCs3dXNwZ|F4rp)_Z@uG!saG z8qFs#Fk>bG$B#FVgmb*1`m84C?`vVR55Z@7jSkiH*$QE zSO6}_+GMjMIwv1U|0Js}z6H>q6tQp)Y#b1FMD2)Cn2r-Pq~YNG>?Z{{&%ErKs7sRMr?S zwp%PNHZgEB09E3I0CVL|o31qicS=|o6Ch7EThnZd=B4c&5-_7QswxclpE!&|1t;*$PuY3x?{j;4 zR<AoBzVY=Xp`_H5k*vv|M9yBx&ZcE%!PY5yvl!PtG3OCnQ^V>YeX0yf&`nL~ zLBOl^EoA3tzQvwau4!>G9rq!xxTL>?q`&-O8ujWg_b~9*b$iy=U-_mK6^9arO%~+m zceWl^r_9Z01*WBemG@$C6s2KrZ-6LH$=X`?^=m<0U3(Xos>2R#ou?&5pIW=64Vx8V z(i@P~Lsj=G_$As%56chUs z!?uO$`4$D`(Ooo>(eWy$-L^m3v|~QleLR`y7W;fx>=KoX=EYvmj8?tN-vOB*kO58PsodC^uPI`taZco5wG#Hm zXpTwgYOh*a{%)~km7bmLE1y{xF21Ls?ofAiiPwGzK2Bq!(c8BvEkRKEg+c0CJyY6Q0yUcTqy2!bBbCQwg#{xQm*CS+9c`6Y-Q0IkFfo`IoQVlIm(~hgGr8Ai z>RpbvSF|k(;1vUz#MRZE^tw*7OBAZ!H|WUA-$g=dfHoQ%$3-$; ze8ze}>PkavSeKXA0pHi^<0-rroN=%=_4T)orX5vN3jVnf=kw3q#6Qx0c>E05&PSW! zt*w>&_vj<0&$e9iC)pGjsHnE$;?nXpcw=2wuBSZG)6{ztKi;?d6A;zZy5AvBPk*y` zxYO5nm)*3cx6*QCclR3s%Q*^$lQ-5I+3j}?Ud3lhC%?W?@T*sTVt&4J3cU@JYif$0DqYJ@Ac@7Iy^bQ6y(RmhUSl^BPDd5`Eng<_ za?1#sesKT(40yH=1pjv0OVM^wc_=C$zdKk3(iJ z%eK(Dl>z6KR3_E^i=mv%Z{IHEHMVx3aM<*v`5j)6>zo~?=e%ti9evTR zlg^@dOjF=ifAvm6!qL~zPGq{ZRiP3MX!*Avyku@qTU`a7NM_08M2EnHl@3JZI?^JBxqzhe0|X^)Ln!s;(6ds}?pNmuuz!CPg2j+8tt z<8?w};^y*l*Zj(L^Uk);3N)Pu8ynX-Z?dzp=6|Pl4E*d7jPc07ruIxKZh3W)p=@8=L&Dm|wqt+syvl$z}lc=?e9_(o!UHg_gjK$060PzP;CZYWx;5v=_gBH^LuE zONC&;8k?}aZkk`2sj%4WOC|P9sj8}aLmM6y3;EV6RaL$zw4UMN^ooj~t)kyETOb!j z<$+IdXKJ!!!(k-dFUPZK;EzVti^wn>Wfh<0*j;w^K#yS9%)=*|ZB_?$f4Y_5ArGKq zR8$C4QL{BU^?`k<1Y7iVbmJfMhiHJiO)#t$BwyOuzeBFhD3gvS5gh`S)zBXvl9^HE z**`laX+OM0uxg`3P(dlS#?x~nPi@KZh~#kV)zzbX&-nP*)%hrKWA@Da%`vkcdgUJ) zlyn^(5>k>ibzoTa^;ztzok(FO-C&H&QJ0|f7#yUw<8cN%<#gXfamY2H%-AXSWUm|= z2OBX3MN^&zw?#*Ua;cmgPN`1YGp(5s;m6M-J8E68P@HivGXF54MRpYADN@G{UOvc4 z_+n_hZ?sE{u~om6Zi1q!_jk(8jl5?a1uUTHS!7B|ix)MfQ%+!(f#4f?Gk%A#bQ@%awpP*L$jFQu`>sFR#Kb(X=M~f*>Hz^QFhcqH z-9;sbb7`sj0_)ME$Zxw#@!XM$UU%ULhf?h(cZ6 ze)rq_1vxojG@G>s)7<==UNj4o3S|8J7o4lqJ9a3KxY0}}Ux=WJNmL8X%(Js?JPj9L zw$1GCp93cM6t1*ih3)NW-k7c`YHIVVtK4?xQ3CJeG&GX?S%k)lVTw@FIi77G|N8X- zNPZrOW&HhqeDm{SqN`>alC1OF%>!CW+}XQ*;IL3M74z$!B6JMzYG-Z`8|2_TwLE7IZcZWvTl$)3^$Seea2WV zw98>%Eq(XP2E)5Udqpb#bY-r|%)_&ilpA+t@gT;~wXg!uyCMEX;Y6C4X;xPG%6D8Q zmnW=)CYR^IFWrB0+1e-^>J)Q^QdW9;Ri$T4vp;)A%(;6J&4Sd>(8PaPA$HbvRB2gG z44boE#ZsNK(F(=tw{O3<%`FrLYamAH?d{lmrv$fHU*y_wQjR)4+fuT#+t({DoocMG z+j;kHmdLoQZ01^mcmul(X$W=VbN0rQNG0J{9=R%(lGG)?ZIXI;+AYm)i_0C*4-dG~ zF>3OFx4H56FFQJA@>$2CqC_NyR+%xWhIg{?zx)zz*-HVJ3X8j?;eiPssq{q zx#hat+%#;eGL+jvj@x9OU3ym>*cX_5GqX7bjAgpU&;SNhFnGsP;fy;yAaY!6&jLFG z9HVFq5amoNeW#0)6u-N3XJ_ZmdoDB}CLi_;|3^6W-Mw%Bo8Ox6`oHJrcel2NtxzMz z@fej78-67c!CKV*!JHie^DI&#Uz4}ViVU&Q8crtyY3yHCphum={o{9XS2T-=h(CU0 ztRpZdn@&~N>uGCuTfIVbib~bSN7-$x4t;>Q78+`A*+bB65-27k81icPa}MRH`T(YK zJe*4wGLn*{=jA=K-kR=dN~enK(C6ZE8&*_5rv@uMEp1IqY^1iP3X_m^cEaq6`Ps8~ zT-SoUG@`E)O#n{R;D!Fg<0&QO<>5rSmg@y27guRrg6{kG`g(d3S@L+mcqAQf%)qcg zPj3vlm4Tg`tU;1*X~X~WyTmbt{{^e&+qd(S$8Ga1CpT`?J|bRU>cQNYam7mva&?9P zWR3vy_&x1wf{dPM7C)@V;o_t`cEPc+v9Nu{#|MX5v2z@KmK~*ezGKFxmDs~EyL0c@ z$(d2K{IUd=6p9Q3t^|f7Hj6UA`7HSKYTC(s(dpuBAf*yGyY~E zB^n;aWuk>v68+R-?`fO7{;9d9niw}SG|bM)$+=8Et%Q1R;1vxq(6Rwn8{9HLKxlIX zM*?j8L!mMX3JUm}@Pl$C>!QacfI!%#lM|S{2VV1zMM46C=a0ThS3*Q7p4+w=*mPh5 zz{vlW9fwpP0)g+Y1C!wY+rP(YI5;?>B{L31K-dHnwM~dYEgeyU@-($q+SA(`w)1KW zN5HOtHvP22S{{24z-bVwB;Vu=G6jW%fU0St!Wk|C^t=h_f4>vUJmROKqEb^+^Lh*}p&PE34$gSNh^8ahuka%>_Qi1@ zZs0;`qb@N5AQwl+t zN(Bj$iIh~eGX05Q@$_PS*U`uFAa_-Baj1rjjJ#h$j&$4O9&zun&cwvSBv3VZ{-OCC zG(K(}E#H6~?|ttTL`)_K?R4oGnaMrGnw^2DFiHT9upCZ$X68|60+aMcVGPJLrln_; ziQeNU;hSvA@B>bN@>kS2Bs^Bfzad>3y2Y_Pyid11Np;`^ZG#9j_z2$j2moz7%6=OZ zi`>d~zUBEJuK&?cQpy~EfR81sqLP)xAJnonTKK`enI%)EK)JAnhF2?Y{6lG>^Vwnd z`7F|DF<_ga7{bR#Y~EC={-%l38_+^fX9UR;e(wQ-62>^!Yau8i{aHw*37Xoz#C|L&qj(OQ362HwcG6hx8wlOu$m!)3s zPnU4dYVYXS+uN(QUOVhe2mo0HC|(+xW%C?AMq}lRhzK=QTpKBXPg!4HZfivP{lehK zLcs+Fe7v6>YZMZ%H9!JEUjDj-@8UpERyOhX@0(m*4(G=^VQr!IJf>n|SwTTPkwhGC z6%^LbT{2%i2Av|!a#LPj^)cnA;hX0!ROC84a}>bj7vT6nFzw9>(5wQY1IqaJcK3iR z-DczTGuEfY_V7x}rHZPGzl)1S`}=jr=YDQKe>Nv)^G5vBvpeJxk@SIn)$h&BsDLv2 z9@qM4r95X3jMLxlcqr)4+#hM?g;LiN^}@5GP~h7y)lw`S5#J~Tk*4v`e!eTe3DRPw zz4s0_(q*lhgX1lRR714wuK&gYP4zdNPLkK1;0eQr(=H7h5_Z@MfX-*cM(#S4D^ndW9aU?$6yiTAC(pGnM! zg&G!+t)euaPy$^#j5F})J32aujs{(t+S?PLh`?|wl`y+V zZle%Jbud98CkE>>e+xh8&V^S10nh4aGIoI|UzO>Fekw3Lvl{#e3F-Sr;m5C1Db9wi zNR0!5J6zm&=yP~Lmnt)?SpzD~GM&Mp1JTYP&M{8Fq94!iE|Ty%R#jCz5Cm)&llqIq z(0F--5>cJA(NpyK*qE$hreUwlOyrmF%6S$hSn4iur zC@|an#)%Mcqzo4aMT=71j<*>|pUbwt)k@94+KG!JhJw&!+2#4Qv-+!x&AC-o6_t}T zD1tvf0U@wbJRfLuiHtTamX3}N2u<*dAe{JS#>Yst;;zD1VjQdcm z9>T|EWz8)u`fm)rd#39O3nP;^!bGLUaXFi^<+fcHm5~|gm-hogmX*T&PozAuCRXO= zUxR{15(*4BhyB!lX2ia*|1yIglyE@= zUyf0SwgC(hk|OWNih@RRRTv`aK=2~0W7Mpc&2%S4SQnCwpY$Pmk~}`HI#ggSrL6J} zOIWVwC{p~<+VA!TD_HI`KkZ<&vdi9tcR)qkZ?`6)d> z3Qw>#B2P{!UsJ8d&PVhq8hZSzEekk~Uq22}R#RziY@}9u?TgUT1j{ONtT}pAeD}_<2{oALm2`-w? ztPXY>xLoQrH>$Nm8yYAjw;-;Fu91iwB&e|c1+)8k)uTTIMHPAwJ8#K^dBo$oEj z?J31k`$k5t4(7}xMfw!3bW*17*f;Zs*72OR#R`e6IPr~-HcQ1uFsap9we^pW$MmJn z5VJY32DPL{7Q%iD+j0Yy%u7nNq#SxKYeL@BE}476Q1DFriTxFJ##+vE#VkJIkoXByoi z-a+`!of^NQ1VHv`qVA&X<-FrSW<7_qgIW_ZLNexX+R^=T>i|mYJ6c-2O;rj3dz0w$ zz=s%^$8PUqlCbE}*G`W``S`2=2zR7FODXlcN~NLVmgZ*=pNsLrd-zbJ)}|K9Z-51H zzac9?D`~Jq!qRAvk`j21_hSQrO>U~HQdd{cmzQTS@F5zq2UfCxvYL_v>hp)F zPapVX{Hd#RiRZF@?9qGHL9LaPmYJfJw7;)#WnNFo^kxRjYN+GrrhIjg>C||mN*qfFmhaH^>vD4ew64cyH9n^RfL_y+uMDQZ;|eD3f%7o$$2&O+?bc za$iGFk6Fv%h6fhJl~gTdlY{pT4%pDsl!#U6BX*J0WMl@+>-e;+b2IR$OJ&t&wqJH5 z*%ms!6G(zL7S+9P68+0W2dQ`-MM8Mr=M!l`0_JnGB~S?C9=}Xw%tWazk8+ zC9jeW*i%A1@N}(vnTcb!dRgVTT3&#dJmoRJ8KwBy`QWF8RK&LUiQU-lRJAKLJ@vxg z$$w?kJ7eTo=b!8tKBxH%AQBgVB{(j6zFRBz}6 zM{~oL^;RZw+@O-h8?Et`71yvloMdXlw(r(nu244}pu4^RoGOrhAtWUHySN0->Bjg068Qqy&vzd` zR##Ww-Q62?Fiv^%^Y_Gr+DUg(#vjl$i{`cs%<(hQ)MS*9+4AeDM@7At=56PABr0B2 zz)LWsP%mVH9@yNVmNneGXX1YeioXlOBd-)qUKFl($vp`o<@0d@pLI69H$SwmxruVn zMqZ8oS_aP|3-#_@Kgzc;NjcsCV`^?BE-WohrKWvRp(QO{R$FT@)*=B#F{b)vTI%Y= zvs)u%h@qc@7*}>H-@wca3=9N+;L@co`$7siL#Dkw#!)KlfSYh+)?lvmjUzHp2MKMY z54+%c1n(qo9g=Kq;LT0V8SN!rl&p94J*iheQnZkBbS1xs7!i>Cl_|FyI_J zyeyg+R#1>=cm<|NKE}9Vcup;4`{^TeLvz*+zrk^X;q(mPntT{3*7P~QE1=kC(n)=D zMy9>9)iC|!hCmDJS^z1+KxKo209eAIAwbza#0HkE3z>$XwAbg-)Gmzosd|Sbq9^L&TS!4mB>=BhtFZZb+mAPnSfQpPzns^?)dYe zrm2(a94$htLFF$CC+ixHI-vs z=5J`I6e^f*-K9oK;TJ@MLA?sJDHbxN;gqa@_D*ndBkDD3L{WW$g6g3tsaV<^_7*eNu&N;gaLz^kx)naFe4j{$?M+V?Yr4aFOa1U zoqQ#65Sqdp*^+1i#U(R3Vc+T4lQT2RKMk#hJb7(rd*tgoKAtI~rMrZ3@T4Tn*FZe| zPM(}Fh~kY^SC8ngjew(m|G%=GRK3gs{U^bMC(%BVd7HaDRm~B*XJv5;M9gOQ9-VeN z5Hl&)yAKzYvX>kULZdb=`2199NvHN!LO8y7J;6qHQ}Pu|uDFjE3DVz?+CBa5D5d8kv6n6G%6(q{6=r5+FkaZvTvTl*x?YY|i27x4vM@92)$t2y&49=o zxZmsi=DqFhtKIS3#e7jT4>+MZq@LeW&+b?!CHb^{FI?wFe4k4q!I0vA*f7f+>EMtu zULJA}BtNHQqv>jz;yexN;pW-eONHjXDCzmWvn6RT_7f~+ekt8IB??*}1s=D7W&!oo z-a&A1vXJ-6+8VaCuqta8=UIbFVy^m7rVOc|sD)gJdNP>@y*gH*V~-|8^(xi*l3ced zEX+VtfFr+d*NH+!Ad-y0#E66>0a$x^?N`$R0=nuhAjq3pYZnuwIsNXPPVZzPe=eUt zOf-S;!&N%;7XZU?@W4?;LQ2?Ng~*S=hXGH6?{)o?-{_M*T%R93FaHTHvDdl^xLu{m z9t8E(yn*T-UFNakv(lo$vya7^YW@31(KdNJ9?*L?R@%`1+*La0s#On=>YblELE%_g zYzC)2k0u;|$m$tBpLS!?FLxbgmG|$H$5-ikG`=BQ zdF4~2c0v0<53tn=XG0Xw|6b^cC&&Bydj}WGsg*G{pA31kjt2A&)KqC4ZTPCzLWLSm z17B03Ap{7+#mKv|>K@}d0!VLvd-JkyvQn;Z;stSltrT0=$&iv39uDq4+P&q?Mf;vCG;)6bjDI|HEg`pMGLQ;_`P%84Ps(0hOi5Y7PTk%{GEAba+s;`?&v z7|T{2cS6S^c&fVnX}zjs;g27ztgM|KJ(iz7jhC+77KCJl5(KN}SLXm~(a}F}Hn+!g^Cr^J zBULau#w!F~gA+V|lfVP3l#N+6RlsZf4@fDfV%`5UH}@?vv1QmXW*4oiQ&6Y@mAt8` z$rk&;^3>{t=IRA2bcG>u*!G#iUhqJ-Ot24xaF@}<%NLg5xKPp4)qR5lS{ePt`ay7% z`=$t@V2DadrBi1^df2u=AX@VE5x@2BLJKLA;v>_6vD25*7{YRph%cxe23(F`%J(|w zFZ}}pE1dE1#Pj)DX6=2>&Q7p(Qu|g}uSFDxet7?$Tv!fxGl4wa$`t}xx=SR}Qy_{( z?MujPCu?j>Kb0&>3qpT}^R7UCW6RV7AGS&#zMQ6J!uV^c%$aJXchWZO!g9jG!qR~n ziZaO?_7 z^vhrHkkGx)0zZsT&@xiplwvR_Q_;m0mWl8UXrCqH z1|4lZnTC*F%6F6|`h{IX>-j-a4f)UaQj%Z4Ho|Fz;_d+Ny%Q(Txfvw37c{noqwv)_ zK9)tpM#E?-9qXz!@=MmWWf!U8>@hY(u6t>?j@fGseSE=LhSKUBhG%{IcfbHIEj@rz z(>vt0Ta=9;Lb|i8il&2w{_mLuk)Pkccgy|o?vO(k=GyTKU;r8psKJ-2f0ajj;Bp#w zqeI%&(ZX(~uNBJX5mx@t3+=*|z9%A%cD9K}eUsmpP4*|21MW)V;Nm*iJG^?;$^XN( zJ~Fcf44RV8N>1iaXAnmHI>oP2m;z}B<1SsM7)>&FgYO}IgviWxKEr>tF8u4rHfJChX^Y?`Sf@Mex^Ib0KC%D8o%es%{K=~NQ?db!D-0yPr}iF z@llP`3?YPwp+?zpcTg-^vP@?0H16}~mjGd%V15RXZ?{Oox36Oj--)*V4941UmL&tQ z10qS~2Qy?a0fYGR|9`)^QUH*1V5Fh(NInF*C@?@yfUH3lBAS~=|3O&z094%UV-@q1lo>S`sM09}EIAtOMZdcIM6v^nW>wN_9c#y}Ur#D6&;a~t!~>BZ5N z^Tm)7(A3}ay3Qp9K$E6^=@r*cR($OHjl4f0!5r=1v*h;*!vjlRe!z5UvWS@_I`BSR zdWqCVy&Oiu>u`K>vN2j0kM(=;)8ePfT@f_TIFJNTH-KxBP`=6avXMf-$MFc$6WP;= zPm2r-ctR7fc7d>KX@TcQc{${M;mTu7=#G(pKtLqDN=$sbFsjdgU{L>ls+1JDZsOIi z_gs)Z10>fHz;LPS0||K@2ABKxmmuqQKr* z4$LpB?2vS0N(Hub;7>C;UGXPi*_^B#h}c0qLxx10d;vstAlEi{Y0weD01Lom-VPFO z5vi%E01&j_)0-!yprV4rvxB2!xw8Vo1oQeP$le)-_CW$mD(cxw8O(a?8?)(nBqT5f zo6Q@L*SmA~uF;-3BIRRP{{58j~_fG1)$UGve{crs6oBLgaQ3{(QHk{XJrYYeY5j%+%u!TbO+ zgDzy-Yj_c5dwFOoH9w;{&i7xMwOl{h}RMkaf1f9o)A3aC3wP6@l$`kd-npw zWOINB06g8!*T}sQ@YL#z7=P_j*ry&`Cb=sS`=wB4d_eT-0oyJlC?Fl?8c4G%M~r&M@E(uJ_l)`axhO8KG~a_KO6WA1_l`q%l~_u;m;pH zA7awim(2k6T{^RF!Jm-`OLA1pO-<%%9rH*v_EKQNFk%cqzn7E1+_=t60nI|sI`KdG zW6UAkWLdlI-amJjdS+zm3O*`8S*9eVK8;*f3bk(vH7{?j1Hz5{m<0lbo*+En z$gKvp4ZjvCX<`C6d-c|P84;H}B=xZHvKgQl4Hp*|6s_}!Kkl(|WdFB(u_DadM{a<3 zaf?`5S+U5tLYHcgW#egDYWUV?&HV1)1W$HW~oIO;6X+ zjAj0(dCm>+lfG0DaI;a#H?<3|v#SXRgy`!V2vsF0C^%4d0M7;ZDdqLPC%V?XA0Pb4 zn4iyGKSL8DT2os)lBagnnFYQ=3E5*1H>Y6Y56a8jxB&%9{?S`Ky(1j6d-fC*6la*k z*E@&#pYv}`e%02NZ~`YlY%xtN`AwG9;P((dzB;fwTwFjtWDZIO@=0yHy}V+g?{sx` z!c32Jsj=#eDpU=$2KopU(oP&7VrJ(4nM6(&9;Z)`iE`EyezVfOW&1!7mq}9_vRM`S zmW)pk%al(6k;YJvlte~rNO$dBHfhxJna?5|D2i@?J@%ocdmvM~Y3i#{dr1eMCgiX! zxE;^t=H?Kt{0zMMt}oU?!*f83SO}Gdk@g!Mjz{prj!4q06{?Wd@9a6skB z>B))F>i_IF^Tz$>sfP^s2Wm18ROH`)^c4J>B_ONG2yVxlLn|Ab?)FYAOIsyJ`e?}r zP!)&6ZeOWVJtR8%&&tZdW8NFH;a>nbleDO!tlVjL<$St#{`Kom#1)Nv=Frd(4R>pM z;>Ba0*oG`6g5OJf579h#bJR8SK9Yg5cgI6?LVKPBbw(u@Md}47XJ4 zs;bph!=VIq5*c{~9+IBHLDpwv!Iy;p@~$r@$&g3-u@RcOcCjRgBx{IP!d5gkJ}&U!(f8^E2f1V46S*d|!z#(d_;ElZhrjk6<8_2gHIAVe9-36u9hkjcAPw z4MEDQe#TWsN(y2Yc&NAV7~`lspcH?GlM{2Dt)3aI2;n0rS!sn_jI&nuOK8>q=yv~2 z@K;A5ko(16y;S&@3r>FVME)}w&)sgx=B-5l_@z|BR zIdDb0Vva~4{+}uEdkl>d`JC^N11~yZewU z{a;Ps{s%vmw460$m3!%)B~?c*`GitcS*-~ER~AQ%mtPYJoIt!a)vm0zrV9J)7)vt~ z1_7z#|53ma#%cQQ9a&_<&OR1@F%_bwT^UFC`6DERKy?|wv!GhH)M$kHkth*xBFR&F z(`lXGMi?k66M%1lKs1AahH$%j_Uzg6L^;!d9O7rr%{H)O&Y?t9xy%XqzyAde9e@X2 z-}8U#w;Lfe9VVEetJQKZ`C|7vKuNz`FNg0t+kYDJ)XLdS`7P!ep=l-StB}I)x}Ky0 z0l-HFh6uaqOtq~UP%%!lfYNTxKeqw55G-9wV0j;EPD@Mk^+n_7=g)w1pqKZ0ZyUUe zi8)j2SZ>(y-{47Tw-EvyU{NAuduC?pb93n_C_JI=M2!d=o5khaPA?Vie7>%j^Y)*i z;%?F|WYnxNFg4XwSC0z~ou8e>A|~#%l7%!ZG9BzXgitKm60&y8=20`YvrKM$Hz;b`NPZF?9N%H?1 zkI=RZnQQR5!Ta}pKtlxC@QHFWeO+A*s22b*2HYok8x@iCD2#ykZ=%UW*}=v{ zB-Z25Hd;EmYkNk!5K{3_c5S;czBo7c+bRm0k1!iRLa;7uZMlNHMxFB+kii~;K?cf? zfQNz~pmE!RhzEo_fT}MnHn!tmcU`ypYNtWnGYyQG0D-|nnZJeTMZcbi$4Vd@XKcJ4_51@wA^^sc9^>;s5TY(`bCoUNi$irX z5VXOb!19m^;npnx?%8&MhsUi#Wl2<(Y8w*>PRwIKLKCi_^7z^`2l9qx)=u#0Zo`cI zSr1`&_b*>i$>9WzImN-j85|xyJv)OKQ@Mr?T!i+|MPU9H7Zt%S9oWqK5`ZKxh^0+U z854WV8hXL%#0D^{o2$LOJ;l?fSb|=dq}}s7gNFpnI;i9eAb|(4FcU&zgd3yab<>!j zT?MwFNznW2SF*+J&jMHv9}1&p<>w#n?;Ecj!{adic^o7%0QKj3{KwlPxUumSFp_~( zbwB^yjvW{qP(rKDXbYCVMzxLb6cqg8d2_)4qvxp Date: Sun, 26 Apr 2015 20:40:28 +0200 Subject: [PATCH 0014/1763] Added a configuration test for dblatex --- docs/book/wscript | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/book/wscript b/docs/book/wscript index 7fe02c155f..fda45b544a 100644 --- a/docs/book/wscript +++ b/docs/book/wscript @@ -95,6 +95,7 @@ def configure(conf): conf.find_program('convert', var='CONVERT') conf.find_program('source-highlight', var='SOURCE_HIGHLIGHT') conf.find_program('dot') + conf.find_program('dblatex') try: conf.find_program('semantik-d') except conf.errors.ConfigurationError: From 44211e0bb5bed674389bd8df4e5e6c9340b7fb47 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sun, 26 Apr 2015 21:00:15 +0200 Subject: [PATCH 0015/1763] Enabled errors on warnings for the apidoc generation --- docs/sphinx/index.rst | 1 + docs/sphinx/wscript | 7 ++++--- waflib/Tools/c_tests.py | 3 +++ waflib/Tools/ccroot.py | 3 +++ waflib/Tools/fc.py | 3 +++ waflib/Tools/intltool.py | 3 +++ waflib/Tools/javaw.py | 3 +++ waflib/Tools/msvc.py | 6 ++++++ waflib/Tools/python.py | 1 + waflib/Tools/vala.py | 3 +++ 10 files changed, 30 insertions(+), 3 deletions(-) diff --git a/docs/sphinx/index.rst b/docs/sphinx/index.rst index 91aa36dbd5..61153ba66e 100644 --- a/docs/sphinx/index.rst +++ b/docs/sphinx/index.rst @@ -8,6 +8,7 @@ Waf documentation tutorial.rst about.rst copyright.rst + confmap.rst featuremap.rst Build.rst diff --git a/docs/sphinx/wscript b/docs/sphinx/wscript index 86bc021838..130dc25869 100644 --- a/docs/sphinx/wscript +++ b/docs/sphinx/wscript @@ -19,16 +19,17 @@ def configure(cfg): cfg.find_program('convert', var='CONVERT') cfg.load('daemon', tooldir=['../../playground/daemon/']) cfg.find_program("sphinx-build", var="SPHINX_BUILD") + cfg.env.SPHINX_ARGS = ['-W'] def build(bld): - + bld.path.make_node('_static').mkdir() bld( - rule = "${SPHINX_BUILD} -b html -d %s . %s" % (os.path.join(out, "doctrees"), os.path.join(out, "html")), + rule = "${SPHINX_BUILD} ${SPHINX_ARGS} -b html -d %s . %s" % (os.path.join(out, "doctrees"), os.path.join(out, "html")), cwd = bld.path.abspath(), source = bld.path.parent.parent.find_dir('waflib').ant_glob('**/*.py') + bld.path.ant_glob('**/*.rst') + bld.path.ant_glob('_templates/indexcontent.html') + bld.path.ant_glob('conf.py'), target = bld.path.find_or_declare('html/index.html') - ) + ) diff --git a/waflib/Tools/c_tests.py b/waflib/Tools/c_tests.py index bac171a332..2888828d3f 100644 --- a/waflib/Tools/c_tests.py +++ b/waflib/Tools/c_tests.py @@ -211,6 +211,9 @@ def run(self): @feature('grep_for_endianness') @after_method('process_source') def grep_for_endianness_fun(self): + """ + Used by the endiannes configuration test + """ self.create_task('grep_for_endianness', self.compiled_tasks[0].outputs[0]) @conf diff --git a/waflib/Tools/ccroot.py b/waflib/Tools/ccroot.py index 30577477bc..05484e3093 100644 --- a/waflib/Tools/ccroot.py +++ b/waflib/Tools/ccroot.py @@ -686,6 +686,9 @@ def read_object(self, obj): @feature('cxxprogram', 'cprogram') @after_method('apply_link', 'process_use') def set_full_paths_hpux(self): + """ + On hp-ux, extend the libpaths and static library paths to absolute paths + """ if self.env.DEST_OS != 'hp-ux': return base = self.bld.bldnode.abspath() diff --git a/waflib/Tools/fc.py b/waflib/Tools/fc.py index 15010e0f68..a028004726 100644 --- a/waflib/Tools/fc.py +++ b/waflib/Tools/fc.py @@ -19,6 +19,9 @@ @feature('fcprogram', 'fcshlib', 'fcstlib', 'fcprogram_test') def dummy(self): + """ + Unused function that does nothing (TODO: remove in waf 1.9) + """ pass @extension('.f', '.f90', '.F', '.F90', '.for', '.FOR') diff --git a/waflib/Tools/intltool.py b/waflib/Tools/intltool.py index fa8e2af5fc..5676f93c98 100644 --- a/waflib/Tools/intltool.py +++ b/waflib/Tools/intltool.py @@ -47,6 +47,9 @@ def build(bld): @taskgen_method def ensure_localedir(self): + """ + Expand LOCALEDIR from DATAROOTDIR/locale if possible, or fallback to PREFIX/share/locale + """ # use the tool gnu_dirs to provide options to define this if not self.env.LOCALEDIR: if self.env.DATAROOTDIR: diff --git a/waflib/Tools/javaw.py b/waflib/Tools/javaw.py index ce9a812635..6690469386 100644 --- a/waflib/Tools/javaw.py +++ b/waflib/Tools/javaw.py @@ -310,6 +310,9 @@ def post_run(self): @feature('javadoc') @after_method('process_rule') def create_javadoc(self): + """ + Creates a javadoc task (feature 'javadoc') + """ tsk = self.create_task('javadoc') tsk.classpath = getattr(self, 'classpath', []) self.javadoc_package = Utils.to_list(self.javadoc_package) diff --git a/waflib/Tools/msvc.py b/waflib/Tools/msvc.py index 62862e1aab..973232477b 100644 --- a/waflib/Tools/msvc.py +++ b/waflib/Tools/msvc.py @@ -1050,6 +1050,9 @@ def make_winapp(self, family): @after_method('process_use') @after_method('propagate_uselib_vars') def make_winphone_app(self): + """ + Insert configuration flags for windows phone applications (adds /ZW, /TP...) + """ make_winapp(self, 'WINAPI_FAMILY_PHONE_APP') conf.env.append_unique('LINKFLAGS', '/NODEFAULTLIB:ole32.lib') conf.env.append_unique('LINKFLAGS', 'PhoneAppModelHost.lib') @@ -1059,4 +1062,7 @@ def make_winphone_app(self): @after_method('process_use') @after_method('propagate_uselib_vars') def make_windows_app(self): + """ + Insert configuration flags for windows applications (adds /ZW, /TP...) + """ make_winapp(self, 'WINAPI_FAMILY_DESKTOP_APP') diff --git a/waflib/Tools/python.py b/waflib/Tools/python.py index f183d324c1..00d9f07c69 100644 --- a/waflib/Tools/python.py +++ b/waflib/Tools/python.py @@ -162,6 +162,7 @@ def init_pyext(self): @feature('pyext') @before_method('apply_link', 'apply_bundle') def set_bundle(self): + """Mac-specific pyext extension that enables bundles from c_osx.py""" if Utils.unversioned_sys_platform() == 'darwin': self.mac_bundle = True diff --git a/waflib/Tools/vala.py b/waflib/Tools/vala.py index b09377e47b..5d237c58ec 100644 --- a/waflib/Tools/vala.py +++ b/waflib/Tools/vala.py @@ -43,6 +43,9 @@ def run(self): @taskgen_method def init_vala_task(self): + """ + Initializes the vala task with the relevant data (acts as a constructor) + """ self.profile = getattr(self, 'profile', 'gobject') if self.profile == 'gobject': From 06e49b2a82166aeb14dde8357c58387f252fc722 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sun, 26 Apr 2015 21:13:52 +0200 Subject: [PATCH 0016/1763] undefined variables --- waflib/Tools/gcc.py | 1 + waflib/Tools/gxx.py | 1 + 2 files changed, 2 insertions(+) diff --git a/waflib/Tools/gcc.py b/waflib/Tools/gcc.py index 0de826a220..8cb954f87d 100644 --- a/waflib/Tools/gcc.py +++ b/waflib/Tools/gcc.py @@ -131,6 +131,7 @@ def gcc_modifier_openbsd(conf): @conf def gcc_modifier_osf1V(conf): + v = conf.env v['SHLIB_MARKER'] = [] v['STLIB_MARKER'] = [] v['SONAME_ST'] = [] diff --git a/waflib/Tools/gxx.py b/waflib/Tools/gxx.py index b6f692cb0a..55bf2a7024 100644 --- a/waflib/Tools/gxx.py +++ b/waflib/Tools/gxx.py @@ -132,6 +132,7 @@ def gxx_modifier_openbsd(conf): @conf def gcc_modifier_osf1V(conf): + v = conf.env v['SHLIB_MARKER'] = [] v['STLIB_MARKER'] = [] v['SONAME_ST'] = [] From 3d6a35070ac56905cd35101279b28f068872ad00 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sun, 26 Apr 2015 21:32:12 +0200 Subject: [PATCH 0017/1763] waf-1.8.9 --- waf-light | 2 +- waflib/Context.py | 6 +++--- wscript | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/waf-light b/waf-light index 320745f6c0..5ac0bcfc54 100755 --- a/waf-light +++ b/waf-light @@ -32,7 +32,7 @@ POSSIBILITY OF SUCH DAMAGE. import os, sys, inspect -VERSION="1.8.8" +VERSION="1.8.9" REVISION="x" GIT="x" INSTALL="x" diff --git a/waflib/Context.py b/waflib/Context.py index cb32408cec..cb5e59b859 100644 --- a/waflib/Context.py +++ b/waflib/Context.py @@ -11,13 +11,13 @@ import waflib.Node # the following 3 constants are updated on each new release (do not touch) -HEXVERSION=0x1080800 +HEXVERSION=0x1080900 """Constant updated on new releases""" -WAFVERSION="1.8.8" +WAFVERSION="1.8.9" """Constant updated on new releases""" -WAFREVISION="8ac4646d0966fe22f8ae8955c7e9b9d56ae8288e" +WAFREVISION="06e49b2a82166aeb14dde8357c58387f252fc722" """Git revision when the waf version is updated""" ABI = 98 diff --git a/wscript b/wscript index f8923890fb..8182259d43 100644 --- a/wscript +++ b/wscript @@ -10,7 +10,7 @@ To add a tool that does not exist in the folder compat15, pass an absolute path: """ -VERSION="1.8.8" +VERSION="1.8.9" APPNAME='waf' REVISION='' From 3e3c84abfb4f0fb005c6a00f5eed72bf9552110d Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Thu, 30 Apr 2015 20:58:44 +0200 Subject: [PATCH 0018/1763] hcode in why.py - https://github.com/waf-project/waf/issues/1561 --- waflib/extras/why.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/waflib/extras/why.py b/waflib/extras/why.py index 554914e388..b2f5d7e1af 100644 --- a/waflib/extras/why.py +++ b/waflib/extras/why.py @@ -21,7 +21,7 @@ def signature(self): except AttributeError: pass self.m = Utils.md5() - self.m.update(self.hcode.encode()) + self.m.update(self.hcode) id_sig = self.m.digest() # explicit deps From de6b9bde38c0ada782984beafa0cb77893913e78 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Fri, 1 May 2015 13:00:45 +0200 Subject: [PATCH 0019/1763] Replace cygwin paths in solution files - https://github.com/waf-project/waf/issues/1562 --- waflib/extras/msvs.py | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/waflib/extras/msvs.py b/waflib/extras/msvs.py index 31abd7bb22..f8c1f3e140 100644 --- a/waflib/extras/msvs.py +++ b/waflib/extras/msvs.py @@ -150,7 +150,7 @@ def build(bld): ${for x in project.source} - <${project.get_key(x)} Include='${x.abspath()}' /> + <${project.get_key(x)} Include='${x.win32path()}' /> ${endfor} @@ -163,7 +163,7 @@ def build(bld): ${for x in project.source} - <${project.get_key(x)} Include="${x.abspath()}"> + <${project.get_key(x)} Include="${x.win32path()}"> ${project.get_filter_name(x.parent)} ${endfor} @@ -171,7 +171,7 @@ def build(bld): ${for x in project.dirs()} - {${project.make_uuid(x.abspath())}} + {${project.make_uuid(x.win32path())}} ${endfor} @@ -374,9 +374,18 @@ def stealth_write(self, data, flags='wb'): except (IOError, ValueError): self.write(data, flags=flags) else: - Logs.debug('msvs: skipping %s' % self.abspath()) + Logs.debug('msvs: skipping %s' % self.win32path()) Node.Node.stealth_write = stealth_write +re_win32 = re.compile(r'^([/\\]cygdrive)?[/\\]([a-z])([^a-z0-9_-].*)', re.I) +def win32path(self): + p = self.abspath() + m = re_win32.match(p) + if m: + return "%s:%s" % (m.group(2).upper(), m.group(3)) + return p +Node.Node.win32path = win32path + re_quote = re.compile("[^a-zA-Z0-9-]") def quote(s): return re_quote.sub("_", s) @@ -452,7 +461,7 @@ def get_waf(self): """ Override in subclasses... """ - return 'cd /d "%s" & %s' % (self.ctx.srcnode.abspath(), getattr(self.ctx, 'waf_command', 'waf.bat')) + return 'cd /d "%s" & %s' % (self.ctx.srcnode.win32path(), getattr(self.ctx, 'waf_command', 'waf.bat')) def ptype(self): """ @@ -498,9 +507,9 @@ def ptype(self): def __init__(self, ctx, node): vsnode.__init__(self, ctx) self.path = node - self.uuid = make_uuid(node.abspath()) + self.uuid = make_uuid(node.win32path()) self.name = node.name - self.title = self.path.abspath() + self.title = self.path.win32path() self.source = [] # list of node objects self.build_properties = [] # list of properties (nmake commands, output dir, etc) @@ -564,7 +573,7 @@ def collect_properties(self): self.build_properties = ret def get_build_params(self, props): - opt = '--execsolution=%s' % self.ctx.get_solution_node().abspath() + opt = '--execsolution=%s' % self.ctx.get_solution_node().win32path() return (self.get_waf(), opt) def get_build_command(self, props): @@ -662,7 +671,7 @@ def get_build_params(self, props): """ Override the default to add the target name """ - opt = '--execsolution=%s' % self.ctx.get_solution_node().abspath() + opt = '--execsolution=%s' % self.ctx.get_solution_node().win32path() if getattr(self, 'tg', None): opt += " --targets=%s" % self.tg.name return (self.get_waf(), opt) @@ -681,7 +690,7 @@ def collect_source(self): # remove duplicates self.source.extend(list(set(source_files + include_files))) - self.source.sort(key=lambda x: x.abspath()) + self.source.sort(key=lambda x: x.win32path()) def collect_properties(self): """ @@ -689,7 +698,7 @@ def collect_properties(self): """ super(vsnode_target, self).collect_properties() for x in self.build_properties: - x.outdir = self.path.parent.abspath() + x.outdir = self.path.parent.win32path() x.preprocessor_definitions = '' x.includes_search_path = '' @@ -698,7 +707,7 @@ def collect_properties(self): except AttributeError: pass else: - x.output_file = tsk.outputs[0].abspath() + x.output_file = tsk.outputs[0].win32path() x.preprocessor_definitions = ';'.join(tsk.env.DEFINES) x.includes_search_path = ';'.join(self.tg.env.INCPATHS) @@ -766,7 +775,7 @@ def collect_projects(self): def sortfun(x): if x.name == default_project: return '' - return getattr(x, 'path', None) and x.path.abspath() or x.name + return getattr(x, 'path', None) and x.path.win32path() or x.name self.all_projects.sort(key=sortfun) def write_files(self): @@ -858,7 +867,7 @@ def add_aliases(self): p_view.collect_properties() self.all_projects.append(p_view) - n = self.vsnode_vsdir(self, make_uuid(self.srcnode.abspath() + 'build_aliases'), "build_aliases") + n = self.vsnode_vsdir(self, make_uuid(self.srcnode.win32path() + 'build_aliases'), "build_aliases") p_build.parent = p_install.parent = p_view.parent = n self.all_projects.append(n) @@ -879,7 +888,7 @@ def make_parents(proj): # There is not vsnode_vsdir for x. # So create a project representing the folder "x" - n = proj.parent = seen[x] = self.vsnode_vsdir(self, make_uuid(x.abspath()), x.name) + n = proj.parent = seen[x] = self.vsnode_vsdir(self, make_uuid(x.win32path()), x.name) n.iter_path = x.parent self.all_projects.append(n) @@ -934,7 +943,7 @@ def add_path(lst): def display(n): buf = [] for x in n.source: - buf.append('\n' % (xml_escape(x.abspath()), self.get_key(x))) + buf.append('\n' % (xml_escape(x.win32path()), self.get_key(x))) for x in n.subfilters: buf.append('' % xml_escape(x.name)) buf.append(display(x)) From d4ec554cdfeaff2b582b91442753d14081f5c29e Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sat, 2 May 2015 16:48:48 +0200 Subject: [PATCH 0020/1763] Simplify initialization of --top and --out in out-of-tree builds --- waflib/Scripting.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/waflib/Scripting.py b/waflib/Scripting.py index 4a78557c57..82d0eb0f87 100644 --- a/waflib/Scripting.py +++ b/waflib/Scripting.py @@ -61,10 +61,17 @@ def waf_entry_point(current_directory, version, wafdir): no_climb = True break + # if --top is provided assume the build started in the top directory + for x in sys.argv: + if x.startswith('--top='): + Context.run_dir = Context.top_dir = x[6:] + if x.startswith('--out='): + Context.out_dir = x[6:] + # try to find a lock file (if the project was configured) # at the same time, store the first wscript file seen cur = current_directory - while cur: + while cur and not Context.run_dir: lst = os.listdir(cur) if Options.lockfile in lst: env = ConfigSet.ConfigSet() From 9fdfec763dcb9765d7838bcff90487f6411d7b18 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sat, 2 May 2015 17:13:00 +0200 Subject: [PATCH 0021/1763] provide --no-lock-in-top and --no-lock-in-run for packagers --- waflib/Configure.py | 6 +++--- waflib/Options.py | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/waflib/Configure.py b/waflib/Configure.py index 1433336d2d..0e3734cb43 100644 --- a/waflib/Configure.py +++ b/waflib/Configure.py @@ -192,11 +192,11 @@ def execute(self): env['files'] = self.files env['environ'] = dict(self.environ) - if not self.env.NO_LOCK_IN_RUN: + if not self.env.NO_LOCK_IN_RUN and not getattr(Options.options, 'no_lock_in_run'): env.store(os.path.join(Context.run_dir, Options.lockfile)) - if not self.env.NO_LOCK_IN_TOP: + if not self.env.NO_LOCK_IN_TOP and not getattr(Options.options, 'no_lock_in_top'): env.store(os.path.join(Context.top_dir, Options.lockfile)) - if not self.env.NO_LOCK_IN_OUT: + if not self.env.NO_LOCK_IN_OUT and not getattr(Options.options, 'no_lock_in_out'): env.store(os.path.join(Context.out_dir, Options.lockfile)) def prepare_env(self, env): diff --git a/waflib/Options.py b/waflib/Options.py index ad6a44ff3d..f11fe3e399 100644 --- a/waflib/Options.py +++ b/waflib/Options.py @@ -126,6 +126,10 @@ def __init__(self, **kw): gr.add_option('-o', '--out', action='store', default='', help='build dir for the project', dest='out') gr.add_option('-t', '--top', action='store', default='', help='src dir for the project', dest='top') + gr.add_option('--no-lock-in-run', action='store_true', default='', help=optparse.SUPPRESS_HELP, dest='no_lock_in_run') + gr.add_option('--no-lock-in-out', action='store_true', default='', help=optparse.SUPPRESS_HELP, dest='no_lock_in_out') + gr.add_option('--no-lock-in-top', action='store_true', default='', help=optparse.SUPPRESS_HELP, dest='no_lock_in_top') + default_prefix = getattr(Context.g_module, 'default_prefix', os.environ.get('PREFIX')) if not default_prefix: if platform == 'win32': From 120af4f1d00078c1a86ebdc5cb1dec3ebefaa008 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sun, 3 May 2015 01:03:11 +0200 Subject: [PATCH 0022/1763] docs --- waflib/Tools/c_config.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/waflib/Tools/c_config.py b/waflib/Tools/c_config.py index e9c22204f4..0f3920533f 100755 --- a/waflib/Tools/c_config.py +++ b/waflib/Tools/c_config.py @@ -383,7 +383,9 @@ def configure(conf): conf.check_cfg(path='sdl-config', args='--cflags --libs', package='', uselib_store='SDL') conf.check_cfg(path='mpicc', args='--showme:compile --showme:link', package='', uselib_store='OPEN_MPI', mandatory=False) - + # variables + conf.check_cfg(package='gtk+-2.0', variables='includedir', uselib_store='FOO') + print(conf.env.FOO_includedir) """ if k: lst = k[0].split() From b45f52165b1d893fa3ebc2cfd8d0f85465c2777a Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sun, 3 May 2015 10:22:28 +0200 Subject: [PATCH 0023/1763] docs --- ChangeLog | 7 +++++++ waflib/Task.py | 6 +++++- waflib/Tools/c_config.py | 2 +- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 242e9f4401..53433b5156 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +NEW IN WAF 1.8.10 +----------------- +* Replace cygwin paths in solution files - https://github.com/waf-project/waf/issues/1562 +* Fixed the hcode in why.py - https://github.com/waf-project/waf/issues/1561 +* Enabled execution from any folder: "waf configure --top=/arbitrary/folder --out=/tmp/build" +* Enabled stateless out-of-tree builds by default: "waf configure --no-lock-in-top --no-lock-in-run" + NEW IN WAF 1.8.9 ---------------- * VS 2013 supports cross-compiling for x86 and arm from amd64 diff --git a/waflib/Task.py b/waflib/Task.py index b70532e5fb..326ac3034c 100644 --- a/waflib/Task.py +++ b/waflib/Task.py @@ -64,7 +64,7 @@ def to_list(xx): ''' classes = {} -"class tasks created by user scripts or Waf tools are kept in this dict name -> class object" +"Class tasks created by user scripts or Waf tools (maps names to class objects). Task classes defined in Waf tools are registered here through the metaclass :py:class:`waflib.Task.store_task_type`." class store_task_type(type): """ @@ -118,6 +118,8 @@ class TaskBase(evil): #. runnable_status: ask the task if it should be run, skipped, or if we have to ask later #. run: let threads execute the task #. post_run: let threads update the data regarding the task (cache) + + .. warning:: For backward compatibility reasons, the suffix "_task" is truncated in derived class names. This limitation will be removed in Waf 1.9. """ color = 'GREEN' @@ -402,6 +404,8 @@ class Task(TaskBase): uses a hash value (from :py:class:`waflib.Task.Task.signature`) which is persistent from build to build. When the value changes, the task has to be executed. The method :py:class:`waflib.Task.Task.post_run` will assign the task signature to the output nodes (if present). + + .. warning:: For backward compatibility reasons, the suffix "_task" is truncated in derived class names. This limitation will be removed in Waf 1.9. """ vars = [] """Variables to depend on (class attribute used for :py:meth:`waflib.Task.Task.sig_vars`)""" diff --git a/waflib/Tools/c_config.py b/waflib/Tools/c_config.py index 0f3920533f..d4cc43c717 100755 --- a/waflib/Tools/c_config.py +++ b/waflib/Tools/c_config.py @@ -384,7 +384,7 @@ def configure(conf): conf.check_cfg(path='mpicc', args='--showme:compile --showme:link', package='', uselib_store='OPEN_MPI', mandatory=False) # variables - conf.check_cfg(package='gtk+-2.0', variables='includedir', uselib_store='FOO') + conf.check_cfg(package='gtk+-2.0', variables=['includedir', 'prefix'], uselib_store='FOO') print(conf.env.FOO_includedir) """ if k: From 533599b7ba4a79b49023b3e6028d4669a4fd5555 Mon Sep 17 00:00:00 2001 From: "christophe.duvernois" Date: Sun, 3 May 2015 16:52:01 +0200 Subject: [PATCH 0024/1763] swig tool can handle -outdir parameter --- waflib/extras/swig.py | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/waflib/extras/swig.py b/waflib/extras/swig.py index 43aff46daf..1c6fde4244 100644 --- a/waflib/extras/swig.py +++ b/waflib/extras/swig.py @@ -130,12 +130,18 @@ def swig_c(self): @swigf def swig_python(tsk): - tsk.set_outputs(tsk.inputs[0].parent.find_or_declare(tsk.module + '.py')) + node = tsk.inputs[0].parent + if tsk.outdir: + node = tsk.outdir + tsk.set_outputs(node.find_or_declare(tsk.module+'.py')) @swigf def swig_ocaml(tsk): - tsk.set_outputs(tsk.inputs[0].parent.find_or_declare(tsk.module + '.ml')) - tsk.set_outputs(tsk.inputs[0].parent.find_or_declare(tsk.module + '.mli')) + node = tsk.inputs[0].parent + if tsk.outdir: + node = tsk.outdir + tsk.set_outputs(node.find_or_declare(tsk.module+'.ml')) + tsk.set_outputs(node.find_or_declare(tsk.module+'.mli')) @extension(*SWIG_EXTS) def i_file(self, node): @@ -147,9 +153,12 @@ def i_file(self, node): flags = self.to_list(getattr(self, 'swig_flags', [])) tsk.env.append_value('SWIGFLAGS', flags) - # looks like this is causing problems - #if not '-outdir' in flags: - # tsk.env.append_value('SWIGFLAGS', ['-outdir', node.parent.abspath()]) + tsk.outdir = None + if '-outdir' in flags: + outdir = flags[flags.index('-outdir')+1] + outdir = tsk.generator.bld.bldnode.make_node(outdir) + outdir.mkdir() + tsk.outdir = outdir @conf def check_swig_version(self): From 28639e5c98fbed86b1faa7e80c8b283e83697b0f Mon Sep 17 00:00:00 2001 From: "christophe.duvernois" Date: Sun, 3 May 2015 18:47:05 +0200 Subject: [PATCH 0025/1763] playground test update for swig with -outdir parameter --- playground/swig/wscript | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/playground/swig/wscript b/playground/swig/wscript index b461c4e785..671dfe586a 100644 --- a/playground/swig/wscript +++ b/playground/swig/wscript @@ -92,10 +92,10 @@ def build(bld): from waflib.extras import swig - srcdir = bld.path.get_bld().make_node('extend/java/hmm') # destination for generated java file (without the packages!) + srcdir = bld.path.get_bld().make_node('extend/java') # destination for generated java file #""" # BEGIN BLOCK 1 - d = bld.path.make_node('extend/java') + d = bld.path.make_node('extend/java/foo/bar/pouet') javanodes = [d.find_or_declare(x) for x in 'A.java test_swig_waf.java test_swig_wafJNI.java'.split()] dec = bld.tools['swig'].swigf #@dec <- python 2.3 does not support the @decorator notation @@ -106,23 +106,17 @@ def build(bld): #"""# do not remove - - - bld( features = 'cxx cxxshlib', source = 'extend/java/test_swig_waf.i', target = 'extend/java/_test_swig_waf', - swig_flags = '-c++ -java -package foo.bar.pouet', + swig_flags = '-c++ -java -package foo.bar.pouet -outdir extend/java/foo/bar/pouet', includes = 'extend', vnum = '1.2.3', uselib = 'JAVA', use = 'mylib') #""" # BEGIN BLOCK 2 - for x in javanodes: - bld(rule='cp ${SRC} ${TGT}', source=x, - target=srcdir.make_node('foo/bar/pouet/' + x.name), before=['javac'], after=['swig']) """ # END BLOCK 2 def move_java_files(task): @@ -130,22 +124,18 @@ def build(bld): from waflib import Utils node = srcdir.make_node('foo/bar/pouet/') - node.mkdir() - orig = task.inputs[0].parent.get_bld().abspath() - files = Utils.listdir(orig) + files = Utils.listdir(node.abspath()) for x in files: if x.endswith('.java'): # create a node in the directory we want to j = node.make_node(x) # create a node - shutil.copy2(orig + os.sep + x, j.abspath()) # create the physical file for the node j.sig = Utils.h_file(j.abspath()) # update the node signature # depend on the .i file to make sure the .java files are copied after swig is executed bld(name='move_and_read', rule=move_java_files, source='extend/java/test_swig_waf.i', after=['swig'], before=['javac']) #""" - bld(rule='cp ${SRC} ${TGT}', source=bld.path.find_resource('extend/java/Foo.java'), - target=srcdir.make_node('foo/bar/pouet/Foo.java'), before=['javac'], after=['swig']) + bld(rule='cp ${SRC} ${TGT}', source=bld.path.find_resource('extend/java/Foo.java'), target=srcdir.make_node('foo/bar/pouet/Foo.java'), before=['javac'], after=['swig']) tmp = bld.path.get_bld().make_node('maha') From a4c2370ee4669ca7cce30768dd8211295a4eda78 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Tue, 5 May 2015 07:33:47 +0200 Subject: [PATCH 0026/1763] WriteConsole type - https://github.com/waf-project/waf/issues/1567 --- waflib/ansiterm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/waflib/ansiterm.py b/waflib/ansiterm.py index e7a4ce7521..64fa14071a 100644 --- a/waflib/ansiterm.py +++ b/waflib/ansiterm.py @@ -284,7 +284,7 @@ def write(self, text): wlock.release() def writeconsole(self, txt): - chars_written = c_int() + chars_written = c_ulong() writeconsole = windll.kernel32.WriteConsoleA if isinstance(txt, _type): writeconsole = windll.kernel32.WriteConsoleW From 085b80fdb3476216604eea807216d9fdc81e759f Mon Sep 17 00:00:00 2001 From: Syl Date: Wed, 6 May 2015 19:19:05 +0200 Subject: [PATCH 0027/1763] cpplint: fixed import. The version on pypi is now up to date and works with Python3. --- waflib/extras/cpplint.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/waflib/extras/cpplint.py b/waflib/extras/cpplint.py index bbeb53640b..71d037026c 100644 --- a/waflib/extras/cpplint.py +++ b/waflib/extras/cpplint.py @@ -49,7 +49,7 @@ def build(bld): import threading from waflib import Task, Build, TaskGen, Logs, Utils try: - from cpplint.cpplint import ProcessFile, _cpplint_state + from cpplint import ProcessFile, _cpplint_state except ImportError: pass From 8ef1fa773370290ba848bc2ce4e17d52c27f522f Mon Sep 17 00:00:00 2001 From: Syl Date: Wed, 6 May 2015 22:33:31 +0200 Subject: [PATCH 0028/1763] cpplint: keep the old import --- waflib/extras/cpplint.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/waflib/extras/cpplint.py b/waflib/extras/cpplint.py index 71d037026c..fed18e9bab 100644 --- a/waflib/extras/cpplint.py +++ b/waflib/extras/cpplint.py @@ -49,9 +49,12 @@ def build(bld): import threading from waflib import Task, Build, TaskGen, Logs, Utils try: - from cpplint import ProcessFile, _cpplint_state + from cpplint.cpplint import ProcessFile, _cpplint_state except ImportError: - pass + try: + from cpplint import ProcessFile, _cpplint_state + except ImportError: + pass critical_errors = 0 From 802e937d7328a0ff87516147d1f80dceb982120b Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Fri, 8 May 2015 18:16:48 +0200 Subject: [PATCH 0029/1763] Regression caused by 588f809ffa4dd514ea90bdcd0341d9baf508784f - https://github.com/waf-project/waf/pull/1572 --- waflib/Tools/python.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/waflib/Tools/python.py b/waflib/Tools/python.py index 00d9f07c69..bc566068db 100644 --- a/waflib/Tools/python.py +++ b/waflib/Tools/python.py @@ -462,7 +462,7 @@ def check_python_version(conf, minver=None): "get_python_lib(standard_lib=0) or ''"]) else: python_LIBDEST = None - (pydir,) = conf.get_python_variables( ["get_python_lib(standard_lib=0, prefix='%s') or ''" % conf.env['PREFIX']]) + (pydir,) = conf.get_python_variables( ["get_python_lib(standard_lib=0, prefix=%r) or ''" % conf.env.PREFIX]) if python_LIBDEST is None: if conf.env['LIBDIR']: python_LIBDEST = os.path.join(conf.env['LIBDIR'], "python" + pyver) @@ -477,7 +477,7 @@ def check_python_version(conf, minver=None): pyarchdir = conf.environ['PYTHONARCHDIR'] else: # Finally, try to guess - (pyarchdir, ) = conf.get_python_variables( ["get_python_lib(plat_specific=1, standard_lib=0, prefix='%s') or ''" % conf.env['PREFIX']]) + (pyarchdir, ) = conf.get_python_variables( ["get_python_lib(plat_specific=1, standard_lib=0, prefix=%r) or ''" % conf.env.PREFIX]) if not pyarchdir: pyarchdir = pydir From 1bc6c745c96bcde82644d1cb0096819b4622c9da Mon Sep 17 00:00:00 2001 From: Dale Stewart Date: Thu, 14 May 2015 16:15:57 -0500 Subject: [PATCH 0030/1763] qt5: cope with library names like 'Qt5Core' instead of 'QtCore5', as in Qt 5.4 on Windows --- waflib/Tools/qt5.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/waflib/Tools/qt5.py b/waflib/Tools/qt5.py index e4a21148b8..7341b532a8 100644 --- a/waflib/Tools/qt5.py +++ b/waflib/Tools/qt5.py @@ -642,7 +642,7 @@ def find_qt5_libraries(self): env.append_unique('LIBPATH_' + uselib, qtlibs) env.append_unique('INCLUDES_' + uselib, qtincludes) - env.append_unique('INCLUDES_' + uselib, os.path.join(qtincludes, i)) + env.append_unique('INCLUDES_' + uselib, os.path.join(qtincludes, i.replace('Qt5', 'Qt'))) # Debug library names are like QtCore5d uselib = i.upper() + "_debug" @@ -657,7 +657,7 @@ def find_qt5_libraries(self): env.append_unique('LIBPATH_' + uselib, qtlibs) env.append_unique('INCLUDES_' + uselib, qtincludes) - env.append_unique('INCLUDES_' + uselib, os.path.join(qtincludes, i)) + env.append_unique('INCLUDES_' + uselib, os.path.join(qtincludes, i.replace('Qt5', 'Qt'))) else: for i in self.qt5_vars_debug + self.qt5_vars: self.check_cfg(package=i, args='--cflags --libs', mandatory=False) @@ -721,7 +721,7 @@ def set_qt5_defines(self): if sys.platform != 'win32': return for x in self.qt5_vars: - y = x[2:].upper() + y=x.replace('Qt5', 'Qt')[2:].upper() self.env.append_unique('DEFINES_%s' % x.upper(), 'QT_%s_LIB' % y) self.env.append_unique('DEFINES_%s_DEBUG' % x.upper(), 'QT_%s_LIB' % y) From f048d6d20f3b274e65d397ee87b25927346f0ff5 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sat, 16 May 2015 14:26:43 +0200 Subject: [PATCH 0031/1763] Do not duplicate flags from the OS environment - https://github.com/waf-project/waf/issues/1574 --- ChangeLog | 2 ++ waflib/Configure.py | 14 ++++++++++---- waflib/Tools/c_config.py | 12 ++++++------ waflib/Tools/fc_config.py | 6 +++--- 4 files changed, 21 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 53433b5156..78261b9f0c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,8 @@ NEW IN WAF 1.8.10 * Fixed the hcode in why.py - https://github.com/waf-project/waf/issues/1561 * Enabled execution from any folder: "waf configure --top=/arbitrary/folder --out=/tmp/build" * Enabled stateless out-of-tree builds by default: "waf configure --no-lock-in-top --no-lock-in-run" +* Fixed the waf file generation on windows in Waf 1.8.9 +* Add OS flags such as LDFLAGS only once - https://github.com/waf-project/waf/issues/1574 NEW IN WAF 1.8.9 ---------------- diff --git a/waflib/Configure.py b/waflib/Configure.py index 0e3734cb43..173d409463 100644 --- a/waflib/Configure.py +++ b/waflib/Configure.py @@ -352,7 +352,7 @@ def fun(*k, **kw): return f @conf -def add_os_flags(self, var, dest=None): +def add_os_flags(self, var, dest=None, dup=True): """ Import operating system environment values into ``conf.env`` dict:: @@ -363,10 +363,16 @@ def configure(conf): :type var: string :param dest: destination variable, by default the same as var :type dest: string + :param dup: add the same set of flags again + :type dup: bool """ - # do not use 'get' to make certain the variable is not defined - try: self.env.append_value(dest or var, shlex.split(self.environ[var])) - except KeyError: pass + try: + flags = shlex.split(self.environ[var]) + except KeyError: + return + # TODO: in waf 1.9, make dup=False the default + if dup or ''.join(flags) not in ''.join(Utils.to_list(self.env[dest or var])): + self.env.append_value(dest or var, flags) @conf def cmd_to_list(self, cmd): diff --git a/waflib/Tools/c_config.py b/waflib/Tools/c_config.py index d4cc43c717..71a0604646 100755 --- a/waflib/Tools/c_config.py +++ b/waflib/Tools/c_config.py @@ -933,24 +933,24 @@ def cc_add_flags(conf): """ Add CFLAGS / CPPFLAGS from os.environ to conf.env """ - conf.add_os_flags('CPPFLAGS', 'CFLAGS') - conf.add_os_flags('CFLAGS') + conf.add_os_flags('CPPFLAGS', dup=False) + conf.add_os_flags('CFLAGS', dup=False) @conf def cxx_add_flags(conf): """ Add CXXFLAGS / CPPFLAGS from os.environ to conf.env """ - conf.add_os_flags('CPPFLAGS', 'CXXFLAGS') - conf.add_os_flags('CXXFLAGS') + conf.add_os_flags('CPPFLAGS', dup=False) + conf.add_os_flags('CXXFLAGS', dup=False) @conf def link_add_flags(conf): """ Add LINKFLAGS / LDFLAGS from os.environ to conf.env """ - conf.add_os_flags('LINKFLAGS') - conf.add_os_flags('LDFLAGS') + conf.add_os_flags('LINKFLAGS', dup=False) + conf.add_os_flags('LDFLAGS', dup=False) @conf def cc_load_tools(conf): diff --git a/waflib/Tools/fc_config.py b/waflib/Tools/fc_config.py index 76a547a546..7a4c0671e5 100644 --- a/waflib/Tools/fc_config.py +++ b/waflib/Tools/fc_config.py @@ -51,9 +51,9 @@ def fc_add_flags(conf): """ Add FCFLAGS / LDFLAGS / LINKFLAGS from os.environ to conf.env """ - conf.add_os_flags('FCFLAGS') - conf.add_os_flags('LINKFLAGS') - conf.add_os_flags('LDFLAGS') + conf.add_os_flags('FCFLAGS', dup=False) + conf.add_os_flags('LINKFLAGS', dup=False) + conf.add_os_flags('LDFLAGS', dup=False) @conf def check_fortran(self, *k, **kw): From ea59b302c53aa18adf7c7048f9e31281dac0e934 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sat, 23 May 2015 15:09:37 +0200 Subject: [PATCH 0032/1763] Fixed conf.multicheck error handling --- waflib/Tools/c_config.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/waflib/Tools/c_config.py b/waflib/Tools/c_config.py index 71a0604646..585f9c0ba2 100755 --- a/waflib/Tools/c_config.py +++ b/waflib/Tools/c_config.py @@ -1167,6 +1167,7 @@ def __init__(self): self.keep = False self.returned_tasks = [] self.task_sigs = {} + self.progress_bar = 0 def total(self): return len(tasks) def to_log(self, *k, **kw): @@ -1197,10 +1198,17 @@ def it(): for x in tasks: x.logger.memhandler.flush() + if p.error: + for x in p.error: + if getattr(x, 'err_msg', None): + self.to_log(x.err_msg) + self.end_msg('fail', color='RED') + raise Errors.WafError('There is an error in the library, read config.log for more information') + for x in tasks: if x.hasrun != Task.SUCCESS: self.end_msg(kw.get('errmsg', 'no'), color='YELLOW', **kw) - self.fatal(kw.get('fatalmsg', None) or 'One of the tests has failed, see the config.log for more information') + self.fatal(kw.get('fatalmsg', None) or 'One of the tests has failed, read config.log for more information') self.end_msg('ok', **kw) From 3886c709292baf4bdd4fda7b7ebded5261669221 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sun, 24 May 2015 15:39:46 +0200 Subject: [PATCH 0033/1763] waf 1.8.10 --- ChangeLog | 1 + waf-light | 2 +- waflib/Context.py | 6 +++--- wscript | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 78261b9f0c..576f541072 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,7 @@ NEW IN WAF 1.8.10 * Enabled stateless out-of-tree builds by default: "waf configure --no-lock-in-top --no-lock-in-run" * Fixed the waf file generation on windows in Waf 1.8.9 * Add OS flags such as LDFLAGS only once - https://github.com/waf-project/waf/issues/1574 +* Fixed conf.multicheck error handling NEW IN WAF 1.8.9 ---------------- diff --git a/waf-light b/waf-light index 5ac0bcfc54..b4faa5eb18 100755 --- a/waf-light +++ b/waf-light @@ -32,7 +32,7 @@ POSSIBILITY OF SUCH DAMAGE. import os, sys, inspect -VERSION="1.8.9" +VERSION="1.8.10" REVISION="x" GIT="x" INSTALL="x" diff --git a/waflib/Context.py b/waflib/Context.py index cb5e59b859..c818006318 100644 --- a/waflib/Context.py +++ b/waflib/Context.py @@ -11,13 +11,13 @@ import waflib.Node # the following 3 constants are updated on each new release (do not touch) -HEXVERSION=0x1080900 +HEXVERSION=0x1080a00 """Constant updated on new releases""" -WAFVERSION="1.8.9" +WAFVERSION="1.8.10" """Constant updated on new releases""" -WAFREVISION="06e49b2a82166aeb14dde8357c58387f252fc722" +WAFREVISION="ea59b302c53aa18adf7c7048f9e31281dac0e934" """Git revision when the waf version is updated""" ABI = 98 diff --git a/wscript b/wscript index 8182259d43..d55192863a 100644 --- a/wscript +++ b/wscript @@ -10,7 +10,7 @@ To add a tool that does not exist in the folder compat15, pass an absolute path: """ -VERSION="1.8.9" +VERSION="1.8.10" APPNAME='waf' REVISION='' From f14678f3e63d31a27b3428640b0aec9dceab84cd Mon Sep 17 00:00:00 2001 From: Guillaume Poirier-Morency Date: Tue, 26 May 2015 03:23:33 -0400 Subject: [PATCH 0034/1763] Fix the '--threading' option for valac. The actual compiler option is named '--thread', not '--threading'. Renames the waf option for 'thread': it shouldn't be breaking anyone as it was not even working. --- waflib/Tools/vala.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/waflib/Tools/vala.py b/waflib/Tools/vala.py index 5d237c58ec..f9bf976030 100644 --- a/waflib/Tools/vala.py +++ b/waflib/Tools/vala.py @@ -59,17 +59,17 @@ def addflags(flags): if self.profile: addflags('--profile=%s' % self.profile) - if hasattr(self, 'threading'): + if hasattr(self, 'thread'): if self.profile == 'gobject': if not 'GTHREAD' in self.uselib: self.uselib.append('GTHREAD') else: #Vala doesn't have threading support for dova nor posix Logs.warn("Profile %s means no threading support" % self.profile) - self.threading = False + self.thread = False - if self.threading: - addflags('--threading') + if self.thread: + addflags('--thread') valatask = self.valatask @@ -223,7 +223,7 @@ def build(bld): #install_binding = False # profile = 'xyz' # adds --profile= to enable profiling - # threading = True, # add --threading, except if profile is on or not on 'gobject' + # thread = True, # adds --thread, except if profile is on or not on 'gobject' # vala_target_glib = 'xyz' # adds --target-glib=, can be given through the command-line option --vala-target-glib= ) From 04556a4d28ce1ff59f80b9d109a75dd197822506 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Wed, 27 May 2015 18:45:20 +0200 Subject: [PATCH 0035/1763] Use adequate variable for include paths in protoc.py --- waflib/extras/protoc.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/waflib/extras/protoc.py b/waflib/extras/protoc.py index f8fd070f86..4d3d13fac6 100644 --- a/waflib/extras/protoc.py +++ b/waflib/extras/protoc.py @@ -51,8 +51,6 @@ def scan(self): if not node: return (nodes, names) - search_paths = [self.generator.path.find_node(x) for x in self.generator.includes] - def parse_node(node): if node in seen: return @@ -62,7 +60,7 @@ def parse_node(node): m = re.search(r'^import\s+"(.*)";.*(//)?.*', line) if m: dep = m.groups()[0] - for incpath in search_paths: + for incpath in self.env.INCPATHS: found = incpath.find_resource(dep) if found: nodes.append(found) From f6b61914806d4ed664cfa1394c8d781282257322 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Thu, 28 May 2015 23:08:07 +0200 Subject: [PATCH 0036/1763] Additional crutches for protoc --- waflib/extras/protoc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/waflib/extras/protoc.py b/waflib/extras/protoc.py index 4d3d13fac6..ef84973899 100644 --- a/waflib/extras/protoc.py +++ b/waflib/extras/protoc.py @@ -80,7 +80,7 @@ def process_protoc(self, node): if 'cxx' in self.features and not self.env.PROTOC_FLAGS: #self.env.PROTOC_FLAGS = '--cpp_out=%s' % node.parent.get_bld().abspath() # <- this does not work - self.env.PROTOC_FLAGS = '--cpp_out=.' + self.env.PROTOC_FLAGS = '--cpp_out=%s' % node.parent.get_bld().bldpath() use = getattr(self, 'use', '') if not 'PROTOBUF' in use: From 92f584fd8f4319d45b9f51e5c76af4197870eda3 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sun, 31 May 2015 16:51:44 +0200 Subject: [PATCH 0037/1763] Repeated failures remove signatures - Issue 1580 --- waflib/Tools/fc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/waflib/Tools/fc.py b/waflib/Tools/fc.py index a028004726..845b8eacb7 100644 --- a/waflib/Tools/fc.py +++ b/waflib/Tools/fc.py @@ -111,7 +111,7 @@ def runnable_status(self): if x.startswith('MOD@'): name = bld.modfile(x.replace('MOD@', '')) node = bld.srcnode.find_or_declare(name) - if not hasattr(node, 'sig'): + if not getattr(node, 'sig', None): node.sig = Utils.SIG_NIL tsk.set_outputs(node) outs[id(node)].add(tsk) From 728205fe3ce786f8b4af4311b701cad80e467c64 Mon Sep 17 00:00:00 2001 From: Alexander Afanasyev Date: Fri, 5 Jun 2015 17:10:11 -0700 Subject: [PATCH 0038/1763] Change with shared library compatibility version handling For ELF binaries (e.g., Linux): default compatible version (SONAME = `.so.`) can be specialized using additional `cnum` parameter to `.so..` or `.so...`. For Mach-O binaries (e.g., OS X): - (bugfix) install-name points to compatible version (not absolute path to a non-versioned library) - Default install-name `/..dylib` can be specialized using `cnum` parameter to `/...dylib` or `/....dylib` - `-Wl,-compatibility_version` and `-Wl,-current_version` flags use version from cnum/vnum (default cnum is vnum.split('.')[0]) --- demos/c++/wscript | 2 ++ waflib/Tools/ccroot.py | 28 ++++++++++++++++++++++------ waflib/Tools/fc_config.py | 2 +- waflib/Tools/gcc.py | 2 +- waflib/Tools/gxx.py | 2 +- 5 files changed, 27 insertions(+), 9 deletions(-) diff --git a/demos/c++/wscript b/demos/c++/wscript index 1b7751f239..ca9d9822fa 100644 --- a/demos/c++/wscript +++ b/demos/c++/wscript @@ -19,6 +19,8 @@ def configure(conf): def build(bld): bld.shlib(source='a.cpp', target='mylib', vnum='9.8.7') + bld.shlib(source='a.cpp', target='mylib2', vnum='9.8.7', cnum='9.8') + bld.shlib(source='a.cpp', target='mylib3') bld.program(source='main.cpp', target='app', use='mylib') bld.stlib(target='foo', source='b.cpp') diff --git a/waflib/Tools/ccroot.py b/waflib/Tools/ccroot.py index 05484e3093..363d18d118 100644 --- a/waflib/Tools/ccroot.py +++ b/waflib/Tools/ccroot.py @@ -489,10 +489,19 @@ def apply_vnum(self): def build(bld): bld.shlib(source='a.c', target='foo', vnum='14.15.16') - In this example, ``libfoo.so`` is installed as ``libfoo.so.1.2.3``, and the following symbolic links are created: + In this example on Linux platform, ``libfoo.so`` is installed as ``libfoo.so.14.15.16``, and the following symbolic links are created: - * ``libfoo.so → libfoo.so.1.2.3`` - * ``libfoo.so.1 → libfoo.so.1.2.3`` + * ``libfoo.so → libfoo.so.14.15.16`` + * ``libfoo.so.14 → libfoo.so.14.15.16`` + + By default, the library will be assigned SONAME ``libfoo.so.14``, effectively declaring ABI compatibility between all minor and patch releases for the major version of the library. When necessary, the compatibility can be explicitly defined using `cnum` parameter: + + def build(bld): + bld.shlib(source='a.c', target='foo', vnum='14.15.16', cnum='14.15') + + In this case, the assigned SONAME will be ``libfoo.so.14.15`` with ABI compatibility only between path releases for a specific major and minor version of the library. + + On OS X platform, install-name parameter will follow the above logic for SONAME with exception that it also specifies an absolute path (based on install_path) of the library. """ if not getattr(self, 'vnum', '') or os.name != 'posix' or self.env.DEST_BINFMT not in ('elf', 'mac-o'): return @@ -503,13 +512,18 @@ def build(bld): nums = self.vnum.split('.') node = link.outputs[0] + cnum = getattr(self, 'cnum', str(nums[0])) + cnums = cnum.split('.') + if len(cnums)>len(nums) or nums[0:len(cnums)] != cnums: + raise Errors.WafError('invalid compatibility version %s' % cnum) + libname = node.name if libname.endswith('.dylib'): name3 = libname.replace('.dylib', '.%s.dylib' % self.vnum) - name2 = libname.replace('.dylib', '.%s.dylib' % nums[0]) + name2 = libname.replace('.dylib', '.%s.dylib' % cnum) else: name3 = libname + '.' + self.vnum - name2 = libname + '.' + nums[0] + name2 = libname + '.' + cnum # add the so name for the ld linker - to disable, just unset env.SONAME_ST if self.env.SONAME_ST: @@ -548,8 +562,10 @@ def build(bld): inst_to = self.link_task.__class__.inst_to if inst_to: p = Utils.subst_vars(inst_to, self.env) - path = os.path.join(p, self.link_task.outputs[0].name) + path = os.path.join(p, name2) self.env.append_value('LINKFLAGS', ['-install_name', path]) + self.env.append_value('LINKFLAGS', '-Wl,-compatibility_version,%s' % cnum) + self.env.append_value('LINKFLAGS', '-Wl,-current_version,%s' % self.vnum) class vnum(Task.Task): """ diff --git a/waflib/Tools/fc_config.py b/waflib/Tools/fc_config.py index 7a4c0671e5..8d795d63c2 100644 --- a/waflib/Tools/fc_config.py +++ b/waflib/Tools/fc_config.py @@ -93,7 +93,7 @@ def fortran_modifier_darwin(conf): """ v = conf.env v['FCFLAGS_fcshlib'] = ['-fPIC'] - v['LINKFLAGS_fcshlib'] = ['-dynamiclib', '-Wl,-compatibility_version,1', '-Wl,-current_version,1'] + v['LINKFLAGS_fcshlib'] = ['-dynamiclib'] v['fcshlib_PATTERN'] = 'lib%s.dylib' v['FRAMEWORKPATH_ST'] = '-F%s' v['FRAMEWORK_ST'] = '-framework %s' diff --git a/waflib/Tools/gcc.py b/waflib/Tools/gcc.py index 8cb954f87d..741a2e3ffa 100644 --- a/waflib/Tools/gcc.py +++ b/waflib/Tools/gcc.py @@ -97,7 +97,7 @@ def gcc_modifier_darwin(conf): """Configuration flags for executing gcc on MacOS""" v = conf.env v['CFLAGS_cshlib'] = ['-fPIC'] - v['LINKFLAGS_cshlib'] = ['-dynamiclib', '-Wl,-compatibility_version,1', '-Wl,-current_version,1'] + v['LINKFLAGS_cshlib'] = ['-dynamiclib'] v['cshlib_PATTERN'] = 'lib%s.dylib' v['FRAMEWORKPATH_ST'] = '-F%s' v['FRAMEWORK_ST'] = ['-framework'] diff --git a/waflib/Tools/gxx.py b/waflib/Tools/gxx.py index 55bf2a7024..4c89273b40 100644 --- a/waflib/Tools/gxx.py +++ b/waflib/Tools/gxx.py @@ -97,7 +97,7 @@ def gxx_modifier_darwin(conf): """Configuration flags for executing g++ on MacOS""" v = conf.env v['CXXFLAGS_cxxshlib'] = ['-fPIC'] - v['LINKFLAGS_cxxshlib'] = ['-dynamiclib', '-Wl,-compatibility_version,1', '-Wl,-current_version,1'] + v['LINKFLAGS_cxxshlib'] = ['-dynamiclib'] v['cxxshlib_PATTERN'] = 'lib%s.dylib' v['FRAMEWORKPATH_ST'] = '-F%s' v['FRAMEWORK_ST'] = ['-framework'] From 9fc9464238d467e54d01132f395a4ba277c40933 Mon Sep 17 00:00:00 2001 From: Nikolaus Lieb Date: Wed, 10 Jun 2015 21:44:37 +0800 Subject: [PATCH 0039/1763] Add tooldir to cache-check on loading module in Configure context. --- waflib/Configure.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/waflib/Configure.py b/waflib/Configure.py index 173d409463..49b52247ac 100644 --- a/waflib/Configure.py +++ b/waflib/Configure.py @@ -252,7 +252,7 @@ def load(self, input, tooldir=None, funs=None): # avoid loading the same tool more than once with the same functions # used by composite projects - mag = (tool, id(self.env), funs) + mag = (tool, id(self.env), tooldir, funs) if mag in self.tool_cache: self.to_log('(tool %s is already loaded, skipping)' % tool) continue From c91214e216ecff5e1445b8c0cdfc04de7a26135d Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Thu, 11 Jun 2015 18:15:10 +0200 Subject: [PATCH 0040/1763] generated .py files might need to be byte-compiled and installed --- waflib/Tools/python.py | 1 - 1 file changed, 1 deletion(-) diff --git a/waflib/Tools/python.py b/waflib/Tools/python.py index bc566068db..f66d876f65 100644 --- a/waflib/Tools/python.py +++ b/waflib/Tools/python.py @@ -79,7 +79,6 @@ def process_py(self, node): """ Add signature of .py file, so it will be byte-compiled when necessary """ - assert(node.get_bld_sig()) assert(getattr(self, 'install_path')), 'add features="py"' # where to install the python file From 65150769cdfdb4c5fd554e074a7a9221320bd513 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sun, 14 Jun 2015 11:48:05 +0200 Subject: [PATCH 0041/1763] Cleanup --- waflib/extras/lru_cache.py | 98 -------------------------------------- 1 file changed, 98 deletions(-) delete mode 100644 waflib/extras/lru_cache.py diff --git a/waflib/extras/lru_cache.py b/waflib/extras/lru_cache.py deleted file mode 100644 index 2bc964426b..0000000000 --- a/waflib/extras/lru_cache.py +++ /dev/null @@ -1,98 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# Thomas Nagy 2011 - -import os, shutil, re -from waflib import Options, Build, Logs - -""" -Apply a least recently used policy to the Waf cache. - -For performance reasons, it is called after the build is complete. - -We assume that the the folders are written atomically - -Do export WAFCACHE=/tmp/foo_xyz where xyz represents the cache size in bytes -If missing, the default cache size will be set to 10GB -""" - -re_num = re.compile('[a-zA-Z_-]+(\d+)') - -CACHESIZE = 10*1024*1024*1024 # in bytes -CLEANRATIO = 0.8 -DIRSIZE = 4096 - -def compile(self): - if Options.cache_global and not Options.options.nocache: - try: - os.makedirs(Options.cache_global) - except: - pass - - try: - self.raw_compile() - finally: - if Options.cache_global and not Options.options.nocache: - self.sweep() - -def sweep(self): - global CACHESIZE - CACHEDIR = Options.cache_global - - # get the cache max size from the WAFCACHE filename - re_num = re.compile('[a-zA-Z_]+(\d+)') - val = re_num.sub('\\1', os.path.basename(Options.cache_global)) - try: - CACHESIZE = int(val) - except: - pass - - # map folder names to timestamps - flist = {} - for x in os.listdir(CACHEDIR): - j = os.path.join(CACHEDIR, x) - if os.path.isdir(j) and len(x) == 64: # dir names are md5 hexdigests - flist[x] = [os.stat(j).st_mtime, 0] - - for (x, v) in flist.items(): - cnt = DIRSIZE # each entry takes 4kB - d = os.path.join(CACHEDIR, x) - for k in os.listdir(d): - cnt += os.stat(os.path.join(d, k)).st_size - flist[x][1] = cnt - - total = sum([x[1] for x in flist.values()]) - Logs.debug('lru: Cache size is %r' % total) - - if total >= CACHESIZE: - Logs.debug('lru: Trimming the cache since %r > %r' % (total, CACHESIZE)) - - # make a list to sort the folders by timestamp - lst = [(p, v[0], v[1]) for (p, v) in flist.items()] - lst.sort(key=lambda x: x[1]) # sort by timestamp - lst.reverse() - - while total >= CACHESIZE * CLEANRATIO: - (k, t, s) = lst.pop() - p = os.path.join(CACHEDIR, k) - v = p + '.del' - try: - os.rename(p, v) - except: - # someone already did it - pass - else: - try: - shutil.rmtree(v) - except: - # this should not happen, but who knows? - Logs.warn('If you ever see this message, report it (%r)' % v) - total -= s - del flist[k] - - Logs.debug('lru: Total at the end %r' % total) - -Build.BuildContext.raw_compile = Build.BuildContext.compile -Build.BuildContext.compile = compile -Build.BuildContext.sweep = sweep - From 9d763fc74fdcda19dfc481d9ac2ad4028da20ffe Mon Sep 17 00:00:00 2001 From: Caitlin Potter Date: Sun, 14 Jun 2015 15:44:58 -0400 Subject: [PATCH 0042/1763] [macplist]: interpolate file Rather than using an inline interpolated heredoc string, or generating the file in a pre-build step, allow the macplist task itself to perform string interpolation on the contents of a plist file. --- tests/macplist/src/main.c | 3 + tests/macplist/wscript | 124 ++++++++++++++++++++++++++++++++++++++ waflib/Tools/c_osx.py | 15 ++++- 3 files changed, 139 insertions(+), 3 deletions(-) create mode 100644 tests/macplist/src/main.c create mode 100644 tests/macplist/wscript diff --git a/tests/macplist/src/main.c b/tests/macplist/src/main.c new file mode 100644 index 0000000000..691b6bba2d --- /dev/null +++ b/tests/macplist/src/main.c @@ -0,0 +1,3 @@ +int main(int argc, const char** argv) { + return 0; +} diff --git a/tests/macplist/wscript b/tests/macplist/wscript new file mode 100644 index 0000000000..4973f1e9a0 --- /dev/null +++ b/tests/macplist/wscript @@ -0,0 +1,124 @@ +#! /usr/bin/env python3 + +import platform, sys + +top = '.' +out = 'bin' + +plist_string = ''' + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + {app_name} + + CFBundleIdentifier + {bundle_domain} + + CFBundleVersion + {bundle_version} + + MiscKey + {env[PLATFORM_NAME]} + + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + {bundle_name} + + CFBundlePackageType + APPL + + CFBundleSignature + ???? + + +''' + +plist_context = { + 'bundle_domain': 'com.foo.bar.baz', + 'app_name': 'macplist_test', + 'bundle_version': '1.6.7' +} +expected_dict = { + 'env': { + 'PLATFORM_NAME': 'darwin' + } +} + +def options(opt): + opt.load('compiler_c') + +def configure(conf): + conf.load('compiler_c') + +def build(bld): + # Only testing feature on Darwin + if (platform.system() != 'Darwin'): + return + bld.env.PLATFORM_NAME = 'darwin' + plist = {'bundle_name': 'InterpolatedPlistFileTest'} + plist.update(plist_context) + bld.path.make_node('Info.plist').write(plist_string) + bld.program( + features="c cprogram", + target="InterpolatedPlistFileTest", + source="src/main.c", + mac_app=True, + mac_plist="Info.plist", + plist_context=plist) + bld.add_post_fun(test1) + + plist = {'bundle_name': 'InterpolatedPlistStringTest'} + plist.update(plist_context) + bld.program( + features="c cprogram", + target="InterpolatedPlistStringTest", + source="src/main.c", + mac_app=True, + mac_plist=plist_string, + plist_context=plist) + bld.add_post_fun(test2) + + bld.program( + features="c cprogram", + target="DefaultPlistTest", + source="src/main.c", + mac_app=True) + bld.add_post_fun(test3) + +def assert_eq(expected, actual): + exception_string = ''' +Expected `{expected}` +but instead got `{actual}` +''' + if (expected != actual): + raise Exception(exception_string.format(expected=expected,actual=actual)) + +def test1(ctx): + expected_plist = {'bundle_name': 'InterpolatedPlistFileTest'} + expected_plist.update(plist_context) + expected_plist.update(expected_dict) + expected_plist = plist_string.format(**expected_plist) + plist = ctx.path.make_node('bin/InterpolatedPlistFileTest.app/Contents/Info.plist').read() + assert_eq(expected_plist, plist) + + +def test2(ctx): + expected_plist = {'bundle_name': 'InterpolatedPlistStringTest'} + expected_plist.update(plist_context) + expected_plist.update(expected_dict) + expected_plist = plist_string.format(**expected_plist) + plist = ctx.path.make_node('bin/InterpolatedPlistStringTest.app/Contents/Info.plist').read() + assert_eq(expected_plist, plist) + +def test3(ctx): + from waflib.Tools import c_osx + expected_plist = {'app_name': 'DefaultPlistTest'} + expected_plist = c_osx.app_info.format(**expected_plist) + plist = ctx.path.make_node('bin/DefaultPlistTest.app/Contents/Info.plist').read() + assert_eq(expected_plist, plist) diff --git a/waflib/Tools/c_osx.py b/waflib/Tools/c_osx.py index a2f62412d4..8eac6c97c5 100644 --- a/waflib/Tools/c_osx.py +++ b/waflib/Tools/c_osx.py @@ -24,7 +24,7 @@ NOTE THIS IS A GENERATED FILE, DO NOT MODIFY CFBundleExecutable - %s + {app_name} ''' @@ -127,6 +127,14 @@ def create_task_macplist(self): dir = self.create_bundle_dirs(name, out) n1 = dir.find_or_declare(['Contents', 'Info.plist']) self.plisttask = plisttask = self.create_task('macplist', [], n1) + plisttask.context = { + 'app_name': self.link_task.outputs[0].name, + 'env': self.env + } + + plist_ctx = getattr(self, 'plist_context', None) + if (plist_ctx): + plisttask.context.update(plist_ctx) if getattr(self, 'mac_plist', False): node = self.path.find_resource(self.mac_plist) @@ -135,7 +143,7 @@ def create_task_macplist(self): else: plisttask.code = self.mac_plist else: - plisttask.code = app_info % self.link_task.outputs[0].name + plisttask.code = app_info inst_to = getattr(self, 'install_path', '/Applications') + '/%s/Contents/' % name self.bld.install_files(inst_to, n1) @@ -184,5 +192,6 @@ def run(self): txt = self.code else: txt = self.inputs[0].read() + context = getattr(self, 'context', {}) + txt = txt.format(**context) self.outputs[0].write(txt) - From dfd6f7e958e181d81960b10918c28bae1d8a5d2d Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Tue, 16 Jun 2015 07:35:46 +0200 Subject: [PATCH 0043/1763] Grey color --- waflib/Logs.py | 1 + 1 file changed, 1 insertion(+) diff --git a/waflib/Logs.py b/waflib/Logs.py index a880719913..1edcfab2ec 100644 --- a/waflib/Logs.py +++ b/waflib/Logs.py @@ -35,6 +35,7 @@ 'PINK' :'\x1b[35m', 'BLUE' :'\x1b[01;34m', 'CYAN' :'\x1b[36m', +'GREY' :'\x1b[37m', 'NORMAL':'\x1b[0m', 'cursor_on' :'\x1b[?25h', 'cursor_off' :'\x1b[?25l', From 57d804c16e4fe7bcc114d6dbc43fa3e30e3e7eaa Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sat, 20 Jun 2015 14:54:41 +0200 Subject: [PATCH 0044/1763] docs --- TODO | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index 94d56e8ffa..e28dfdc7d0 100644 --- a/TODO +++ b/TODO @@ -7,12 +7,12 @@ Waf 1.9 * Ensure _cache.py are valid python files * Include the tool 'nobuild' by default * cflags in the beginning / cppflags at the end +* remove qt4 from the default modules, rework qt5 +* remove the command called "update" Waf 1.8.x --------- -* Update the docs - Can be useful: def bld_command(*k): From 42fb4f08a0b41009c2f2d24c643fe26f2ff5a08c Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sat, 20 Jun 2015 14:55:08 +0200 Subject: [PATCH 0045/1763] Hide the command update that appears in the logs --- waflib/Scripting.py | 1 - 1 file changed, 1 deletion(-) diff --git a/waflib/Scripting.py b/waflib/Scripting.py index 82d0eb0f87..277cc27f5d 100644 --- a/waflib/Scripting.py +++ b/waflib/Scripting.py @@ -564,7 +564,6 @@ def distcheck(ctx): pass def update(ctx): - '''updates the plugins from the *waflib/extras* directory''' lst = Options.options.files.split(',') if not lst: lst = [x for x in Utils.listdir(Context.waf_dir + '/waflib/extras') if x.endswith('.py')] From d761ad1397db52a4d287e1c98c002224b5803dc9 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sat, 20 Jun 2015 22:21:43 +0200 Subject: [PATCH 0046/1763] Better error message when the c compiler is clang and gcc is not found --- waflib/Tools/c_config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/waflib/Tools/c_config.py b/waflib/Tools/c_config.py index 585f9c0ba2..f43354a957 100755 --- a/waflib/Tools/c_config.py +++ b/waflib/Tools/c_config.py @@ -1001,7 +1001,7 @@ def get_cc_version(conf, cc, gcc=False, icc=False, clang=False): if clang and out.find('__clang__') < 0: conf.fatal('Not clang/clang++') if not clang and out.find('__clang__') >= 0: - conf.fatal('Could not find g++, if renamed try eg: CXX=g++48 waf configure') + conf.fatal('Could not find gcc/g++, if renamed try eg: CC=gcc48 CXX=g++48 waf configure') k = {} if icc or gcc or clang: From a336bb1b8b39d401df17b56280fbeae4627d4a65 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sat, 20 Jun 2015 22:24:30 +0200 Subject: [PATCH 0047/1763] waf 1.8.11 --- waf-light | 2 +- waflib/Context.py | 6 +++--- wscript | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/waf-light b/waf-light index b4faa5eb18..de62b2f432 100755 --- a/waf-light +++ b/waf-light @@ -32,7 +32,7 @@ POSSIBILITY OF SUCH DAMAGE. import os, sys, inspect -VERSION="1.8.10" +VERSION="1.8.11" REVISION="x" GIT="x" INSTALL="x" diff --git a/waflib/Context.py b/waflib/Context.py index c818006318..8a1c7a4884 100644 --- a/waflib/Context.py +++ b/waflib/Context.py @@ -11,13 +11,13 @@ import waflib.Node # the following 3 constants are updated on each new release (do not touch) -HEXVERSION=0x1080a00 +HEXVERSION=0x1080b00 """Constant updated on new releases""" -WAFVERSION="1.8.10" +WAFVERSION="1.8.11" """Constant updated on new releases""" -WAFREVISION="ea59b302c53aa18adf7c7048f9e31281dac0e934" +WAFREVISION="d761ad1397db52a4d287e1c98c002224b5803dc9" """Git revision when the waf version is updated""" ABI = 98 diff --git a/wscript b/wscript index d55192863a..1ca1e0fd42 100644 --- a/wscript +++ b/wscript @@ -10,7 +10,7 @@ To add a tool that does not exist in the folder compat15, pass an absolute path: """ -VERSION="1.8.10" +VERSION="1.8.11" APPNAME='waf' REVISION='' From 1debaf5f03f9ef677f2be9de438431ca853e868d Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sat, 20 Jun 2015 23:17:24 +0200 Subject: [PATCH 0048/1763] Better error message when the c compiler is clang and gcc is not found --- waflib/Tools/c_config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/waflib/Tools/c_config.py b/waflib/Tools/c_config.py index f43354a957..e4761ab3bf 100755 --- a/waflib/Tools/c_config.py +++ b/waflib/Tools/c_config.py @@ -1001,7 +1001,7 @@ def get_cc_version(conf, cc, gcc=False, icc=False, clang=False): if clang and out.find('__clang__') < 0: conf.fatal('Not clang/clang++') if not clang and out.find('__clang__') >= 0: - conf.fatal('Could not find gcc/g++, if renamed try eg: CC=gcc48 CXX=g++48 waf configure') + conf.fatal('Could not find gcc/g++ (only Clang), if renamed try eg: CC=gcc48 CXX=g++48 waf configure') k = {} if icc or gcc or clang: From 1ee400aca5671a1f0c2ece636a692e58562f4f4b Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sun, 21 Jun 2015 21:55:12 +0200 Subject: [PATCH 0049/1763] docs --- ChangeLog | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index 576f541072..714738db98 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +NEW IN WAF 1.8.11 +----------------- +* Fortran fixes https://github.com/waf-project/waf/issues/1580 +* Enabled installation of generated .py files +* Fixed the '--threading' option for valac https://github.com/waf-project/waf/issues/1577 +* Shared library compatibility version handling on OSX + NEW IN WAF 1.8.10 ----------------- * Replace cygwin paths in solution files - https://github.com/waf-project/waf/issues/1562 From f7b4940158c393dabb04c3af1cc9db2ca453a796 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sun, 21 Jun 2015 22:43:19 +0200 Subject: [PATCH 0050/1763] docs --- README.md | 2 +- demos/asm/wscript | 2 +- docs/sphinx/conf.py | 2 +- waflib/Tools/errcheck.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 921a9aff46..458f358b93 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,6 @@ Waf is a Python-based framework for configuring, compiling and installing applic Waf is used in particular by innovative companies such as [Avalanche Studios](http://www.avalanchestudios.se) and by open-source projects such as [the Samba project](https://www.samba.org/). Learn more about Waf by reading [The Waf Book](https://waf.io/book/). -For researchers and build system writers, Waf also provides a framework for creating [custom build systems](http://code.google.com/p/waf/source/browse/build_system_kit/) and [package distribution systems](http://code.google.com/p/waf/source/browse/playground/distnet/README.rst). +For researchers and build system writers, Waf also provides a framework for creating [custom build systems](https://github.com/waf-project/waf/tree/master/build_system_kit) and [package distribution systems](https://github.com/waf-project/waf/tree/master/playground/distnet/README.rst). Download the project from our page on [waf.io](https://waf.io/) or from the mirror on [freehackers.org](http://www.freehackers.org/~tnagy/release/). diff --git a/demos/asm/wscript b/demos/asm/wscript index c56e7fe446..6d9e5ea504 100644 --- a/demos/asm/wscript +++ b/demos/asm/wscript @@ -13,7 +13,7 @@ def configure(conf): conf.fatal('this example is for 64-bit systems only') def build(bld): - # http://docs.waf.googlecode.com/git/apidocs_16/tools/asm.html + # https://waf.io/apidocs/tools/asm.html bld.program( source = 'main.c test.S', target = 'asmtest', diff --git a/docs/sphinx/conf.py b/docs/sphinx/conf.py index f2639e7bd8..0eceb0ae07 100644 --- a/docs/sphinx/conf.py +++ b/docs/sphinx/conf.py @@ -348,7 +348,7 @@ def configure(ctx): # built documents. # # The short X.Y version. -#version = '1.8.9' +#version = '1.8.10' # The full version, including alpha/beta/rc tags. #release = version # diff --git a/waflib/Tools/errcheck.py b/waflib/Tools/errcheck.py index 9ac0cafe6c..14ce28fbea 100644 --- a/waflib/Tools/errcheck.py +++ b/waflib/Tools/errcheck.py @@ -64,7 +64,7 @@ def check_task(tsk): if not dupe: for (k, v) in uids.items(): if len(v) > 1: - Logs.error('* Several tasks use the same identifier. Please check the information on\n http://docs.waf.googlecode.com/git/apidocs_16/Task.html#waflib.Task.Task.uid') + Logs.error('* Several tasks use the same identifier. Please check the information on\n https://waf.io/apidocs/Task.html?highlight=uid#waflib.Task.Task.uid') for tsk in v: Logs.error(' - object %r (%r) defined in %r' % (tsk.__class__.__name__, tsk, tsk.generator)) From acf903268766428829e43ed44771876d72648dee Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sun, 21 Jun 2015 23:58:43 +0200 Subject: [PATCH 0051/1763] enable more tests on the build farm --- demos/wscript | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/demos/wscript b/demos/wscript index f9caaffda9..9491bd639b 100644 --- a/demos/wscript +++ b/demos/wscript @@ -21,7 +21,8 @@ from waflib import Logs, Errors PYTHONS = "2.5 2.6 2.7 3.0 3.1 3.2 3.3 3.4".split() DIRS = ['c', 'python'] -#DIRS = [x for x in os.listdir('.') if os.path.isdir(x) and x not in ('variants', 'build', 'mac_app', 'precious')] +if os.environ.get('BUILDFARM', None): + DIRS = [x for x in os.listdir('.') if os.path.isdir(x) and x not in ('variants', 'build', 'mac_app', 'precious')] def options(opt): for d in opt.path.ant_glob(DIRS, excl=['build', 'variants'], src=False, dir=True): From ae508f2f82fbfad4420f7920b6f68a6801e383fd Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Wed, 24 Jun 2015 18:54:03 +0200 Subject: [PATCH 0052/1763] Building in subdirectory broke in 1.8.10 #1590 --- waflib/Scripting.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/waflib/Scripting.py b/waflib/Scripting.py index 277cc27f5d..ba2893e40c 100644 --- a/waflib/Scripting.py +++ b/waflib/Scripting.py @@ -71,7 +71,7 @@ def waf_entry_point(current_directory, version, wafdir): # try to find a lock file (if the project was configured) # at the same time, store the first wscript file seen cur = current_directory - while cur and not Context.run_dir: + while cur and not Context.top_dir: lst = os.listdir(cur) if Options.lockfile in lst: env = ConfigSet.ConfigSet() From c34269bb8cc9a183ecadf5595209eba2a0ffaaaf Mon Sep 17 00:00:00 2001 From: Simon Date: Wed, 24 Jun 2015 19:32:46 +0200 Subject: [PATCH 0053/1763] Initial impl. for Xcode 6 - basic tests --- .gitignore | 25 ++++++++++ demos/xcode/src/class.cpp | 0 demos/xcode/src/test.cpp | 6 +++ demos/xcode/wscript | 13 ++++++ waflib/extras/xcode.py | 98 ++++++++++++++++++++++++++++----------- 5 files changed, 116 insertions(+), 26 deletions(-) create mode 100644 demos/xcode/src/class.cpp create mode 100644 demos/xcode/src/test.cpp create mode 100644 demos/xcode/wscript diff --git a/.gitignore b/.gitignore index 5f7dc13726..1a64b1f836 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,28 @@ demos/*/build* playground/*/build* .waf-* *.log +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + diff --git a/demos/xcode/src/class.cpp b/demos/xcode/src/class.cpp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/demos/xcode/src/test.cpp b/demos/xcode/src/test.cpp new file mode 100644 index 0000000000..6f625bbf66 --- /dev/null +++ b/demos/xcode/src/test.cpp @@ -0,0 +1,6 @@ +#include +int main(int argc, char const *argv[]) +{ + std::cout << "Hello World!"; + return 0; +} \ No newline at end of file diff --git a/demos/xcode/wscript b/demos/xcode/wscript new file mode 100644 index 0000000000..307e892780 --- /dev/null +++ b/demos/xcode/wscript @@ -0,0 +1,13 @@ +from waflib import Task, TaskGen + +top = '.' +out = 'build' + +def configure(opt): + opt.load('cxx') + opt.load('xcode') + +def build(bld): + bld.load('xcode') + bld(source=bld.path.ant_glob('**/*.cpp'), target='Avocada', mac_app=True) + bld(source=bld.path.ant_glob('**/*.cpp'), target='AvocadaFramework', framework=True) \ No newline at end of file diff --git a/waflib/extras/xcode.py b/waflib/extras/xcode.py index 4a975771fa..baaf95c325 100644 --- a/waflib/extras/xcode.py +++ b/waflib/extras/xcode.py @@ -2,6 +2,8 @@ # encoding: utf-8 # XCode 3/XCode 4 generator for Waf # Nicolas Mercier 2011 +# Modified by Simon Warg 2015 +# XCode project file format based on http://www.monobjc.net/xcode-project-file-format.html """ Usage: @@ -50,6 +52,13 @@ def options(opt): ".xib": "text.xib", } +PRODUCT_TYPE_APPLICATION = 'com.apple.product-type.application' +PRODUCT_TYPE_FRAMEWORK = 'com.apple.product-type.framework' +PRODUCT_TYPE_TOOL = 'com.apple.product-type.tool' +PRODUCT_TYPE_LIB_STATIC = 'com.apple.product-type.library.static' +PRODUCT_TYPE_LIB_DYNAMIC = 'com.apple.product-type.library.dynamic' +PRODUCT_TYPE_EXTENSION = 'com.apple.product-type.kernel-extension' +PRODUCT_TYPE_IOKIT = 'com.apple.product-type.kernel-extension.iokit' part1 = 0 part2 = 10000 @@ -140,6 +149,18 @@ def __init__(self, name, path, filetype = '', sourcetree = "SOURCE_ROOT"): self.path = path self.sourceTree = sourcetree +class PBXBuildFile(XCodeNode): + """ This element indicate a file reference that is used in a PBXBuildPhase (either as an include or resource). """ + def __init__(self, fileRef, settings={}): + XCodeNode.__init__(self) + + # fileRef is a reference to a PBXFileReference object + self.fileRef = fileRef + + # A map of key/value pairs for additionnal settings. + self.settings = settings + + class PBXGroup(XCodeNode): def __init__(self, name, sourcetree = ""): XCodeNode.__init__(self) @@ -161,11 +182,28 @@ def folder(n): p.children.append(f) return f for s in sources: - f = folder(s.parent) + # f = folder(s.parent) source = PBXFileReference(s.name, s.abspath()) - f.children.append(source) + self.children.append(source) + # f.children.append(source) + +# Framework sources +class PBXFrameworksBuildPhase(XCodeNode): + """ This is the element for the framework link build phase, i.e. linking to frameworks """ + def __init__(self, pbxbuildfiles): + XCodeNode.__init__(self) + self.buildActionMask = 2147483647 + self.runOnlyForDeploymentPostprocessing = 0 + self.files = pbxbuildfiles #List of PBXBuildFile (.o, .framework, .dylib) +# Compile Sources +class PBXSourcesBuildPhase(XCodeNode): + """ Represents the 'Compile Sources' build phase in a Xcode target """ + def __init__(self, buildfiles): + XCodeNode.__init__(self) + self.files = buildfiles # List of PBXBuildFile objects + # Targets class PBXLegacyTarget(XCodeNode): def __init__(self, action, target=''): @@ -195,17 +233,17 @@ def __init__(self, action, target): self.shellScript = "%s %s %s --targets=%s" % (sys.executable, sys.argv[0], action, target) class PBXNativeTarget(XCodeNode): - def __init__(self, action, target, node, env): + def __init__(self, action, target, node, buildphases, env, product_type=PRODUCT_TYPE_APPLICATION): XCodeNode.__init__(self) - conf = XCBuildConfiguration('waf', {'PRODUCT_NAME':target, 'CONFIGURATION_BUILD_DIR':node.parent.abspath()}, env) + conf = XCBuildConfiguration('Debug', {'PRODUCT_NAME':target, 'CONFIGURATION_BUILD_DIR':node.parent.abspath()}, env) self.buildConfigurationList = XCConfigurationList([conf]) - self.buildPhases = [PBXShellScriptBuildPhase(action, target)] + self.buildPhases = buildphases #[PBXShellScriptBuildPhase(action, target)] self.buildRules = [] self.dependencies = [] self.name = target self.productName = target - self.productType = "com.apple.product-type.application" - self.productReference = PBXFileReference(target, node.abspath(), 'wrapper.application', 'BUILT_PRODUCTS_DIR') + self.productType = product_type + self.productReference = PBXFileReference(target, node.abspath(), 'wrapper.application', 'CONFIGURATION_BUILD_DIR') # Root project object class PBXProject(XCodeNode): @@ -219,7 +257,7 @@ def __init__(self, name, version): self.projectDirPath = "" self.targets = [] self._objectVersion = version[1] - self._output = PBXGroup('out') + self._output = PBXGroup('Products') self.mainGroup.children.append(self._output) def write(self, file): @@ -238,13 +276,9 @@ def write(self, file): w("\trootObject = %s;\n" % self._id) w("}\n") - def add_task_gen(self, tg): - if not getattr(tg, 'mac_app', False): - self.targets.append(PBXLegacyTarget('build', tg.name)) - else: - target = PBXNativeTarget('build', tg.name, tg.link_task.outputs[0].change_ext('.app'), tg.env) - self.targets.append(target) - self._output.children.append(target.productReference) + def add_task_gen(self, target): + self.targets.append(target) + self._output.children.append(target.productReference) class xcode(Build.BuildContext): cmd = 'xcode' @@ -289,22 +323,34 @@ def execute(self): tg.post() - features = Utils.to_list(getattr(tg, 'features', '')) + #features = Utils.to_list(getattr(tg, 'features', '')) + group = PBXGroup(tg.name) group.add(tg.path, self.collect_source(tg)) p.mainGroup.children.append(group) - if 'cprogram' or 'cxxprogram' in features: - p.add_task_gen(tg) - - - # targets that don't produce the executable but that you might want to run - p.targets.append(PBXLegacyTarget('configure')) - p.targets.append(PBXLegacyTarget('dist')) - p.targets.append(PBXLegacyTarget('install')) - p.targets.append(PBXLegacyTarget('check')) - node = self.srcnode.make_node('%s.xcodeproj' % appname) + # if ('cprogram' in features) or ('cxxprogram' in features): + # p.add_task_gen(tg) + + # if not getattr(tg, 'mac_app', False): + # self.targets.append(PBXLegacyTarget('build', tg.name)) + if getattr(tg, 'framework', False): + print "Building framework" + node = tg.path.find_or_declare(tg.name+'.framework') + buildfiles = [PBXBuildFile(fileref) for fileref in group.children] + compilesources = PBXSourcesBuildPhase(buildfiles) + framework = PBXFrameworksBuildPhase(buildfiles) + target = PBXNativeTarget('build', tg.name, node, [compilesources], tg.env, PRODUCT_TYPE_FRAMEWORK) + p.add_task_gen(target) + else: + node = tg.path.find_or_declare(tg.name+'.app') + buildfiles = [PBXBuildFile(fileref) for fileref in group.children] + compilesources = PBXSourcesBuildPhase(buildfiles) + target = PBXNativeTarget('build', tg.name, node, [compilesources], tg.env) + p.add_task_gen(target) + + node = self.bldnode.make_node('%s.xcodeproj' % appname) node.mkdir() node = node.make_node('project.pbxproj') p.write(open(node.abspath(), 'w')) From b5b1d520ad7e86cb12c585008a5996e15e73dd0c Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 25 Jun 2015 00:44:28 +0200 Subject: [PATCH 0054/1763] Added headers search paths and support for other build settings --- demos/xcode/include/MyLib/TestClass.h | 10 ++++++++++ demos/xcode/include/TestClass.h | 10 ++++++++++ demos/xcode/src/MyLib/TestClass.cpp | 5 +++++ demos/xcode/src/class.cpp | 0 demos/xcode/src/test.cpp | 5 ++++- demos/xcode/wscript | 14 ++++++++++++-- waflib/extras/xcode.py | 18 ++++++++++++++++-- 7 files changed, 57 insertions(+), 5 deletions(-) create mode 100644 demos/xcode/include/MyLib/TestClass.h create mode 100644 demos/xcode/include/TestClass.h create mode 100644 demos/xcode/src/MyLib/TestClass.cpp delete mode 100644 demos/xcode/src/class.cpp diff --git a/demos/xcode/include/MyLib/TestClass.h b/demos/xcode/include/MyLib/TestClass.h new file mode 100644 index 0000000000..e987cc04d4 --- /dev/null +++ b/demos/xcode/include/MyLib/TestClass.h @@ -0,0 +1,10 @@ +#include + +class TestClass +{ +public: + TestClass(); + ~TestClass(); + + std::string message(); +}; \ No newline at end of file diff --git a/demos/xcode/include/TestClass.h b/demos/xcode/include/TestClass.h new file mode 100644 index 0000000000..e987cc04d4 --- /dev/null +++ b/demos/xcode/include/TestClass.h @@ -0,0 +1,10 @@ +#include + +class TestClass +{ +public: + TestClass(); + ~TestClass(); + + std::string message(); +}; \ No newline at end of file diff --git a/demos/xcode/src/MyLib/TestClass.cpp b/demos/xcode/src/MyLib/TestClass.cpp new file mode 100644 index 0000000000..80b8e034dd --- /dev/null +++ b/demos/xcode/src/MyLib/TestClass.cpp @@ -0,0 +1,5 @@ +#include "MyLib/TestClass.h" + +std::string TestClass::message() { + return "Hello from TestClass"; +} \ No newline at end of file diff --git a/demos/xcode/src/class.cpp b/demos/xcode/src/class.cpp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/demos/xcode/src/test.cpp b/demos/xcode/src/test.cpp index 6f625bbf66..35ae7eac9d 100644 --- a/demos/xcode/src/test.cpp +++ b/demos/xcode/src/test.cpp @@ -1,6 +1,9 @@ #include +#include "MyLib/TestClass.h" + int main(int argc, char const *argv[]) { - std::cout << "Hello World!"; + TestClass a; + std::cout << a.message(); return 0; } \ No newline at end of file diff --git a/demos/xcode/wscript b/demos/xcode/wscript index 307e892780..587f774bfc 100644 --- a/demos/xcode/wscript +++ b/demos/xcode/wscript @@ -2,6 +2,8 @@ from waflib import Task, TaskGen top = '.' out = 'build' +APPNAME = 'Avocada' +VERSION = '1.0' def configure(opt): opt.load('cxx') @@ -9,5 +11,13 @@ def configure(opt): def build(bld): bld.load('xcode') - bld(source=bld.path.ant_glob('**/*.cpp'), target='Avocada', mac_app=True) - bld(source=bld.path.ant_glob('**/*.cpp'), target='AvocadaFramework', framework=True) \ No newline at end of file + + bld.env.VERSION = '1.0' + bld.env.CONFIG_NAME = 'Debug' + bld.env.ARCHS = 'x86_64' + bld.env.MACOSX_DEPLOYMENT_TARGET = '10.9' + bld.env.SDKROOT = 'macosx10.9' + + bld(source=bld.path.ant_glob('src/MyLib/*.cpp'), includes=bld.path.ant_glob('include/**/*.h', 'include/'), target='MyLib', framework=True) + + bld(source=bld.path.ant_glob('**/*.cpp|'), target='MyApp', mac_app=True) \ No newline at end of file diff --git a/waflib/extras/xcode.py b/waflib/extras/xcode.py index baaf95c325..a589790640 100644 --- a/waflib/extras/xcode.py +++ b/waflib/extras/xcode.py @@ -235,7 +235,20 @@ def __init__(self, action, target): class PBXNativeTarget(XCodeNode): def __init__(self, action, target, node, buildphases, env, product_type=PRODUCT_TYPE_APPLICATION): XCodeNode.__init__(self) - conf = XCBuildConfiguration('Debug', {'PRODUCT_NAME':target, 'CONFIGURATION_BUILD_DIR':node.parent.abspath()}, env) + + buildsettings = env.get_merged_dict() + print env + buildsettings.update({ + 'FRAMEWORK_VERSION': env.VERSION, + 'PRODUCT_NAME':target, + 'CONFIGURATION_BUILD_DIR':node.parent.abspath(), + 'HEADER_SEARCH_PATHS': ' '.join(env.HEADER_SEARCH_PATHS) + }) + + # if not isinstance(buildsettings['HEADER_SEARCH_PATHS'], str): + # buildsettings['HEADER_SEARCH_PATHS'] = ' '.join(buildsettings['HEADER_SEARCH_PATHS']) + + conf = XCBuildConfiguration(env.CONFIG_NAME, buildsettings, env) self.buildConfigurationList = XCConfigurationList([conf]) self.buildPhases = buildphases #[PBXShellScriptBuildPhase(action, target)] self.buildRules = [] @@ -299,6 +312,8 @@ def collect_source(self, tg): lst = [y for y in d.ant_glob(HEADERS_GLOB, flat=False)] include_files.extend(lst) + tg.env.append_value('HEADER_SEARCH_PATHS', [node.parent.abspath() for node in include_files]) + # remove duplicates source = list(set(source_files + plist_files + resource_files + include_files)) source.sort(key=lambda x: x.abspath()) @@ -336,7 +351,6 @@ def execute(self): # if not getattr(tg, 'mac_app', False): # self.targets.append(PBXLegacyTarget('build', tg.name)) if getattr(tg, 'framework', False): - print "Building framework" node = tg.path.find_or_declare(tg.name+'.framework') buildfiles = [PBXBuildFile(fileref) for fileref in group.children] compilesources = PBXSourcesBuildPhase(buildfiles) From 11d85e44eeb122e0fb45177177a3561f1737dd39 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 26 Jun 2015 21:42:02 +0200 Subject: [PATCH 0055/1763] Removed duplicate elements being written --- demos/xcode/wscript | 13 ++++++---- waflib/extras/xcode.py | 54 +++++++++++++++++++++++++++++------------- 2 files changed, 46 insertions(+), 21 deletions(-) diff --git a/demos/xcode/wscript b/demos/xcode/wscript index 587f774bfc..40cf7b559d 100644 --- a/demos/xcode/wscript +++ b/demos/xcode/wscript @@ -1,5 +1,5 @@ from waflib import Task, TaskGen - +from waflib.extras import xcode top = '.' out = 'build' APPNAME = 'Avocada' @@ -18,6 +18,11 @@ def build(bld): bld.env.MACOSX_DEPLOYMENT_TARGET = '10.9' bld.env.SDKROOT = 'macosx10.9' - bld(source=bld.path.ant_glob('src/MyLib/*.cpp'), includes=bld.path.ant_glob('include/**/*.h', 'include/'), target='MyLib', framework=True) - - bld(source=bld.path.ant_glob('**/*.cpp|'), target='MyApp', mac_app=True) \ No newline at end of file + tg = bld(source=bld.path.ant_glob('src/MyLib/*.cpp'), + includes=bld.path.ant_glob('include/**/*.h', 'include/'), + target='MyLib', + target_type=xcode.TARGET_TYPE_FRAMEWORK + ) + # print tg.get_outputs() + # bld(source=bld.path.ant_glob('**/*.cpp|'), includes='include', target='MyApp', target_type=xcode.TARGET_TYPE_APPLICATION, link_framework=['MyLib']) + # print bld.targets \ No newline at end of file diff --git a/waflib/extras/xcode.py b/waflib/extras/xcode.py index a589790640..ea3ac15d78 100644 --- a/waflib/extras/xcode.py +++ b/waflib/extras/xcode.py @@ -52,6 +52,7 @@ def options(opt): ".xib": "text.xib", } +# Used in PBXNativeTarget elements PRODUCT_TYPE_APPLICATION = 'com.apple.product-type.application' PRODUCT_TYPE_FRAMEWORK = 'com.apple.product-type.framework' PRODUCT_TYPE_TOOL = 'com.apple.product-type.tool' @@ -60,6 +61,15 @@ def options(opt): PRODUCT_TYPE_EXTENSION = 'com.apple.product-type.kernel-extension' PRODUCT_TYPE_IOKIT = 'com.apple.product-type.kernel-extension.iokit' +# Used in PBXFileReference elements +FILE_TYPE_APPLICATION = 'wrapper.cfbundle' +FILE_TYPE_FRAMEWORK = 'wrapper.framework' + +TARGET_TYPE_FRAMEWORK = (PRODUCT_TYPE_FRAMEWORK, FILE_TYPE_FRAMEWORK, '.framework') +TARGET_TYPE_APPLICATION = (PRODUCT_TYPE_APPLICATION, FILE_TYPE_APPLICATION, '.app') + +import sys, traceback + part1 = 0 part2 = 10000 part3 = 0 @@ -149,13 +159,20 @@ def __init__(self, name, path, filetype = '', sourcetree = "SOURCE_ROOT"): self.path = path self.sourceTree = sourcetree + # i = 0 + # def write(self, f): + # if self.name == 'MyLib' and self.i == 1: + # pass + # print "HEJ %s" % self.name + # self.i += 1 + class PBXBuildFile(XCodeNode): """ This element indicate a file reference that is used in a PBXBuildPhase (either as an include or resource). """ def __init__(self, fileRef, settings={}): XCodeNode.__init__(self) # fileRef is a reference to a PBXFileReference object - self.fileRef = fileRef + self.fileRef = fileRef._id # A map of key/value pairs for additionnal settings. self.settings = settings @@ -183,6 +200,7 @@ def folder(n): return f for s in sources: # f = folder(s.parent) + source = PBXFileReference(s.name, s.abspath()) self.children.append(source) # f.children.append(source) @@ -233,11 +251,10 @@ def __init__(self, action, target): self.shellScript = "%s %s %s --targets=%s" % (sys.executable, sys.argv[0], action, target) class PBXNativeTarget(XCodeNode): - def __init__(self, action, target, node, buildphases, env, product_type=PRODUCT_TYPE_APPLICATION): + def __init__(self, action, target, node, buildphases, env, target_type=TARGET_TYPE_APPLICATION): XCodeNode.__init__(self) buildsettings = env.get_merged_dict() - print env buildsettings.update({ 'FRAMEWORK_VERSION': env.VERSION, 'PRODUCT_NAME':target, @@ -245,8 +262,8 @@ def __init__(self, action, target, node, buildphases, env, product_type=PRODUCT_ 'HEADER_SEARCH_PATHS': ' '.join(env.HEADER_SEARCH_PATHS) }) - # if not isinstance(buildsettings['HEADER_SEARCH_PATHS'], str): - # buildsettings['HEADER_SEARCH_PATHS'] = ' '.join(buildsettings['HEADER_SEARCH_PATHS']) + product_type = target_type[0] + file_type = target_type[1] conf = XCBuildConfiguration(env.CONFIG_NAME, buildsettings, env) self.buildConfigurationList = XCConfigurationList([conf]) @@ -255,8 +272,8 @@ def __init__(self, action, target, node, buildphases, env, product_type=PRODUCT_ self.dependencies = [] self.name = target self.productName = target - self.productType = product_type - self.productReference = PBXFileReference(target, node.abspath(), 'wrapper.application', 'CONFIGURATION_BUILD_DIR') + self.productType = product_type # See TARGET_TYPE_ tuples constants + self.productReference = PBXFileReference(target, node.abspath(), file_type, 'CONFIGURATION_BUILD_DIR') # Root project object class PBXProject(XCodeNode): @@ -291,7 +308,7 @@ def write(self, file): def add_task_gen(self, target): self.targets.append(target) - self._output.children.append(target.productReference) + self._output.children.append(target.productReference._id) class xcode(Build.BuildContext): cmd = 'xcode' @@ -350,23 +367,26 @@ def execute(self): # if not getattr(tg, 'mac_app', False): # self.targets.append(PBXLegacyTarget('build', tg.name)) - if getattr(tg, 'framework', False): - node = tg.path.find_or_declare(tg.name+'.framework') + if hasattr(tg, 'target_type'): + file_ext = tg.target_type[2] + node = tg.path.find_or_declare(tg.name+file_ext) buildfiles = [PBXBuildFile(fileref) for fileref in group.children] compilesources = PBXSourcesBuildPhase(buildfiles) framework = PBXFrameworksBuildPhase(buildfiles) - target = PBXNativeTarget('build', tg.name, node, [compilesources], tg.env, PRODUCT_TYPE_FRAMEWORK) - p.add_task_gen(target) - else: - node = tg.path.find_or_declare(tg.name+'.app') - buildfiles = [PBXBuildFile(fileref) for fileref in group.children] - compilesources = PBXSourcesBuildPhase(buildfiles) - target = PBXNativeTarget('build', tg.name, node, [compilesources], tg.env) + target = PBXNativeTarget('build', tg.name, node, [compilesources], tg.env, tg.target_type) + # p.mainGroup.children.append(PBXBuildFile(target.productReference)) p.add_task_gen(target) + # else: + # node = tg.path.find_or_declare(tg.name+file_ext) + # buildfiles = [PBXBuildFile(fileref) for fileref in group.children] + # compilesources = PBXSourcesBuildPhase(buildfiles) + # target = PBXNativeTarget('build', tg.name, node, [compilesources], tg.env) + # p.add_task_gen(target) node = self.bldnode.make_node('%s.xcodeproj' % appname) node.mkdir() node = node.make_node('project.pbxproj') + print "POP" p.write(open(node.abspath(), 'w')) From 616dd559ecb52003add838f3412d1d048bac04b8 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 26 Jun 2015 23:16:37 +0200 Subject: [PATCH 0056/1763] Added ID print wrapper --- waflib/extras/xcode.py | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/waflib/extras/xcode.py b/waflib/extras/xcode.py index ea3ac15d78..5fbbdb8ff5 100644 --- a/waflib/extras/xcode.py +++ b/waflib/extras/xcode.py @@ -126,6 +126,11 @@ def write(self, file): w("\t\t%s = %s;\n" % (attribute, self.tostring(value))) w("\t};\n\n") +class XCID(XCodeNode): + def __init__(self, id): + self._id = id + def write(self, file): + pass # Configurations @@ -159,20 +164,13 @@ def __init__(self, name, path, filetype = '', sourcetree = "SOURCE_ROOT"): self.path = path self.sourceTree = sourcetree - # i = 0 - # def write(self, f): - # if self.name == 'MyLib' and self.i == 1: - # pass - # print "HEJ %s" % self.name - # self.i += 1 - class PBXBuildFile(XCodeNode): """ This element indicate a file reference that is used in a PBXBuildPhase (either as an include or resource). """ def __init__(self, fileRef, settings={}): XCodeNode.__init__(self) # fileRef is a reference to a PBXFileReference object - self.fileRef = fileRef._id + self.fileRef = XCID(fileRef._id) # A map of key/value pairs for additionnal settings. self.settings = settings @@ -308,7 +306,7 @@ def write(self, file): def add_task_gen(self, target): self.targets.append(target) - self._output.children.append(target.productReference._id) + # self._output.children.append(target.productReference._id) class xcode(Build.BuildContext): cmd = 'xcode' @@ -374,8 +372,8 @@ def execute(self): compilesources = PBXSourcesBuildPhase(buildfiles) framework = PBXFrameworksBuildPhase(buildfiles) target = PBXNativeTarget('build', tg.name, node, [compilesources], tg.env, tg.target_type) - # p.mainGroup.children.append(PBXBuildFile(target.productReference)) p.add_task_gen(target) + # p.mainGroup.children.append(PBXBuildFile(target.productReference)) # else: # node = tg.path.find_or_declare(tg.name+file_ext) # buildfiles = [PBXBuildFile(fileref) for fileref in group.children] @@ -386,7 +384,6 @@ def execute(self): node = self.bldnode.make_node('%s.xcodeproj' % appname) node.mkdir() node = node.make_node('project.pbxproj') - print "POP" p.write(open(node.abspath(), 'w')) From f8a3d567755a1f328eb265872248d592c6ef63f1 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sat, 27 Jun 2015 12:41:16 +0200 Subject: [PATCH 0057/1763] Preparations for Waf 1.8.12 --- ChangeLog | 4 ++++ waf-light | 2 +- waflib/Context.py | 6 +++--- wscript | 2 +- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 714738db98..f093bf99f8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +NEW IN WAF 1.8.12 +----------------- +* Fixed a regression when building in sub-folders - https://github.com/waf-project/waf/issues/1590 + NEW IN WAF 1.8.11 ----------------- * Fortran fixes https://github.com/waf-project/waf/issues/1580 diff --git a/waf-light b/waf-light index de62b2f432..0633844951 100755 --- a/waf-light +++ b/waf-light @@ -32,7 +32,7 @@ POSSIBILITY OF SUCH DAMAGE. import os, sys, inspect -VERSION="1.8.11" +VERSION="1.8.12" REVISION="x" GIT="x" INSTALL="x" diff --git a/waflib/Context.py b/waflib/Context.py index 8a1c7a4884..5d9945cc98 100644 --- a/waflib/Context.py +++ b/waflib/Context.py @@ -11,13 +11,13 @@ import waflib.Node # the following 3 constants are updated on each new release (do not touch) -HEXVERSION=0x1080b00 +HEXVERSION=0x1080c00 """Constant updated on new releases""" -WAFVERSION="1.8.11" +WAFVERSION="1.8.12" """Constant updated on new releases""" -WAFREVISION="d761ad1397db52a4d287e1c98c002224b5803dc9" +WAFREVISION="ae508f2f82fbfad4420f7920b6f68a6801e383fd" """Git revision when the waf version is updated""" ABI = 98 diff --git a/wscript b/wscript index 1ca1e0fd42..cfe627f374 100644 --- a/wscript +++ b/wscript @@ -10,7 +10,7 @@ To add a tool that does not exist in the folder compat15, pass an absolute path: """ -VERSION="1.8.11" +VERSION="1.8.12" APPNAME='waf' REVISION='' From a946ca8383c69836bbe52c2004e6220f55e807c3 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sat, 27 Jun 2015 14:03:04 +0200 Subject: [PATCH 0058/1763] Removed the executable bit on c_config.py --- waflib/Tools/c_config.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 waflib/Tools/c_config.py diff --git a/waflib/Tools/c_config.py b/waflib/Tools/c_config.py old mode 100755 new mode 100644 From 705404211adf9133a75042bd4c37d85fd56be87c Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sat, 27 Jun 2015 14:04:36 +0200 Subject: [PATCH 0059/1763] Removed the unnecessary executable bit on files --- waflib/extras/nobuild.py | 0 waflib/extras/preforkjava.py | 0 waflib/extras/preforkunix.py | 0 3 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 waflib/extras/nobuild.py mode change 100755 => 100644 waflib/extras/preforkjava.py mode change 100755 => 100644 waflib/extras/preforkunix.py diff --git a/waflib/extras/nobuild.py b/waflib/extras/nobuild.py old mode 100755 new mode 100644 diff --git a/waflib/extras/preforkjava.py b/waflib/extras/preforkjava.py old mode 100755 new mode 100644 diff --git a/waflib/extras/preforkunix.py b/waflib/extras/preforkunix.py old mode 100755 new mode 100644 From 933feab352f11179e63b17f762648d307d26e68d Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sat, 27 Jun 2015 15:18:57 +0200 Subject: [PATCH 0060/1763] Glob mac_app resource trees - Issue 1586 --- demos/mac_app/wscript | 17 +++++++++-------- waflib/Tools/c_osx.py | 17 ++++++++++++++++- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/demos/mac_app/wscript b/demos/mac_app/wscript index a244b54845..0cb9c5fff6 100644 --- a/demos/mac_app/wscript +++ b/demos/mac_app/wscript @@ -25,14 +25,15 @@ def configure(conf): def build(bld): bld.program( - features = 'c cprogram', - target = 'MacApp', - source = 'sources/main.m', - mac_app = True, - mac_plist = 'Info.plist', - mac_resources = 'resources/MainMenu.nib resources/MacApp.icns', - use = 'COCOA', - install_path = '${PREFIX}', + features = 'c cprogram', + target = 'MacApp', + source = 'sources/main.m', + mac_app = True, + mac_plist = 'Info.plist', + mac_files = bld.path.ant_glob('resources/**'), + mac_files_root = 'resources', + use = 'COCOA', + install_path = '${PREFIX}', ) return diff --git a/waflib/Tools/c_osx.py b/waflib/Tools/c_osx.py index 8eac6c97c5..2b3c647498 100644 --- a/waflib/Tools/c_osx.py +++ b/waflib/Tools/c_osx.py @@ -71,7 +71,7 @@ def create_task_macapp(self): To compile an executable into a Mac application (a .app), set its *mac_app* attribute:: def build(bld): - bld.shlib(source='a.c', target='foo', mac_app = True) + bld.shlib(source='a.c', target='foo', mac_app=True) To force *all* executables to be transformed into Mac applications:: @@ -91,7 +91,22 @@ def build(bld): inst_to = getattr(self, 'install_path', '/Applications') + '/%s/Contents/MacOS/' % name self.bld.install_files(inst_to, n1, chmod=Utils.O755) + if getattr(self, 'mac_files', None): + # this only accepts files; they will be installed as seen from mac_files_root + mac_files_root = getattr(self, 'mac_files_root', None) + if isinstance(mac_files_root, str): + mac_files_root = self.path.find_node(mac_files_root) + if not mac_files_root: + self.bld.fatal('Invalid mac_files_root %r' % self.mac_files_root) + res_dir = n1.parent.parent.make_node('Resources') + 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.bld.install_as(os.path.join(inst_to, relpath), node) + if getattr(self, 'mac_resources', None): + # TODO remove in waf 1.9 res_dir = n1.parent.parent.make_node('Resources') inst_to = getattr(self, 'install_path', '/Applications') + '/%s/Resources' % name for x in self.to_list(self.mac_resources): From 03a510f4801084a96317bec893da0eeafd276162 Mon Sep 17 00:00:00 2001 From: Sean Bartell Date: Sun, 28 Jun 2015 14:59:49 -0500 Subject: [PATCH 0061/1763] Fix exec_command and cmd_and_log when cmd is tuple --- waflib/Context.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/waflib/Context.py b/waflib/Context.py index 5d9945cc98..fe733e4d2d 100644 --- a/waflib/Context.py +++ b/waflib/Context.py @@ -325,7 +325,7 @@ def run(tsk): """ subprocess = Utils.subprocess kw['shell'] = isinstance(cmd, str) - Logs.debug('runner: %r' % cmd) + Logs.debug('runner: %r' % (cmd,)) Logs.debug('runner_env: kw=%s' % kw) if self.logger: @@ -386,7 +386,7 @@ def configure(conf): """ subprocess = Utils.subprocess kw['shell'] = isinstance(cmd, str) - Logs.debug('runner: %r' % cmd) + Logs.debug('runner: %r' % (cmd,)) if 'quiet' in kw: quiet = kw['quiet'] From ce6a58cd5f662f34d38810cb2582603c2e914758 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 29 Jun 2015 18:31:37 +0200 Subject: [PATCH 0062/1763] Removed recusive writing --- waflib/extras/xcode.py | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/waflib/extras/xcode.py b/waflib/extras/xcode.py index 5fbbdb8ff5..c05ba18916 100644 --- a/waflib/extras/xcode.py +++ b/waflib/extras/xcode.py @@ -68,8 +68,6 @@ def options(opt): TARGET_TYPE_FRAMEWORK = (PRODUCT_TYPE_FRAMEWORK, FILE_TYPE_FRAMEWORK, '.framework') TARGET_TYPE_APPLICATION = (PRODUCT_TYPE_APPLICATION, FILE_TYPE_APPLICATION, '.app') -import sys, traceback - part1 = 0 part2 = 10000 part3 = 0 @@ -114,9 +112,9 @@ def write_recursive(self, value, file): value.write(file) def write(self, file): - for attribute,value in self.__dict__.items(): - if attribute[0] != '_': - self.write_recursive(value, file) + # for attribute,value in self.__dict__.items(): + # if attribute[0] != '_': + # self.write_recursive(value, file) w = file.write w("\t%s = {\n" % self._id) @@ -196,6 +194,8 @@ def folder(n): folders[n] = f p.children.append(f) return f + self.children.extend(sources) + return for s in sources: # f = folder(s.parent) @@ -277,7 +277,8 @@ def __init__(self, action, target, node, buildphases, env, target_type=TARGET_TY class PBXProject(XCodeNode): def __init__(self, name, version): XCodeNode.__init__(self) - self.buildConfigurationList = XCConfigurationList([XCBuildConfiguration('waf', {})]) + build_config = XCBuildConfiguration('waf', {}) + self.buildConfigurationList = XCConfigurationList([build_config]) self.compatibilityVersion = version[0] self.hasScannedForEncodings = 1; self.mainGroup = PBXGroup(name) @@ -286,8 +287,16 @@ def __init__(self, name, version): self.targets = [] self._objectVersion = version[1] self._output = PBXGroup('Products') + self._XCNodes_to_write = [self.mainGroup, self._output, build_config, self.buildConfigurationList] self.mainGroup.children.append(self._output) + def write_xnode(self, node): + if isinstance(node, list): + for node_ in node: + self._XCNodes_to_write.append(node_) + else: + self._XCNodes_to_write.append(node) + def write(self, file): w = file.write w("// !$*UTF8*$!\n") @@ -298,6 +307,9 @@ def write(self, file): w("\tobjectVersion = %d;\n" % self._objectVersion) w("\tobjects = {\n\n") + for n in self._XCNodes_to_write: + n.write(file) + XCodeNode.write(self, file) w("\t};\n") @@ -306,6 +318,7 @@ def write(self, file): def add_task_gen(self, target): self.targets.append(target) + self.write_xnode(target) # self._output.children.append(target.productReference._id) class xcode(Build.BuildContext): @@ -355,10 +368,12 @@ def execute(self): #features = Utils.to_list(getattr(tg, 'features', '')) - + sources = [PBXFileReference(n.name, n.abspath()) for n in self.collect_source(tg)] group = PBXGroup(tg.name) - group.add(tg.path, self.collect_source(tg)) + group.add(tg.path, sources) p.mainGroup.children.append(group) + p.write_xnode(group) + p.write_xnode(sources) # if ('cprogram' in features) or ('cxxprogram' in features): # p.add_task_gen(tg) @@ -370,6 +385,8 @@ def execute(self): node = tg.path.find_or_declare(tg.name+file_ext) buildfiles = [PBXBuildFile(fileref) for fileref in group.children] compilesources = PBXSourcesBuildPhase(buildfiles) + p.write_xnode(buildfiles) + p.write_xnode(compilesources) framework = PBXFrameworksBuildPhase(buildfiles) target = PBXNativeTarget('build', tg.name, node, [compilesources], tg.env, tg.target_type) p.add_task_gen(target) From 19473a072135f4504243c75feab0587d0ab565a2 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Thu, 2 Jul 2015 20:52:41 +0200 Subject: [PATCH 0063/1763] env = conf.env.derive().detach() --- waflib/ConfigSet.py | 1 + 1 file changed, 1 insertion(+) diff --git a/waflib/ConfigSet.py b/waflib/ConfigSet.py index de0c3aeecf..2fac2166e2 100644 --- a/waflib/ConfigSet.py +++ b/waflib/ConfigSet.py @@ -167,6 +167,7 @@ def detach(self): for x in keys: tbl[x] = copy.deepcopy(tbl[x]) self.table = tbl + return self def get_flat(self, key): """ From 7992473f7dbf9ccef98563c4c2a1f19e3cafd5dc Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 3 Jul 2015 21:16:27 +0200 Subject: [PATCH 0064/1763] Found out and made some fixes to parent build configurations --- demos/xcode/wscript | 10 ++-- waflib/extras/xcode.py | 125 +++++++++++++++++++++-------------------- 2 files changed, 70 insertions(+), 65 deletions(-) diff --git a/demos/xcode/wscript b/demos/xcode/wscript index 40cf7b559d..00e51d03b2 100644 --- a/demos/xcode/wscript +++ b/demos/xcode/wscript @@ -13,16 +13,18 @@ def build(bld): bld.load('xcode') bld.env.VERSION = '1.0' - bld.env.CONFIG_NAME = 'Debug' + bld.env.FRAMEWORK_VERSION = '1.0' + bld.env.CONFIG_NAME = 'Kuk' bld.env.ARCHS = 'x86_64' bld.env.MACOSX_DEPLOYMENT_TARGET = '10.9' bld.env.SDKROOT = 'macosx10.9' + # bld.env.CONFIGURATION_BUILD_DIR = '/test/path' tg = bld(source=bld.path.ant_glob('src/MyLib/*.cpp'), includes=bld.path.ant_glob('include/**/*.h', 'include/'), target='MyLib', target_type=xcode.TARGET_TYPE_FRAMEWORK ) - # print tg.get_outputs() - # bld(source=bld.path.ant_glob('**/*.cpp|'), includes='include', target='MyApp', target_type=xcode.TARGET_TYPE_APPLICATION, link_framework=['MyLib']) - # print bld.targets \ No newline at end of file + + bld(source=bld.path.ant_glob('**/*.cpp|'), includes='include', target='MyApp', target_type=xcode.TARGET_TYPE_APPLICATION, link_framework=['MyLib']) + \ No newline at end of file diff --git a/waflib/extras/xcode.py b/waflib/extras/xcode.py index c05ba18916..887b52f47d 100644 --- a/waflib/extras/xcode.py +++ b/waflib/extras/xcode.py @@ -16,7 +16,7 @@ def options(opt): # TODO: support iOS projects -from waflib import Context, TaskGen, Build, Utils +from waflib import Context, TaskGen, Build, Utils, ConfigSet import os, sys, random, time HEADERS_GLOB = '**/(*.h|*.hpp|*.H|*.inl)' @@ -80,6 +80,7 @@ def newid(): class XCodeNode: def __init__(self): self._id = newid() + self._been_written = False def tostring(self, value): if isinstance(value, dict): @@ -112,17 +113,18 @@ def write_recursive(self, value, file): value.write(file) def write(self, file): - # for attribute,value in self.__dict__.items(): - # if attribute[0] != '_': - # self.write_recursive(value, file) - - w = file.write - w("\t%s = {\n" % self._id) - w("\t\tisa = %s;\n" % self.__class__.__name__) for attribute,value in self.__dict__.items(): if attribute[0] != '_': - w("\t\t%s = %s;\n" % (attribute, self.tostring(value))) - w("\t};\n\n") + self.write_recursive(value, file) + if not self._been_written: + w = file.write + w("\t%s = {\n" % self._id) + w("\t\tisa = %s;\n" % self.__class__.__name__) + for attribute,value in self.__dict__.items(): + if attribute[0] != '_': + w("\t\t%s = %s;\n" % (attribute, self.tostring(value))) + w("\t};\n\n") + self._been_written = True class XCID(XCodeNode): def __init__(self, id): @@ -168,7 +170,7 @@ def __init__(self, fileRef, settings={}): XCodeNode.__init__(self) # fileRef is a reference to a PBXFileReference object - self.fileRef = XCID(fileRef._id) + self.fileRef = fileRef # A map of key/value pairs for additionnal settings. self.settings = settings @@ -249,36 +251,30 @@ def __init__(self, action, target): self.shellScript = "%s %s %s --targets=%s" % (sys.executable, sys.argv[0], action, target) class PBXNativeTarget(XCodeNode): - def __init__(self, action, target, node, buildphases, env, target_type=TARGET_TYPE_APPLICATION): + def __init__(self, action, target, node, buildphases, configlist, target_type=TARGET_TYPE_APPLICATION): XCodeNode.__init__(self) - buildsettings = env.get_merged_dict() - buildsettings.update({ - 'FRAMEWORK_VERSION': env.VERSION, - 'PRODUCT_NAME':target, - 'CONFIGURATION_BUILD_DIR':node.parent.abspath(), - 'HEADER_SEARCH_PATHS': ' '.join(env.HEADER_SEARCH_PATHS) - }) - product_type = target_type[0] file_type = target_type[1] - conf = XCBuildConfiguration(env.CONFIG_NAME, buildsettings, env) - self.buildConfigurationList = XCConfigurationList([conf]) + # conf = XCBuildConfiguration(env.CONFIG_NAME, env.get_merged_dict(), env) + self.buildConfigurationList = configlist self.buildPhases = buildphases #[PBXShellScriptBuildPhase(action, target)] self.buildRules = [] self.dependencies = [] self.name = target self.productName = target self.productType = product_type # See TARGET_TYPE_ tuples constants - self.productReference = PBXFileReference(target, node.abspath(), file_type, 'CONFIGURATION_BUILD_DIR') + print node.abspath() + self.productReference = PBXFileReference(target, node.abspath(), file_type, '') # Root project object class PBXProject(XCodeNode): - def __init__(self, name, version): + def __init__(self, name, version, buildsettings): XCodeNode.__init__(self) - build_config = XCBuildConfiguration('waf', {}) - self.buildConfigurationList = XCConfigurationList([build_config]) + cf_debug = XCBuildConfiguration('Debug', buildsettings) + cf_release = XCBuildConfiguration('Release', buildsettings) + self.buildConfigurationList = XCConfigurationList([cf_debug, cf_release]) self.compatibilityVersion = version[0] self.hasScannedForEncodings = 1; self.mainGroup = PBXGroup(name) @@ -286,16 +282,8 @@ def __init__(self, name, version): self.projectDirPath = "" self.targets = [] self._objectVersion = version[1] - self._output = PBXGroup('Products') - self._XCNodes_to_write = [self.mainGroup, self._output, build_config, self.buildConfigurationList] - self.mainGroup.children.append(self._output) - - def write_xnode(self, node): - if isinstance(node, list): - for node_ in node: - self._XCNodes_to_write.append(node_) - else: - self._XCNodes_to_write.append(node) + self._output = {} + # self.mainGroup.children.append(self._output) def write(self, file): w = file.write @@ -307,9 +295,6 @@ def write(self, file): w("\tobjectVersion = %d;\n" % self._objectVersion) w("\tobjects = {\n\n") - for n in self._XCNodes_to_write: - n.write(file) - XCodeNode.write(self, file) w("\t};\n") @@ -318,7 +303,7 @@ def write(self, file): def add_task_gen(self, target): self.targets.append(target) - self.write_xnode(target) + self._output[target.name] = PBXBuildFile(target.productReference) # self._output.children.append(target.productReference._id) class xcode(Build.BuildContext): @@ -340,7 +325,7 @@ def collect_source(self, tg): lst = [y for y in d.ant_glob(HEADERS_GLOB, flat=False)] include_files.extend(lst) - tg.env.append_value('HEADER_SEARCH_PATHS', [node.parent.abspath() for node in include_files]) + # tg.env.append_value('HEADER_SEARCH_PATHS', [node.parent.abspath() for node in include_files]) # remove duplicates source = list(set(source_files + plist_files + resource_files + include_files)) @@ -357,7 +342,11 @@ def execute(self): self.recurse([self.run_dir]) appname = getattr(Context.g_module, Context.APPNAME, os.path.basename(self.srcnode.abspath())) - p = PBXProject(appname, ('Xcode 3.2', 46)) + + buildsettings = self.env.get_merged_dict() + buildsettings.update() + + p = PBXProject(appname, ('Xcode 3.2', 46), buildsettings) for g in self.groups: for tg in g: @@ -366,38 +355,52 @@ def execute(self): tg.post() - #features = Utils.to_list(getattr(tg, 'features', '')) + include_dirs = Utils.to_list(getattr(tg, 'includes', [])) + include_dirs_ = [] + for x in include_dirs: + if not isinstance(x, str): + d = x + else: + d = tg.path.find_node(x) + include_dirs_.append(d.parent.abspath()) + tg.env.append_value('HEADER_SEARCH_PATHS', include_dirs_) sources = [PBXFileReference(n.name, n.abspath()) for n in self.collect_source(tg)] group = PBXGroup(tg.name) group.add(tg.path, sources) p.mainGroup.children.append(group) - p.write_xnode(group) - p.write_xnode(sources) - # if ('cprogram' in features) or ('cxxprogram' in features): - # p.add_task_gen(tg) + buildsettings = tg.env.get_merged_dict() + buildsettings.update({ + 'FRAMEWORK_VERSION': self.env.VERSION, + 'PRODUCT_NAME':tg.name + }) + + if hasattr(tg, 'settings') and isinstance(tg.settings, dict): + buildsettings.update(buildsettings) - # if not getattr(tg, 'mac_app', False): - # self.targets.append(PBXLegacyTarget('build', tg.name)) + target_type = TARGET_TYPE_APPLICATION if hasattr(tg, 'target_type'): file_ext = tg.target_type[2] node = tg.path.find_or_declare(tg.name+file_ext) buildfiles = [PBXBuildFile(fileref) for fileref in group.children] compilesources = PBXSourcesBuildPhase(buildfiles) - p.write_xnode(buildfiles) - p.write_xnode(compilesources) - framework = PBXFrameworksBuildPhase(buildfiles) - target = PBXNativeTarget('build', tg.name, node, [compilesources], tg.env, tg.target_type) - p.add_task_gen(target) - # p.mainGroup.children.append(PBXBuildFile(target.productReference)) - # else: - # node = tg.path.find_or_declare(tg.name+file_ext) - # buildfiles = [PBXBuildFile(fileref) for fileref in group.children] - # compilesources = PBXSourcesBuildPhase(buildfiles) - # target = PBXNativeTarget('build', tg.name, node, [compilesources], tg.env) - # p.add_task_gen(target) + buildphases = [compilesources] + + framework = getattr(tg, 'link_framework', []) + for fw in framework: + if fw and fw in p._output: + print tg + fw = PBXFrameworksBuildPhase([p._output[fw]]) + buildphases.append(fw) + + cf = XCBuildConfiguration('Debug', {"CONFIG_NAME": "Fitta"}) + cflst = XCConfigurationList([cf]) + target = PBXNativeTarget('build', tg.name, node, buildphases, cflst, tg.target_type) + + p.add_task_gen(target) + node = self.bldnode.make_node('%s.xcodeproj' % appname) node.mkdir() node = node.make_node('project.pbxproj') From 2424b81f30e9b8de7d9ea257263bec15cba4c4ec Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 3 Jul 2015 23:41:05 +0200 Subject: [PATCH 0065/1763] Clean-up --- demos/xcode/include/MyLib/TestClass.h | 3 - demos/xcode/include/TestClass.h | 10 ---- demos/xcode/wscript | 27 +++++---- waflib/extras/xcode.py | 83 +++++++++++++-------------- 4 files changed, 56 insertions(+), 67 deletions(-) delete mode 100644 demos/xcode/include/TestClass.h diff --git a/demos/xcode/include/MyLib/TestClass.h b/demos/xcode/include/MyLib/TestClass.h index e987cc04d4..73f087caf9 100644 --- a/demos/xcode/include/MyLib/TestClass.h +++ b/demos/xcode/include/MyLib/TestClass.h @@ -3,8 +3,5 @@ class TestClass { public: - TestClass(); - ~TestClass(); - std::string message(); }; \ No newline at end of file diff --git a/demos/xcode/include/TestClass.h b/demos/xcode/include/TestClass.h deleted file mode 100644 index e987cc04d4..0000000000 --- a/demos/xcode/include/TestClass.h +++ /dev/null @@ -1,10 +0,0 @@ -#include - -class TestClass -{ -public: - TestClass(); - ~TestClass(); - - std::string message(); -}; \ No newline at end of file diff --git a/demos/xcode/wscript b/demos/xcode/wscript index 00e51d03b2..58339486ec 100644 --- a/demos/xcode/wscript +++ b/demos/xcode/wscript @@ -8,23 +8,28 @@ VERSION = '1.0' def configure(opt): opt.load('cxx') opt.load('xcode') + opt.env.FRAMEWORK_VERSION = '1.0' + opt.env.CONFIG_NAME = 'Kuk' + opt.env.ARCHS = 'x86_64' + opt.env.MACOSX_DEPLOYMENT_TARGET = '10.9' + opt.env.SDKROOT = 'macosx10.9' + opt.env.PRODUCT_NAME = '$(TARGET_NAME)' def build(bld): bld.load('xcode') - bld.env.VERSION = '1.0' - bld.env.FRAMEWORK_VERSION = '1.0' - bld.env.CONFIG_NAME = 'Kuk' - bld.env.ARCHS = 'x86_64' - bld.env.MACOSX_DEPLOYMENT_TARGET = '10.9' - bld.env.SDKROOT = 'macosx10.9' - # bld.env.CONFIGURATION_BUILD_DIR = '/test/path' - - tg = bld(source=bld.path.ant_glob('src/MyLib/*.cpp'), - includes=bld.path.ant_glob('include/**/*.h', 'include/'), + tg = bld( + source=bld.path.ant_glob('src/MyLib/*.cpp'), + includes=['include'], target='MyLib', target_type=xcode.TARGET_TYPE_FRAMEWORK ) - bld(source=bld.path.ant_glob('**/*.cpp|'), includes='include', target='MyApp', target_type=xcode.TARGET_TYPE_APPLICATION, link_framework=['MyLib']) + bld(source=bld.path.ant_glob('src/*.cpp|'), + includes=tg.includes, + target='MyApp', + target_type=xcode.TARGET_TYPE_APPLICATION, + link_framework=['MyLib'], + settings={"Debug": {"CONFIG_NAME": 'Debug'}} + ) \ No newline at end of file diff --git a/waflib/extras/xcode.py b/waflib/extras/xcode.py index 887b52f47d..4c1f459ef1 100644 --- a/waflib/extras/xcode.py +++ b/waflib/extras/xcode.py @@ -251,21 +251,19 @@ def __init__(self, action, target): self.shellScript = "%s %s %s --targets=%s" % (sys.executable, sys.argv[0], action, target) class PBXNativeTarget(XCodeNode): - def __init__(self, action, target, node, buildphases, configlist, target_type=TARGET_TYPE_APPLICATION): + def __init__(self, target, node, buildphases, configlist, target_type=TARGET_TYPE_APPLICATION): XCodeNode.__init__(self) product_type = target_type[0] file_type = target_type[1] - # conf = XCBuildConfiguration(env.CONFIG_NAME, env.get_merged_dict(), env) self.buildConfigurationList = configlist - self.buildPhases = buildphases #[PBXShellScriptBuildPhase(action, target)] + self.buildPhases = buildphases self.buildRules = [] self.dependencies = [] self.name = target self.productName = target self.productType = product_type # See TARGET_TYPE_ tuples constants - print node.abspath() self.productReference = PBXFileReference(target, node.abspath(), file_type, '') # Root project object @@ -283,7 +281,6 @@ def __init__(self, name, version, buildsettings): self.targets = [] self._objectVersion = version[1] self._output = {} - # self.mainGroup.children.append(self._output) def write(self, file): w = file.write @@ -304,7 +301,6 @@ def write(self, file): def add_task_gen(self, target): self.targets.append(target) self._output[target.name] = PBXBuildFile(target.productReference) - # self._output.children.append(target.productReference._id) class xcode(Build.BuildContext): cmd = 'xcode' @@ -325,8 +321,6 @@ def collect_source(self, tg): lst = [y for y in d.ant_glob(HEADERS_GLOB, flat=False)] include_files.extend(lst) - # tg.env.append_value('HEADER_SEARCH_PATHS', [node.parent.abspath() for node in include_files]) - # remove duplicates source = list(set(source_files + plist_files + resource_files + include_files)) source.sort(key=lambda x: x.abspath()) @@ -355,6 +349,39 @@ def execute(self): tg.post() + + sources = [PBXFileReference(n.name, n.abspath()) for n in self.collect_source(tg)] + group = PBXGroup(tg.name) + group.add(tg.path, sources) + p.mainGroup.children.append(group) + + buildfiles = [PBXBuildFile(fileref) for fileref in group.children] + compilesources = PBXSourcesBuildPhase(buildfiles) + buildphases = [compilesources] + + settings = { + "Debug": {}, + "Release": {} + } + if hasattr(tg, 'settings'): + isinstance(tg.settings, dict) + settings.update(tg.settings) + + target_type = getattr(tg, 'target_type', TARGET_TYPE_APPLICATION) + file_ext = target_type[2] + target_node = tg.path.find_or_declare(tg.name+file_ext) + + framework = getattr(tg, 'link_framework', []) + for fw in framework: + if fw and fw in p._output: + fw = PBXFrameworksBuildPhase([p._output[fw]]) + buildphases.append(fw) + + cflst = [] + for k,v in settings.items(): + cflst.append(XCBuildConfiguration(k, v)) + cflst = XCConfigurationList(cflst) + include_dirs = Utils.to_list(getattr(tg, 'includes', [])) include_dirs_ = [] for x in include_dirs: @@ -362,42 +389,12 @@ def execute(self): d = x else: d = tg.path.find_node(x) - include_dirs_.append(d.parent.abspath()) - tg.env.append_value('HEADER_SEARCH_PATHS', include_dirs_) + include_dirs_.append(d.abspath()) + print include_dirs_ + for k,v in settings.items(): + v['HEADER_SEARCH_PATHS'] = ' '.join(include_dirs_) - sources = [PBXFileReference(n.name, n.abspath()) for n in self.collect_source(tg)] - group = PBXGroup(tg.name) - group.add(tg.path, sources) - p.mainGroup.children.append(group) - - buildsettings = tg.env.get_merged_dict() - buildsettings.update({ - 'FRAMEWORK_VERSION': self.env.VERSION, - 'PRODUCT_NAME':tg.name - }) - - if hasattr(tg, 'settings') and isinstance(tg.settings, dict): - buildsettings.update(buildsettings) - - target_type = TARGET_TYPE_APPLICATION - if hasattr(tg, 'target_type'): - file_ext = tg.target_type[2] - node = tg.path.find_or_declare(tg.name+file_ext) - buildfiles = [PBXBuildFile(fileref) for fileref in group.children] - compilesources = PBXSourcesBuildPhase(buildfiles) - - buildphases = [compilesources] - - framework = getattr(tg, 'link_framework', []) - for fw in framework: - if fw and fw in p._output: - print tg - fw = PBXFrameworksBuildPhase([p._output[fw]]) - buildphases.append(fw) - - cf = XCBuildConfiguration('Debug', {"CONFIG_NAME": "Fitta"}) - cflst = XCConfigurationList([cf]) - target = PBXNativeTarget('build', tg.name, node, buildphases, cflst, tg.target_type) + target = PBXNativeTarget(tg.name, target_node, buildphases, cflst, target_type) p.add_task_gen(target) From a62bef1323a9e90bdbd3a4273b49a368a1d7e7de Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 4 Jul 2015 12:11:10 +0200 Subject: [PATCH 0066/1763] Target dependecies now works --- demos/xcode/wscript | 3 ++- waflib/extras/xcode.py | 40 ++++++++++++++++++++++++++++++++++------ 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/demos/xcode/wscript b/demos/xcode/wscript index 58339486ec..152000cddd 100644 --- a/demos/xcode/wscript +++ b/demos/xcode/wscript @@ -25,7 +25,8 @@ def build(bld): target_type=xcode.TARGET_TYPE_FRAMEWORK ) - bld(source=bld.path.ant_glob('src/*.cpp|'), + bld( + source=bld.path.ant_glob('src/*.cpp|'), includes=tg.includes, target='MyApp', target_type=xcode.TARGET_TYPE_APPLICATION, diff --git a/waflib/extras/xcode.py b/waflib/extras/xcode.py index 4c1f459ef1..92f1884c7f 100644 --- a/waflib/extras/xcode.py +++ b/waflib/extras/xcode.py @@ -113,10 +113,11 @@ def write_recursive(self, value, file): value.write(file) def write(self, file): - for attribute,value in self.__dict__.items(): - if attribute[0] != '_': - self.write_recursive(value, file) if not self._been_written: + self._been_written = True + for attribute,value in self.__dict__.items(): + if attribute[0] != '_': + self.write_recursive(value, file) w = file.write w("\t%s = {\n" % self._id) w("\t\tisa = %s;\n" % self.__class__.__name__) @@ -124,7 +125,6 @@ def write(self, file): if attribute[0] != '_': w("\t\t%s = %s;\n" % (attribute, self.tostring(value))) w("\t};\n\n") - self._been_written = True class XCID(XCodeNode): def __init__(self, id): @@ -205,6 +205,24 @@ def folder(n): self.children.append(source) # f.children.append(source) +class PBXContainerItemProxy(XCodeNode): + """ This is the element for to decorate a target item. """ + def __init__(self, containerPortal, remoteGlobalIDString, remoteInfo='', proxyType=1): + XCodeNode.__init__(self) + self.containerPortal = containerPortal # PBXProject + self.remoteGlobalIDString = remoteGlobalIDString # PBXNativeTarget + self.remoteInfo = remoteInfo # Target name + self.proxyType = proxyType + + +class PBXTargetDependency(XCodeNode): + """ This is the element for referencing other target through content proxies. """ + def __init__(self, native_target, proxy): + XCodeNode.__init__(self) + self.target = native_target + self.targetProxy = proxy + + # Framework sources class PBXFrameworksBuildPhase(XCodeNode): """ This is the element for the framework link build phase, i.e. linking to frameworks """ @@ -283,6 +301,8 @@ def __init__(self, name, version, buildsettings): self._output = {} def write(self, file): + if self._been_written: + return w = file.write w("// !$*UTF8*$!\n") w("{\n") @@ -300,7 +320,7 @@ def write(self, file): def add_task_gen(self, target): self.targets.append(target) - self._output[target.name] = PBXBuildFile(target.productReference) + self._output[target.name] = target class xcode(Build.BuildContext): cmd = 'xcode' @@ -348,6 +368,7 @@ def execute(self): continue tg.post() + print tg.name sources = [PBXFileReference(n.name, n.abspath()) for n in self.collect_source(tg)] @@ -358,6 +379,7 @@ def execute(self): buildfiles = [PBXBuildFile(fileref) for fileref in group.children] compilesources = PBXSourcesBuildPhase(buildfiles) buildphases = [compilesources] + dependency_targets = [] settings = { "Debug": {}, @@ -374,8 +396,13 @@ def execute(self): framework = getattr(tg, 'link_framework', []) for fw in framework: if fw and fw in p._output: - fw = PBXFrameworksBuildPhase([p._output[fw]]) + target = p._output[fw] + product = PBXBuildFile(target.productReference) + fw = PBXFrameworksBuildPhase([product]) buildphases.append(fw) + proxy = PBXContainerItemProxy(p, target, target.name) + dependecy = PBXTargetDependency(target, proxy) + dependency_targets.append(dependecy) cflst = [] for k,v in settings.items(): @@ -395,6 +422,7 @@ def execute(self): v['HEADER_SEARCH_PATHS'] = ' '.join(include_dirs_) target = PBXNativeTarget(tg.name, target_node, buildphases, cflst, target_type) + target.dependencies.extend(dependency_targets) p.add_task_gen(target) From b7e4aed28b9bc8876ae0a988d81ef4b730ee2b2d Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 4 Jul 2015 19:13:11 +0200 Subject: [PATCH 0067/1763] Custom project build configurations --- demos/xcode/wscript | 6 ++--- waflib/extras/xcode.py | 51 ++++++++++++++++++++++++++++++++++-------- 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/demos/xcode/wscript b/demos/xcode/wscript index 152000cddd..c8533c60b7 100644 --- a/demos/xcode/wscript +++ b/demos/xcode/wscript @@ -7,7 +7,7 @@ VERSION = '1.0' def configure(opt): opt.load('cxx') - opt.load('xcode') + # opt.load('xcode') opt.env.FRAMEWORK_VERSION = '1.0' opt.env.CONFIG_NAME = 'Kuk' opt.env.ARCHS = 'x86_64' @@ -16,8 +16,8 @@ def configure(opt): opt.env.PRODUCT_NAME = '$(TARGET_NAME)' def build(bld): - bld.load('xcode') - + # bld.load('xcode') + # bld.load('cxx') tg = bld( source=bld.path.ant_glob('src/MyLib/*.cpp'), includes=['include'], diff --git a/waflib/extras/xcode.py b/waflib/extras/xcode.py index 92f1884c7f..ec3f99fde8 100644 --- a/waflib/extras/xcode.py +++ b/waflib/extras/xcode.py @@ -16,7 +16,7 @@ def options(opt): # TODO: support iOS projects -from waflib import Context, TaskGen, Build, Utils, ConfigSet +from waflib import Context, TaskGen, Build, Utils, ConfigSet, Configure, Errors import os, sys, random, time HEADERS_GLOB = '**/(*.h|*.hpp|*.H|*.inl)' @@ -68,6 +68,36 @@ def options(opt): TARGET_TYPE_FRAMEWORK = (PRODUCT_TYPE_FRAMEWORK, FILE_TYPE_FRAMEWORK, '.framework') TARGET_TYPE_APPLICATION = (PRODUCT_TYPE_APPLICATION, FILE_TYPE_APPLICATION, '.app') +class XcodeConfiguration(Configure.ConfigurationContext): + """ Configuration of the project """ + def __init__(self): + Configure.ConfigurationContext.__init__(self) + + def execute(self): + + # Run user configure() + Context.Context.execute(self) + + if not self.env.PROJ_CONFIGURATION: + self.to_log("A default project configuration was created since no custom one was given in the configure(ctx) stage. Define your custom project settings by adding PROJ_CONFIGURATION to env. The env.PROJ_CONFIGURATION must be a dictionary with at least one key, where each key is the configuration name, and the value is a dictionary of key/value settings.\n") + + # Create default project configuration? + # if 'PROJ_CONFIGURATION' not in self.env.keys(): + self.env.PROJ_CONFIGURATION = { + "Debug": self.env.get_merged_dict(), + "Release": self.env.get_merged_dict(), + } + + + # Run user configuration(ctx) for customization + Configure.ConfigurationContext.execute(self) + + # Error check customization + if not isinstance(self.env.PROJ_CONFIGURATION, dict): + raise Errors.ConfigurationError("The env.PROJ_CONFIGURATION must be a dictionary with at least one key, where each key is the configuration name, and the value is a dictionary of key/value settings.") + + + part1 = 0 part2 = 10000 part3 = 0 @@ -286,11 +316,16 @@ def __init__(self, target, node, buildphases, configlist, target_type=TARGET_TYP # Root project object class PBXProject(XCodeNode): - def __init__(self, name, version, buildsettings): + def __init__(self, name, version, env): XCodeNode.__init__(self) - cf_debug = XCBuildConfiguration('Debug', buildsettings) - cf_release = XCBuildConfiguration('Release', buildsettings) - self.buildConfigurationList = XCConfigurationList([cf_debug, cf_release]) + + # Retreive project configuration + configurations = [] + for config_name, settings in env.PROJ_CONFIGURATION.items(): + cf = XCBuildConfiguration(config_name, settings) + configurations.append(cf) + + self.buildConfigurationList = XCConfigurationList(configurations) self.compatibilityVersion = version[0] self.hasScannedForEncodings = 1; self.mainGroup = PBXGroup(name) @@ -360,7 +395,7 @@ def execute(self): buildsettings = self.env.get_merged_dict() buildsettings.update() - p = PBXProject(appname, ('Xcode 3.2', 46), buildsettings) + p = PBXProject(appname, ('Xcode 3.2', 46), self.env) for g in self.groups: for tg in g: @@ -368,8 +403,6 @@ def execute(self): continue tg.post() - print tg.name - sources = [PBXFileReference(n.name, n.abspath()) for n in self.collect_source(tg)] group = PBXGroup(tg.name) @@ -417,7 +450,6 @@ def execute(self): else: d = tg.path.find_node(x) include_dirs_.append(d.abspath()) - print include_dirs_ for k,v in settings.items(): v['HEADER_SEARCH_PATHS'] = ' '.join(include_dirs_) @@ -430,5 +462,6 @@ def execute(self): node.mkdir() node = node.make_node('project.pbxproj') p.write(open(node.abspath(), 'w')) + From 0c864ecaacaa882bc69e865bee5dd00d21676002 Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 4 Jul 2015 22:22:19 +0200 Subject: [PATCH 0068/1763] Custom project build configurations fix --- waflib/extras/xcode.py | 1 - 1 file changed, 1 deletion(-) diff --git a/waflib/extras/xcode.py b/waflib/extras/xcode.py index ec3f99fde8..d3c47079a8 100644 --- a/waflib/extras/xcode.py +++ b/waflib/extras/xcode.py @@ -88,7 +88,6 @@ def execute(self): "Release": self.env.get_merged_dict(), } - # Run user configuration(ctx) for customization Configure.ConfigurationContext.execute(self) From d5c5db686aabf15b40ab219e2eda79e48b9e627b Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 4 Jul 2015 22:23:16 +0200 Subject: [PATCH 0069/1763] Custom project build configurations fix --- waflib/extras/xcode.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/waflib/extras/xcode.py b/waflib/extras/xcode.py index d3c47079a8..b0e56a4e92 100644 --- a/waflib/extras/xcode.py +++ b/waflib/extras/xcode.py @@ -413,13 +413,7 @@ def execute(self): buildphases = [compilesources] dependency_targets = [] - settings = { - "Debug": {}, - "Release": {} - } - if hasattr(tg, 'settings'): - isinstance(tg.settings, dict) - settings.update(tg.settings) + settings = getattr(tg, 'settings', {}) target_type = getattr(tg, 'target_type', TARGET_TYPE_APPLICATION) file_ext = target_type[2] From 922be2ff58def71664554cf7e182f2131cf439d9 Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 4 Jul 2015 22:56:54 +0200 Subject: [PATCH 0070/1763] Custom source/include heirarchy --- demos/xcode/wscript | 23 ++++++++++------------- waflib/extras/xcode.py | 24 +++++++++++++++++++++--- 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/demos/xcode/wscript b/demos/xcode/wscript index c8533c60b7..3a824c4961 100644 --- a/demos/xcode/wscript +++ b/demos/xcode/wscript @@ -5,31 +5,28 @@ out = 'build' APPNAME = 'Avocada' VERSION = '1.0' -def configure(opt): - opt.load('cxx') - # opt.load('xcode') - opt.env.FRAMEWORK_VERSION = '1.0' - opt.env.CONFIG_NAME = 'Kuk' - opt.env.ARCHS = 'x86_64' - opt.env.MACOSX_DEPLOYMENT_TARGET = '10.9' - opt.env.SDKROOT = 'macosx10.9' - opt.env.PRODUCT_NAME = '$(TARGET_NAME)' +def configure(conf): + conf.load('cxx') + conf.env.FRAMEWORK_VERSION = '1.0' + conf.env.CONFIG_NAME = 'Kuk' + conf.env.ARCHS = 'x86_64' + conf.env.MACOSX_DEPLOYMENT_TARGET = '10.9' + conf.env.SDKROOT = 'macosx10.9' + conf.env.PRODUCT_NAME = '$(TARGET_NAME)' def build(bld): - # bld.load('xcode') - # bld.load('cxx') tg = bld( source=bld.path.ant_glob('src/MyLib/*.cpp'), includes=['include'], target='MyLib', - target_type=xcode.TARGET_TYPE_FRAMEWORK + target_type='framework' ) bld( source=bld.path.ant_glob('src/*.cpp|'), includes=tg.includes, target='MyApp', - target_type=xcode.TARGET_TYPE_APPLICATION, + target_type='app', link_framework=['MyLib'], settings={"Debug": {"CONFIG_NAME": 'Debug'}} ) diff --git a/waflib/extras/xcode.py b/waflib/extras/xcode.py index b0e56a4e92..6a895ff4dd 100644 --- a/waflib/extras/xcode.py +++ b/waflib/extras/xcode.py @@ -68,6 +68,11 @@ def options(opt): TARGET_TYPE_FRAMEWORK = (PRODUCT_TYPE_FRAMEWORK, FILE_TYPE_FRAMEWORK, '.framework') TARGET_TYPE_APPLICATION = (PRODUCT_TYPE_APPLICATION, FILE_TYPE_APPLICATION, '.app') +TARGET_TYPES = { + 'framework': TARGET_TYPE_FRAMEWORK, + 'app': TARGET_TYPE_APPLICATION +} + class XcodeConfiguration(Configure.ConfigurationContext): """ Configuration of the project """ def __init__(self): @@ -318,6 +323,9 @@ class PBXProject(XCodeNode): def __init__(self, name, version, env): XCodeNode.__init__(self) + if not isinstance(env.PROJ_CONFIGURATION, dict): + raise Errors.WafError("env.PROJ_CONFIGURATION is not a dictionary. Did you import the xcode module in your wscript?") + # Retreive project configuration configurations = [] for config_name, settings in env.PROJ_CONFIGURATION.items(): @@ -411,30 +419,40 @@ def execute(self): buildfiles = [PBXBuildFile(fileref) for fileref in group.children] compilesources = PBXSourcesBuildPhase(buildfiles) buildphases = [compilesources] - dependency_targets = [] - settings = getattr(tg, 'settings', {}) - target_type = getattr(tg, 'target_type', TARGET_TYPE_APPLICATION) + target_type = getattr(tg, 'target_type', '') + if target_type not in TARGET_TYPES: + raise Errors.WafError("Target type %s does not exists. Available options are %s. In target %s" % (target_type, ', '.join(TARGET_TYPES.keys()), tg.name)) file_ext = target_type[2] target_node = tg.path.find_or_declare(tg.name+file_ext) + # Check if any framework to link against is some other target we've made + dependency_targets = [] framework = getattr(tg, 'link_framework', []) for fw in framework: if fw and fw in p._output: + # Target framework found. Make a build file of it target = p._output[fw] product = PBXBuildFile(target.productReference) fw = PBXFrameworksBuildPhase([product]) buildphases.append(fw) + + # Create an XCode dependency so that it knows to build that framework before this target proxy = PBXContainerItemProxy(p, target, target.name) dependecy = PBXTargetDependency(target, proxy) dependency_targets.append(dependecy) + + # Create settings which can override the project settings. Defaults to none if user + # did not pass argument. + settings = getattr(tg, 'settings', {}) cflst = [] for k,v in settings.items(): cflst.append(XCBuildConfiguration(k, v)) cflst = XCConfigurationList(cflst) + # Setup include search paths include_dirs = Utils.to_list(getattr(tg, 'includes', [])) include_dirs_ = [] for x in include_dirs: From d0279469df15abdc4d9039c2487650e030421573 Mon Sep 17 00:00:00 2001 From: Simon Date: Sun, 5 Jul 2015 00:06:56 +0200 Subject: [PATCH 0071/1763] Getting Custom source/include heirarchy to work --- demos/xcode/wscript | 2 +- waflib/extras/xcode.py | 26 +++++++++++++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/demos/xcode/wscript b/demos/xcode/wscript index 3a824c4961..fe14d0aaa5 100644 --- a/demos/xcode/wscript +++ b/demos/xcode/wscript @@ -16,7 +16,7 @@ def configure(conf): def build(bld): tg = bld( - source=bld.path.ant_glob('src/MyLib/*.cpp'), + sources={'MySources': bld.path.ant_glob('src/MyLib/*.cpp')}, includes=['include'], target='MyLib', target_type='framework' diff --git a/waflib/extras/xcode.py b/waflib/extras/xcode.py index 6a895ff4dd..5c91b3aa68 100644 --- a/waflib/extras/xcode.py +++ b/waflib/extras/xcode.py @@ -369,7 +369,7 @@ class xcode(Build.BuildContext): fun = 'build' def collect_source(self, tg): - source_files = tg.to_nodes(getattr(tg, 'source', [])) + source_files = tg.to_nodes(getattr(tg, 'source', {})) plist_files = tg.to_nodes(getattr(tg, 'mac_plist', [])) resource_files = [tg.path.find_node(i) for i in Utils.to_list(getattr(tg, 'mac_resources', []))] include_dirs = Utils.to_list(getattr(tg, 'includes', [])) + Utils.to_list(getattr(tg, 'export_dirs', [])) @@ -388,6 +388,22 @@ def collect_source(self, tg): source.sort(key=lambda x: x.abspath()) return source + def as_nodes(self, files): + nodes = [] + for x in files: + if not isinstance(x, str): + d = x + else: + d = tg.path.find_node(x) + nodes.append(d) + return nodes + + def create_group(self, name, files): + group = PBXGroup(name) + files = [PBXFileReference(d.name, d.abspath()) for d in self.as_nodes(files)] + group.children.extend(files) + return group + def execute(self): """ Entry point @@ -415,6 +431,14 @@ def execute(self): group = PBXGroup(tg.name) group.add(tg.path, sources) p.mainGroup.children.append(group) + + if isinstance(getattr(tg, 'sources', None), dict): + for grpname,files in tg.sources.items(): + g = self.create_group(grpname, files) + group.children.append(g) + else: + g1 = self.create_group('Source', getattr(tg, 'source', [])) + group.children.append(g1) buildfiles = [PBXBuildFile(fileref) for fileref in group.children] compilesources = PBXSourcesBuildPhase(buildfiles) From db2587ea6173ae367a881eb237c9e1ad7bca5f27 Mon Sep 17 00:00:00 2001 From: Simon Date: Sun, 5 Jul 2015 12:37:25 +0200 Subject: [PATCH 0072/1763] Getting Custom source/include heirarchy to work - fixes --- demos/xcode/wscript | 2 +- waflib/extras/xcode.py | 57 +++++++++++++++++++++++++++++------------- 2 files changed, 41 insertions(+), 18 deletions(-) diff --git a/demos/xcode/wscript b/demos/xcode/wscript index fe14d0aaa5..229ad78aed 100644 --- a/demos/xcode/wscript +++ b/demos/xcode/wscript @@ -17,7 +17,7 @@ def configure(conf): def build(bld): tg = bld( sources={'MySources': bld.path.ant_glob('src/MyLib/*.cpp')}, - includes=['include'], + includes={'Important': bld.path.ant_glob('include/**/*.h')}, target='MyLib', target_type='framework' ) diff --git a/waflib/extras/xcode.py b/waflib/extras/xcode.py index 5c91b3aa68..5db412939c 100644 --- a/waflib/extras/xcode.py +++ b/waflib/extras/xcode.py @@ -394,7 +394,7 @@ def as_nodes(self, files): if not isinstance(x, str): d = x else: - d = tg.path.find_node(x) + d = self.srcnode.find_node(x) nodes.append(d) return nodes @@ -427,20 +427,40 @@ def execute(self): tg.post() - sources = [PBXFileReference(n.name, n.abspath()) for n in self.collect_source(tg)] + # sources = [PBXFileReference(n.name, n.abspath()) for n in self.collect_source(tg)] group = PBXGroup(tg.name) - group.add(tg.path, sources) + # group.add(tg.path, sources) p.mainGroup.children.append(group) - if isinstance(getattr(tg, 'sources', None), dict): - for grpname,files in tg.sources.items(): + source_files = [] + if hasattr(tg, 'sources'): + if isinstance(tg.sources, dict): + for grpname,files in tg.sources.items(): + sources = self.create_group(grpname, files) + group.children.append(sources) + source_files.append(sources) + elif isinstance(tg.sources, list): + sources = self.create_group('Source', tg.sources) + group.children.append(sources) + source_files.append(sources) + else: + self.to_log("Argument 'sources' passed to target '%s' was not a list nor a dictionary. Hence, some source files may not be included. Please provide a list of source files, or a dictionary with group name as key and list of source files as value.\n" % tg.name) + if hasattr(tg, 'source') and (len(tg.source) > 0): + sources = self.create_group('Source', getattr(tg, 'source', [])) + group.children.append(sources) + source_files.append(sources) + + if isinstance(getattr(tg, 'includes', None), dict): + for grpname,files in tg.includes.items(): g = self.create_group(grpname, files) group.children.append(g) else: - g1 = self.create_group('Source', getattr(tg, 'source', [])) - group.children.append(g1) - - buildfiles = [PBXBuildFile(fileref) for fileref in group.children] + g = self.create_group('Includes', getattr(tg, 'includes', [])) + group.children.append(g) + + for sourcegrp in source_files: + buildfiles = [PBXBuildFile(fileref) for fileref in sourcegrp.children] + compilesources = PBXSourcesBuildPhase(buildfiles) buildphases = [compilesources] @@ -448,8 +468,12 @@ def execute(self): target_type = getattr(tg, 'target_type', '') if target_type not in TARGET_TYPES: raise Errors.WafError("Target type %s does not exists. Available options are %s. In target %s" % (target_type, ', '.join(TARGET_TYPES.keys()), tg.name)) + else: + target_type = TARGET_TYPES[target_type] + file_ext = target_type[2] target_node = tg.path.find_or_declare(tg.name+file_ext) + # Check if any framework to link against is some other target we've made dependency_targets = [] @@ -478,15 +502,14 @@ def execute(self): # Setup include search paths include_dirs = Utils.to_list(getattr(tg, 'includes', [])) - include_dirs_ = [] - for x in include_dirs: - if not isinstance(x, str): - d = x - else: - d = tg.path.find_node(x) - include_dirs_.append(d.abspath()) + if isinstance(include_dirs, dict): + tmp = [] + map(lambda lst: tmp.extend(lst), include_dirs.values()) + include_dirs = tmp + + include_dirs = [x.abspath() for x in self.as_nodes(include_dirs)] for k,v in settings.items(): - v['HEADER_SEARCH_PATHS'] = ' '.join(include_dirs_) + v['HEADER_SEARCH_PATHS'] = ' '.join(include_dirs) target = PBXNativeTarget(tg.name, target_node, buildphases, cflst, target_type) target.dependencies.extend(dependency_targets) From 4167c43c2a299544f9c27d649455353dfbdd0367 Mon Sep 17 00:00:00 2001 From: Simon Date: Sun, 5 Jul 2015 15:53:59 +0200 Subject: [PATCH 0073/1763] Getting Custom file grouping reworked --- demos/xcode/wscript | 8 +++-- waflib/extras/xcode.py | 69 ++++++++++++++++++------------------------ 2 files changed, 35 insertions(+), 42 deletions(-) diff --git a/demos/xcode/wscript b/demos/xcode/wscript index 229ad78aed..571bb0d090 100644 --- a/demos/xcode/wscript +++ b/demos/xcode/wscript @@ -16,8 +16,12 @@ def configure(conf): def build(bld): tg = bld( - sources={'MySources': bld.path.ant_glob('src/MyLib/*.cpp')}, - includes={'Important': bld.path.ant_glob('include/**/*.h')}, + source=bld.path.ant_glob('src/MyLib/*.cpp'), + source_grpname='Fucker', + includes='include', + group_files={ + 'Include': bld.path.ant_glob('include/MyLib/*.h') + }, target='MyLib', target_type='framework' ) diff --git a/waflib/extras/xcode.py b/waflib/extras/xcode.py index 5db412939c..d50c19c299 100644 --- a/waflib/extras/xcode.py +++ b/waflib/extras/xcode.py @@ -427,42 +427,27 @@ def execute(self): tg.post() - # sources = [PBXFileReference(n.name, n.abspath()) for n in self.collect_source(tg)] group = PBXGroup(tg.name) - # group.add(tg.path, sources) p.mainGroup.children.append(group) - source_files = [] - if hasattr(tg, 'sources'): - if isinstance(tg.sources, dict): - for grpname,files in tg.sources.items(): - sources = self.create_group(grpname, files) - group.children.append(sources) - source_files.append(sources) - elif isinstance(tg.sources, list): - sources = self.create_group('Source', tg.sources) - group.children.append(sources) - source_files.append(sources) + extra_groups = [] + if hasattr(tg, 'group_files'): + if isinstance(tg.group_files, dict): + for grpname,files in tg.group_files.items(): + group_files = self.create_group(grpname, files) + group.children.append(group_files) + extra_groups.append(group_files) else: self.to_log("Argument 'sources' passed to target '%s' was not a list nor a dictionary. Hence, some source files may not be included. Please provide a list of source files, or a dictionary with group name as key and list of source files as value.\n" % tg.name) - if hasattr(tg, 'source') and (len(tg.source) > 0): - sources = self.create_group('Source', getattr(tg, 'source', [])) - group.children.append(sources) - source_files.append(sources) - - if isinstance(getattr(tg, 'includes', None), dict): - for grpname,files in tg.includes.items(): - g = self.create_group(grpname, files) - group.children.append(g) - else: - g = self.create_group('Includes', getattr(tg, 'includes', [])) - group.children.append(g) - - for sourcegrp in source_files: - buildfiles = [PBXBuildFile(fileref) for fileref in sourcegrp.children] - compilesources = PBXSourcesBuildPhase(buildfiles) - buildphases = [compilesources] + buildphases = [] + + if len(tg.source) > 0: + g = self.create_group(getattr(tg, 'source_grpname', 'Source'), tg.source) + buildfiles = [PBXBuildFile(fileref) for fileref in g.children] + compilesources = PBXSourcesBuildPhase(buildfiles) + buildphases.append(compilesources) + group.children.append(g) target_type = getattr(tg, 'target_type', '') @@ -495,21 +480,25 @@ def execute(self): # Create settings which can override the project settings. Defaults to none if user # did not pass argument. settings = getattr(tg, 'settings', {}) + + # Setup include search paths + include_dirs = Utils.to_list(getattr(tg, 'includes', [])) + include_dirs = [x.abspath() for x in self.as_nodes(include_dirs)] + + # Set the HEADER_SEARCH_PATHS for all configurations + keys = set(settings.keys() + self.env.PROJ_CONFIGURATION.keys()) + paths = ' '.join(include_dirs) + for k in keys: + if k in settings: + settings[k]['HEADER_SEARCH_PATHS'] = paths + else: + settings[k] = {'HEADER_SEARCH_PATHS': paths} + cflst = [] for k,v in settings.items(): cflst.append(XCBuildConfiguration(k, v)) cflst = XCConfigurationList(cflst) - # Setup include search paths - include_dirs = Utils.to_list(getattr(tg, 'includes', [])) - if isinstance(include_dirs, dict): - tmp = [] - map(lambda lst: tmp.extend(lst), include_dirs.values()) - include_dirs = tmp - - include_dirs = [x.abspath() for x in self.as_nodes(include_dirs)] - for k,v in settings.items(): - v['HEADER_SEARCH_PATHS'] = ' '.join(include_dirs) target = PBXNativeTarget(tg.name, target_node, buildphases, cflst, target_type) target.dependencies.extend(dependency_targets) From 1f918ce54688b1e7bf2f2473437ff472e0259641 Mon Sep 17 00:00:00 2001 From: Simon Date: Sun, 5 Jul 2015 16:57:27 +0200 Subject: [PATCH 0074/1763] Added documentation --- waflib/extras/xcode.py | 57 +++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 34 deletions(-) diff --git a/waflib/extras/xcode.py b/waflib/extras/xcode.py index d50c19c299..d9519f65fb 100644 --- a/waflib/extras/xcode.py +++ b/waflib/extras/xcode.py @@ -65,16 +65,32 @@ def options(opt): FILE_TYPE_APPLICATION = 'wrapper.cfbundle' FILE_TYPE_FRAMEWORK = 'wrapper.framework' +# Tuple packs of the above TARGET_TYPE_FRAMEWORK = (PRODUCT_TYPE_FRAMEWORK, FILE_TYPE_FRAMEWORK, '.framework') TARGET_TYPE_APPLICATION = (PRODUCT_TYPE_APPLICATION, FILE_TYPE_APPLICATION, '.app') +# Maps a target type as a string to its data TARGET_TYPES = { 'framework': TARGET_TYPE_FRAMEWORK, 'app': TARGET_TYPE_APPLICATION } class XcodeConfiguration(Configure.ConfigurationContext): - """ Configuration of the project """ + """ Configuration of the global project settings. Sets a environment variable 'PROJ_CONFIGURATION' + which is a dictionary of configuration name and buildsettings pair. + E.g.: + { + 'Debug': { + 'ARCHS': 'x86', + ... + } + 'Release': { + 'ARCHS' x86_64' + ... + } + } + The user can define a completely customized dictionary in configure() stage. Otherwise a default Debug/Release will be created + based on env variable """ def __init__(self): Configure.ConfigurationContext.__init__(self) @@ -160,13 +176,6 @@ def write(self, file): w("\t\t%s = %s;\n" % (attribute, self.tostring(value))) w("\t};\n\n") -class XCID(XCodeNode): - def __init__(self, id): - self._id = id - def write(self, file): - pass - - # Configurations class XCBuildConfiguration(XCodeNode): def __init__(self, name, settings = {}, env=None): @@ -217,27 +226,9 @@ def __init__(self, name, sourcetree = ""): self.name = name self.sourceTree = sourcetree - def add(self, root, sources): - folders = {} - def folder(n): - if not n.is_child_of(root): - return self - try: - return folders[n] - except KeyError: - f = PBXGroup(n.name) - p = folder(n.parent) - folders[n] = f - p.children.append(f) - return f + def add(self, sources): + """ sources param should be a list of PBXFileReference objects """ self.children.extend(sources) - return - for s in sources: - # f = folder(s.parent) - - source = PBXFileReference(s.name, s.abspath()) - self.children.append(source) - # f.children.append(source) class PBXContainerItemProxy(XCodeNode): """ This is the element for to decorate a target item. """ @@ -256,8 +247,6 @@ def __init__(self, native_target, proxy): self.target = native_target self.targetProxy = proxy - -# Framework sources class PBXFrameworksBuildPhase(XCodeNode): """ This is the element for the framework link build phase, i.e. linking to frameworks """ def __init__(self, pbxbuildfiles): @@ -266,15 +255,12 @@ def __init__(self, pbxbuildfiles): self.runOnlyForDeploymentPostprocessing = 0 self.files = pbxbuildfiles #List of PBXBuildFile (.o, .framework, .dylib) - -# Compile Sources class PBXSourcesBuildPhase(XCodeNode): """ Represents the 'Compile Sources' build phase in a Xcode target """ def __init__(self, buildfiles): XCodeNode.__init__(self) self.files = buildfiles # List of PBXBuildFile objects -# Targets class PBXLegacyTarget(XCodeNode): def __init__(self, action, target=''): XCodeNode.__init__(self) @@ -343,8 +329,11 @@ def __init__(self, name, version, env): self._output = {} def write(self, file): + + # Make sure this is written only once if self._been_written: return + w = file.write w("// !$*UTF8*$!\n") w("{\n") @@ -418,7 +407,7 @@ def execute(self): buildsettings = self.env.get_merged_dict() buildsettings.update() - p = PBXProject(appname, ('Xcode 3.2', 46), self.env) + p = PBXProject(appname, ('Xcode 6.0', 46), self.env) for g in self.groups: for tg in g: From 1427497785a594dedeaac09013db635791f068c4 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sun, 5 Jul 2015 20:24:39 +0200 Subject: [PATCH 0075/1763] Docs --- ChangeLog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ChangeLog b/ChangeLog index f093bf99f8..2ba4d73e8e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,8 @@ NEW IN WAF 1.8.12 ----------------- * Fixed a regression when building in sub-folders - https://github.com/waf-project/waf/issues/1590 +* New mac_files attribute which is expected to replace mac_resources in waf 1.9 (demos/mac_app/) +* env = env.derive().detach() to simplify deep copies NEW IN WAF 1.8.11 ----------------- From 79c91daffc26bb4c981b83f991d9c154e5ee9f58 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 6 Jul 2015 13:38:27 +0200 Subject: [PATCH 0076/1763] Improved include paths. Added support for c_config files --- waflib/extras/xcode.py | 73 ++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 41 deletions(-) diff --git a/waflib/extras/xcode.py b/waflib/extras/xcode.py index d9519f65fb..f3d5d2ddd9 100644 --- a/waflib/extras/xcode.py +++ b/waflib/extras/xcode.py @@ -93,6 +93,7 @@ class XcodeConfiguration(Configure.ConfigurationContext): based on env variable """ def __init__(self): Configure.ConfigurationContext.__init__(self) + self.init_dirs() def execute(self): @@ -102,6 +103,16 @@ def execute(self): if not self.env.PROJ_CONFIGURATION: self.to_log("A default project configuration was created since no custom one was given in the configure(ctx) stage. Define your custom project settings by adding PROJ_CONFIGURATION to env. The env.PROJ_CONFIGURATION must be a dictionary with at least one key, where each key is the configuration name, and the value is a dictionary of key/value settings.\n") + # Set include dir variable + if 'HEADER_SEARCH_PATHS' not in self.env: + self.env.HEADER_SEARCH_PATHS = ['$(inherited)'] + else: + self.env.HEADER_SEARCH_PATHS = [self.srcnode.make_node(f).abspath() for f in Utils.to_list(self.env.HEADER_SEARCH_PATHS)] + + # Check for any added config files added by the tool 'c_config'. + if 'cfg_files' in self.env: + self.env.HEADER_SEARCH_PATHS.extend([os.path.abspath(os.path.dirname(f)) for f in self.env.cfg_files]) + # Create default project configuration? # if 'PROJ_CONFIGURATION' not in self.env.keys(): self.env.PROJ_CONFIGURATION = { @@ -333,7 +344,7 @@ def write(self, file): # Make sure this is written only once if self._been_written: return - + w = file.write w("// !$*UTF8*$!\n") w("{\n") @@ -351,33 +362,17 @@ def write(self, file): def add_task_gen(self, target): self.targets.append(target) + + # Collect all targets the project produces. If any other target + # depends on this target, we can retreive it from here later. self._output[target.name] = target class xcode(Build.BuildContext): cmd = 'xcode' fun = 'build' - def collect_source(self, tg): - source_files = tg.to_nodes(getattr(tg, 'source', {})) - plist_files = tg.to_nodes(getattr(tg, 'mac_plist', [])) - resource_files = [tg.path.find_node(i) for i in Utils.to_list(getattr(tg, 'mac_resources', []))] - include_dirs = Utils.to_list(getattr(tg, 'includes', [])) + Utils.to_list(getattr(tg, 'export_dirs', [])) - include_files = [] - for x in include_dirs: - if not isinstance(x, str): - include_files.append(x) - continue - d = tg.path.find_node(x) - if d: - lst = [y for y in d.ant_glob(HEADERS_GLOB, flat=False)] - include_files.extend(lst) - - # remove duplicates - source = list(set(source_files + plist_files + resource_files + include_files)) - source.sort(key=lambda x: x.abspath()) - return source - def as_nodes(self, files): + """ Returns a list of waflib.Nodes from a list of string of file paths """ nodes = [] for x in files: if not isinstance(x, str): @@ -388,6 +383,7 @@ def as_nodes(self, files): return nodes def create_group(self, name, files): + """ Returns a new PBXGroup containing the files (paths) passed in the files arg """ group = PBXGroup(name) files = [PBXFileReference(d.name, d.abspath()) for d in self.as_nodes(files)] group.children.extend(files) @@ -404,9 +400,6 @@ def execute(self): appname = getattr(Context.g_module, Context.APPNAME, os.path.basename(self.srcnode.abspath())) - buildsettings = self.env.get_merged_dict() - buildsettings.update() - p = PBXProject(appname, ('Xcode 6.0', 46), self.env) for g in self.groups: @@ -416,18 +409,16 @@ def execute(self): tg.post() - group = PBXGroup(tg.name) - p.mainGroup.children.append(group) + target_group = PBXGroup(tg.name) + p.mainGroup.children.append(target_group) - extra_groups = [] if hasattr(tg, 'group_files'): if isinstance(tg.group_files, dict): for grpname,files in tg.group_files.items(): group_files = self.create_group(grpname, files) - group.children.append(group_files) - extra_groups.append(group_files) + target_group.children.append(group_files) else: - self.to_log("Argument 'sources' passed to target '%s' was not a list nor a dictionary. Hence, some source files may not be included. Please provide a list of source files, or a dictionary with group name as key and list of source files as value.\n" % tg.name) + self.to_log("Argument 'group_files' passed to target '%s' was not a dictionary. Hence, some source files may not be included. Please provide a dict of source files, with group name as key and list of source files as value.\n" % tg.name) buildphases = [] @@ -436,19 +427,19 @@ def execute(self): buildfiles = [PBXBuildFile(fileref) for fileref in g.children] compilesources = PBXSourcesBuildPhase(buildfiles) buildphases.append(compilesources) - group.children.append(g) + target_group.children.append(g) - - target_type = getattr(tg, 'target_type', '') + # Determine what type to build - framework, app bundle etc. + target_type = getattr(tg, 'target_type', 'app') if target_type not in TARGET_TYPES: - raise Errors.WafError("Target type %s does not exists. Available options are %s. In target %s" % (target_type, ', '.join(TARGET_TYPES.keys()), tg.name)) + raise Errors.WafError("Target type '%s' does not exists. Available options are '%s'. In target '%s'" % (target_type, "', '".join(TARGET_TYPES.keys()), tg.name)) else: target_type = TARGET_TYPES[target_type] - file_ext = target_type[2] + + # Create the output node target_node = tg.path.find_or_declare(tg.name+file_ext) - # Check if any framework to link against is some other target we've made dependency_targets = [] framework = getattr(tg, 'link_framework', []) @@ -460,7 +451,7 @@ def execute(self): fw = PBXFrameworksBuildPhase([product]) buildphases.append(fw) - # Create an XCode dependency so that it knows to build that framework before this target + # Create an XCode dependency so that XCode knows to build that framework before this target proxy = PBXContainerItemProxy(p, target, target.name) dependecy = PBXTargetDependency(target, proxy) dependency_targets.append(dependecy) @@ -473,22 +464,22 @@ def execute(self): # Setup include search paths include_dirs = Utils.to_list(getattr(tg, 'includes', [])) include_dirs = [x.abspath() for x in self.as_nodes(include_dirs)] + includes_dirs_dict = {'HEADER_SEARCH_PATHS': ['$(inherited)'] + include_dirs} # Set the HEADER_SEARCH_PATHS for all configurations keys = set(settings.keys() + self.env.PROJ_CONFIGURATION.keys()) - paths = ' '.join(include_dirs) for k in keys: if k in settings: - settings[k]['HEADER_SEARCH_PATHS'] = paths + settings[k].update(includes_dirs_dict) else: - settings[k] = {'HEADER_SEARCH_PATHS': paths} + settings[k] = includes_dirs_dict + # Create the config lists cflst = [] for k,v in settings.items(): cflst.append(XCBuildConfiguration(k, v)) cflst = XCConfigurationList(cflst) - target = PBXNativeTarget(tg.name, target_node, buildphases, cflst, target_type) target.dependencies.extend(dependency_targets) From 9563da7875210b9faf0d0bb41d576fa592fbe262 Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 7 Jul 2015 12:17:43 +0200 Subject: [PATCH 0077/1763] Streamlined API more --- demos/xcode/wscript | 11 +++++++++- waflib/extras/xcode.py | 50 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 54 insertions(+), 7 deletions(-) diff --git a/demos/xcode/wscript b/demos/xcode/wscript index 571bb0d090..56e9ac612f 100644 --- a/demos/xcode/wscript +++ b/demos/xcode/wscript @@ -15,7 +15,9 @@ def configure(conf): conf.env.PRODUCT_NAME = '$(TARGET_NAME)' def build(bld): + bld.load('cxx') tg = bld( + features='cxx', source=bld.path.ant_glob('src/MyLib/*.cpp'), source_grpname='Fucker', includes='include', @@ -26,12 +28,19 @@ def build(bld): target_type='framework' ) - bld( + tg2 = bld( + features='cxx', source=bld.path.ant_glob('src/*.cpp|'), includes=tg.includes, target='MyApp', target_type='app', link_framework=['MyLib'], + use='MyLib Olle', settings={"Debug": {"CONFIG_NAME": 'Debug'}} ) + + # print tg2.env + # tg2.process_use() + # print bld.get_targets() + \ No newline at end of file diff --git a/waflib/extras/xcode.py b/waflib/extras/xcode.py index f3d5d2ddd9..8e225f637f 100644 --- a/waflib/extras/xcode.py +++ b/waflib/extras/xcode.py @@ -315,6 +315,20 @@ def __init__(self, target, node, buildphases, configlist, target_type=TARGET_TYP self.productType = product_type # See TARGET_TYPE_ tuples constants self.productReference = PBXFileReference(target, node.abspath(), file_type, '') + def add_build_phase(self, phase): + # Some build phase types may appear only once. If a phase type already exists, then merge them. + if ( phase.__name__ == PBXFrameworksBuildPhase.__name__ + or phase.__name__ == PBXSourcesBuildPhase.__name__): + for b in self.buildPhases: + if b.__name__ == phase.__name__: + b.files.extend(phase.files) + break + else: + self.buildPhases.append(phase) + + def add_dependency(self, depnd): + self.dependencies.append(dep) + # Root project object class PBXProject(XCodeNode): def __init__(self, name, version, env): @@ -337,7 +351,15 @@ def __init__(self, name, version, env): self.projectDirPath = "" self.targets = [] self._objectVersion = version[1] - self._output = {} + # self._output = {} + + def create_build_file(self, fileref, settings={}): + return PBXBuildFile(fileref, settings) + + def create_target_dependency(self, target, name): + proxy = PBXContainerItemProxy(self, target, name) + dependecy = PBXTargetDependency(target, proxy) + return dependecy def write(self, file): @@ -360,12 +382,18 @@ def write(self, file): w("\trootObject = %s;\n" % self._id) w("}\n") - def add_task_gen(self, target): + def add_target(self, target): self.targets.append(target) # Collect all targets the project produces. If any other target # depends on this target, we can retreive it from here later. - self._output[target.name] = target + # self._output[target.name] = target + + def get_target(self, name): + for t in self.targets: + if t.name == name: + return t + return None class xcode(Build.BuildContext): cmd = 'xcode' @@ -389,6 +417,12 @@ def create_group(self, name, files): group.children.extend(files) return group + def get_target(self, name): + for tg in self.get_all_task_gen(): + if tg.name == name: + return tg + return None + def execute(self): """ Entry point @@ -443,14 +477,18 @@ def execute(self): # Check if any framework to link against is some other target we've made dependency_targets = [] framework = getattr(tg, 'link_framework', []) + for fw in framework: - if fw and fw in p._output: + target = p.get_target(fw) + if target: # Target framework found. Make a build file of it - target = p._output[fw] + # target = p._output[fw] product = PBXBuildFile(target.productReference) fw = PBXFrameworksBuildPhase([product]) buildphases.append(fw) + print Utils.to_list(tg.use) + # Create an XCode dependency so that XCode knows to build that framework before this target proxy = PBXContainerItemProxy(p, target, target.name) dependecy = PBXTargetDependency(target, proxy) @@ -483,7 +521,7 @@ def execute(self): target = PBXNativeTarget(tg.name, target_node, buildphases, cflst, target_type) target.dependencies.extend(dependency_targets) - p.add_task_gen(target) + p.add_target(target) node = self.bldnode.make_node('%s.xcodeproj' % appname) node.mkdir() From ae4f1f5e276ae31b0c0a5c2f187801cb1c9a5474 Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 7 Jul 2015 17:54:08 +0200 Subject: [PATCH 0078/1763] Fixed some issues --- demos/xcode/wscript | 1 - waflib/extras/xcode.py | 71 ++++++++++++++++-------------------------- 2 files changed, 26 insertions(+), 46 deletions(-) diff --git a/demos/xcode/wscript b/demos/xcode/wscript index 56e9ac612f..9f66768690 100644 --- a/demos/xcode/wscript +++ b/demos/xcode/wscript @@ -19,7 +19,6 @@ def build(bld): tg = bld( features='cxx', source=bld.path.ant_glob('src/MyLib/*.cpp'), - source_grpname='Fucker', includes='include', group_files={ 'Include': bld.path.ant_glob('include/MyLib/*.h') diff --git a/waflib/extras/xcode.py b/waflib/extras/xcode.py index 8e225f637f..5932c0750f 100644 --- a/waflib/extras/xcode.py +++ b/waflib/extras/xcode.py @@ -300,9 +300,8 @@ def __init__(self, action, target): self.shellScript = "%s %s %s --targets=%s" % (sys.executable, sys.argv[0], action, target) class PBXNativeTarget(XCodeNode): - def __init__(self, target, node, buildphases, configlist, target_type=TARGET_TYPE_APPLICATION): + def __init__(self, target, node, configlist, target_type=TARGET_TYPE_APPLICATION, buildphases=[]): XCodeNode.__init__(self) - product_type = target_type[0] file_type = target_type[1] @@ -313,21 +312,20 @@ def __init__(self, target, node, buildphases, configlist, target_type=TARGET_TYP self.name = target self.productName = target self.productType = product_type # See TARGET_TYPE_ tuples constants - self.productReference = PBXFileReference(target, node.abspath(), file_type, '') + self.productReference = PBXFileReference(node.name, node.abspath(), file_type, '') def add_build_phase(self, phase): # Some build phase types may appear only once. If a phase type already exists, then merge them. - if ( phase.__name__ == PBXFrameworksBuildPhase.__name__ - or phase.__name__ == PBXSourcesBuildPhase.__name__): + if ( (phase.__class__ == PBXFrameworksBuildPhase) + or (phase.__class__ == PBXSourcesBuildPhase) ): for b in self.buildPhases: - if b.__name__ == phase.__name__: + if b.__class__ == phase.__class__: b.files.extend(phase.files) - break - else: - self.buildPhases.append(phase) + return + self.buildPhases.append(phase) def add_dependency(self, depnd): - self.dependencies.append(dep) + self.dependencies.append(depnd) # Root project object class PBXProject(XCodeNode): @@ -353,9 +351,6 @@ def __init__(self, name, version, env): self._objectVersion = version[1] # self._output = {} - def create_build_file(self, fileref, settings={}): - return PBXBuildFile(fileref, settings) - def create_target_dependency(self, target, name): proxy = PBXContainerItemProxy(self, target, name) dependecy = PBXTargetDependency(target, proxy) @@ -454,15 +449,6 @@ def execute(self): else: self.to_log("Argument 'group_files' passed to target '%s' was not a dictionary. Hence, some source files may not be included. Please provide a dict of source files, with group name as key and list of source files as value.\n" % tg.name) - buildphases = [] - - if len(tg.source) > 0: - g = self.create_group(getattr(tg, 'source_grpname', 'Source'), tg.source) - buildfiles = [PBXBuildFile(fileref) for fileref in g.children] - compilesources = PBXSourcesBuildPhase(buildfiles) - buildphases.append(compilesources) - target_group.children.append(g) - # Determine what type to build - framework, app bundle etc. target_type = getattr(tg, 'target_type', 'app') if target_type not in TARGET_TYPES: @@ -474,27 +460,6 @@ def execute(self): # Create the output node target_node = tg.path.find_or_declare(tg.name+file_ext) - # Check if any framework to link against is some other target we've made - dependency_targets = [] - framework = getattr(tg, 'link_framework', []) - - for fw in framework: - target = p.get_target(fw) - if target: - # Target framework found. Make a build file of it - # target = p._output[fw] - product = PBXBuildFile(target.productReference) - fw = PBXFrameworksBuildPhase([product]) - buildphases.append(fw) - - print Utils.to_list(tg.use) - - # Create an XCode dependency so that XCode knows to build that framework before this target - proxy = PBXContainerItemProxy(p, target, target.name) - dependecy = PBXTargetDependency(target, proxy) - dependency_targets.append(dependecy) - - # Create settings which can override the project settings. Defaults to none if user # did not pass argument. settings = getattr(tg, 'settings', {}) @@ -518,8 +483,24 @@ def execute(self): cflst.append(XCBuildConfiguration(k, v)) cflst = XCConfigurationList(cflst) - target = PBXNativeTarget(tg.name, target_node, buildphases, cflst, target_type) - target.dependencies.extend(dependency_targets) + target = PBXNativeTarget(tg.name, target_node, cflst, target_type, []) + + if len(tg.source) > 0: + g = self.create_group(getattr(tg, 'source_grpname', 'Source'), tg.source) + buildfiles = [PBXBuildFile(fileref) for fileref in g.children] + target.add_build_phase(PBXSourcesBuildPhase(buildfiles)) + target_group.children.append(g) + + # Check if any framework to link against is some other target we've made + framework = getattr(tg, 'link_framework', []) + + for fw in framework: + use_target = p.get_target(fw) + if use_target: + # Target framework found. Make a build file of it + # Create an XCode dependency so that XCode knows to build that framework before this target + target.add_dependency(p.create_target_dependency(use_target, use_target.name)) + target.add_build_phase(PBXFrameworksBuildPhase([PBXBuildFile(use_target.productReference)])) p.add_target(target) From 5f9a900dc1470147f33fa1c46fbd3a3df90b4fb5 Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 7 Jul 2015 18:07:21 +0200 Subject: [PATCH 0079/1763] Made better integrations with the standard INCPATHS variable --- demos/xcode/wscript | 1 + waflib/extras/xcode.py | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/demos/xcode/wscript b/demos/xcode/wscript index 9f66768690..16c8742ddd 100644 --- a/demos/xcode/wscript +++ b/demos/xcode/wscript @@ -26,6 +26,7 @@ def build(bld): target='MyLib', target_type='framework' ) + tg2 = bld( features='cxx', diff --git a/waflib/extras/xcode.py b/waflib/extras/xcode.py index 5932c0750f..88c0620b1e 100644 --- a/waflib/extras/xcode.py +++ b/waflib/extras/xcode.py @@ -427,6 +427,7 @@ def execute(self): self.load_envs() self.recurse([self.run_dir]) + appname = getattr(Context.g_module, Context.APPNAME, os.path.basename(self.srcnode.abspath())) p = PBXProject(appname, ('Xcode 6.0', 46), self.env) @@ -465,9 +466,9 @@ def execute(self): settings = getattr(tg, 'settings', {}) # Setup include search paths - include_dirs = Utils.to_list(getattr(tg, 'includes', [])) - include_dirs = [x.abspath() for x in self.as_nodes(include_dirs)] - includes_dirs_dict = {'HEADER_SEARCH_PATHS': ['$(inherited)'] + include_dirs} + # include_dirs = Utils.to_list(getattr(tg, 'includes', [])) + # include_dirs = [x.abspath() for x in self.as_nodes(include_dirs)] + includes_dirs_dict = {'HEADER_SEARCH_PATHS': ['$(inherited)'] + tg.env['INCPATHS']} # Set the HEADER_SEARCH_PATHS for all configurations keys = set(settings.keys() + self.env.PROJ_CONFIGURATION.keys()) From b8330b29cb3700805589c1a6c6167f485f5a3ddb Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 7 Jul 2015 18:21:35 +0200 Subject: [PATCH 0080/1763] Improved Project -> Configuration API --- waflib/extras/xcode.py | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/waflib/extras/xcode.py b/waflib/extras/xcode.py index 88c0620b1e..19397a0eac 100644 --- a/waflib/extras/xcode.py +++ b/waflib/extras/xcode.py @@ -199,11 +199,12 @@ def __init__(self, name, settings = {}, env=None): class XCConfigurationList(XCodeNode): - def __init__(self, settings): + def __init__(self, configlst): + """ :param configlst: list of XCConfigurationList """ XCodeNode.__init__(self) - self.buildConfigurations = settings + self.buildConfigurations = configlst self.defaultConfigurationIsVisible = 0 - self.defaultConfigurationName = settings and settings[0].name or "" + self.defaultConfigurationName = configlst and configlst[0].name or "" # Group/Files class PBXFileReference(XCodeNode): @@ -300,12 +301,12 @@ def __init__(self, action, target): self.shellScript = "%s %s %s --targets=%s" % (sys.executable, sys.argv[0], action, target) class PBXNativeTarget(XCodeNode): - def __init__(self, target, node, configlist, target_type=TARGET_TYPE_APPLICATION, buildphases=[]): + def __init__(self, target, node, target_type=TARGET_TYPE_APPLICATION, configlist=[], buildphases=[]): XCodeNode.__init__(self) product_type = target_type[0] file_type = target_type[1] - self.buildConfigurationList = configlist + self.buildConfigurationList = XCConfigurationList(configlist) self.buildPhases = buildphases self.buildRules = [] self.dependencies = [] @@ -314,6 +315,10 @@ def __init__(self, target, node, configlist, target_type=TARGET_TYPE_APPLICATION self.productType = product_type # See TARGET_TYPE_ tuples constants self.productReference = PBXFileReference(node.name, node.abspath(), file_type, '') + def add_configuration(self, cf): + """ :type cf: XCBuildConfiguration """ + self.buildConfigurationList.buildConfigurations.append(cf) + def add_build_phase(self, phase): # Some build phase types may appear only once. If a phase type already exists, then merge them. if ( (phase.__class__ == PBXFrameworksBuildPhase) @@ -466,8 +471,6 @@ def execute(self): settings = getattr(tg, 'settings', {}) # Setup include search paths - # include_dirs = Utils.to_list(getattr(tg, 'includes', [])) - # include_dirs = [x.abspath() for x in self.as_nodes(include_dirs)] includes_dirs_dict = {'HEADER_SEARCH_PATHS': ['$(inherited)'] + tg.env['INCPATHS']} # Set the HEADER_SEARCH_PATHS for all configurations @@ -478,13 +481,12 @@ def execute(self): else: settings[k] = includes_dirs_dict - # Create the config lists - cflst = [] - for k,v in settings.items(): - cflst.append(XCBuildConfiguration(k, v)) - cflst = XCConfigurationList(cflst) - target = PBXNativeTarget(tg.name, target_node, cflst, target_type, []) + target = PBXNativeTarget(tg.name, target_node, target_type, [], []) + + # Add the configs + for k,v in settings.items(): + target.add_configuration(XCBuildConfiguration(k, v)) if len(tg.source) > 0: g = self.create_group(getattr(tg, 'source_grpname', 'Source'), tg.source) From 140453a959fe861c06cd228ab71163dbd9cbe6b8 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Tue, 7 Jul 2015 20:58:58 +0200 Subject: [PATCH 0081/1763] Prevent installation tasks having postpone=False from running twice --- waflib/Build.py | 1 + 1 file changed, 1 insertion(+) diff --git a/waflib/Build.py b/waflib/Build.py index fdd59fb032..154e5c8c68 100644 --- a/waflib/Build.py +++ b/waflib/Build.py @@ -1015,6 +1015,7 @@ def run_task_now(self, tsk, postpone): if tsk.runnable_status() == Task.ASK_LATER: raise self.WafError('cannot post the task %r' % tsk) tsk.run() + tsk.hasrun = True def install_files(self, dest, files, env=None, chmod=Utils.O644, relative_trick=False, cwd=None, add=True, postpone=True, task=None): """ From 4949c0d894ccd4cc679b47d6fdc5993a5a5d7075 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Tue, 7 Jul 2015 21:00:18 +0200 Subject: [PATCH 0082/1763] Ensure Doxygen outputs are installed even when the task is not run --- waflib/extras/doxygen.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/waflib/extras/doxygen.py b/waflib/extras/doxygen.py index acd4398dcf..0a6f6a63d6 100644 --- a/waflib/extras/doxygen.py +++ b/waflib/extras/doxygen.py @@ -112,7 +112,11 @@ def runnable_status(self): self.output_dir = bld.root.find_dir(self.pars['OUTPUT_DIRECTORY']) self.signature() - return Task.Task.runnable_status(self) + ret = Task.Task.runnable_status(self) + if ret == Task.SKIP_ME: + # in case the files were removed + self.add_install() + return ret def scan(self): exclude_patterns = self.pars.get('EXCLUDE_PATTERNS','').split() @@ -146,6 +150,11 @@ def post_run(self): nodes = self.output_dir.ant_glob('**/*', quiet=True) for x in nodes: x.sig = Utils.h_file(x.abspath()) + self.add_install() + return Task.Task.post_run(self) + + def add_install(self): + nodes = self.output_dir.ant_glob('**/*', quiet=True) self.outputs += nodes if getattr(self.generator, 'install_path', None): if not getattr(self.generator, 'doxy_tar', None): @@ -154,7 +163,6 @@ def post_run(self): postpone=False, cwd=self.output_dir, relative_trick=True) - return Task.Task.post_run(self) class tar(Task.Task): "quick tar creation" From 4f93b4e8145034afeaf07e2d9f535a646d4b259d Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Tue, 7 Jul 2015 22:30:00 +0200 Subject: [PATCH 0083/1763] docs --- waflib/Tools/c_config.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/waflib/Tools/c_config.py b/waflib/Tools/c_config.py index e4761ab3bf..b713efdb96 100644 --- a/waflib/Tools/c_config.py +++ b/waflib/Tools/c_config.py @@ -663,6 +663,16 @@ def check(self, *k, **kw): Perform a configuration test by calling :py:func:`waflib.Configure.run_build`. For the complete list of parameters, see :py:func:`waflib.Tools.c_config.validate_c`. To force a specific compiler, pass "compiler='c'" or "compiler='cxx'" in the arguments + + Besides build targets, complete builds can be given though a build function. All files will + be written to a temporary directory:: + + def build(bld): + lib_node = bld.srcnode.make_node('libdir/liblc1.c') + lib_node.parent.mkdir() + lib_node.write('#include \\nint lib_func(void) { FILE *f = fopen("foo", "r");}\\n', 'w') + bld(features='c cshlib', source=[lib_node], linkflags=conf.env.EXTRA_LDFLAGS, target='liblc') + conf.check(build_fun=build, msg=msg) """ self.validate_c(kw) self.start_msg(kw['msg'], **kw) From 0d9a9b7e775a6b94a67e6694bb56d518b08eaff0 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sat, 11 Jul 2015 12:01:26 +0200 Subject: [PATCH 0084/1763] Let write_config_header use env.WAF_CONFIG_H_PRELUDE A prelude will be added from the variable env.WAF_CONFIG_H_PRELUDE if provided. This can be used to insert complex macros or include guards:: def configure(conf): conf.env.WAF_CONFIG_H_PRELUDE = '#include \\n' conf.write_config_header('config.h') --- waflib/Tools/c_config.py | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/waflib/Tools/c_config.py b/waflib/Tools/c_config.py index b713efdb96..77e1211ddb 100644 --- a/waflib/Tools/c_config.py +++ b/waflib/Tools/c_config.py @@ -867,7 +867,10 @@ def configure(cnf): cnf.define('A', 1) cnf.write_config_header('config.h') - :param configfile: relative path to the file to create + This function only adds include guards (if necessary), consult + :py:func:`waflib.Tools.c_config.get_config_header` for details on the body. + + :param configfile: path to the file to create (relative or absolute) :type configfile: string :param guard: include guard name to add, by default it is computed from the file name :type guard: string @@ -896,7 +899,7 @@ def configure(cnf): node.write('\n'.join(lst)) - # config files are not removed on "waf clean" + # config files must not be removed on "waf clean" self.env.append_unique(Build.CFG_FILES, [node.abspath()]) if remove: @@ -910,9 +913,16 @@ def get_config_header(self, defines=True, headers=False, define_prefix=''): Create the contents of a ``config.h`` file from the defines and includes set in conf.env.define_key / conf.env.include_key. No include guards are added. + A prelude will be added from the variable env.WAF_CONFIG_H_PRELUDE if provided. This + can be used to insert complex macros or include guards:: + + def configure(conf): + conf.env.WAF_CONFIG_H_PRELUDE = '#include \\n' + conf.write_config_header('config.h') + :param defines: write the defines values :type defines: bool - :param headers: write the headers + :param headers: write include entries for each element in self.env.INCKEYS :type headers: bool :type define_prefix: string :param define_prefix: prefix all the defines with a particular prefix @@ -920,6 +930,10 @@ def get_config_header(self, defines=True, headers=False, define_prefix=''): :rtype: string """ lst = [] + + if self.env.WAF_CONFIG_H_PRELUDE: + lst.append(self.env.WAF_CONFIG_H_PRELUDE) + if headers: for x in self.env[INCKEYS]: lst.append('#include <%s>' % x) From 6891ebb7c9dd7ae32b358cd823361c43e8c58634 Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 11 Jul 2015 16:04:10 +0200 Subject: [PATCH 0085/1763] Switched over to use tmp_use_seen istead of link_framework --- demos/xcode/wscript | 8 ++++---- waflib/extras/xcode.py | 22 ++++++++-------------- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/demos/xcode/wscript b/demos/xcode/wscript index 16c8742ddd..e6ca06ba77 100644 --- a/demos/xcode/wscript +++ b/demos/xcode/wscript @@ -14,6 +14,7 @@ def configure(conf): conf.env.SDKROOT = 'macosx10.9' conf.env.PRODUCT_NAME = '$(TARGET_NAME)' + def build(bld): bld.load('cxx') tg = bld( @@ -34,12 +35,11 @@ def build(bld): includes=tg.includes, target='MyApp', target_type='app', - link_framework=['MyLib'], - use='MyLib Olle', + use='MyLib', settings={"Debug": {"CONFIG_NAME": 'Debug'}} ) - - # print tg2.env + #tg2.propagate_uselib_vars() + # print tg2.tmp_use_seen # tg2.process_use() # print bld.get_targets() diff --git a/waflib/extras/xcode.py b/waflib/extras/xcode.py index 19397a0eac..b15f54ac3c 100644 --- a/waflib/extras/xcode.py +++ b/waflib/extras/xcode.py @@ -357,6 +357,7 @@ def __init__(self, name, version, env): # self._output = {} def create_target_dependency(self, target, name): + """ : param target : PXBNativeTarget """ proxy = PBXContainerItemProxy(self, target, name) dependecy = PBXTargetDependency(target, proxy) return dependecy @@ -385,10 +386,6 @@ def write(self, file): def add_target(self, target): self.targets.append(target) - # Collect all targets the project produces. If any other target - # depends on this target, we can retreive it from here later. - # self._output[target.name] = target - def get_target(self, name): for t in self.targets: if t.name == name: @@ -418,10 +415,7 @@ def create_group(self, name, files): return group def get_target(self, name): - for tg in self.get_all_task_gen(): - if tg.name == name: - return tg - return None + return self.get_tgen_by_name(name) def execute(self): """ @@ -495,13 +489,13 @@ def execute(self): target_group.children.append(g) # Check if any framework to link against is some other target we've made - framework = getattr(tg, 'link_framework', []) - - for fw in framework: - use_target = p.get_target(fw) + libs = getattr(tg, 'tmp_use_seen', []) + print tg.tmp_use_seen + for lib in libs: + use_target = p.get_target(lib) if use_target: - # Target framework found. Make a build file of it - # Create an XCode dependency so that XCode knows to build that framework before this target + # Target libs found. Make a build file of it + # Create an XCode dependency so that XCode knows to build that libs before this target target.add_dependency(p.create_target_dependency(use_target, use_target.name)) target.add_build_phase(PBXFrameworksBuildPhase([PBXBuildFile(use_target.productReference)])) From e10398fcd38271ca45bfb37b78f30b6791abc10a Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sat, 11 Jul 2015 20:17:16 +0200 Subject: [PATCH 0086/1763] docs --- demos/c/wscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demos/c/wscript b/demos/c/wscript index 880146b61c..b13103fa73 100644 --- a/demos/c/wscript +++ b/demos/c/wscript @@ -66,7 +66,7 @@ def build(bld): bld.env.FOO =['m', 'ncurses'] bld.env.ST = '-L%s' - bld(rule='echo ${ST:FOO}', always=True, shell=1) + bld(rule='echo ${ST:FOO} ${ST:SRC}', always=True, source='wscript', shell=1) # illustrate how to add a command 'foo' and to execute things in it if bld.cmd == 'foo': From e44ab6e6ecc35b7b434b05d86f145c39fcdd4be8 Mon Sep 17 00:00:00 2001 From: Simon Date: Sun, 12 Jul 2015 22:06:51 +0200 Subject: [PATCH 0087/1763] Support for framework,lib,stlib, etc. --- demos/xcode/wscript | 16 +++++++------- waflib/extras/xcode.py | 47 +++++++++++++++++++++++++++--------------- 2 files changed, 37 insertions(+), 26 deletions(-) diff --git a/demos/xcode/wscript b/demos/xcode/wscript index e6ca06ba77..07dc61cc3d 100644 --- a/demos/xcode/wscript +++ b/demos/xcode/wscript @@ -13,7 +13,7 @@ def configure(conf): conf.env.MACOSX_DEPLOYMENT_TARGET = '10.9' conf.env.SDKROOT = 'macosx10.9' conf.env.PRODUCT_NAME = '$(TARGET_NAME)' - + # conf.env.FRAMEWORK_SDL2 = '/Library/Frameworks/SDL2.framework' def build(bld): bld.load('cxx') @@ -28,19 +28,17 @@ def build(bld): target_type='framework' ) - + bld.env.LIB_SDL2 = '/Library/Frameworks/SDL2.framework/SDL2' tg2 = bld( - features='cxx', + features='cxx cxxprogram', source=bld.path.ant_glob('src/*.cpp|'), includes=tg.includes, target='MyApp', target_type='app', - use='MyLib', + use='MyLib Yolo', + uselib='SDL2', + cxxflags='-O3', + framework='Cocoa', settings={"Debug": {"CONFIG_NAME": 'Debug'}} ) - #tg2.propagate_uselib_vars() - # print tg2.tmp_use_seen - # tg2.process_use() - # print bld.get_targets() - \ No newline at end of file diff --git a/waflib/extras/xcode.py b/waflib/extras/xcode.py index b15f54ac3c..93032fd37b 100644 --- a/waflib/extras/xcode.py +++ b/waflib/extras/xcode.py @@ -460,27 +460,16 @@ def execute(self): # Create the output node target_node = tg.path.find_or_declare(tg.name+file_ext) + target = PBXNativeTarget(tg.name, target_node, target_type, [], []) + # Create settings which can override the project settings. Defaults to none if user # did not pass argument. settings = getattr(tg, 'settings', {}) - # Setup include search paths - includes_dirs_dict = {'HEADER_SEARCH_PATHS': ['$(inherited)'] + tg.env['INCPATHS']} - - # Set the HEADER_SEARCH_PATHS for all configurations - keys = set(settings.keys() + self.env.PROJ_CONFIGURATION.keys()) - for k in keys: - if k in settings: - settings[k].update(includes_dirs_dict) - else: - settings[k] = includes_dirs_dict - - - target = PBXNativeTarget(tg.name, target_node, target_type, [], []) + print tg.env + print getattr(tg, 'use', '') + print getattr(tg, 'uselib', '') - # Add the configs - for k,v in settings.items(): - target.add_configuration(XCBuildConfiguration(k, v)) if len(tg.source) > 0: g = self.create_group(getattr(tg, 'source_grpname', 'Source'), tg.source) @@ -490,7 +479,6 @@ def execute(self): # Check if any framework to link against is some other target we've made libs = getattr(tg, 'tmp_use_seen', []) - print tg.tmp_use_seen for lib in libs: use_target = p.get_target(lib) if use_target: @@ -499,6 +487,31 @@ def execute(self): target.add_dependency(p.create_target_dependency(use_target, use_target.name)) target.add_build_phase(PBXFrameworksBuildPhase([PBXBuildFile(use_target.productReference)])) + # Check for libs to link + libs = Utils.to_list(tg.env.FRAMEWORK) + ld_flags = ['-framework %s' % lib for lib in libs] + ld_flags.extend(Utils.to_list(tg.env.STLIB) + Utils.to_list(tg.env.LIB)) + + # Setup include search paths + includes_dirs_dict = { + 'HEADER_SEARCH_PATHS': ['$(inherited)'] + tg.env['INCPATHS'], + 'LIBRARY_SEARCH_PATHS': ['$(inherited)'] + Utils.to_list(tg.env.LIBPATH) + Utils.to_list(tg.env.STLIBPATH), + 'FRAMEWORK_SEARCH_PATHS': ['$(inherited)'] + Utils.to_list(tg.env.FRAMEWORKPATH), + 'OTHER_LDFLAGS': r'\n'.join(ld_flags) + } + + # Set the HEADER_SEARCH_PATHS for all configurations + keys = set(settings.keys() + self.env.PROJ_CONFIGURATION.keys()) + for k in keys: + if k in settings: + settings[k].update(includes_dirs_dict) + else: + settings[k] = includes_dirs_dict + + # Add the configs + for k,v in settings.items(): + target.add_configuration(XCBuildConfiguration(k, v)) + p.add_target(target) node = self.bldnode.make_node('%s.xcodeproj' % appname) From a59e38835d34c8fd01e42fe2d779476b21cc5e79 Mon Sep 17 00:00:00 2001 From: Simon Date: Sun, 12 Jul 2015 22:17:26 +0200 Subject: [PATCH 0088/1763] Clean up --- demos/xcode/wscript | 1 - waflib/extras/xcode.py | 39 +++++++++++++++------------------------ 2 files changed, 15 insertions(+), 25 deletions(-) diff --git a/demos/xcode/wscript b/demos/xcode/wscript index 07dc61cc3d..c544f1b23c 100644 --- a/demos/xcode/wscript +++ b/demos/xcode/wscript @@ -13,7 +13,6 @@ def configure(conf): conf.env.MACOSX_DEPLOYMENT_TARGET = '10.9' conf.env.SDKROOT = 'macosx10.9' conf.env.PRODUCT_NAME = '$(TARGET_NAME)' - # conf.env.FRAMEWORK_SDL2 = '/Library/Frameworks/SDL2.framework' def build(bld): bld.load('cxx') diff --git a/waflib/extras/xcode.py b/waflib/extras/xcode.py index 93032fd37b..76ac628f45 100644 --- a/waflib/extras/xcode.py +++ b/waflib/extras/xcode.py @@ -426,7 +426,6 @@ def execute(self): self.load_envs() self.recurse([self.run_dir]) - appname = getattr(Context.g_module, Context.APPNAME, os.path.basename(self.srcnode.abspath())) p = PBXProject(appname, ('Xcode 6.0', 46), self.env) @@ -462,53 +461,48 @@ def execute(self): target = PBXNativeTarget(tg.name, target_node, target_type, [], []) - # Create settings which can override the project settings. Defaults to none if user - # did not pass argument. - settings = getattr(tg, 'settings', {}) - - print tg.env - print getattr(tg, 'use', '') - print getattr(tg, 'uselib', '') - - + # Collect source and put them in a group with name set to 'Source', which can be overriden if len(tg.source) > 0: g = self.create_group(getattr(tg, 'source_grpname', 'Source'), tg.source) buildfiles = [PBXBuildFile(fileref) for fileref in g.children] target.add_build_phase(PBXSourcesBuildPhase(buildfiles)) target_group.children.append(g) + # Create build settings which can override the project settings. Defaults to none if user + # did not pass argument. However, this will be filled up further below with target specfic + # search paths, libs to link etc. + settings = getattr(tg, 'settings', {}) + # Check if any framework to link against is some other target we've made libs = getattr(tg, 'tmp_use_seen', []) for lib in libs: use_target = p.get_target(lib) if use_target: - # Target libs found. Make a build file of it - # Create an XCode dependency so that XCode knows to build that libs before this target + # Create an XCode dependency so that XCode knows to build the other target before this target target.add_dependency(p.create_target_dependency(use_target, use_target.name)) target.add_build_phase(PBXFrameworksBuildPhase([PBXBuildFile(use_target.productReference)])) - # Check for libs to link - libs = Utils.to_list(tg.env.FRAMEWORK) - ld_flags = ['-framework %s' % lib for lib in libs] + # Merge frameworks and libs into one list, and prefix the frameworks + ld_flags = ['-framework %s' % lib for lib in Utils.to_list(tg.env.FRAMEWORK)] ld_flags.extend(Utils.to_list(tg.env.STLIB) + Utils.to_list(tg.env.LIB)) - # Setup include search paths - includes_dirs_dict = { + # Override target specfic build settings + bldsettings = { 'HEADER_SEARCH_PATHS': ['$(inherited)'] + tg.env['INCPATHS'], 'LIBRARY_SEARCH_PATHS': ['$(inherited)'] + Utils.to_list(tg.env.LIBPATH) + Utils.to_list(tg.env.STLIBPATH), 'FRAMEWORK_SEARCH_PATHS': ['$(inherited)'] + Utils.to_list(tg.env.FRAMEWORKPATH), 'OTHER_LDFLAGS': r'\n'.join(ld_flags) } - # Set the HEADER_SEARCH_PATHS for all configurations + # The keys represents different build configuration, e.g. Debug, Release and so on.. + # Insert our generated build settings to all configuration names keys = set(settings.keys() + self.env.PROJ_CONFIGURATION.keys()) for k in keys: if k in settings: - settings[k].update(includes_dirs_dict) + settings[k].update(bldsettings) else: - settings[k] = includes_dirs_dict + settings[k] = bldsettings - # Add the configs for k,v in settings.items(): target.add_configuration(XCBuildConfiguration(k, v)) @@ -518,6 +512,3 @@ def execute(self): node.mkdir() node = node.make_node('project.pbxproj') p.write(open(node.abspath(), 'w')) - - - From da9a86d2a6ecb0df3c4f72ce3ce1dd7ff93b1675 Mon Sep 17 00:00:00 2001 From: Simon Date: Sun, 12 Jul 2015 22:31:10 +0200 Subject: [PATCH 0089/1763] Clean up --- waflib/extras/xcode.py | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/waflib/extras/xcode.py b/waflib/extras/xcode.py index 76ac628f45..518fc28bcf 100644 --- a/waflib/extras/xcode.py +++ b/waflib/extras/xcode.py @@ -69,17 +69,17 @@ def options(opt): TARGET_TYPE_FRAMEWORK = (PRODUCT_TYPE_FRAMEWORK, FILE_TYPE_FRAMEWORK, '.framework') TARGET_TYPE_APPLICATION = (PRODUCT_TYPE_APPLICATION, FILE_TYPE_APPLICATION, '.app') -# Maps a target type as a string to its data +# Maps target type string to its data TARGET_TYPES = { 'framework': TARGET_TYPE_FRAMEWORK, 'app': TARGET_TYPE_APPLICATION } class XcodeConfiguration(Configure.ConfigurationContext): - """ Configuration of the global project settings. Sets a environment variable 'PROJ_CONFIGURATION' + """ Configuration of the global project settings. Sets an environment variable 'PROJ_CONFIGURATION' which is a dictionary of configuration name and buildsettings pair. E.g.: - { + env.PROJ_CONFIGURATION = { 'Debug': { 'ARCHS': 'x86', ... @@ -101,13 +101,13 @@ def execute(self): Context.Context.execute(self) if not self.env.PROJ_CONFIGURATION: - self.to_log("A default project configuration was created since no custom one was given in the configure(ctx) stage. Define your custom project settings by adding PROJ_CONFIGURATION to env. The env.PROJ_CONFIGURATION must be a dictionary with at least one key, where each key is the configuration name, and the value is a dictionary of key/value settings.\n") + self.to_log("A default project configuration was created since no custom one was given in the configure(conf) stage. Define your custom project settings by adding PROJ_CONFIGURATION to env. The env.PROJ_CONFIGURATION must be a dictionary with at least one key, where each key is the configuration name, and the value is a dictionary of key/value settings.\n") # Set include dir variable if 'HEADER_SEARCH_PATHS' not in self.env: self.env.HEADER_SEARCH_PATHS = ['$(inherited)'] else: - self.env.HEADER_SEARCH_PATHS = [self.srcnode.make_node(f).abspath() for f in Utils.to_list(self.env.HEADER_SEARCH_PATHS)] + self.env.HEADER_SEARCH_PATHS = [self.srcnode.make_node(f).abspath() for f in Utils.to_list(self.env.INCLUDES)] # Check for any added config files added by the tool 'c_config'. if 'cfg_files' in self.env: @@ -120,15 +120,10 @@ def execute(self): "Release": self.env.get_merged_dict(), } - # Run user configuration(ctx) for customization - Configure.ConfigurationContext.execute(self) - # Error check customization if not isinstance(self.env.PROJ_CONFIGURATION, dict): raise Errors.ConfigurationError("The env.PROJ_CONFIGURATION must be a dictionary with at least one key, where each key is the configuration name, and the value is a dictionary of key/value settings.") - - part1 = 0 part2 = 10000 part3 = 0 From dd19e4b1ee9fc527971c4ed3ffe986bf35293a70 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 13 Jul 2015 00:51:55 +0200 Subject: [PATCH 0090/1763] Fixes --- waflib/extras/xcode.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/waflib/extras/xcode.py b/waflib/extras/xcode.py index 518fc28bcf..48d7c621fb 100644 --- a/waflib/extras/xcode.py +++ b/waflib/extras/xcode.py @@ -19,6 +19,10 @@ def options(opt): from waflib import Context, TaskGen, Build, Utils, ConfigSet, Configure, Errors import os, sys, random, time +@TaskGen.extension('.m', '.mm') +def dummy(self, node): + pass + HEADERS_GLOB = '**/(*.h|*.hpp|*.H|*.inl)' MAP_EXT = { @@ -98,7 +102,8 @@ def __init__(self): def execute(self): # Run user configure() - Context.Context.execute(self) + Configure.ConfigurationContext.execute(self) + if not self.env.PROJ_CONFIGURATION: self.to_log("A default project configuration was created since no custom one was given in the configure(conf) stage. Define your custom project settings by adding PROJ_CONFIGURATION to env. The env.PROJ_CONFIGURATION must be a dictionary with at least one key, where each key is the configuration name, and the value is a dictionary of key/value settings.\n") @@ -114,16 +119,18 @@ def execute(self): self.env.HEADER_SEARCH_PATHS.extend([os.path.abspath(os.path.dirname(f)) for f in self.env.cfg_files]) # Create default project configuration? - # if 'PROJ_CONFIGURATION' not in self.env.keys(): - self.env.PROJ_CONFIGURATION = { - "Debug": self.env.get_merged_dict(), - "Release": self.env.get_merged_dict(), - } + if 'PROJ_CONFIGURATION' not in self.env: + self.env.PROJ_CONFIGURATION = { + "Debug": self.env.get_merged_dict(), + "Release": self.env.get_merged_dict(), + } # Error check customization if not isinstance(self.env.PROJ_CONFIGURATION, dict): raise Errors.ConfigurationError("The env.PROJ_CONFIGURATION must be a dictionary with at least one key, where each key is the configuration name, and the value is a dictionary of key/value settings.") + self.store() + part1 = 0 part2 = 10000 part3 = 0 From a3a74e59c18844e301fc135b45fc8b74ae2d01e4 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 13 Jul 2015 02:16:52 +0200 Subject: [PATCH 0091/1763] Added default values for required build settings --- demos/xcode/wscript | 1 - waflib/extras/xcode.py | 10 +++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/demos/xcode/wscript b/demos/xcode/wscript index c544f1b23c..b73b3006e5 100644 --- a/demos/xcode/wscript +++ b/demos/xcode/wscript @@ -12,7 +12,6 @@ def configure(conf): conf.env.ARCHS = 'x86_64' conf.env.MACOSX_DEPLOYMENT_TARGET = '10.9' conf.env.SDKROOT = 'macosx10.9' - conf.env.PRODUCT_NAME = '$(TARGET_NAME)' def build(bld): bld.load('cxx') diff --git a/waflib/extras/xcode.py b/waflib/extras/xcode.py index 48d7c621fb..1e0cb17019 100644 --- a/waflib/extras/xcode.py +++ b/waflib/extras/xcode.py @@ -125,6 +125,14 @@ def execute(self): "Release": self.env.get_merged_dict(), } + # Some build settings are required to be present by XCode. We will supply default values + # if user hasn't defined any. + defaults_required = [('PRODUCT_NAME', '$(TARGET_NAME')] + for cfgname,settings in self.env.PROJ_CONFIGURATION.iteritems(): + for default_var, default_val in defaults_required: + if default_var not in settings: + settings[default_var] = default_val + # Error check customization if not isinstance(self.env.PROJ_CONFIGURATION, dict): raise Errors.ConfigurationError("The env.PROJ_CONFIGURATION must be a dictionary with at least one key, where each key is the configuration name, and the value is a dictionary of key/value settings.") @@ -430,7 +438,7 @@ def execute(self): appname = getattr(Context.g_module, Context.APPNAME, os.path.basename(self.srcnode.abspath())) - p = PBXProject(appname, ('Xcode 6.0', 46), self.env) + p = PBXProject(appname, ('Xcode 3.2', 46), self.env) for g in self.groups: for tg in g: From 47b5783be5a5a188c1262b5583bdc325f80e0299 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 13 Jul 2015 02:24:49 +0200 Subject: [PATCH 0092/1763] Docs --- waflib/extras/xcode.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/waflib/extras/xcode.py b/waflib/extras/xcode.py index 1e0cb17019..4ace597dbe 100644 --- a/waflib/extras/xcode.py +++ b/waflib/extras/xcode.py @@ -364,7 +364,6 @@ def __init__(self, name, version, env): self.projectDirPath = "" self.targets = [] self._objectVersion = version[1] - # self._output = {} def create_target_dependency(self, target, name): """ : param target : PXBNativeTarget """ @@ -397,6 +396,7 @@ def add_target(self, target): self.targets.append(target) def get_target(self, name): + """ Get a reference to PBXNativeTarget if it exists """ for t in self.targets: if t.name == name: return t @@ -418,13 +418,16 @@ def as_nodes(self, files): return nodes def create_group(self, name, files): - """ Returns a new PBXGroup containing the files (paths) passed in the files arg """ + """ Returns a new PBXGroup containing the files (paths) passed in the files arg + :type files: string + """ group = PBXGroup(name) files = [PBXFileReference(d.name, d.abspath()) for d in self.as_nodes(files)] group.children.extend(files) return group def get_target(self, name): + """ Get TaskGen by name. TODO remove """ return self.get_tgen_by_name(name) def execute(self): From 7d50934a8e7178a5f0171652f4564fa7260de7ff Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 13 Jul 2015 02:25:13 +0200 Subject: [PATCH 0093/1763] Removed unused method --- waflib/extras/xcode.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/waflib/extras/xcode.py b/waflib/extras/xcode.py index 4ace597dbe..f5dbb8ecbd 100644 --- a/waflib/extras/xcode.py +++ b/waflib/extras/xcode.py @@ -426,10 +426,6 @@ def create_group(self, name, files): group.children.extend(files) return group - def get_target(self, name): - """ Get TaskGen by name. TODO remove """ - return self.get_tgen_by_name(name) - def execute(self): """ Entry point From 3924f60974bbc1aae543b0ef0fdd712683b4f6fc Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 13 Jul 2015 12:47:01 +0200 Subject: [PATCH 0094/1763] Added more target types. Added bld wrappers --- demos/xcode/wscript | 19 +++++++++++++++++++ waflib/extras/xcode.py | 34 +++++++++++++++++++++++++++++----- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/demos/xcode/wscript b/demos/xcode/wscript index b73b3006e5..313131d75b 100644 --- a/demos/xcode/wscript +++ b/demos/xcode/wscript @@ -39,4 +39,23 @@ def build(bld): framework='Cocoa', settings={"Debug": {"CONFIG_NAME": 'Debug'}} ) + + bld.dylib( + source=tg.source, + includes=tg.includes, + target='MyDynLibYo', + ) + + bld.exe( + source=tg.source, + includes=tg.includes, + target='MyExe', + ) + + bld.program( + source=tg.source, + includes=tg.includes, + target='MyStaticLib', + target_type='stlib' + ) \ No newline at end of file diff --git a/waflib/extras/xcode.py b/waflib/extras/xcode.py index f5dbb8ecbd..033af26631 100644 --- a/waflib/extras/xcode.py +++ b/waflib/extras/xcode.py @@ -17,6 +17,7 @@ def options(opt): # TODO: support iOS projects from waflib import Context, TaskGen, Build, Utils, ConfigSet, Configure, Errors +from waflib.Build import BuildContext import os, sys, random, time @TaskGen.extension('.m', '.mm') @@ -59,7 +60,7 @@ def dummy(self, node): # Used in PBXNativeTarget elements PRODUCT_TYPE_APPLICATION = 'com.apple.product-type.application' PRODUCT_TYPE_FRAMEWORK = 'com.apple.product-type.framework' -PRODUCT_TYPE_TOOL = 'com.apple.product-type.tool' +PRODUCT_TYPE_EXECUTABLE = 'com.apple.product-type.tool' PRODUCT_TYPE_LIB_STATIC = 'com.apple.product-type.library.static' PRODUCT_TYPE_LIB_DYNAMIC = 'com.apple.product-type.library.dynamic' PRODUCT_TYPE_EXTENSION = 'com.apple.product-type.kernel-extension' @@ -68,17 +69,42 @@ def dummy(self, node): # Used in PBXFileReference elements FILE_TYPE_APPLICATION = 'wrapper.cfbundle' FILE_TYPE_FRAMEWORK = 'wrapper.framework' +FILE_TYPE_LIB_DYNAMIC = 'compiled.mach-o.dylib' +FILE_TYPE_LIB_STATIC = 'archive.ar' +FILE_TYPE_EXECUTABLE = 'compiled.mach-o.executable' # Tuple packs of the above TARGET_TYPE_FRAMEWORK = (PRODUCT_TYPE_FRAMEWORK, FILE_TYPE_FRAMEWORK, '.framework') TARGET_TYPE_APPLICATION = (PRODUCT_TYPE_APPLICATION, FILE_TYPE_APPLICATION, '.app') +TARGET_TYPE_DYNAMIC_LIB = (PRODUCT_TYPE_LIB_DYNAMIC, FILE_TYPE_LIB_DYNAMIC, '.dylib') +TARGET_TYPE_STATIC_LIB = (PRODUCT_TYPE_LIB_STATIC, FILE_TYPE_LIB_STATIC, '.a') +TARGET_TYPE_EXECUTABLE = (PRODUCT_TYPE_EXECUTABLE, FILE_TYPE_EXECUTABLE, '') # Maps target type string to its data TARGET_TYPES = { 'framework': TARGET_TYPE_FRAMEWORK, - 'app': TARGET_TYPE_APPLICATION + 'app': TARGET_TYPE_APPLICATION, + 'dylib': TARGET_TYPE_DYNAMIC_LIB, + 'stlib': TARGET_TYPE_STATIC_LIB, + 'exe' :TARGET_TYPE_EXECUTABLE, } +""" Provide user-friendly methods to build different target types + E.g. bld.framework(source='..', ...) to build a Framework target. + E.g. bld.dylib(source='..', ...) to build a Dynamic library target. + etc... +""" +def build_target(self, tgtype, *k, **kw): + kw['features'] = 'cxx cxxprogram' + kw['target_type'] = tgtype + return self(*k, **kw) + +BuildContext.app = lambda self, *k, **kw: build_target(self, 'app', *k, **kw) +BuildContext.framework = lambda self, *k, **kw: build_target(self, 'framework', *k, **kw) +BuildContext.dylib = lambda self, *k, **kw: build_target(self, 'dylib', *k, **kw) +BuildContext.stlib = lambda self, *k, **kw: build_target(self, 'stlib', *k, **kw) +BuildContext.exe = lambda self, *k, **kw: build_target(self, 'exe', *k, **kw) + class XcodeConfiguration(Configure.ConfigurationContext): """ Configuration of the global project settings. Sets an environment variable 'PROJ_CONFIGURATION' which is a dictionary of configuration name and buildsettings pair. @@ -100,11 +126,9 @@ def __init__(self): self.init_dirs() def execute(self): - # Run user configure() Configure.ConfigurationContext.execute(self) - if not self.env.PROJ_CONFIGURATION: self.to_log("A default project configuration was created since no custom one was given in the configure(conf) stage. Define your custom project settings by adding PROJ_CONFIGURATION to env. The env.PROJ_CONFIGURATION must be a dictionary with at least one key, where each key is the configuration name, and the value is a dictionary of key/value settings.\n") @@ -348,7 +372,7 @@ def __init__(self, name, version, env): XCodeNode.__init__(self) if not isinstance(env.PROJ_CONFIGURATION, dict): - raise Errors.WafError("env.PROJ_CONFIGURATION is not a dictionary. Did you import the xcode module in your wscript?") + raise Errors.WafError("Error: env.PROJ_CONFIGURATION must be a dictionary. This is done for you if you do not define one yourself. However, did you load the xcode module in your wscript configure() ?") # Retreive project configuration configurations = [] From 64405a8c1aab05bc8fc4a4fdb04af249446aa60f Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 13 Jul 2015 13:43:15 +0200 Subject: [PATCH 0095/1763] Reduced the ConfigureContext to a configure() func. Also replaced dependencies cxx/cxxprogram with ccroot --- demos/xcode/wscript | 8 ++-- waflib/extras/xcode.py | 97 ++++++++++++++++++------------------------ 2 files changed, 46 insertions(+), 59 deletions(-) diff --git a/demos/xcode/wscript b/demos/xcode/wscript index 313131d75b..4a38df0369 100644 --- a/demos/xcode/wscript +++ b/demos/xcode/wscript @@ -6,15 +6,17 @@ APPNAME = 'Avocada' VERSION = '1.0' def configure(conf): - conf.load('cxx') + conf.env.FRAMEWORK_VERSION = '1.0' conf.env.CONFIG_NAME = 'Kuk' conf.env.ARCHS = 'x86_64' conf.env.MACOSX_DEPLOYMENT_TARGET = '10.9' conf.env.SDKROOT = 'macosx10.9' + conf.load('xcode') + def build(bld): - bld.load('cxx') + tg = bld( features='cxx', source=bld.path.ant_glob('src/MyLib/*.cpp'), @@ -52,7 +54,7 @@ def build(bld): target='MyExe', ) - bld.program( + bld.stlib( source=tg.source, includes=tg.includes, target='MyStaticLib', diff --git a/waflib/extras/xcode.py b/waflib/extras/xcode.py index 033af26631..3343de6a14 100644 --- a/waflib/extras/xcode.py +++ b/waflib/extras/xcode.py @@ -20,7 +20,7 @@ def options(opt): from waflib.Build import BuildContext import os, sys, random, time -@TaskGen.extension('.m', '.mm') +@TaskGen.extension('.m', '.mm', '.cpp','.cc','.cxx','.C','.c++', '.c') def dummy(self, node): pass @@ -95,6 +95,7 @@ def dummy(self, node): etc... """ def build_target(self, tgtype, *k, **kw): + self.load('ccroot') kw['features'] = 'cxx cxxprogram' kw['target_type'] = tgtype return self(*k, **kw) @@ -105,63 +106,47 @@ def build_target(self, tgtype, *k, **kw): BuildContext.stlib = lambda self, *k, **kw: build_target(self, 'stlib', *k, **kw) BuildContext.exe = lambda self, *k, **kw: build_target(self, 'exe', *k, **kw) -class XcodeConfiguration(Configure.ConfigurationContext): - """ Configuration of the global project settings. Sets an environment variable 'PROJ_CONFIGURATION' - which is a dictionary of configuration name and buildsettings pair. - E.g.: - env.PROJ_CONFIGURATION = { - 'Debug': { - 'ARCHS': 'x86', - ... - } - 'Release': { - 'ARCHS' x86_64' - ... - } +""" Configuration of the global project settings. Sets an environment variable 'PROJ_CONFIGURATION' +which is a dictionary of configuration name and buildsettings pair. +E.g.: +env.PROJ_CONFIGURATION = { + 'Debug': { + 'ARCHS': 'x86', + ... } - The user can define a completely customized dictionary in configure() stage. Otherwise a default Debug/Release will be created - based on env variable """ - def __init__(self): - Configure.ConfigurationContext.__init__(self) - self.init_dirs() - - def execute(self): - # Run user configure() - Configure.ConfigurationContext.execute(self) - - if not self.env.PROJ_CONFIGURATION: - self.to_log("A default project configuration was created since no custom one was given in the configure(conf) stage. Define your custom project settings by adding PROJ_CONFIGURATION to env. The env.PROJ_CONFIGURATION must be a dictionary with at least one key, where each key is the configuration name, and the value is a dictionary of key/value settings.\n") - - # Set include dir variable - if 'HEADER_SEARCH_PATHS' not in self.env: - self.env.HEADER_SEARCH_PATHS = ['$(inherited)'] - else: - self.env.HEADER_SEARCH_PATHS = [self.srcnode.make_node(f).abspath() for f in Utils.to_list(self.env.INCLUDES)] - - # Check for any added config files added by the tool 'c_config'. - if 'cfg_files' in self.env: - self.env.HEADER_SEARCH_PATHS.extend([os.path.abspath(os.path.dirname(f)) for f in self.env.cfg_files]) - - # Create default project configuration? - if 'PROJ_CONFIGURATION' not in self.env: - self.env.PROJ_CONFIGURATION = { - "Debug": self.env.get_merged_dict(), - "Release": self.env.get_merged_dict(), - } - - # Some build settings are required to be present by XCode. We will supply default values - # if user hasn't defined any. - defaults_required = [('PRODUCT_NAME', '$(TARGET_NAME')] - for cfgname,settings in self.env.PROJ_CONFIGURATION.iteritems(): - for default_var, default_val in defaults_required: - if default_var not in settings: - settings[default_var] = default_val + 'Release': { + 'ARCHS' x86_64' + ... + } +} +The user can define a completely customized dictionary in configure() stage. Otherwise a default Debug/Release will be created +based on env variable """ +def configure(self): + if not self.env.PROJ_CONFIGURATION: + self.to_log("A default project configuration was created since no custom one was given in the configure(conf) stage. Define your custom project settings by adding PROJ_CONFIGURATION to env. The env.PROJ_CONFIGURATION must be a dictionary with at least one key, where each key is the configuration name, and the value is a dictionary of key/value settings.\n") + + # Check for any added config files added by the tool 'c_config'. + if 'cfg_files' in self.env: + self.env.INCLUDES = Utils.to_list(self.env.INCLUDES) + [os.path.abspath(os.path.dirname(f)) for f in self.env.cfg_files] + + # Create default project configuration? + if 'PROJ_CONFIGURATION' not in self.env: + self.env.PROJ_CONFIGURATION = { + "Debug": self.env.get_merged_dict(), + "Release": self.env.get_merged_dict(), + } - # Error check customization - if not isinstance(self.env.PROJ_CONFIGURATION, dict): - raise Errors.ConfigurationError("The env.PROJ_CONFIGURATION must be a dictionary with at least one key, where each key is the configuration name, and the value is a dictionary of key/value settings.") + # Some build settings are required to be present by XCode. We will supply default values + # if user hasn't defined any. + defaults_required = [('PRODUCT_NAME', '$(TARGET_NAME')] + for cfgname,settings in self.env.PROJ_CONFIGURATION.iteritems(): + for default_var, default_val in defaults_required: + if default_var not in settings: + settings[default_var] = default_val - self.store() + # Error check customization + if not isinstance(self.env.PROJ_CONFIGURATION, dict): + raise Errors.ConfigurationError("The env.PROJ_CONFIGURATION must be a dictionary with at least one key, where each key is the configuration name, and the value is a dictionary of key/value settings.") part1 = 0 part2 = 10000 @@ -372,7 +357,7 @@ def __init__(self, name, version, env): XCodeNode.__init__(self) if not isinstance(env.PROJ_CONFIGURATION, dict): - raise Errors.WafError("Error: env.PROJ_CONFIGURATION must be a dictionary. This is done for you if you do not define one yourself. However, did you load the xcode module in your wscript configure() ?") + raise Errors.WafError("Error: env.PROJ_CONFIGURATION must be a dictionary. This is done for you if you do not define one yourself. However, did you load the xcode module at the end of your wscript configure() ?") # Retreive project configuration configurations = [] From 20c0b72cbbfce35271930ab1f22c8b56d1319b75 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 13 Jul 2015 20:10:22 +0200 Subject: [PATCH 0096/1763] Removed import statement from demo --- demos/xcode/wscript | 1 - 1 file changed, 1 deletion(-) diff --git a/demos/xcode/wscript b/demos/xcode/wscript index 4a38df0369..d397f22507 100644 --- a/demos/xcode/wscript +++ b/demos/xcode/wscript @@ -1,5 +1,4 @@ from waflib import Task, TaskGen -from waflib.extras import xcode top = '.' out = 'build' APPNAME = 'Avocada' From 70fa79b181b77ccb425d70d7b8f858b71463f67d Mon Sep 17 00:00:00 2001 From: Simon Date: Wed, 15 Jul 2015 12:53:30 +0200 Subject: [PATCH 0097/1763] Clean-up --- demos/xcode/wscript | 15 ++++++--------- waflib/extras/xcode.py | 39 +++++++++++++++++++-------------------- 2 files changed, 25 insertions(+), 29 deletions(-) diff --git a/demos/xcode/wscript b/demos/xcode/wscript index d397f22507..521a3e3964 100644 --- a/demos/xcode/wscript +++ b/demos/xcode/wscript @@ -1,13 +1,15 @@ from waflib import Task, TaskGen top = '.' out = 'build' -APPNAME = 'Avocada' +APPNAME = 'TestProject' VERSION = '1.0' +def options(opt): + opt.load('xcode') + def configure(conf): conf.env.FRAMEWORK_VERSION = '1.0' - conf.env.CONFIG_NAME = 'Kuk' conf.env.ARCHS = 'x86_64' conf.env.MACOSX_DEPLOYMENT_TARGET = '10.9' conf.env.SDKROOT = 'macosx10.9' @@ -16,24 +18,20 @@ def configure(conf): def build(bld): - tg = bld( - features='cxx', + tg = bld.framework( source=bld.path.ant_glob('src/MyLib/*.cpp'), includes='include', group_files={ 'Include': bld.path.ant_glob('include/MyLib/*.h') }, target='MyLib', - target_type='framework' ) bld.env.LIB_SDL2 = '/Library/Frameworks/SDL2.framework/SDL2' - tg2 = bld( - features='cxx cxxprogram', + tg2 = bld.app( source=bld.path.ant_glob('src/*.cpp|'), includes=tg.includes, target='MyApp', - target_type='app', use='MyLib Yolo', uselib='SDL2', cxxflags='-O3', @@ -57,6 +55,5 @@ def build(bld): source=tg.source, includes=tg.includes, target='MyStaticLib', - target_type='stlib' ) \ No newline at end of file diff --git a/waflib/extras/xcode.py b/waflib/extras/xcode.py index 3343de6a14..0dff60c259 100644 --- a/waflib/extras/xcode.py +++ b/waflib/extras/xcode.py @@ -20,9 +20,8 @@ def options(opt): from waflib.Build import BuildContext import os, sys, random, time -@TaskGen.extension('.m', '.mm', '.cpp','.cc','.cxx','.C','.c++', '.c') -def dummy(self, node): - pass +def options(opt): + opt.load('cxx') HEADERS_GLOB = '**/(*.h|*.hpp|*.H|*.inl)' @@ -89,23 +88,6 @@ def dummy(self, node): 'exe' :TARGET_TYPE_EXECUTABLE, } -""" Provide user-friendly methods to build different target types - E.g. bld.framework(source='..', ...) to build a Framework target. - E.g. bld.dylib(source='..', ...) to build a Dynamic library target. - etc... -""" -def build_target(self, tgtype, *k, **kw): - self.load('ccroot') - kw['features'] = 'cxx cxxprogram' - kw['target_type'] = tgtype - return self(*k, **kw) - -BuildContext.app = lambda self, *k, **kw: build_target(self, 'app', *k, **kw) -BuildContext.framework = lambda self, *k, **kw: build_target(self, 'framework', *k, **kw) -BuildContext.dylib = lambda self, *k, **kw: build_target(self, 'dylib', *k, **kw) -BuildContext.stlib = lambda self, *k, **kw: build_target(self, 'stlib', *k, **kw) -BuildContext.exe = lambda self, *k, **kw: build_target(self, 'exe', *k, **kw) - """ Configuration of the global project settings. Sets an environment variable 'PROJ_CONFIGURATION' which is a dictionary of configuration name and buildsettings pair. E.g.: @@ -530,3 +512,20 @@ def execute(self): node.mkdir() node = node.make_node('project.pbxproj') p.write(open(node.abspath(), 'w')) + + def build_target(self, tgtype, *k, **kw): + """ Provide user-friendly methods to build different target types + E.g. bld.framework(source='..', ...) to build a Framework target. + E.g. bld.dylib(source='..', ...) to build a Dynamic library target. + etc... + """ + self.load('ccroot') + kw['features'] = 'cxx cxxprogram' + kw['target_type'] = tgtype + return self(*k, **kw) + + def app(self, *k, **kw): return self.build_target('app', *k, **kw) + def framework(self, *k, **kw): return self.build_target('framework', *k, **kw) + def dylib(self, *k, **kw): return self.build_target('dylib', *k, **kw) + def stlib(self, *k, **kw): return self.build_target('stlib', *k, **kw) + def exe(self, *k, **kw): return self.build_target('exe', *k, **kw) From 70b294f2e1300d3efb1f895cf4572421b75fdf14 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 17 Jul 2015 00:23:27 +0200 Subject: [PATCH 0098/1763] Added unique_fileref() method to get reference of already existing file references --- demos/xcode/wscript | 1 + waflib/extras/xcode.py | 28 +++++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/demos/xcode/wscript b/demos/xcode/wscript index 521a3e3964..007db4e9fd 100644 --- a/demos/xcode/wscript +++ b/demos/xcode/wscript @@ -24,6 +24,7 @@ def build(bld): group_files={ 'Include': bld.path.ant_glob('include/MyLib/*.h') }, + export_headers=bld.path.ant_glob('include/MyLib/*.h'), target='MyLib', ) diff --git a/waflib/extras/xcode.py b/waflib/extras/xcode.py index 0dff60c259..4961ec32f0 100644 --- a/waflib/extras/xcode.py +++ b/waflib/extras/xcode.py @@ -220,6 +220,12 @@ def __init__(self, name, path, filetype = '', sourcetree = "SOURCE_ROOT"): self.path = path self.sourceTree = sourcetree + def __hash__(self): + return (self.path+self.name).__hash__() + + def __eq__(self, other): + return (self.path, self.name) == (other.path, other.name) + class PBXBuildFile(XCodeNode): """ This element indicate a file reference that is used in a PBXBuildPhase (either as an include or resource). """ def __init__(self, fileRef, settings={}): @@ -268,6 +274,14 @@ def __init__(self, pbxbuildfiles): self.runOnlyForDeploymentPostprocessing = 0 self.files = pbxbuildfiles #List of PBXBuildFile (.o, .framework, .dylib) +class PBXHeadersBuildPhase(XCodeNode): + """ This is the element for adding header files to be packaged into the .framework """ + def __init__(self, pbxbuildfiles): + XCodeNode.__init__(self) + self.buildActionMask = 2147483647 + self.runOnlyForDeploymentPostprocessing = 0 + self.files = pbxbuildfiles #List of PBXBuildFile (.o, .framework, .dylib) + class PBXSourcesBuildPhase(XCodeNode): """ Represents the 'Compile Sources' build phase in a Xcode target """ def __init__(self, buildfiles): @@ -397,6 +411,8 @@ class xcode(Build.BuildContext): cmd = 'xcode' fun = 'build' + file_refs = dict() + def as_nodes(self, files): """ Returns a list of waflib.Nodes from a list of string of file paths """ nodes = [] @@ -413,10 +429,15 @@ def create_group(self, name, files): :type files: string """ group = PBXGroup(name) - files = [PBXFileReference(d.name, d.abspath()) for d in self.as_nodes(files)] + files = [self.unique_filereference(PBXFileReference(d.name, d.abspath())) for d in self.as_nodes(files)] group.children.extend(files) return group + def unique_filereference(self, fileref): + if fileref not in self.file_refs: + self.file_refs[fileref] = fileref + return self.file_refs[fileref] + def execute(self): """ Entry point @@ -482,6 +503,11 @@ def execute(self): target.add_dependency(p.create_target_dependency(use_target, use_target.name)) target.add_build_phase(PBXFrameworksBuildPhase([PBXBuildFile(use_target.productReference)])) + hdrs = self.as_nodes(Utils.to_list(getattr(tg, 'export_headers', []))) + files = [self.unique_filereference(PBXFileReference(n.name, n.abspath())) for n in hdrs] + target.add_build_phase(PBXHeadersBuildPhase([PBXBuildFile(f, {'ATTRIBUTES': ('Public',)}) for f in files])) + + # Merge frameworks and libs into one list, and prefix the frameworks ld_flags = ['-framework %s' % lib for lib in Utils.to_list(tg.env.FRAMEWORK)] ld_flags.extend(Utils.to_list(tg.env.STLIB) + Utils.to_list(tg.env.LIB)) From 2424393afda7dbab5ba030e36b8c4f9b34ec9d0f Mon Sep 17 00:00:00 2001 From: Matt Fischer Date: Mon, 27 Jul 2015 11:38:03 -0500 Subject: [PATCH 0099/1763] Handle .. within paths in gccdeps The current code handles .. at the beginning of a path, but not within the path --- waflib/extras/gccdeps.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/waflib/extras/gccdeps.py b/waflib/extras/gccdeps.py index 43c9602e02..bed33b8c5b 100644 --- a/waflib/extras/gccdeps.py +++ b/waflib/extras/gccdeps.py @@ -126,11 +126,17 @@ def post_run(self): node = path_to_node(bld.root, x, cached_nodes) else: path = bld.bldnode - # when calling find_resource, make sure the path does not begin by '..' + # when calling find_resource, make sure the path does not contain '..' x = [k for k in Utils.split_path(x) if k and k != '.'] - while lst and x[0] == '..': - x = x[1:] - path = path.parent + while '..' in x: + idx = x.index('..') + if idx == 0: + x = x[1:] + path = path.parent + else: + del x[idx] + del x[idx-1] + node = path_to_node(path, x, cached_nodes) if not node: From b22118a2de2f8a3bd14f209ab097ef5a9f7865c1 Mon Sep 17 00:00:00 2001 From: Nikolaus Lieb Date: Sat, 25 Jul 2015 18:25:59 +0800 Subject: [PATCH 0100/1763] Add an option to skip searching the regular sys.path when loading waf tools. Granting this control allows the avoidance of issues such as accidentally loading the "cython" module from from Cython itself, rather than the "cython" waf tool. Conflicts: waflib/Configure.py waflib/Context.py --- waflib/Configure.py | 4 ++-- waflib/Context.py | 54 +++++++++++++++++++++++++++------------------ 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/waflib/Configure.py b/waflib/Configure.py index 49b52247ac..3d69b06eba 100644 --- a/waflib/Configure.py +++ b/waflib/Configure.py @@ -234,7 +234,7 @@ def store(self): tmpenv = self.all_envs[key] tmpenv.store(os.path.join(self.cachedir.abspath(), key + Build.CACHE_SUFFIX)) - def load(self, input, tooldir=None, funs=None): + def load(self, input, tooldir=None, funs=None, loadFromSysPath=True): """ Load Waf tools, which will be imported whenever a build is started. @@ -260,7 +260,7 @@ def load(self, input, tooldir=None, funs=None): module = None try: - module = Context.load_tool(tool, tooldir, ctx=self) + module = Context.load_tool(tool, tooldir, ctx=self, loadFromSysPath=loadFromSysPath) except ImportError as e: self.fatal('Could not load the Waf tool %r from %r\n%s' % (tool, sys.path, e)) except Exception as e: diff --git a/waflib/Context.py b/waflib/Context.py index fe733e4d2d..d1a1c7d413 100644 --- a/waflib/Context.py +++ b/waflib/Context.py @@ -210,9 +210,10 @@ def load(self, tool_list, *k, **kw): """ tools = Utils.to_list(tool_list) path = Utils.to_list(kw.get('tooldir', '')) + loadFromSysPath = kw.get('loadFromSysPath', True) for t in tools: - module = load_tool(t, path) + module = load_tool(t, path, loadFromSysPath=loadFromSysPath) fun = getattr(module, kw.get('name', self.fun), None) if fun: fun(self) @@ -627,7 +628,7 @@ def load_module(path, encoding=None): return module -def load_tool(tool, tooldir=None, ctx=None): +def load_tool(tool, tooldir=None, ctx=None, loadFromSysPath=True): """ Import a Waf tool (python module), and store it in the dict :py:const:`waflib.Context.Context.tools` @@ -635,33 +636,44 @@ def load_tool(tool, tooldir=None, ctx=None): :param tool: Name of the tool :type tooldir: list :param tooldir: List of directories to search for the tool module + :type loadFromSysPath: boolean + :param loadFromSysPath: whether or not to search the regular sys.path, besides waf_dir and potentially given tooldirs """ if tool == 'java': tool = 'javaw' # jython else: tool = tool.replace('++', 'xx') - if tooldir: - assert isinstance(tooldir, list) - sys.path = tooldir + sys.path - try: - __import__(tool) + origSysPath = sys.path + if not loadFromSysPath: sys.path = [] + try: + if tooldir: + assert isinstance(tooldir, list) + sys.path = tooldir + sys.path + try: + __import__(tool) + finally: + for d in tooldir: + sys.path.remove(d) ret = sys.modules[tool] Context.tools[tool] = ret return ret - finally: - for d in tooldir: - sys.path.remove(d) - else: - for x in ('waflib.Tools.%s', 'waflib.extras.%s', 'waflib.%s', '%s'): + else: + if not loadFromSysPath: sys.path.insert(0, waf_dir) try: - __import__(x % tool) - break - except ImportError: - x = None - if x is None: # raise an exception - __import__(tool) - ret = sys.modules[x % tool] - Context.tools[tool] = ret - return ret + for x in ('waflib.Tools.%s', 'waflib.extras.%s', 'waflib.%s', '%s'): + try: + __import__(x % tool) + break + except ImportError: + x = None + if x is None: # raise an exception + __import__(tool) + finally: + if not loadFromSysPath: sys.path.remove(waf_dir) + ret = sys.modules[x % tool] + Context.tools[tool] = ret + return ret + finally: + if not loadFromSysPath: sys.path += origSysPath From 64f557a17e00c6b1da07999879c0f79919949620 Mon Sep 17 00:00:00 2001 From: Nikolaus Lieb Date: Sat, 25 Jul 2015 18:27:31 +0800 Subject: [PATCH 0101/1763] Ensure restoration of sys.path in Context.load_module() --- waflib/Context.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/waflib/Context.py b/waflib/Context.py index d1a1c7d413..09600b31ac 100644 --- a/waflib/Context.py +++ b/waflib/Context.py @@ -621,8 +621,8 @@ def load_module(path, encoding=None): module_dir = os.path.dirname(path) sys.path.insert(0, module_dir) - exec(compile(code, path, 'exec'), module.__dict__) - sys.path.remove(module_dir) + try : exec(compile(code, path, 'exec'), module.__dict__) + finally: sys.path.remove(module_dir) cache_modules[path] = module From 699b836728151aa4196bffc5530ca5220f35c8fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Carretero?= Date: Sun, 2 Aug 2015 19:10:43 -0400 Subject: [PATCH 0102/1763] extras: cfg_cross_gnu: make pkg-config also use PKG_CONFIG_LIBDIR... ... to avoid having the default stuff prepended, and system libs found when you want to do x-compilation. --- waflib/extras/cfg_cross_gnu.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/waflib/extras/cfg_cross_gnu.py b/waflib/extras/cfg_cross_gnu.py index e2ed30f7c2..948782436a 100644 --- a/waflib/extras/cfg_cross_gnu.py +++ b/waflib/extras/cfg_cross_gnu.py @@ -1,5 +1,5 @@ #!/usr/bin/python -# -*- coding: utf-8 -*- +# -*- coding: utf-8 vi:ts=4:noexpandtab # Tool to provide dedicated variables for cross-compilation __author__ = __maintainer__ = "Jérôme Carretero " @@ -138,10 +138,13 @@ def xcheck_host(conf): conf.xcheck_host_envar('CXXFLAGS') conf.xcheck_host_envar('LDFLAGS', 'LINKFLAGS') conf.xcheck_host_envar('LIB') + conf.xcheck_host_envar('PKG_CONFIG_LIBDIR') conf.xcheck_host_envar('PKG_CONFIG_PATH') # TODO find a better solution than this ugliness - if conf.env.PKG_CONFIG_PATH: + if conf.env.PKG_CONFIG_PATH or conf.env.PKG_CONFIG_LIBDIR: conf.find_program('pkg-config', var='PKGCONFIG') conf.env.PKGCONFIG = [ - 'env', 'PKG_CONFIG_PATH=%s' % (conf.env.PKG_CONFIG_PATH[0]) + 'env', + 'PKG_CONFIG_LIBDIR=%s' % (conf.env.PKG_CONFIG_LIBDIR[0]), + 'PKG_CONFIG_PATH=%s' % (conf.env.PKG_CONFIG_PATH[0]), ] + conf.env.PKGCONFIG From ae07720a6d6713078cc273a8c069b1eb67a35ffa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Carretero?= Date: Thu, 6 Aug 2015 22:32:46 -0400 Subject: [PATCH 0103/1763] extras: add c_emscripten tool --- waflib/extras/c_emscripten.py | 93 +++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 waflib/extras/c_emscripten.py diff --git a/waflib/extras/c_emscripten.py b/waflib/extras/c_emscripten.py new file mode 100644 index 0000000000..405cf13b63 --- /dev/null +++ b/waflib/extras/c_emscripten.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python +# -*- coding: utf-8 vi:ts=4:noexpandtab + +import os, subprocess, shlex + +from waflib import Logs +from waflib.Tools import ccroot, ar, gcc, gxx +from waflib.Configure import conf +from waflib.TaskGen import after_method, feature + +from waflib.Tools.compiler_c import c_compiler +from waflib.Tools.compiler_cxx import cxx_compiler + +for supported_os in ('linux', 'darwin', 'gnu', 'aix'): + c_compiler[supported_os].append('c_emscripten') + cxx_compiler[supported_os].append('c_emscripten') + + +@conf +def get_emscripten_version(conf, cc): + """ + Emscripten doesn't support processing '-' like clang/gcc + """ + + dummy = conf.cachedir.parent.make_node("waf-emscripten.c") + dummy.write("") + cmd = cc + ['-dM', '-E', '-x', 'c', dummy.abspath()] + env = conf.env.env or None + try: + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env) + out = p.communicate()[0] + except Exception as e: + conf.fatal('Could not determine emscripten version %r: %s' % (cmd, e)) + + if not isinstance(out, str): + out = out.decode(sys.stdout.encoding or 'iso8859-1') + + k = {} + out = out.splitlines() + for line in out: + lst = shlex.split(line) + if len(lst)>2: + key = lst[1] + val = lst[2] + k[key] = val + + if not ('__clang__' in k and 'EMSCRIPTEN' in k): + conf.fatal('Could not determine the emscripten compiler version.') + + conf.env.DEST_OS = 'generic' + conf.env.DEST_BINFMT = 'elf' + conf.env.DEST_CPU = 'asm-js' + conf.env.CC_VERSION = (k['__clang_major__'], k['__clang_minor__'], k['__clang_patchlevel__']) + return k + +@conf +def find_emscripten(conf): + cc = conf.find_program(['emcc'], var='CC') + conf.get_emscripten_version(cc) + conf.env.CC = cc + conf.env.CC_NAME = 'emscripten' + cxx = conf.find_program(['em++'], var='CXX') + conf.env.CXX = cxx + conf.env.CXX_NAME = 'emscripten' + +def configure(conf): + conf.find_emscripten() + conf.find_ar() + conf.gcc_common_flags() + conf.gxx_common_flags() + conf.cc_load_tools() + conf.cc_add_flags() + conf.cxx_load_tools() + conf.cxx_add_flags() + conf.link_add_flags() + conf.env.cshlib_PATTERN = '%s.js' + conf.env.cxxshlib_PATTERN = '%s.js' + conf.env.cstlib_PATTERN = '%s.bc' + conf.env.cxxstlib_PATTERN = '%s.bc' + conf.env.cprogram_PATTERN = '%s.html' + conf.env.cxxprogram_PATTERN = '%s.html' + conf.env.append_value('LINKFLAGS',['-Wl,--enable-auto-import']) + +@feature('c', 'cxx', 'd', 'asm', 'fc', 'includes') +@after_method('propagate_uselib_vars', 'process_source') +def apply_incpaths(self): + """ + Emscripten doesn't like absolute include paths + """ + lst = self.to_incnodes(self.to_list(getattr(self, 'includes', [])) + self.env['INCLUDES']) + self.includes_nodes = lst + self.env['INCPATHS'] = [x.path_from(self.bld.bldnode) for x in lst] + From a98baba3e896b1ab1c9ea7944054a574a855291b Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Fri, 7 Aug 2015 10:47:06 +0200 Subject: [PATCH 0104/1763] Unused code fragment --- waflib/Tools/c_config.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/waflib/Tools/c_config.py b/waflib/Tools/c_config.py index 77e1211ddb..9fcdcff67c 100644 --- a/waflib/Tools/c_config.py +++ b/waflib/Tools/c_config.py @@ -1040,9 +1040,6 @@ def get_cc_version(conf, cc, gcc=False, icc=False, clang=False): def isD(var): return var in k - def isT(var): - return var in k and k[var] != '0' - # Some documentation is available at http://predef.sourceforge.net # The names given to DEST_OS must match what Utils.unversioned_sys_platform() returns. if not conf.env.DEST_OS: From 45ffae6d4eeab3c2fe40903881af7dbcfe04cebd Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Fri, 7 Aug 2015 10:48:22 +0200 Subject: [PATCH 0105/1763] Ensure __GNUC_PATCHLEVEL__ is always of str type --- waflib/Tools/c_config.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/waflib/Tools/c_config.py b/waflib/Tools/c_config.py index 9fcdcff67c..2ed67cb7a0 100644 --- a/waflib/Tools/c_config.py +++ b/waflib/Tools/c_config.py @@ -1083,10 +1083,7 @@ def isD(var): # Some versions of OSX have a faux-gcc "clang" without clang version defines conf.env['CC_VERSION'] = (k['__GNUC__'], k['__GNUC_MINOR__'], k['__GNUC_PATCHLEVEL__']) else: - try: - conf.env['CC_VERSION'] = (k['__GNUC__'], k['__GNUC_MINOR__'], k['__GNUC_PATCHLEVEL__']) - except KeyError: - conf.env['CC_VERSION'] = (k['__GNUC__'], k['__GNUC_MINOR__'], 0) + conf.env['CC_VERSION'] = (k['__GNUC__'], k['__GNUC_MINOR__'], k.get('__GNUC_PATCHLEVEL__', '0')) return k @conf From 6ca1c7cad4c549493e38ddeab479c912fccde3c8 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Fri, 7 Aug 2015 10:51:45 +0200 Subject: [PATCH 0106/1763] Simplify Clang macro detection --- waflib/Tools/c_config.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/waflib/Tools/c_config.py b/waflib/Tools/c_config.py index 2ed67cb7a0..d28538d414 100644 --- a/waflib/Tools/c_config.py +++ b/waflib/Tools/c_config.py @@ -1076,13 +1076,10 @@ def isD(var): ver = k['__INTEL_COMPILER'] conf.env['CC_VERSION'] = (ver[:-2], ver[-2], ver[-1]) else: - if isD('__clang__'): - try: - conf.env['CC_VERSION'] = (k['__clang_major__'], k['__clang_minor__'], k['__clang_patchlevel__']) - except KeyError: - # Some versions of OSX have a faux-gcc "clang" without clang version defines - conf.env['CC_VERSION'] = (k['__GNUC__'], k['__GNUC_MINOR__'], k['__GNUC_PATCHLEVEL__']) + if isD('__clang__') and isD('__clang_major__'): + conf.env['CC_VERSION'] = (k['__clang_major__'], k['__clang_minor__'], k['__clang_patchlevel__']) else: + # older clang versions and gcc conf.env['CC_VERSION'] = (k['__GNUC__'], k['__GNUC_MINOR__'], k.get('__GNUC_PATCHLEVEL__', '0')) return k From c913b779f5aa9338f25888beb61042bbc2baeda8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Carretero?= Date: Fri, 7 Aug 2015 08:49:40 -0400 Subject: [PATCH 0107/1763] extras: c_emscripten: use emar as AR --- waflib/extras/c_emscripten.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/waflib/extras/c_emscripten.py b/waflib/extras/c_emscripten.py index 405cf13b63..bd0254a3e4 100644 --- a/waflib/extras/c_emscripten.py +++ b/waflib/extras/c_emscripten.py @@ -4,7 +4,7 @@ import os, subprocess, shlex from waflib import Logs -from waflib.Tools import ccroot, ar, gcc, gxx +from waflib.Tools import ccroot, gcc, gxx from waflib.Configure import conf from waflib.TaskGen import after_method, feature @@ -62,6 +62,7 @@ def find_emscripten(conf): cxx = conf.find_program(['em++'], var='CXX') conf.env.CXX = cxx conf.env.CXX_NAME = 'emscripten' + conf.find_program(['emar'], var='AR') def configure(conf): conf.find_emscripten() @@ -73,6 +74,7 @@ def configure(conf): conf.cxx_load_tools() conf.cxx_add_flags() conf.link_add_flags() + conf.env.ARFLAGS = ['rcs'] conf.env.cshlib_PATTERN = '%s.js' conf.env.cxxshlib_PATTERN = '%s.js' conf.env.cstlib_PATTERN = '%s.bc' From ccdbd79ffa67a58b366a80de90caccaa8c68ea26 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sun, 9 Aug 2015 23:50:49 +0200 Subject: [PATCH 0108/1763] Python3 fix --- waflib/extras/c_emscripten.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/waflib/extras/c_emscripten.py b/waflib/extras/c_emscripten.py index bd0254a3e4..64c364b2e4 100644 --- a/waflib/extras/c_emscripten.py +++ b/waflib/extras/c_emscripten.py @@ -1,9 +1,8 @@ #!/usr/bin/env python # -*- coding: utf-8 vi:ts=4:noexpandtab -import os, subprocess, shlex +import subprocess, shlex, sys -from waflib import Logs from waflib.Tools import ccroot, gcc, gxx from waflib.Configure import conf from waflib.TaskGen import after_method, feature From e9e8df28a401ae80b950c0c693f47767239b8840 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Wed, 12 Aug 2015 18:31:14 +0200 Subject: [PATCH 0109/1763] iteritems does not work in python3 --- waflib/extras/doxygen.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/waflib/extras/doxygen.py b/waflib/extras/doxygen.py index 0a6f6a63d6..23b50e7b52 100644 --- a/waflib/extras/doxygen.py +++ b/waflib/extras/doxygen.py @@ -90,7 +90,7 @@ def runnable_status(self): # Override with any parameters passed to the task generator if getattr(self.generator, 'pars', None): - for k, v in self.generator.pars.iteritems(): + for k, v in self.generator.pars.items(): self.pars[k] = v self.doxy_inputs = getattr(self, 'doxy_inputs', []) From a08b9fe26a9a5fd83ebeff88490cb1f1797f9beb Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sun, 23 Aug 2015 17:01:25 +0200 Subject: [PATCH 0110/1763] Added new parameters input/timeout to cmd_and_log/exec_command --- waflib/Context.py | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/waflib/Context.py b/waflib/Context.py index 09600b31ac..85fd27d6a8 100644 --- a/waflib/Context.py +++ b/waflib/Context.py @@ -322,7 +322,7 @@ def run(tsk): unlike :py:meth:`waflib.Context.Context.cmd_and_log` :param cmd: command argument for subprocess.Popen - :param kw: keyword arguments for subprocess.Popen + :param kw: keyword arguments for subprocess.Popen. The parameters input/timeout will be passed to wait/communicate. """ subprocess = Utils.subprocess kw['shell'] = isinstance(cmd, str) @@ -340,14 +340,22 @@ def run(tsk): if Logs.verbose and not kw['shell'] and not Utils.check_exe(cmd[0]): raise Errors.WafError("Program %s not found!" % cmd[0]) + wargs = {} + if 'timeout' in kw: + wargs['timeout'] = kw['timeout'] + del kw['timeout'] + if 'input' in kw: + wargs['input'] = kw['input'] + del kw['input'] + try: if kw['stdout'] or kw['stderr']: p = subprocess.Popen(cmd, **kw) - (out, err) = p.communicate() + (out, err) = p.communicate(**wargs) ret = p.returncode else: out, err = (None, None) - ret = subprocess.Popen(cmd, **kw).wait() + ret = subprocess.Popen(cmd, **kw).wait(**wargs) except Exception as e: raise Errors.WafError('Execution failure: %s' % str(e), ex=e) @@ -370,20 +378,21 @@ def run(tsk): def cmd_and_log(self, cmd, **kw): """ - Execute a command and return stdout if the execution is successful. + Execute a command and return stdout/stderr if the execution is successful. An exception is thrown when the exit status is non-0. In that case, both stderr and stdout will be bound to the WafError object:: def configure(conf): out = conf.cmd_and_log(['echo', 'hello'], output=waflib.Context.STDOUT, quiet=waflib.Context.BOTH) (out, err) = conf.cmd_and_log(['echo', 'hello'], output=waflib.Context.BOTH) + (out, err) = conf.cmd_and_log(cmd, input='\n'.encode(), stdin=waflib.Utils.subprocess.PIPE, output=waflib.Context.STDOUT) try: conf.cmd_and_log(['which', 'someapp'], output=waflib.Context.BOTH) except Exception as e: print(e.stdout, e.stderr) :param cmd: args for subprocess.Popen - :param kw: keyword arguments for subprocess.Popen + :param kw: keyword arguments for subprocess.Popen. The parameters input/timeout will be passed to wait/communicate. """ subprocess = Utils.subprocess kw['shell'] = isinstance(cmd, str) @@ -407,9 +416,18 @@ def configure(conf): kw['stdout'] = kw['stderr'] = subprocess.PIPE if quiet is None: self.to_log(cmd) + + wargs = {} + if 'timeout' in kw: + wargs['timeout'] = kw['timeout'] + del kw['timeout'] + if 'input' in kw: + wargs['input'] = kw['input'] + del kw['input'] + try: p = subprocess.Popen(cmd, **kw) - (out, err) = p.communicate() + (out, err) = p.communicate(**wargs) except Exception as e: raise Errors.WafError('Execution failure: %s' % str(e), ex=e) From 274fba398c64919a04da45c5b76da1e840ee1c2f Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sun, 23 Aug 2015 17:05:57 +0200 Subject: [PATCH 0111/1763] Fixed the invalid docstring --- waflib/Context.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/waflib/Context.py b/waflib/Context.py index 85fd27d6a8..ab13b00687 100644 --- a/waflib/Context.py +++ b/waflib/Context.py @@ -385,7 +385,7 @@ def cmd_and_log(self, cmd, **kw): def configure(conf): out = conf.cmd_and_log(['echo', 'hello'], output=waflib.Context.STDOUT, quiet=waflib.Context.BOTH) (out, err) = conf.cmd_and_log(['echo', 'hello'], output=waflib.Context.BOTH) - (out, err) = conf.cmd_and_log(cmd, input='\n'.encode(), stdin=waflib.Utils.subprocess.PIPE, output=waflib.Context.STDOUT) + (out, err) = conf.cmd_and_log(cmd, input='\\n'.encode(), stdin=waflib.Utils.subprocess.PIPE, output=waflib.Context.STDOUT) try: conf.cmd_and_log(['which', 'someapp'], output=waflib.Context.BOTH) except Exception as e: From bfbcc73eb21d19f25ad7ccccc9231522e0a6a897 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sun, 23 Aug 2015 17:16:03 +0200 Subject: [PATCH 0112/1763] C/FC detection and outputs to be written in config.log --- waflib/Tools/c_config.py | 7 +------ waflib/Tools/fc_config.py | 14 +++++--------- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/waflib/Tools/c_config.py b/waflib/Tools/c_config.py index d28538d414..1650ebe27b 100644 --- a/waflib/Tools/c_config.py +++ b/waflib/Tools/c_config.py @@ -1004,15 +1004,10 @@ def get_cc_version(conf, cc, gcc=False, icc=False, clang=False): cmd = cc + ['-dM', '-E', '-'] env = conf.env.env or None try: - p = Utils.subprocess.Popen(cmd, stdin=Utils.subprocess.PIPE, stdout=Utils.subprocess.PIPE, stderr=Utils.subprocess.PIPE, env=env) - p.stdin.write('\n'.encode()) - out = p.communicate()[0] + out, err = conf.cmd_and_log(cmd, output=0, input='\n'.encode(), stdin=Utils.subprocess.PIPE, env=env) except Exception: conf.fatal('Could not determine the compiler version %r' % cmd) - if not isinstance(out, str): - out = out.decode(sys.stdout.encoding or 'iso8859-1') - if gcc: if out.find('__INTEL_COMPILER') >= 0: conf.fatal('The intel compiler pretends to be gcc') diff --git a/waflib/Tools/fc_config.py b/waflib/Tools/fc_config.py index 8d795d63c2..be7ae222ec 100644 --- a/waflib/Tools/fc_config.py +++ b/waflib/Tools/fc_config.py @@ -335,23 +335,19 @@ def check_fortran_clib(self, autoadd=True, *k, **kw): def getoutput(conf, cmd, stdin=False): """ TODO a bit redundant, can be removed anytime + TODO waf 1.9 """ + wargs = {'env': conf.env.env or None, 'output': 0} if stdin: + wargs['stdin'] = Utils.subprocess.PIPE + wargs['input'] = '\n'.encode() stdin = Utils.subprocess.PIPE else: stdin = None - env = conf.env.env or None try: - p = Utils.subprocess.Popen(cmd, stdin=stdin, stdout=Utils.subprocess.PIPE, stderr=Utils.subprocess.PIPE, env=env) - if stdin: - p.stdin.write('\n'.encode()) - out, err = p.communicate() + out, err = conf.cmd_and_log(cmd, **wargs) except Exception: conf.fatal('could not determine the compiler version %r' % cmd) - if not isinstance(out, str): - out = out.decode(sys.stdout.encoding or 'iso8859-1') - if not isinstance(err, str): - err = err.decode(sys.stdout.encoding or 'iso8859-1') return (out, err) # ------------------------------------------------------------------------ From 03ad2fff745d824760c5e7e33e7b486043923850 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sun, 23 Aug 2015 17:39:25 +0200 Subject: [PATCH 0113/1763] Adding input to cmd_and_log/exec_command enables stdin=PIPE --- waflib/Context.py | 10 ++++++---- waflib/Tools/c_config.py | 2 +- waflib/Tools/fc_config.py | 10 ++-------- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/waflib/Context.py b/waflib/Context.py index ab13b00687..73edf25bca 100644 --- a/waflib/Context.py +++ b/waflib/Context.py @@ -341,11 +341,12 @@ def run(tsk): raise Errors.WafError("Program %s not found!" % cmd[0]) wargs = {} - if 'timeout' in kw: + if kw.get('timeout', None): wargs['timeout'] = kw['timeout'] del kw['timeout'] - if 'input' in kw: + if kw.get('input', None) is not None: wargs['input'] = kw['input'] + kw['stdin'] = Utils.subprocess.PIPE del kw['input'] try: @@ -385,7 +386,7 @@ def cmd_and_log(self, cmd, **kw): def configure(conf): out = conf.cmd_and_log(['echo', 'hello'], output=waflib.Context.STDOUT, quiet=waflib.Context.BOTH) (out, err) = conf.cmd_and_log(['echo', 'hello'], output=waflib.Context.BOTH) - (out, err) = conf.cmd_and_log(cmd, input='\\n'.encode(), stdin=waflib.Utils.subprocess.PIPE, output=waflib.Context.STDOUT) + (out, err) = conf.cmd_and_log(cmd, input='\\n'.encode(), output=waflib.Context.STDOUT) try: conf.cmd_and_log(['which', 'someapp'], output=waflib.Context.BOTH) except Exception as e: @@ -418,11 +419,12 @@ def configure(conf): self.to_log(cmd) wargs = {} - if 'timeout' in kw: + if kw.get('timeout', None): wargs['timeout'] = kw['timeout'] del kw['timeout'] if 'input' in kw: wargs['input'] = kw['input'] + kw['stdin'] = Utils.subprocess.PIPE del kw['input'] try: diff --git a/waflib/Tools/c_config.py b/waflib/Tools/c_config.py index 1650ebe27b..91f4c05057 100644 --- a/waflib/Tools/c_config.py +++ b/waflib/Tools/c_config.py @@ -1004,7 +1004,7 @@ def get_cc_version(conf, cc, gcc=False, icc=False, clang=False): cmd = cc + ['-dM', '-E', '-'] env = conf.env.env or None try: - out, err = conf.cmd_and_log(cmd, output=0, input='\n'.encode(), stdin=Utils.subprocess.PIPE, env=env) + out, err = conf.cmd_and_log(cmd, output=0, input='\n'.encode(), env=env) except Exception: conf.fatal('Could not determine the compiler version %r' % cmd) diff --git a/waflib/Tools/fc_config.py b/waflib/Tools/fc_config.py index be7ae222ec..f4cd6600ac 100644 --- a/waflib/Tools/fc_config.py +++ b/waflib/Tools/fc_config.py @@ -337,15 +337,9 @@ def getoutput(conf, cmd, stdin=False): TODO a bit redundant, can be removed anytime TODO waf 1.9 """ - wargs = {'env': conf.env.env or None, 'output': 0} - if stdin: - wargs['stdin'] = Utils.subprocess.PIPE - wargs['input'] = '\n'.encode() - stdin = Utils.subprocess.PIPE - else: - stdin = None + input = stdin and '\n'.encode() or None try: - out, err = conf.cmd_and_log(cmd, **wargs) + out, err = conf.cmd_and_log(cmd, env=conf.env.env or None, output=0, input=input) except Exception: conf.fatal('could not determine the compiler version %r' % cmd) return (out, err) From cadd260a9e66bb577903fb4b1ed321a7b061b9f3 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sun, 23 Aug 2015 18:52:45 +0200 Subject: [PATCH 0114/1763] Always remove the timeout and input arguments from the Popen constructor --- waflib/Context.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/waflib/Context.py b/waflib/Context.py index 73edf25bca..a274302b35 100644 --- a/waflib/Context.py +++ b/waflib/Context.py @@ -341,12 +341,14 @@ def run(tsk): raise Errors.WafError("Program %s not found!" % cmd[0]) wargs = {} - if kw.get('timeout', None): - wargs['timeout'] = kw['timeout'] + if 'timeout' in kw: + if kw['timeout'] is not None: + wargs['timeout'] = kw['timeout'] del kw['timeout'] - if kw.get('input', None) is not None: - wargs['input'] = kw['input'] - kw['stdin'] = Utils.subprocess.PIPE + if 'input' in kw: + if kw['input']: + wargs['input'] = kw['input'] + kw['stdin'] = Utils.subprocess.PIPE del kw['input'] try: @@ -419,12 +421,14 @@ def configure(conf): self.to_log(cmd) wargs = {} - if kw.get('timeout', None): - wargs['timeout'] = kw['timeout'] + if 'timeout' in kw: + if kw['timeout'] is not None: + wargs['timeout'] = kw['timeout'] del kw['timeout'] if 'input' in kw: - wargs['input'] = kw['input'] - kw['stdin'] = Utils.subprocess.PIPE + if kw['input']: + wargs['input'] = kw['input'] + kw['stdin'] = Utils.subprocess.PIPE del kw['input'] try: From 48504f2c3d53a8b3409a89bc2e2a10687cfdff29 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Fri, 28 Aug 2015 21:37:09 +0200 Subject: [PATCH 0115/1763] Enable the wrapped method to be reentrant --- playground/exclusive_link/excl.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/playground/exclusive_link/excl.py b/playground/exclusive_link/excl.py index 732534b61c..351ddb298d 100644 --- a/playground/exclusive_link/excl.py +++ b/playground/exclusive_link/excl.py @@ -1,6 +1,6 @@ #! /usr/bin/env python # encoding: utf-8 -# Thomas Nagy, 2011 (ita) +# Thomas Nagy, 2011-2015 (ita) """ Prevents link tasks from executing in parallel. This can be used to @@ -31,8 +31,12 @@ def runnable_status(self): ret = Task.ASK_LATER if count >= MAX: return ret + + self.m1_excl = getattr(self, 'm1_excl', 0) + 1 ret = old_runnable_status(self) - if ret == Task.RUN_ME: + self.m1_excl -= 1 + + if ret == Task.RUN_ME and not self.m1_excl: lock.acquire() count += 1 lock.release() @@ -43,11 +47,14 @@ def runnable_status(self): def run(self): global count, lock try: + self.m2_excl = getattr(self, 'm2_excl', 0) + 1 ret = old_run(self) finally: - lock.acquire() - count -= 1 - lock.release() + self.m2_excl -= 1 + if not self.m2_excl: + lock.acquire() + count -= 1 + lock.release() return ret cls.run = run From 34c6ee8c0eca66e27e36e765c6d2f2144efcbb38 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Fri, 28 Aug 2015 22:43:38 +0200 Subject: [PATCH 0116/1763] loadFromSysPath -> with_sys_path --- waflib/Configure.py | 4 ++-- waflib/Context.py | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/waflib/Configure.py b/waflib/Configure.py index 3d69b06eba..88468d23ed 100644 --- a/waflib/Configure.py +++ b/waflib/Configure.py @@ -234,7 +234,7 @@ def store(self): tmpenv = self.all_envs[key] tmpenv.store(os.path.join(self.cachedir.abspath(), key + Build.CACHE_SUFFIX)) - def load(self, input, tooldir=None, funs=None, loadFromSysPath=True): + def load(self, input, tooldir=None, funs=None, with_sys_path=True): """ Load Waf tools, which will be imported whenever a build is started. @@ -260,7 +260,7 @@ def load(self, input, tooldir=None, funs=None, loadFromSysPath=True): module = None try: - module = Context.load_tool(tool, tooldir, ctx=self, loadFromSysPath=loadFromSysPath) + module = Context.load_tool(tool, tooldir, ctx=self, with_sys_path=with_sys_path) except ImportError as e: self.fatal('Could not load the Waf tool %r from %r\n%s' % (tool, sys.path, e)) except Exception as e: diff --git a/waflib/Context.py b/waflib/Context.py index a274302b35..c18e7d50f5 100644 --- a/waflib/Context.py +++ b/waflib/Context.py @@ -210,10 +210,10 @@ def load(self, tool_list, *k, **kw): """ tools = Utils.to_list(tool_list) path = Utils.to_list(kw.get('tooldir', '')) - loadFromSysPath = kw.get('loadFromSysPath', True) + with_sys_path = kw.get('with_sys_path', True) for t in tools: - module = load_tool(t, path, loadFromSysPath=loadFromSysPath) + module = load_tool(t, path, with_sys_path=with_sys_path) fun = getattr(module, kw.get('name', self.fun), None) if fun: fun(self) @@ -652,7 +652,7 @@ def load_module(path, encoding=None): return module -def load_tool(tool, tooldir=None, ctx=None, loadFromSysPath=True): +def load_tool(tool, tooldir=None, ctx=None, with_sys_path=True): """ Import a Waf tool (python module), and store it in the dict :py:const:`waflib.Context.Context.tools` @@ -660,8 +660,8 @@ def load_tool(tool, tooldir=None, ctx=None, loadFromSysPath=True): :param tool: Name of the tool :type tooldir: list :param tooldir: List of directories to search for the tool module - :type loadFromSysPath: boolean - :param loadFromSysPath: whether or not to search the regular sys.path, besides waf_dir and potentially given tooldirs + :type with_sys_path: boolean + :param with_sys_path: whether or not to search the regular sys.path, besides waf_dir and potentially given tooldirs """ if tool == 'java': tool = 'javaw' # jython @@ -669,7 +669,7 @@ def load_tool(tool, tooldir=None, ctx=None, loadFromSysPath=True): tool = tool.replace('++', 'xx') origSysPath = sys.path - if not loadFromSysPath: sys.path = [] + if not with_sys_path: sys.path = [] try: if tooldir: assert isinstance(tooldir, list) @@ -683,7 +683,7 @@ def load_tool(tool, tooldir=None, ctx=None, loadFromSysPath=True): Context.tools[tool] = ret return ret else: - if not loadFromSysPath: sys.path.insert(0, waf_dir) + if not with_sys_path: sys.path.insert(0, waf_dir) try: for x in ('waflib.Tools.%s', 'waflib.extras.%s', 'waflib.%s', '%s'): try: @@ -694,10 +694,10 @@ def load_tool(tool, tooldir=None, ctx=None, loadFromSysPath=True): if x is None: # raise an exception __import__(tool) finally: - if not loadFromSysPath: sys.path.remove(waf_dir) + if not with_sys_path: sys.path.remove(waf_dir) ret = sys.modules[x % tool] Context.tools[tool] = ret return ret finally: - if not loadFromSysPath: sys.path += origSysPath + if not with_sys_path: sys.path += origSysPath From 41bd22ebfaca7c46717fa04a9feac2cabb2820e2 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sat, 29 Aug 2015 10:31:02 +0200 Subject: [PATCH 0117/1763] Update use_config - Issue 1608 --- configure | 2 +- utils/launcher/README.md | 2 +- waflib/Context.py | 2 +- waflib/extras/use_config.py | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/configure b/configure index 03fab4b16a..d6d969c013 100755 --- a/configure +++ b/configure @@ -61,7 +61,7 @@ checkWAF() # neither waf nor miniwaf could be found if [ ! -x "$WAF" ] ; then printf "$RED""not found""$NORMAL""\n" - echo "Go to http://code.google.com/p/waf/" + echo "Go to https://waf.io/" echo "and download a waf version" exit $EXIT_FAILURE else diff --git a/utils/launcher/README.md b/utils/launcher/README.md index 62c3787b1b..26b72eed1b 100644 --- a/utils/launcher/README.md +++ b/utils/launcher/README.md @@ -1,6 +1,6 @@ #Waf-launcher This is a simple wrapper for the -[waf build system](http://code.google.com/p/waf/) +[waf build system](https://waf.io/) Since many windows users does not have python installed by default, the exe file from this project can be included along with the copy of diff --git a/waflib/Context.py b/waflib/Context.py index c18e7d50f5..748254ceb7 100644 --- a/waflib/Context.py +++ b/waflib/Context.py @@ -55,7 +55,7 @@ local_repo = '' """Local repository containing additional Waf tools (plugins)""" -remote_repo = 'http://waf.googlecode.com/git/' +remote_repo = 'https://raw.githubusercontent.com/waf-project/waf/master/' """ Remote directory containing downloadable waf tools. The missing tools can be downloaded by using:: diff --git a/waflib/extras/use_config.py b/waflib/extras/use_config.py index e2404f1e3c..8787f4af1b 100644 --- a/waflib/extras/use_config.py +++ b/waflib/extras/use_config.py @@ -130,9 +130,9 @@ def download_tool(tool, force=False, ctx=None): raise Errors.WafError('Could not load the Waf tool') -def load_tool(tool, tooldir=None, ctx=None): +def load_tool(tool, tooldir=None, ctx=None, with_sys_path=True): try: - module = Context.load_tool_default(tool, tooldir) + module = Context.load_tool_default(tool, tooldir, ctx, with_sys_path) except ImportError as e: if Options.options.download: module = download_tool(tool, ctx=ctx) From 3e6b3bc5cab2aa038de2d63130c69b97f5cbbc1c Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sat, 29 Aug 2015 11:01:47 +0200 Subject: [PATCH 0118/1763] Added fortran detection and warn when no link is possible - Issue 1603 and Issue 1610 --- waflib/Tools/c_aliases.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/waflib/Tools/c_aliases.py b/waflib/Tools/c_aliases.py index 65677801c8..4bb6352e11 100644 --- a/waflib/Tools/c_aliases.py +++ b/waflib/Tools/c_aliases.py @@ -1,11 +1,11 @@ #!/usr/bin/env python # encoding: utf-8 -# Thomas Nagy, 2005-2010 (ita) +# Thomas Nagy, 2005-2015 (ita) "base for all c/c++ programs and libraries" import os, sys, re -from waflib import Utils, Build +from waflib import Utils, Build, Errors from waflib.Configure import conf def get_extensions(lst): @@ -44,26 +44,34 @@ def sniff_features(**kw): feats = [] # watch the order, cxx will have the precedence - if 'cxx' in exts or 'cpp' in exts or 'c++' in exts or 'cc' in exts or 'C' in exts: - feats.append('cxx') + for x in 'cxx cpp c++ cc C'.split(): + if x in exts: + feats.append('cxx') + break if 'c' in exts or 'vala' in exts: feats.append('c') + for x in 'f f90 F F90 for FOR'.split(): + if x in exts: + feats.append('fc') + break + if 'd' in exts: feats.append('d') if 'java' in exts: feats.append('java') - - if 'java' in exts: return 'java' if type in ('program', 'shlib', 'stlib'): + will_link = False for x in feats: - if x in ('cxx', 'd', 'c'): + if x in ('cxx', 'd', 'fc', 'c'): 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) return feats def set_features(kw, _type): From 61f09a3f7c7e2ed0382caff8b649d66befaf321f Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sat, 29 Aug 2015 13:05:00 +0200 Subject: [PATCH 0119/1763] Enable 'waf update' when use_config is provided - Issue 1541 --- ChangeLog | 7 +++++++ waflib/Scripting.py | 21 ++++++++++++++++----- waflib/extras/use_config.py | 4 ++-- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2ba4d73e8e..3f56a4552e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +NEW IN WAF 1.8.13 +----------------- +* Exposed the Popen parameters input/timeout to cmd_and_log/exec_command (timeout is for Python >= 3.3) +* Added an option to skip searching the regular sys.path when loading waf tools +* Changed gccdeps so that it handle .. within paths +* env = conf.env.derive().detach() + NEW IN WAF 1.8.12 ----------------- * Fixed a regression when building in sub-folders - https://github.com/waf-project/waf/issues/1590 diff --git a/waflib/Scripting.py b/waflib/Scripting.py index ba2893e40c..832e357323 100644 --- a/waflib/Scripting.py +++ b/waflib/Scripting.py @@ -564,15 +564,26 @@ def distcheck(ctx): pass def update(ctx): - lst = Options.options.files.split(',') - if not lst: - lst = [x for x in Utils.listdir(Context.waf_dir + '/waflib/extras') if x.endswith('.py')] + lst = Options.options.files + if lst: + lst = lst.split(',') + else: + path = os.path.join(Context.waf_dir, 'waflib', 'extras') + lst = [x for x in Utils.listdir(path) if x.endswith('.py')] for x in lst: tool = x.replace('.py', '') + if not tool: + continue try: - Configure.download_tool(tool, force=True, ctx=ctx) + dl = Configure.download_tool + except AttributeError: + ctx.fatal('The command "update" is dangerous; include the tool "use_config" in your project!') + try: + dl(tool, force=True, ctx=ctx) except Errors.WafError: - Logs.error('Could not find the tool %s in the remote repository' % x) + Logs.error('Could not find the tool %r in the remote repository' % x) + else: + Logs.warn('Updated %r' % tool) def autoconfigure(execute_method): """ diff --git a/waflib/extras/use_config.py b/waflib/extras/use_config.py index 8787f4af1b..b0fd1e738e 100644 --- a/waflib/extras/use_config.py +++ b/waflib/extras/use_config.py @@ -58,7 +58,7 @@ def configure(conf): urlopen = request.urlopen -from waflib import Errors, Context, Logs, Utils, Options +from waflib import Errors, Context, Logs, Utils, Options, Configure try: from urllib.parse import urlparse @@ -144,7 +144,7 @@ def load_tool(tool, tooldir=None, ctx=None, with_sys_path=True): Context.load_tool_default = Context.load_tool Context.load_tool = load_tool - +Configure.download_tool = download_tool def configure(self): opts = self.options From ca5b8a873310453d5d78dab8281f4f1855fb0708 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sun, 30 Aug 2015 13:02:17 +0200 Subject: [PATCH 0120/1763] Env variables WAF_LOG_FORMAT/WAF_HOUR_FORMAT for custom log formats --- waflib/Logs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/waflib/Logs.py b/waflib/Logs.py index 1edcfab2ec..8dd2af920a 100644 --- a/waflib/Logs.py +++ b/waflib/Logs.py @@ -20,8 +20,8 @@ # in case someone uses the root logger import logging -LOG_FORMAT = "%(asctime)s %(c1)s%(zone)s%(c2)s %(message)s" -HOUR_FORMAT = "%H:%M:%S" +LOG_FORMAT = os.environ.get('WAF_LOG_FORMAT', '%(asctime)s %(c1)s%(zone)s%(c2)s %(message)s') +HOUR_FORMAT = os.environ.get('WAF_HOUR_FORMAT', '%H:%M:%S') zones = '' verbose = 0 From e72c310b7d25f11d5691e080d22e8eb251e889e3 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sun, 30 Aug 2015 20:05:38 +0200 Subject: [PATCH 0121/1763] Ruby 2.x detection - Issue 1613 --- waflib/Tools/ruby.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/waflib/Tools/ruby.py b/waflib/Tools/ruby.py index 996bb80669..843bb22787 100644 --- a/waflib/Tools/ruby.py +++ b/waflib/Tools/ruby.py @@ -104,12 +104,13 @@ def read_config(key): return read_out('puts RbConfig::CONFIG[%r]' % key) ruby = self.env['RUBY'] - archdir = read_config('archdir') - cpppath = archdir + cpppath = archdir = read_config('archdir') if version >= (1, 9, 0): ruby_hdrdir = read_config('rubyhdrdir') cpppath += ruby_hdrdir + if version >= (2, 0, 0): + cpppath += read_config('rubyarchhdrdir') cpppath += [os.path.join(ruby_hdrdir[0], read_config('arch')[0])] self.check(header_name='ruby.h', includes=cpppath, errmsg='could not find ruby header file') From 4b65d3f8755fca7e3600cd053e499dd92bf22eee Mon Sep 17 00:00:00 2001 From: Shawn Hoover Date: Mon, 31 Aug 2015 14:55:15 -0400 Subject: [PATCH 0122/1763] Optionally lazily check installed msvc compilers' environments and stop when one is found that matches the user's options. This happens during autodetect only when the new option msvc_lazy_autodetect or env.MSVC_LAZY_AUTODETECT is set. --- waflib/Tools/msvc.py | 179 +++++++++++++++++++++++++++++++------------ 1 file changed, 129 insertions(+), 50 deletions(-) diff --git a/waflib/Tools/msvc.py b/waflib/Tools/msvc.py index 973232477b..ad50e55f31 100644 --- a/waflib/Tools/msvc.py +++ b/waflib/Tools/msvc.py @@ -90,8 +90,19 @@ def build(bld): def options(opt): opt.add_option('--msvc_version', type='string', help = 'msvc version, eg: "msvc 10.0,msvc 9.0"', default='') opt.add_option('--msvc_targets', type='string', help = 'msvc targets, eg: "x64,arm"', default='') + opt.add_option('--msvc_lazy_autodetect', action='store_true', help = 'lazily check msvc target environments') def setup_msvc(conf, versions, arch = False): + """ + Checks installed compilers and targets and returns the first combination from the user's + options, env, or the global supported lists that checks. + + :param versions: A list of tuples of all installed compilers and available targets. + :param arch: Whether to return the target architecture. + :return: the compiler, revision, path, include dirs, library paths, and (optionally) target architecture + :rtype: tuple of strings + """ + platforms = getattr(Options.options, 'msvc_targets', '').split(',') if platforms == ['']: platforms=Utils.to_list(conf.env['MSVC_TARGETS']) or [i for i,j in all_msvc_platforms+all_icl_platforms+all_wince_platforms] @@ -102,15 +113,20 @@ def setup_msvc(conf, versions, arch = False): for version in desired_versions: try: - targets = dict(versiondict [version]) + targets = dict(versiondict[version]) for target in platforms: try: - arch,(p1,p2,p3) = targets[target] - compiler,revision = version.rsplit(' ', 1) - if arch: - return compiler,revision,p1,p2,p3,arch + try: + arch,(p1,p2,p3) = targets[target] + except conf.errors.ConfigurationError: + # lazytup target evaluation errors + del(targets[target]) else: - return compiler,revision,p1,p2,p3 + compiler,revision = version.rsplit(' ', 1) + if arch: + return compiler,revision,p1,p2,p3,arch + else: + return compiler,revision,p1,p2,p3 except KeyError: continue except KeyError: continue conf.fatal('msvc: Impossible to find a valid architecture for building (in setup_msvc)') @@ -118,13 +134,14 @@ def setup_msvc(conf, versions, arch = False): @conf def get_msvc_version(conf, compiler, version, target, vcvars): """ - Create a bat file to obtain the location of the libraries - - :param compiler: ? - :param version: ? - :target: ? - :vcvars: ? - :return: the location of msvc, the location of include dirs, and the library paths + Checks that an installed compiler actually runs and uses vcvars to obtain the + environment needed by the compiler. + + :param compiler: compiler type, for looking up the executable name + :param version: compiler version, for debugging only + :param target: target architecture + :param vcvars: batch file to run to check the environment + :return: the location of the compiler executable, the location of include dirs, and the library paths :rtype: tuple of strings """ debug('msvc: get_msvc_version: %r %r %r', compiler, version, target) @@ -186,7 +203,7 @@ def get_msvc_version(conf, compiler, version, target, vcvars): return (MSVC_PATH, MSVC_INCDIR, MSVC_LIBDIR) @conf -def gather_wsdk_versions(conf, versions): +def gather_wsdk_versions(conf, versions, lazy=False): """ Use winreg to add the msvc versions to the input list @@ -219,7 +236,7 @@ def gather_wsdk_versions(conf, versions): targets = [] for target,arch in all_msvc_platforms: try: - targets.append((target, (arch, conf.get_msvc_version('wsdk', version, '/'+target, os.path.join(path, 'bin', 'SetEnv.cmd'))))) + targets.append((target, (arch, get_compiler_env(conf, lazy, 'wsdk', version, '/'+target, os.path.join(path, 'bin', 'SetEnv.cmd'))))) except conf.errors.ConfigurationError: pass versions.append(('wsdk ' + version[1:], targets)) @@ -304,31 +321,88 @@ def fun(tup): detected_versions.sort(key = fun) return detected_versions +def get_compiler_env(conf, lazy, compiler, version, bat_target, bat, select=None): + """ + Gets the compiler environment variables as a tuple, optionally as a lazy tuple + that checks on destructuring, iteration, etc. + + :param conf: configuration context to use to eventually get the version environment + :param lazy: whether to defer checking the environment for all discovered targets or do it immediately + :param compiler: compiler name + :param version: compiler version number + :param bat: path to the batch file to run + :param select: optional function to take the realized environment variables tup and map it (e.g. to combine other constant paths) + """ + def msvc_thunk(): + vs = conf.get_msvc_version(compiler, version, bat_target, bat) + if select: + return select(vs) + else: + return vs + return lazytup(msvc_thunk, lazy, ([], [], [])) + +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): + self.fn = fn + self.default = default + + if not lazy: + self.evaluate() + def __len__(self): + self.evaluate() + return len(self.value) + def __iter__(self): + self.evaluate() + for i, v in enumerate(self.value): + yield v + def __getitem__(self, i): + self.evaluate() + return self.value[i] + def __repr__(self): + if hasattr(self, 'value'): + return repr(self.value) + elif self.default: + return repr(self.default) + else: + self.evaluate() + return repr(self.value) + def evaluate(self): + if hasattr(self, 'value'): + return + self.value = self.fn() + @conf -def gather_msvc_targets(conf, versions, version, vc_path): +def gather_msvc_targets(conf, versions, version, vc_path, lazy=False): #Looking for normal MSVC compilers! targets = [] if os.path.isfile(os.path.join(vc_path, 'vcvarsall.bat')): for target,realtarget in all_msvc_platforms[::-1]: try: - targets.append((target, (realtarget, conf.get_msvc_version('msvc', version, target, os.path.join(vc_path, 'vcvarsall.bat'))))) + targets.append((target, (realtarget, get_compiler_env(conf, lazy, 'msvc', version, target, os.path.join(vc_path, 'vcvarsall.bat'))))) except conf.errors.ConfigurationError: pass elif os.path.isfile(os.path.join(vc_path, 'Common7', 'Tools', 'vsvars32.bat')): try: - targets.append(('x86', ('x86', conf.get_msvc_version('msvc', version, 'x86', os.path.join(vc_path, 'Common7', 'Tools', 'vsvars32.bat'))))) + targets.append(('x86', ('x86', get_compiler_env(conf, lazy, 'msvc', version, 'x86', os.path.join(vc_path, 'Common7', 'Tools', 'vsvars32.bat'))))) except conf.errors.ConfigurationError: pass elif os.path.isfile(os.path.join(vc_path, 'Bin', 'vcvars32.bat')): try: - targets.append(('x86', ('x86', conf.get_msvc_version('msvc', version, '', os.path.join(vc_path, 'Bin', 'vcvars32.bat'))))) + targets.append(('x86', ('x86', get_compiler_env(conf, lazy, 'msvc', version, '', os.path.join(vc_path, 'Bin', 'vcvars32.bat'))))) except conf.errors.ConfigurationError: pass if targets: versions.append(('msvc '+ version, targets)) @conf -def gather_wince_targets(conf, versions, version, vc_path, vsvars, supported_platforms): +def gather_wince_targets(conf, versions, version, vc_path, vsvars, supported_platforms, lazy=False): #Looking for Win CE compilers! for device,platforms in supported_platforms: cetargets = [] @@ -336,32 +410,36 @@ def gather_wince_targets(conf, versions, version, vc_path, vsvars, supported_pla winCEpath = os.path.join(vc_path, 'ce') if not os.path.isdir(winCEpath): continue - try: - common_bindirs,_1,_2 = conf.get_msvc_version('msvc', version, 'x86', vsvars) - except conf.errors.ConfigurationError: - continue + if os.path.isdir(os.path.join(winCEpath, 'lib', platform)): - bindirs = [os.path.join(winCEpath, 'bin', compiler), os.path.join(winCEpath, 'bin', 'x86_'+compiler)] + common_bindirs + bindirs = [os.path.join(winCEpath, 'bin', compiler), os.path.join(winCEpath, 'bin', 'x86_'+compiler)] incdirs = [os.path.join(winCEpath, 'include'), os.path.join(winCEpath, 'atlmfc', 'include'), include] libdirs = [os.path.join(winCEpath, 'lib', platform), os.path.join(winCEpath, 'atlmfc', 'lib', platform), lib] - cetargets.append((platform, (platform, (bindirs,incdirs,libdirs)))) + def combine_common(compiler_env): + (common_bindirs,_1,_2) = compiler_env + return (bindirs + common_bindirs, incdirs, libdirs) + try: + cetargets.append((platform, (platform, get_compiler_env(conf, lazy, 'msvc', version, 'x86', vsvars, combine_common)))) + except conf.errors.ConfigurationError: + continue + if cetargets: versions.append((device + ' ' + version, cetargets)) @conf -def gather_winphone_targets(conf, versions, version, vc_path, vsvars): +def gather_winphone_targets(conf, versions, version, vc_path, vsvars, lazy=False): #Looking for WinPhone compilers targets = [] for target,realtarget in all_msvc_platforms[::-1]: try: - targets.append((target, (realtarget, conf.get_msvc_version('winphone', version, target, vsvars)))) - except conf.errors.ConfigurationError as e: + targets.append((target, (realtarget, get_compiler_env(conf, lazy, 'winphone', version, target, vsvars)))) + except conf.errors.ConfigurationError: pass if targets: versions.append(('winphone '+ version, targets)) @conf -def gather_msvc_versions(conf, versions): +def gather_msvc_versions(conf, versions, lazy=False): vc_paths = [] for (v,version,reg) in gather_msvc_detected_versions(): try: @@ -380,18 +458,18 @@ def gather_msvc_versions(conf, versions): vs_path = os.path.dirname(vc_path) vsvars = os.path.join(vs_path, 'Common7', 'Tools', 'vsvars32.bat') if wince_supported_platforms and os.path.isfile(vsvars): - conf.gather_wince_targets(versions, version, vc_path, vsvars, wince_supported_platforms) + conf.gather_wince_targets(versions, version, vc_path, vsvars, wince_supported_platforms, lazy) vsvars = os.path.join(vs_path, 'VC', 'WPSDK', 'WP80', 'vcvarsphoneall.bat') if os.path.isfile(vsvars): - conf.gather_winphone_targets(versions, '8.0', vc_path, vsvars) + conf.gather_winphone_targets(versions, '8.0', vc_path, vsvars, lazy) for version,vc_path in vc_paths: vs_path = os.path.dirname(vc_path) - conf.gather_msvc_targets(versions, version, vc_path) + conf.gather_msvc_targets(versions, version, vc_path, lazy) @conf -def gather_icl_versions(conf, versions): +def gather_icl_versions(conf, versions, lazy=False): """ Checks ICL compilers @@ -426,7 +504,7 @@ def gather_icl_versions(conf, versions): batch_file=os.path.join(path,'bin','iclvars.bat') if os.path.isfile(batch_file): try: - targets.append((target,(arch,conf.get_msvc_version('intel',version,target,batch_file)))) + targets.append((target,(arch,get_compiler_env(conf,lazy,'intel',version,target,batch_file)))) except conf.errors.ConfigurationError: pass except WindowsError: @@ -438,7 +516,7 @@ def gather_icl_versions(conf, versions): batch_file=os.path.join(path,'bin','iclvars.bat') if os.path.isfile(batch_file): try: - targets.append((target, (arch, conf.get_msvc_version('intel', version, target, batch_file)))) + targets.append((target, (arch, get_compiler_env(conf, lazy, 'intel', version, target, batch_file)))) except conf.errors.ConfigurationError: pass except WindowsError: @@ -447,7 +525,7 @@ def gather_icl_versions(conf, versions): versions.append(('intel ' + major, targets)) @conf -def gather_intel_composer_versions(conf, versions): +def gather_intel_composer_versions(conf, versions, lazy=False): """ Checks ICL compilers that are part of Intel Composer Suites @@ -490,8 +568,8 @@ def gather_intel_composer_versions(conf, versions): batch_file=os.path.join(path,'bin','iclvars.bat') if os.path.isfile(batch_file): try: - targets.append((target,(arch,conf.get_msvc_version('intel',version,target,batch_file)))) - except conf.errors.ConfigurationError as e: + targets.append((target,(arch,get_compiler_env(conf,lazy,'intel',version,target,batch_file)))) + except conf.errors.ConfigurationError: pass # The intel compilervar_arch.bat is broken when used with Visual Studio Express 2012 # http://software.intel.com/en-us/forums/topic/328487 @@ -516,17 +594,17 @@ def gather_intel_composer_versions(conf, versions): versions.append(('intel ' + major, targets)) @conf -def get_msvc_versions(conf): +def get_msvc_versions(conf, lazy=False): """ :return: list of compilers installed :rtype: list of string """ if not conf.env['MSVC_INSTALLED_VERSIONS']: lst = [] - conf.gather_icl_versions(lst) - conf.gather_intel_composer_versions(lst) - conf.gather_wsdk_versions(lst) - conf.gather_msvc_versions(lst) + conf.gather_icl_versions(lst, lazy) + conf.gather_intel_composer_versions(lst, lazy) + conf.gather_wsdk_versions(lst, lazy) + conf.gather_msvc_versions(lst, lazy) conf.env['MSVC_INSTALLED_VERSIONS'] = lst return conf.env['MSVC_INSTALLED_VERSIONS'] @@ -541,8 +619,8 @@ def print_all_msvc_detected(conf): Logs.info("\t"+target) @conf -def detect_msvc(conf, arch = False): - versions = get_msvc_versions(conf) +def detect_msvc(conf, arch=False, lazy=False): + versions = get_msvc_versions(conf, lazy) return setup_msvc(conf, versions, arch) @conf @@ -664,7 +742,8 @@ def configure(conf): """ Configuration methods to call for detecting msvc """ - conf.autodetect(True) + lazy = getattr(Options.options, 'msvc_lazy_autodetect', False) or conf.env['MSVC_LAZY_AUTODETECT'] + conf.autodetect(True, lazy) conf.find_msvc() conf.msvc_common_flags() conf.cc_load_tools() @@ -680,15 +759,15 @@ def no_autodetect(conf): configure(conf) @conf -def autodetect(conf, arch = False): +def autodetect(conf, arch=False, lazy=False): v = conf.env if v.NO_MSVC_DETECT: return if arch: - compiler, version, path, includes, libdirs, arch = conf.detect_msvc(True) + compiler, version, path, includes, libdirs, arch = conf.detect_msvc(True, lazy) v['DEST_CPU'] = arch else: - compiler, version, path, includes, libdirs = conf.detect_msvc() + compiler, version, path, includes, libdirs = conf.detect_msvc(False, lazy) v['PATH'] = path v['INCLUDES'] = includes From 7e62e3a54f887848c2fdc71c7568501bd2196c60 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Mon, 31 Aug 2015 23:41:19 +0200 Subject: [PATCH 0123/1763] search -> search_node - Issue 1617 --- docs/book/nodes.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/book/nodes.txt b/docs/book/nodes.txt index 8e3e302aa8..f0d69eca2c 100644 --- a/docs/book/nodes.txt +++ b/docs/book/nodes.txt @@ -108,10 +108,10 @@ def dosomething(ctx): nd1 = ctx.path.make_node('foo.txt') <2> print(nd1) - nd2 = ctx.path.search('foo.txt') <3> + nd2 = ctx.path.search_node('foo.txt') <3> print(nd2) - nd3 = ctx.path.search('bar.txt') <4> + nd3 = ctx.path.search_node('bar.txt') <4> print(nd3) nd2.write('some text') <5> From 5e833ef3f888cdcf0db7cc64a1bf3abe86724dfb Mon Sep 17 00:00:00 2001 From: Shawn Hoover Date: Mon, 31 Aug 2015 22:06:34 -0400 Subject: [PATCH 0124/1763] Read the lazy autodetect option instead of passing a value everywhere. --- waflib/Tools/msvc.py | 76 ++++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 35 deletions(-) diff --git a/waflib/Tools/msvc.py b/waflib/Tools/msvc.py index ad50e55f31..25c32b2751 100644 --- a/waflib/Tools/msvc.py +++ b/waflib/Tools/msvc.py @@ -30,6 +30,10 @@ def build(bld): Platforms and targets will be tested in the order they appear; the first good configuration will be used. + +To skip testing all the configurations that are not used, use the ``--msvc_lazy_autodetect`` option +or set ``conf.env['MSVC_LAZY_AUTODETECT']=True``. + Supported platforms: ia64, x64, x86, x86_amd64, x86_ia64, x86_arm, amd64_x86, amd64_arm Compilers supported: @@ -203,7 +207,7 @@ def get_msvc_version(conf, compiler, version, target, vcvars): return (MSVC_PATH, MSVC_INCDIR, MSVC_LIBDIR) @conf -def gather_wsdk_versions(conf, versions, lazy=False): +def gather_wsdk_versions(conf, versions): """ Use winreg to add the msvc versions to the input list @@ -236,7 +240,7 @@ def gather_wsdk_versions(conf, versions, lazy=False): targets = [] for target,arch in all_msvc_platforms: try: - targets.append((target, (arch, get_compiler_env(conf, lazy, 'wsdk', version, '/'+target, os.path.join(path, 'bin', 'SetEnv.cmd'))))) + targets.append((target, (arch, get_compiler_env(conf, 'wsdk', version, '/'+target, os.path.join(path, 'bin', 'SetEnv.cmd'))))) except conf.errors.ConfigurationError: pass versions.append(('wsdk ' + version[1:], targets)) @@ -321,18 +325,21 @@ def fun(tup): detected_versions.sort(key = fun) return detected_versions -def get_compiler_env(conf, lazy, compiler, version, bat_target, bat, select=None): +def get_compiler_env(conf, compiler, version, bat_target, bat, select=None): """ - Gets the compiler environment variables as a tuple, optionally as a lazy tuple - that checks on destructuring, iteration, etc. + 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`. :param conf: configuration context to use to eventually get the version environment - :param lazy: whether to defer checking the environment for all discovered targets or do it immediately :param compiler: compiler name :param version: compiler version number :param bat: path to the batch file to run :param select: optional function to take the realized environment variables tup and map it (e.g. to combine other constant paths) """ + lazy = getattr(Options.options, 'msvc_lazy_autodetect', False) or conf.env['MSVC_LAZY_AUTODETECT'] + def msvc_thunk(): vs = conf.get_msvc_version(compiler, version, bat_target, bat) if select: @@ -379,30 +386,30 @@ def evaluate(self): self.value = self.fn() @conf -def gather_msvc_targets(conf, versions, version, vc_path, lazy=False): +def gather_msvc_targets(conf, versions, version, vc_path): #Looking for normal MSVC compilers! targets = [] if os.path.isfile(os.path.join(vc_path, 'vcvarsall.bat')): for target,realtarget in all_msvc_platforms[::-1]: try: - targets.append((target, (realtarget, get_compiler_env(conf, lazy, 'msvc', version, target, os.path.join(vc_path, 'vcvarsall.bat'))))) + targets.append((target, (realtarget, get_compiler_env(conf, 'msvc', version, target, os.path.join(vc_path, 'vcvarsall.bat'))))) except conf.errors.ConfigurationError: pass elif os.path.isfile(os.path.join(vc_path, 'Common7', 'Tools', 'vsvars32.bat')): try: - targets.append(('x86', ('x86', get_compiler_env(conf, lazy, 'msvc', version, 'x86', os.path.join(vc_path, 'Common7', 'Tools', 'vsvars32.bat'))))) + targets.append(('x86', ('x86', get_compiler_env(conf, 'msvc', version, 'x86', os.path.join(vc_path, 'Common7', 'Tools', 'vsvars32.bat'))))) except conf.errors.ConfigurationError: pass elif os.path.isfile(os.path.join(vc_path, 'Bin', 'vcvars32.bat')): try: - targets.append(('x86', ('x86', get_compiler_env(conf, lazy, 'msvc', version, '', os.path.join(vc_path, 'Bin', 'vcvars32.bat'))))) + targets.append(('x86', ('x86', get_compiler_env(conf, 'msvc', version, '', os.path.join(vc_path, 'Bin', 'vcvars32.bat'))))) except conf.errors.ConfigurationError: pass if targets: versions.append(('msvc '+ version, targets)) @conf -def gather_wince_targets(conf, versions, version, vc_path, vsvars, supported_platforms, lazy=False): +def gather_wince_targets(conf, versions, version, vc_path, vsvars, supported_platforms): #Looking for Win CE compilers! for device,platforms in supported_platforms: cetargets = [] @@ -419,7 +426,7 @@ def combine_common(compiler_env): (common_bindirs,_1,_2) = compiler_env return (bindirs + common_bindirs, incdirs, libdirs) try: - cetargets.append((platform, (platform, get_compiler_env(conf, lazy, 'msvc', version, 'x86', vsvars, combine_common)))) + cetargets.append((platform, (platform, get_compiler_env(conf, 'msvc', version, 'x86', vsvars, combine_common)))) except conf.errors.ConfigurationError: continue @@ -427,19 +434,19 @@ def combine_common(compiler_env): versions.append((device + ' ' + version, cetargets)) @conf -def gather_winphone_targets(conf, versions, version, vc_path, vsvars, lazy=False): +def gather_winphone_targets(conf, versions, version, vc_path, vsvars): #Looking for WinPhone compilers targets = [] for target,realtarget in all_msvc_platforms[::-1]: try: - targets.append((target, (realtarget, get_compiler_env(conf, lazy, 'winphone', version, target, vsvars)))) + targets.append((target, (realtarget, get_compiler_env(conf, 'winphone', version, target, vsvars)))) except conf.errors.ConfigurationError: pass if targets: versions.append(('winphone '+ version, targets)) @conf -def gather_msvc_versions(conf, versions, lazy=False): +def gather_msvc_versions(conf, versions): vc_paths = [] for (v,version,reg) in gather_msvc_detected_versions(): try: @@ -458,18 +465,18 @@ def gather_msvc_versions(conf, versions, lazy=False): vs_path = os.path.dirname(vc_path) vsvars = os.path.join(vs_path, 'Common7', 'Tools', 'vsvars32.bat') if wince_supported_platforms and os.path.isfile(vsvars): - conf.gather_wince_targets(versions, version, vc_path, vsvars, wince_supported_platforms, lazy) + conf.gather_wince_targets(versions, version, vc_path, vsvars, wince_supported_platforms) vsvars = os.path.join(vs_path, 'VC', 'WPSDK', 'WP80', 'vcvarsphoneall.bat') if os.path.isfile(vsvars): - conf.gather_winphone_targets(versions, '8.0', vc_path, vsvars, lazy) + conf.gather_winphone_targets(versions, '8.0', vc_path, vsvars) for version,vc_path in vc_paths: vs_path = os.path.dirname(vc_path) - conf.gather_msvc_targets(versions, version, vc_path, lazy) + conf.gather_msvc_targets(versions, version, vc_path) @conf -def gather_icl_versions(conf, versions, lazy=False): +def gather_icl_versions(conf, versions): """ Checks ICL compilers @@ -504,7 +511,7 @@ def gather_icl_versions(conf, versions, lazy=False): batch_file=os.path.join(path,'bin','iclvars.bat') if os.path.isfile(batch_file): try: - targets.append((target,(arch,get_compiler_env(conf,lazy,'intel',version,target,batch_file)))) + targets.append((target,(arch,get_compiler_env(conf,'intel',version,target,batch_file)))) except conf.errors.ConfigurationError: pass except WindowsError: @@ -516,7 +523,7 @@ def gather_icl_versions(conf, versions, lazy=False): batch_file=os.path.join(path,'bin','iclvars.bat') if os.path.isfile(batch_file): try: - targets.append((target, (arch, get_compiler_env(conf, lazy, 'intel', version, target, batch_file)))) + targets.append((target, (arch, get_compiler_env(conf, 'intel', version, target, batch_file)))) except conf.errors.ConfigurationError: pass except WindowsError: @@ -525,7 +532,7 @@ def gather_icl_versions(conf, versions, lazy=False): versions.append(('intel ' + major, targets)) @conf -def gather_intel_composer_versions(conf, versions, lazy=False): +def gather_intel_composer_versions(conf, versions): """ Checks ICL compilers that are part of Intel Composer Suites @@ -568,7 +575,7 @@ def gather_intel_composer_versions(conf, versions, lazy=False): batch_file=os.path.join(path,'bin','iclvars.bat') if os.path.isfile(batch_file): try: - targets.append((target,(arch,get_compiler_env(conf,lazy,'intel',version,target,batch_file)))) + targets.append((target,(arch,get_compiler_env(conf,'intel',version,target,batch_file)))) except conf.errors.ConfigurationError: pass # The intel compilervar_arch.bat is broken when used with Visual Studio Express 2012 @@ -594,17 +601,17 @@ def gather_intel_composer_versions(conf, versions, lazy=False): versions.append(('intel ' + major, targets)) @conf -def get_msvc_versions(conf, lazy=False): +def get_msvc_versions(conf): """ :return: list of compilers installed :rtype: list of string """ if not conf.env['MSVC_INSTALLED_VERSIONS']: lst = [] - conf.gather_icl_versions(lst, lazy) - conf.gather_intel_composer_versions(lst, lazy) - conf.gather_wsdk_versions(lst, lazy) - conf.gather_msvc_versions(lst, lazy) + conf.gather_icl_versions(lst) + conf.gather_intel_composer_versions(lst) + conf.gather_wsdk_versions(lst) + conf.gather_msvc_versions(lst) conf.env['MSVC_INSTALLED_VERSIONS'] = lst return conf.env['MSVC_INSTALLED_VERSIONS'] @@ -619,8 +626,8 @@ def print_all_msvc_detected(conf): Logs.info("\t"+target) @conf -def detect_msvc(conf, arch=False, lazy=False): - versions = get_msvc_versions(conf, lazy) +def detect_msvc(conf, arch = False): + versions = get_msvc_versions(conf) return setup_msvc(conf, versions, arch) @conf @@ -742,8 +749,7 @@ def configure(conf): """ Configuration methods to call for detecting msvc """ - lazy = getattr(Options.options, 'msvc_lazy_autodetect', False) or conf.env['MSVC_LAZY_AUTODETECT'] - conf.autodetect(True, lazy) + conf.autodetect(True) conf.find_msvc() conf.msvc_common_flags() conf.cc_load_tools() @@ -759,15 +765,15 @@ def no_autodetect(conf): configure(conf) @conf -def autodetect(conf, arch=False, lazy=False): +def autodetect(conf, arch = False): v = conf.env if v.NO_MSVC_DETECT: return if arch: - compiler, version, path, includes, libdirs, arch = conf.detect_msvc(True, lazy) + compiler, version, path, includes, libdirs, arch = conf.detect_msvc(True) v['DEST_CPU'] = arch else: - compiler, version, path, includes, libdirs = conf.detect_msvc(False, lazy) + compiler, version, path, includes, libdirs = conf.detect_msvc() v['PATH'] = path v['INCLUDES'] = includes From 143ccb7a742d8e425cd617ca5e3456f03846ce47 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Tue, 1 Sep 2015 19:40:26 +0200 Subject: [PATCH 0125/1763] Pull request 1618 - cpplint --- waflib/extras/cpplint.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/waflib/extras/cpplint.py b/waflib/extras/cpplint.py index fed18e9bab..d4f5d9dcf8 100644 --- a/waflib/extras/cpplint.py +++ b/waflib/extras/cpplint.py @@ -98,9 +98,9 @@ def options(opt): def configure(conf): conf.start_msg('Checking cpplint') try: - import cpplint + _cpplint_state conf.end_msg('ok') - except ImportError: + except NameError: conf.env.CPPLINT_SKIP = True conf.end_msg('not found, skipping it.') From 973863e4187dc57d69ce6010aa956ca060d0b7aa Mon Sep 17 00:00:00 2001 From: Syl Date: Tue, 1 Sep 2015 20:52:03 +0200 Subject: [PATCH 0126/1763] boost: check Boost.Log in check_boost if the user uses it. --- waflib/extras/boost.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/waflib/extras/boost.py b/waflib/extras/boost.py index d3c4869060..7d833261a7 100644 --- a/waflib/extras/boost.py +++ b/waflib/extras/boost.py @@ -74,6 +74,18 @@ def build(bld): int main() { boost::thread t; } ''' +BOOST_LOG_CODE = ''' +#include +#include +#include +int main() { + using namespace boost::log; + add_common_attributes(); + add_console_log(std::clog, keywords::format = "%Message%"); + BOOST_LOG_TRIVIAL(debug) << "log is working" << std::endl; +} +''' + # toolsets from {boost_dir}/tools/build/v2/tools/common.jam PLATFORM = Utils.unversioned_sys_platform() detect_intel = lambda env: (PLATFORM == 'win32') and 'iw' or 'il' @@ -345,6 +357,9 @@ def try_link(): if (params['lib'] and 'thread' in params['lib']) or \ params['stlib'] and 'thread' in params['stlib']: self.check_cxx(fragment=BOOST_THREAD_CODE, use=var, execute=False) + if (params['lib'] and 'log' in params['lib']) or \ + params['stlib'] and 'log' in params['stlib']: + self.check_cxx(fragment=BOOST_LOG_CODE, use=var, execute=False) if params.get('linkage_autodetect', False): self.start_msg("Attempting to detect boost linkage flags") From fa41ac821316445ca466bb494d6a942fcb605cde Mon Sep 17 00:00:00 2001 From: Shawn Hoover Date: Wed, 2 Sep 2015 09:16:48 -0400 Subject: [PATCH 0127/1763] Fixed a local variable shadowing the arch return switch for setup_msvc. --- waflib/Tools/msvc.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/waflib/Tools/msvc.py b/waflib/Tools/msvc.py index 25c32b2751..fcc969cfef 100644 --- a/waflib/Tools/msvc.py +++ b/waflib/Tools/msvc.py @@ -121,14 +121,14 @@ def setup_msvc(conf, versions, arch = False): for target in platforms: try: try: - arch,(p1,p2,p3) = targets[target] + realtarget,(p1,p2,p3) = targets[target] except conf.errors.ConfigurationError: # lazytup target evaluation errors del(targets[target]) else: compiler,revision = version.rsplit(' ', 1) if arch: - return compiler,revision,p1,p2,p3,arch + return compiler,revision,p1,p2,p3,realtarget else: return compiler,revision,p1,p2,p3 except KeyError: continue From eb13629bda3bc9e08cdfe7936f4bb9d3d82e7ea0 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Thu, 3 Sep 2015 20:58:47 +0200 Subject: [PATCH 0128/1763] clang seems to provide llvm-ar --- waflib/Tools/clang.py | 1 + waflib/Tools/clangxx.py | 1 + 2 files changed, 2 insertions(+) diff --git a/waflib/Tools/clang.py b/waflib/Tools/clang.py index 999c604cbb..0740e00baf 100644 --- a/waflib/Tools/clang.py +++ b/waflib/Tools/clang.py @@ -21,6 +21,7 @@ def find_clang(conf): def configure(conf): conf.find_clang() + conf.find_program(['llvm-ar', 'ar'], var='AR') conf.find_ar() conf.gcc_common_flags() conf.gcc_modifier_platform() diff --git a/waflib/Tools/clangxx.py b/waflib/Tools/clangxx.py index c8d34a71b0..b52fc3521f 100644 --- a/waflib/Tools/clangxx.py +++ b/waflib/Tools/clangxx.py @@ -21,6 +21,7 @@ def find_clangxx(conf): def configure(conf): conf.find_clangxx() + conf.find_program(['llvm-ar', 'ar'], var='AR') conf.find_ar() conf.gxx_common_flags() conf.gxx_modifier_platform() From c2f4f1b1e850cb9b7877f46093afe4a98d354fd0 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Thu, 3 Sep 2015 21:31:46 +0200 Subject: [PATCH 0129/1763] Force a chmod value for configuration tests executed --- waflib/Tools/c_config.py | 1 + 1 file changed, 1 insertion(+) diff --git a/waflib/Tools/c_config.py b/waflib/Tools/c_config.py index 91f4c05057..f78838f21c 100644 --- a/waflib/Tools/c_config.py +++ b/waflib/Tools/c_config.py @@ -589,6 +589,7 @@ def to_header(dct): kw['execute'] = False if kw['execute']: kw['features'].append('test_exec') + kw['chmod'] = 493 if not 'errmsg' in kw: kw['errmsg'] = 'not found' From 7cca5e060ff8d01c011005647cc03af6744b3db2 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Thu, 3 Sep 2015 23:34:34 +0200 Subject: [PATCH 0130/1763] Broken configurations may leave stale variables --- demos/wscript | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/demos/wscript b/demos/wscript index 9491bd639b..1c990a257c 100644 --- a/demos/wscript +++ b/demos/wscript @@ -31,7 +31,7 @@ def options(opt): try: opt.recurse(d.name) - except: + except Exception: pass # one sub-project uses autoconfig, but i do not want it here from waflib import Configure @@ -60,10 +60,11 @@ def configure(conf): for d in conf.path.ant_glob(DIRS, excl=['build', 'variants', 'precious'], src=False, dir=True): if d.name[0] == '.': continue - + conf.env.stash() try: conf.recurse(d.name) except Exception: + conf.env.revert() node = conf.path.find_node('%s/build/config.log' % d.name) if node: Logs.info("-- BEGIN %s config.log --\n%s-- END %s config.log --" % (d.name, node.read(), d.name)) @@ -74,6 +75,7 @@ def configure(conf): except Exception: pass else: + conf.env.revert() conf.env.append_value('CFG', [d.name]) print("The configurations enabled are %r" % conf.env.CFG) From 48e48babb49c434313323f3ab228a01c8b0e471f Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Mon, 7 Sep 2015 21:03:16 +0200 Subject: [PATCH 0131/1763] Override rule function outputs - Issue 1598 --- waflib/TaskGen.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/waflib/TaskGen.py b/waflib/TaskGen.py index b1110080de..44aa25d56c 100644 --- a/waflib/TaskGen.py +++ b/waflib/TaskGen.py @@ -593,6 +593,12 @@ def scan(self): if getattr(self, 'cache_rule', 'True'): cache[(name, self.rule)] = cls + if getattr(self, 'cls_str', None): + setattr(cls, '__str__', self.cls_str) + + if getattr(self, 'cls_keyword', None): + setattr(cls, 'keyword', self.cls_keyword) + # now create one instance tsk = self.create_task(name) From b00b9ab4e375f363dbfe5f8bfb2be215758c735a Mon Sep 17 00:00:00 2001 From: Shawn Hoover Date: Wed, 9 Sep 2015 10:52:20 -0400 Subject: [PATCH 0132/1763] Don't save/print MSVC_INSTALLED_VERSIONS for lazy detection. --- waflib/Tools/msvc.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/waflib/Tools/msvc.py b/waflib/Tools/msvc.py index fcc969cfef..e48fcc3431 100644 --- a/waflib/Tools/msvc.py +++ b/waflib/Tools/msvc.py @@ -383,7 +383,7 @@ def __repr__(self): def evaluate(self): if hasattr(self, 'value'): return - self.value = self.fn() + self.value = self.fn() @conf def gather_msvc_targets(conf, versions, version, vc_path): @@ -606,14 +606,20 @@ def get_msvc_versions(conf): :return: list of compilers installed :rtype: list of string """ - if not conf.env['MSVC_INSTALLED_VERSIONS']: - lst = [] - conf.gather_icl_versions(lst) - conf.gather_intel_composer_versions(lst) - conf.gather_wsdk_versions(lst) - conf.gather_msvc_versions(lst) + if conf.env['MSVC_INSTALLED_VERSIONS']: + return conf.env['MSVC_INSTALLED_VERSIONS'] + + lst = [] + conf.gather_icl_versions(lst) + conf.gather_intel_composer_versions(lst) + conf.gather_wsdk_versions(lst) + conf.gather_msvc_versions(lst) + + lazy = getattr(Options.options, 'msvc_lazy_autodetect', False) or conf.env['MSVC_LAZY_AUTODETECT'] + if not lazy: conf.env['MSVC_INSTALLED_VERSIONS'] = lst - return conf.env['MSVC_INSTALLED_VERSIONS'] + + return lst @conf def print_all_msvc_detected(conf): From eb18a77a5fef6495f70f0616595e6f0ffcce1774 Mon Sep 17 00:00:00 2001 From: Shawn Hoover Date: Wed, 9 Sep 2015 10:52:23 -0400 Subject: [PATCH 0133/1763] Override lazy detection and save MSVC_INSTALLED_VERSIONS if get_msvc_versions is called directly. --- waflib/Tools/msvc.py | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/waflib/Tools/msvc.py b/waflib/Tools/msvc.py index e48fcc3431..992c4f4660 100644 --- a/waflib/Tools/msvc.py +++ b/waflib/Tools/msvc.py @@ -601,22 +601,33 @@ def gather_intel_composer_versions(conf, versions): versions.append(('intel ' + major, targets)) @conf -def get_msvc_versions(conf): +def get_msvc_versions(conf, eval_and_save=True): """ :return: list of compilers installed :rtype: list of string """ if conf.env['MSVC_INSTALLED_VERSIONS']: return conf.env['MSVC_INSTALLED_VERSIONS'] - + + # Gather all the compiler versions and targets. This phase can be lazy + # per lazy detection settings. lst = [] conf.gather_icl_versions(lst) conf.gather_intel_composer_versions(lst) conf.gather_wsdk_versions(lst) conf.gather_msvc_versions(lst) - lazy = getattr(Options.options, 'msvc_lazy_autodetect', False) or conf.env['MSVC_LAZY_AUTODETECT'] - if not lazy: + # Override lazy detection by evaluating after the fact. + if eval_and_save: + def checked_target(t): + target,(arch,paths) = t + try: + paths.evaluate() + except conf.errors.ConfigurationError: + return None + else: + return t + lst = [(version,filter(checked_target, targets)) for version, targets in lst] conf.env['MSVC_INSTALLED_VERSIONS'] = lst return lst @@ -633,7 +644,9 @@ def print_all_msvc_detected(conf): @conf def detect_msvc(conf, arch = False): - versions = get_msvc_versions(conf) + # Save installed versions only if lazy detection is disabled. + lazy_detect = getattr(Options.options, 'msvc_lazy_autodetect', False) or conf.env['MSVC_LAZY_AUTODETECT'] + versions = get_msvc_versions(conf, not lazy_detect) return setup_msvc(conf, versions, arch) @conf From a8480cc2ff14d49239df6ac36c3389a40517d281 Mon Sep 17 00:00:00 2001 From: Shawn Hoover Date: Wed, 9 Sep 2015 12:30:23 -0400 Subject: [PATCH 0134/1763] Fix to consolidate WinCE versions in the compiler versions list. --- waflib/Tools/msvc.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/waflib/Tools/msvc.py b/waflib/Tools/msvc.py index fcc969cfef..3dbedccde1 100644 --- a/waflib/Tools/msvc.py +++ b/waflib/Tools/msvc.py @@ -283,12 +283,12 @@ def gather_wince_supported_platforms(): path,device = os.path.split(path) if not device: path,device = os.path.split(path) + platforms = [] for arch,compiler in all_wince_platforms: - platforms = [] if os.path.isdir(os.path.join(path, device, 'Lib', arch)): platforms.append((arch, compiler, os.path.join(path, device, 'Include', arch), os.path.join(path, device, 'Lib', arch))) - if platforms: - supported_wince_platforms.append((device, platforms)) + if platforms: + supported_wince_platforms.append((device, platforms)) return supported_wince_platforms def gather_msvc_detected_versions(): From c376be6f616b2b38f98b826b8588536b2d0620a2 Mon Sep 17 00:00:00 2001 From: Shawn Hoover Date: Wed, 9 Sep 2015 12:31:09 -0400 Subject: [PATCH 0135/1763] Fix duplicate winphone 8.0 targets in the detected versions list. --- waflib/Tools/msvc.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/waflib/Tools/msvc.py b/waflib/Tools/msvc.py index 3dbedccde1..68e77827fd 100644 --- a/waflib/Tools/msvc.py +++ b/waflib/Tools/msvc.py @@ -467,9 +467,14 @@ def gather_msvc_versions(conf, versions): if wince_supported_platforms and os.path.isfile(vsvars): conf.gather_wince_targets(versions, version, vc_path, vsvars, wince_supported_platforms) + # WP80 works with 11.0Exp and 11.0, both of which resolve to the same vc_path. + # Stop after one is found. + for version,vc_path in vc_paths: + vs_path = os.path.dirname(vc_path) vsvars = os.path.join(vs_path, 'VC', 'WPSDK', 'WP80', 'vcvarsphoneall.bat') if os.path.isfile(vsvars): conf.gather_winphone_targets(versions, '8.0', vc_path, vsvars) + break for version,vc_path in vc_paths: vs_path = os.path.dirname(vc_path) From 411672c069638c9d6dd5b3aab7dfcc23894f7ae1 Mon Sep 17 00:00:00 2001 From: Chen He Date: Thu, 10 Sep 2015 10:37:40 -0400 Subject: [PATCH 0136/1763] Update the pic build flag used for Sun CC `-Kpic` had been used to generate position-indenpendent code for Sun CC. This permits only 2^10 unqiue symbols per shared object on 64-bit systems. This is an unreasonably small default. Switching to `-KPIC` increases the number to 2^29. According to http://docs.oracle.com/cd/E37069_01/html/E37074/bjapp.html#OSSCGbjatt, both `-Kpic` and `-KPIC` have been deprecated, and the `-xcode` option should be used instead. `-xcode` has been available since at least Sun Studio 8. --- waflib/Tools/suncc.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/waflib/Tools/suncc.py b/waflib/Tools/suncc.py index e705c328ed..21cbfb737b 100644 --- a/waflib/Tools/suncc.py +++ b/waflib/Tools/suncc.py @@ -53,7 +53,7 @@ def scc_common_flags(conf): v['cprogram_PATTERN'] = '%s' # shared library - v['CFLAGS_cshlib'] = ['-Kpic', '-DPIC'] + v['CFLAGS_cshlib'] = ['-xcode=pic32', '-DPIC'] v['LINKFLAGS_cshlib'] = ['-G'] v['cshlib_PATTERN'] = 'lib%s.so' @@ -68,4 +68,3 @@ def configure(conf): conf.cc_load_tools() conf.cc_add_flags() conf.link_add_flags() - From 49f51d547bf8539ef98c1936aa9cf47197f59c8b Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sat, 12 Sep 2015 23:32:39 +0200 Subject: [PATCH 0137/1763] Missing change -Kpic/-xcode=pic32 for sun compilers in c++ mode --- waflib/Tools/suncxx.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/waflib/Tools/suncxx.py b/waflib/Tools/suncxx.py index 01b3f8d251..ec48369f4e 100644 --- a/waflib/Tools/suncxx.py +++ b/waflib/Tools/suncxx.py @@ -51,7 +51,7 @@ def sxx_common_flags(conf): v['cxxprogram_PATTERN'] = '%s' # shared library - v['CXXFLAGS_cxxshlib'] = ['-Kpic', '-DPIC'] + v['CXXFLAGS_cxxshlib'] = ['-xcode=pic32', '-DPIC'] v['LINKFLAGS_cxxshlib'] = ['-G'] v['cxxshlib_PATTERN'] = 'lib%s.so' From 002706431d0a177fddafa8413a9321b3041e4bdc Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sat, 12 Sep 2015 23:49:38 +0200 Subject: [PATCH 0138/1763] docs --- ChangeLog | 7 +++++-- waflib/Tools/suncc.py | 1 - waflib/Tools/suncxx.py | 1 - 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3f56a4552e..0b3e4e845b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,12 @@ NEW IN WAF 1.8.13 ----------------- * Exposed the Popen parameters input/timeout to cmd_and_log/exec_command (timeout is for Python >= 3.3) -* Added an option to skip searching the regular sys.path when loading waf tools -* Changed gccdeps so that it handle .. within paths +* Added 'with_sys_path' to Context.load_tool to use/skip sys.path +* Changed gccdeps so that it handle '..' within paths * env = conf.env.derive().detach() +* Changed Sun compiler's default flags from -Kpic to -xcode=pic32 - #1625 +* Added bld(rule=, ..., cls_str=, cls_keyword=) for more descriptive outputs - #1598 +* Added a lazy Visual Studio detection option --msvc_lazy_autodetect - #1614 NEW IN WAF 1.8.12 ----------------- diff --git a/waflib/Tools/suncc.py b/waflib/Tools/suncc.py index 21cbfb737b..4909854eee 100644 --- a/waflib/Tools/suncc.py +++ b/waflib/Tools/suncc.py @@ -3,7 +3,6 @@ # Thomas Nagy, 2006-2010 (ita) # Ralf Habacker, 2006 (rh) -from waflib import Utils from waflib.Tools import ccroot, ar from waflib.Configure import conf diff --git a/waflib/Tools/suncxx.py b/waflib/Tools/suncxx.py index ec48369f4e..5a04b48333 100644 --- a/waflib/Tools/suncxx.py +++ b/waflib/Tools/suncxx.py @@ -3,7 +3,6 @@ # Thomas Nagy, 2006-2010 (ita) # Ralf Habacker, 2006 (rh) -from waflib import Utils from waflib.Tools import ccroot, ar from waflib.Configure import conf From c5952e19ab05ce6d3595e406e35a36a38c92b462 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sun, 13 Sep 2015 22:14:31 +0200 Subject: [PATCH 0139/1763] waf 1.8.13 --- waf-light | 2 +- waflib/Context.py | 6 +++--- wscript | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/waf-light b/waf-light index 0633844951..80da68e88b 100755 --- a/waf-light +++ b/waf-light @@ -32,7 +32,7 @@ POSSIBILITY OF SUCH DAMAGE. import os, sys, inspect -VERSION="1.8.12" +VERSION="1.8.13" REVISION="x" GIT="x" INSTALL="x" diff --git a/waflib/Context.py b/waflib/Context.py index 748254ceb7..91fd32d134 100644 --- a/waflib/Context.py +++ b/waflib/Context.py @@ -11,13 +11,13 @@ import waflib.Node # the following 3 constants are updated on each new release (do not touch) -HEXVERSION=0x1080c00 +HEXVERSION=0x1080d00 """Constant updated on new releases""" -WAFVERSION="1.8.12" +WAFVERSION="1.8.13" """Constant updated on new releases""" -WAFREVISION="ae508f2f82fbfad4420f7920b6f68a6801e383fd" +WAFREVISION="002706431d0a177fddafa8413a9321b3041e4bdc" """Git revision when the waf version is updated""" ABI = 98 diff --git a/wscript b/wscript index cfe627f374..7c35597bf6 100644 --- a/wscript +++ b/wscript @@ -10,7 +10,7 @@ To add a tool that does not exist in the folder compat15, pass an absolute path: """ -VERSION="1.8.12" +VERSION="1.8.13" APPNAME='waf' REVISION='' From 6de1ac07d51a4cb3a9619866ef19c459512bf668 Mon Sep 17 00:00:00 2001 From: Mohammad Alsaleh Date: Tue, 8 Sep 2015 18:11:05 +0300 Subject: [PATCH 0140/1763] c_config: Avoid warnings/errors when checking for C functions The check for C functions fails with '-Werror' in GCC (5.2). return (int)p; ^ The cast here triggers this error: error: cast from pointer to integer of different size [-Werror=pointer-to-int-cast] p=(void*)(%s); ^ This conversion triggers another error with '-pedantic -Werror': error: ISO C forbids conversion of function pointer to object pointer type [-Werror=pedantic] This patch fixes both errors. Signed-off-by: Mohammad Alsaleh --- waflib/Tools/c_config.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/waflib/Tools/c_config.py b/waflib/Tools/c_config.py index f78838f21c..14243cd823 100644 --- a/waflib/Tools/c_config.py +++ b/waflib/Tools/c_config.py @@ -25,10 +25,10 @@ SNIP_FUNCTION = ''' int main(int argc, char **argv) { - void *p; + void (*p)(); (void)argc; (void)argv; - p=(void*)(%s); - return (int)p; + p=(void(*)())(%s); + return !p; } ''' """Code template for checking for functions""" From 80d26d5dabfb3977fcf0738a72f092a8c25899e5 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sun, 13 Sep 2015 22:45:56 +0200 Subject: [PATCH 0141/1763] docs --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 0b3e4e845b..962722fafe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,7 @@ NEW IN WAF 1.8.13 * Changed Sun compiler's default flags from -Kpic to -xcode=pic32 - #1625 * Added bld(rule=, ..., cls_str=, cls_keyword=) for more descriptive outputs - #1598 * Added a lazy Visual Studio detection option --msvc_lazy_autodetect - #1614 +* Changed the definition of function tests to prevent warnings with gcc - #1622 NEW IN WAF 1.8.12 ----------------- From 8ea1de44a73edbe03de7d6172a33f6ea3e09e487 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sat, 19 Sep 2015 09:53:53 +0200 Subject: [PATCH 0142/1763] Vala resources - Issue 1626 --- demos/vala/resources/appwindow.ui | 8 ++++++++ demos/vala/resources/test.gresource.xml | 7 +++++++ demos/vala/resources/test.vala | 22 ++++++++++++++++++++++ demos/vala/resources/wscript | 25 +++++++++++++++++++++++++ demos/vala/wscript | 2 +- waflib/Tools/vala.py | 11 ++++++++++- 6 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 demos/vala/resources/appwindow.ui create mode 100644 demos/vala/resources/test.gresource.xml create mode 100644 demos/vala/resources/test.vala create mode 100644 demos/vala/resources/wscript diff --git a/demos/vala/resources/appwindow.ui b/demos/vala/resources/appwindow.ui new file mode 100644 index 0000000000..f4db45f847 --- /dev/null +++ b/demos/vala/resources/appwindow.ui @@ -0,0 +1,8 @@ + + + + diff --git a/demos/vala/resources/test.gresource.xml b/demos/vala/resources/test.gresource.xml new file mode 100644 index 0000000000..ccd51bf6b1 --- /dev/null +++ b/demos/vala/resources/test.gresource.xml @@ -0,0 +1,7 @@ + + + + + appwindow.ui + + diff --git a/demos/vala/resources/test.vala b/demos/vala/resources/test.vala new file mode 100644 index 0000000000..80b1f7919c --- /dev/null +++ b/demos/vala/resources/test.vala @@ -0,0 +1,22 @@ +using Gtk; + +[GtkTemplate (ui="/org/test/appwindow.ui")] +class TestWindow : Gtk.ApplicationWindow { + public TestWindow(Gtk.Application app) { + Object(application: app); + } +} + +class TestApp : Gtk.Application { + public override void activate() { + var window = new TestWindow(this); + + window.show_all(); + } +} + +int main(string[] args) { + var app = new TestApp(); + + return app.run(); +} diff --git a/demos/vala/resources/wscript b/demos/vala/resources/wscript new file mode 100644 index 0000000000..717cfb1dde --- /dev/null +++ b/demos/vala/resources/wscript @@ -0,0 +1,25 @@ +#! /usr/bin/env python + +def configure(conf): + try: + conf.check_cfg(package='gtk+-3.0', uselib_store='GTK3', args='--cflags --libs') + conf.load('glib2') + except conf.errors.ConfigurationError: + pass + else: + conf.env.build_gtk3 = True + +def build(bld): + if not bld.env.build_gtk3: + return + + bld ( + features = 'c cprogram glib2', + use = 'GTK3', + packages = 'gtk+-3.0', + source = 'test.vala', + vala_resources = 'test.gresource.xml', # adds --gresources /path/to/test.gresources.xml + target = 'compositewidget', + vala_target_glib = '2.38' + ) + diff --git a/demos/vala/wscript b/demos/vala/wscript index 4324846063..4375ac44eb 100644 --- a/demos/vala/wscript +++ b/demos/vala/wscript @@ -20,5 +20,5 @@ def configure(conf): conf.check_cfg(package='gtk+-2.0', uselib_store='GTK', atleast_version='2.10.0', mandatory=1, args='--cflags --libs') def build(bld): - bld.recurse('src shlib multi-file stlib') + bld.recurse('src shlib multi-file stlib resources') diff --git a/waflib/Tools/vala.py b/waflib/Tools/vala.py index f9bf976030..c6c11b8d9b 100644 --- a/waflib/Tools/vala.py +++ b/waflib/Tools/vala.py @@ -24,7 +24,8 @@ class valac(Task.Task): def run(self): cmd = self.env.VALAC + self.env.VALAFLAGS - cmd.extend([a.abspath() for a in self.inputs]) + resources = getattr(self, 'vala_exclude', []) + cmd.extend([a.abspath() for a in self.inputs if a not in resources]) ret = self.exec_command(cmd, cwd=self.outputs[0].parent.abspath()) if ret: @@ -200,6 +201,14 @@ def _get_api_version(): except AttributeError: self.install_gir = self.bld.install_files(getattr(self, 'gir_path', '${DATAROOTDIR}/gir-1.0'), gir_list, self.env) + if hasattr(self, 'vala_resources'): + nodes = self.to_nodes(self.vala_resources) + print nodes + valatask.vala_exclude = getattr(valatask, 'vala_exclude', []) + nodes + valatask.inputs.extend(nodes) + for x in nodes: + addflags(['--gresources', x.abspath()]) + @extension('.vala', '.gs') def vala_file(self, node): """ From 19042c840e1fab64e8fc6347847ad6344689dcca Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sat, 19 Sep 2015 17:01:03 +0200 Subject: [PATCH 0143/1763] clean up in demos/vala --- demos/vala/resources/appwindow.ui | 2 +- demos/vala/src/vala-gtk-example.vala | 40 ---------------------------- demos/vala/src/wscript_build | 13 --------- demos/vala/wscript | 3 +-- waflib/Tools/vala.py | 1 - 5 files changed, 2 insertions(+), 57 deletions(-) delete mode 100644 demos/vala/src/vala-gtk-example.vala delete mode 100644 demos/vala/src/wscript_build diff --git a/demos/vala/resources/appwindow.ui b/demos/vala/resources/appwindow.ui index f4db45f847..a4ead6f128 100644 --- a/demos/vala/resources/appwindow.ui +++ b/demos/vala/resources/appwindow.ui @@ -1,5 +1,5 @@ - +