0002-waf-upgrade-to-2.0.18.patch 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736
  1. From 9fdae71c29e7e80f463c0205b508d52c2bb7385b Mon Sep 17 00:00:00 2001
  2. From: Uri Simchoni <uri@samba.org>
  3. Date: Mon, 7 Oct 2019 00:36:42 +0300
  4. Subject: [PATCH] waf: upgrade to 2.0.18
  5. This is required to get the new test_args parameter to conf.check, which
  6. facilitates passing arguments to configuration test programs.
  7. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13846
  8. Signed-off-by: Uri Simchoni <uri@samba.org>
  9. Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
  10. ---
  11. buildtools/bin/waf | 2 +-
  12. buildtools/wafsamba/wafsamba.py | 2 +-
  13. third_party/waf/waflib/Configure.py | 20 +-
  14. third_party/waf/waflib/Context.py | 6 +-
  15. third_party/waf/waflib/Scripting.py | 7 +-
  16. third_party/waf/waflib/TaskGen.py | 2 +-
  17. third_party/waf/waflib/Tools/asm.py | 37 +++-
  18. third_party/waf/waflib/Tools/c_aliases.py | 6 +-
  19. third_party/waf/waflib/Tools/c_config.py | 9 +-
  20. third_party/waf/waflib/Tools/c_tests.py | 3 +-
  21. third_party/waf/waflib/Tools/gas.py | 1 +
  22. third_party/waf/waflib/Tools/javaw.py | 2 +-
  23. third_party/waf/waflib/Tools/nasm.py | 5 +
  24. third_party/waf/waflib/Tools/python.py | 27 ++-
  25. third_party/waf/waflib/extras/doxygen.py | 11 +-
  26. third_party/waf/waflib/extras/fast_partial.py | 28 ++-
  27. third_party/waf/waflib/extras/genpybind.py | 194 ++++++++++++++++++
  28. third_party/waf/waflib/extras/local_rpath.py | 8 +-
  29. third_party/waf/waflib/extras/objcopy.py | 9 +-
  30. 19 files changed, 329 insertions(+), 50 deletions(-)
  31. create mode 100644 third_party/waf/waflib/extras/genpybind.py
  32. diff --git a/buildtools/bin/waf b/buildtools/bin/waf
  33. index 8413f2332b7..11ce8e7480a 100755
  34. --- a/buildtools/bin/waf
  35. +++ b/buildtools/bin/waf
  36. @@ -32,7 +32,7 @@ POSSIBILITY OF SUCH DAMAGE.
  37. import os, sys, inspect
  38. -VERSION="2.0.17"
  39. +VERSION="2.0.18"
  40. REVISION="x"
  41. GIT="x"
  42. INSTALL="x"
  43. diff --git a/buildtools/wafsamba/wafsamba.py b/buildtools/wafsamba/wafsamba.py
  44. index 76d65ebfcb6..205d5b4ac32 100644
  45. --- a/buildtools/wafsamba/wafsamba.py
  46. +++ b/buildtools/wafsamba/wafsamba.py
  47. @@ -38,7 +38,7 @@ LIB_PATH="shared"
  48. os.environ['PYTHONUNBUFFERED'] = '1'
  49. -if Context.HEXVERSION not in (0x2001100,):
  50. +if Context.HEXVERSION not in (0x2001200,):
  51. Logs.error('''
  52. Please use the version of waf that comes with Samba, not
  53. a system installed version. See http://wiki.samba.org/index.php/Waf
  54. diff --git a/third_party/waf/waflib/Configure.py b/third_party/waf/waflib/Configure.py
  55. index db09c0e3a40..5762eb66954 100644
  56. --- a/third_party/waf/waflib/Configure.py
  57. +++ b/third_party/waf/waflib/Configure.py
  58. @@ -524,7 +524,7 @@ def run_build(self, *k, **kw):
  59. Though this function returns *0* by default, the build may set an attribute named *retval* on the
  60. build context object to return a particular value. See :py:func:`waflib.Tools.c_config.test_exec_fun` for example.
  61. - This function also provides a limited cache. To use it, provide the following option::
  62. + This function also features a cache which can be enabled by the following option::
  63. def options(opt):
  64. opt.add_option('--confcache', dest='confcache', default=0,
  65. @@ -535,10 +535,21 @@ def run_build(self, *k, **kw):
  66. $ waf configure --confcache
  67. """
  68. - lst = [str(v) for (p, v) in kw.items() if p != 'env']
  69. - h = Utils.h_list(lst)
  70. + buf = []
  71. + for key in sorted(kw.keys()):
  72. + v = kw[key]
  73. + if hasattr(v, '__call__'):
  74. + buf.append(Utils.h_fun(v))
  75. + else:
  76. + buf.append(str(v))
  77. + h = Utils.h_list(buf)
  78. dir = self.bldnode.abspath() + os.sep + (not Utils.is_win32 and '.' or '') + 'conf_check_' + Utils.to_hex(h)
  79. + cachemode = kw.get('confcache', getattr(Options.options, 'confcache', None))
  80. +
  81. + if not cachemode and os.path.exists(dir):
  82. + shutil.rmtree(dir)
  83. +
  84. try:
  85. os.makedirs(dir)
  86. except OSError:
  87. @@ -549,7 +560,6 @@ def run_build(self, *k, **kw):
  88. except OSError:
  89. self.fatal('cannot use the configuration test folder %r' % dir)
  90. - cachemode = getattr(Options.options, 'confcache', None)
  91. if cachemode == 1:
  92. try:
  93. proj = ConfigSet.ConfigSet(os.path.join(dir, 'cache_run_build'))
  94. @@ -589,7 +599,7 @@ def run_build(self, *k, **kw):
  95. else:
  96. ret = getattr(bld, 'retval', 0)
  97. finally:
  98. - if cachemode == 1:
  99. + if cachemode:
  100. # cache the results each time
  101. proj = ConfigSet.ConfigSet()
  102. proj['cache_run_build'] = ret
  103. diff --git a/third_party/waf/waflib/Context.py b/third_party/waf/waflib/Context.py
  104. index d0759aada58..e3305fa3341 100644
  105. --- a/third_party/waf/waflib/Context.py
  106. +++ b/third_party/waf/waflib/Context.py
  107. @@ -11,13 +11,13 @@ from waflib import Utils, Errors, Logs
  108. import waflib.Node
  109. # the following 3 constants are updated on each new release (do not touch)
  110. -HEXVERSION=0x2001100
  111. +HEXVERSION=0x2001200
  112. """Constant updated on new releases"""
  113. -WAFVERSION="2.0.17"
  114. +WAFVERSION="2.0.18"
  115. """Constant updated on new releases"""
  116. -WAFREVISION="6bc6cb599c702e985780e9f705b291b812123693"
  117. +WAFREVISION="314689b8994259a84f0de0aaef74d7ce91f541ad"
  118. """Git revision when the waf version is updated"""
  119. ABI = 20
  120. diff --git a/third_party/waf/waflib/Scripting.py b/third_party/waf/waflib/Scripting.py
  121. index ae17a8b4503..68dccf29ce0 100644
  122. --- a/third_party/waf/waflib/Scripting.py
  123. +++ b/third_party/waf/waflib/Scripting.py
  124. @@ -332,7 +332,12 @@ def distclean(ctx):
  125. else:
  126. remove_and_log(env.out_dir, shutil.rmtree)
  127. - for k in (env.out_dir, env.top_dir, env.run_dir):
  128. + env_dirs = [env.out_dir]
  129. + if not ctx.options.no_lock_in_top:
  130. + env_dirs.append(env.top_dir)
  131. + if not ctx.options.no_lock_in_run:
  132. + env_dirs.append(env.run_dir)
  133. + for k in env_dirs:
  134. p = os.path.join(k, Options.lockfile)
  135. remove_and_log(p, os.remove)
  136. diff --git a/third_party/waf/waflib/TaskGen.py b/third_party/waf/waflib/TaskGen.py
  137. index 532b7d5cdb4..f8f92bd57c1 100644
  138. --- a/third_party/waf/waflib/TaskGen.py
  139. +++ b/third_party/waf/waflib/TaskGen.py
  140. @@ -905,7 +905,7 @@ def process_subst(self):
  141. # paranoid safety measure for the general case foo.in->foo.h with ambiguous dependencies
  142. for xt in HEADER_EXTS:
  143. if b.name.endswith(xt):
  144. - tsk.ext_in = tsk.ext_in + ['.h']
  145. + tsk.ext_out = tsk.ext_out + ['.h']
  146. break
  147. inst_to = getattr(self, 'install_path', None)
  148. diff --git a/third_party/waf/waflib/Tools/asm.py b/third_party/waf/waflib/Tools/asm.py
  149. index b6f26fb3df3..a57e83bb5ec 100644
  150. --- a/third_party/waf/waflib/Tools/asm.py
  151. +++ b/third_party/waf/waflib/Tools/asm.py
  152. @@ -34,9 +34,22 @@ Support for pure asm programs and libraries should also work::
  153. target = 'asmtest')
  154. """
  155. -from waflib import Task
  156. +import re
  157. +from waflib import Errors, Logs, Task
  158. from waflib.Tools.ccroot import link_task, stlink_task
  159. from waflib.TaskGen import extension
  160. +from waflib.Tools import c_preproc
  161. +
  162. +re_lines = re.compile(
  163. + '^[ \t]*(?:%)[ \t]*(ifdef|ifndef|if|else|elif|endif|include|import|define|undef)[ \t]*(.*)\r*$',
  164. + re.IGNORECASE | re.MULTILINE)
  165. +
  166. +class asm_parser(c_preproc.c_parser):
  167. + def filter_comments(self, node):
  168. + code = node.read()
  169. + code = c_preproc.re_nl.sub('', code)
  170. + code = c_preproc.re_cpp.sub(c_preproc.repl, code)
  171. + return re_lines.findall(code)
  172. class asm(Task.Task):
  173. """
  174. @@ -45,6 +58,28 @@ class asm(Task.Task):
  175. color = 'BLUE'
  176. run_str = '${AS} ${ASFLAGS} ${ASMPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${AS_SRC_F}${SRC} ${AS_TGT_F}${TGT}'
  177. + def scan(self):
  178. + if self.env.ASM_NAME == 'gas':
  179. + return c_preproc.scan(self)
  180. + Logs.warn('There is no dependency scanner for Nasm!')
  181. + return [[], []]
  182. + elif self.env.ASM_NAME == 'nasm':
  183. + Logs.warn('The Nasm dependency scanner is incomplete!')
  184. +
  185. + try:
  186. + incn = self.generator.includes_nodes
  187. + except AttributeError:
  188. + raise Errors.WafError('%r is missing the "asm" feature' % self.generator)
  189. +
  190. + if c_preproc.go_absolute:
  191. + nodepaths = incn
  192. + else:
  193. + nodepaths = [x for x in incn if x.is_child_of(x.ctx.srcnode) or x.is_child_of(x.ctx.bldnode)]
  194. +
  195. + tmp = asm_parser(nodepaths)
  196. + tmp.start(self.inputs[0], self.env)
  197. + return (tmp.nodes, tmp.names)
  198. +
  199. @extension('.s', '.S', '.asm', '.ASM', '.spp', '.SPP')
  200. def asm_hook(self, node):
  201. """
  202. diff --git a/third_party/waf/waflib/Tools/c_aliases.py b/third_party/waf/waflib/Tools/c_aliases.py
  203. index c9d53692e8f..985e048bdb7 100644
  204. --- a/third_party/waf/waflib/Tools/c_aliases.py
  205. +++ b/third_party/waf/waflib/Tools/c_aliases.py
  206. @@ -47,10 +47,12 @@ def sniff_features(**kw):
  207. if x in exts:
  208. feats.append('cxx')
  209. break
  210. -
  211. if 'c' in exts or 'vala' in exts or 'gs' in exts:
  212. feats.append('c')
  213. + if 's' in exts or 'S' in exts:
  214. + feats.append('asm')
  215. +
  216. for x in 'f f90 F F90 for FOR'.split():
  217. if x in exts:
  218. feats.append('fc')
  219. @@ -66,7 +68,7 @@ def sniff_features(**kw):
  220. if typ in ('program', 'shlib', 'stlib'):
  221. will_link = False
  222. for x in feats:
  223. - if x in ('cxx', 'd', 'fc', 'c'):
  224. + if x in ('cxx', 'd', 'fc', 'c', 'asm'):
  225. feats.append(x + typ)
  226. will_link = True
  227. if not will_link and not kw.get('features', []):
  228. diff --git a/third_party/waf/waflib/Tools/c_config.py b/third_party/waf/waflib/Tools/c_config.py
  229. index d546be95614..80580cc9fcb 100644
  230. --- a/third_party/waf/waflib/Tools/c_config.py
  231. +++ b/third_party/waf/waflib/Tools/c_config.py
  232. @@ -659,20 +659,21 @@ class test_exec(Task.Task):
  233. """
  234. color = 'PINK'
  235. def run(self):
  236. + cmd = [self.inputs[0].abspath()] + getattr(self.generator, 'test_args', [])
  237. if getattr(self.generator, 'rpath', None):
  238. if getattr(self.generator, 'define_ret', False):
  239. - self.generator.bld.retval = self.generator.bld.cmd_and_log([self.inputs[0].abspath()])
  240. + self.generator.bld.retval = self.generator.bld.cmd_and_log(cmd)
  241. else:
  242. - self.generator.bld.retval = self.generator.bld.exec_command([self.inputs[0].abspath()])
  243. + self.generator.bld.retval = self.generator.bld.exec_command(cmd)
  244. else:
  245. env = self.env.env or {}
  246. env.update(dict(os.environ))
  247. for var in ('LD_LIBRARY_PATH', 'DYLD_LIBRARY_PATH', 'PATH'):
  248. env[var] = self.inputs[0].parent.abspath() + os.path.pathsep + env.get(var, '')
  249. if getattr(self.generator, 'define_ret', False):
  250. - self.generator.bld.retval = self.generator.bld.cmd_and_log([self.inputs[0].abspath()], env=env)
  251. + self.generator.bld.retval = self.generator.bld.cmd_and_log(cmd, env=env)
  252. else:
  253. - self.generator.bld.retval = self.generator.bld.exec_command([self.inputs[0].abspath()], env=env)
  254. + self.generator.bld.retval = self.generator.bld.exec_command(cmd, env=env)
  255. @feature('test_exec')
  256. @after_method('apply_link')
  257. diff --git a/third_party/waf/waflib/Tools/c_tests.py b/third_party/waf/waflib/Tools/c_tests.py
  258. index f858df5763c..7a4094f2450 100644
  259. --- a/third_party/waf/waflib/Tools/c_tests.py
  260. +++ b/third_party/waf/waflib/Tools/c_tests.py
  261. @@ -224,6 +224,7 @@ def check_endianness(self):
  262. def check_msg(self):
  263. return tmp[0]
  264. self.check(fragment=ENDIAN_FRAGMENT, features='c grep_for_endianness',
  265. - msg='Checking for endianness', define='ENDIANNESS', tmp=tmp, okmsg=check_msg)
  266. + msg='Checking for endianness', define='ENDIANNESS', tmp=tmp,
  267. + okmsg=check_msg, confcache=None)
  268. return tmp[0]
  269. diff --git a/third_party/waf/waflib/Tools/gas.py b/third_party/waf/waflib/Tools/gas.py
  270. index 77afed7038f..4a8745afd7e 100644
  271. --- a/third_party/waf/waflib/Tools/gas.py
  272. +++ b/third_party/waf/waflib/Tools/gas.py
  273. @@ -16,3 +16,4 @@ def configure(conf):
  274. conf.env.ASLNK_TGT_F = ['-o']
  275. conf.find_ar()
  276. conf.load('asm')
  277. + conf.env.ASM_NAME = 'gas'
  278. diff --git a/third_party/waf/waflib/Tools/javaw.py b/third_party/waf/waflib/Tools/javaw.py
  279. index fd1cf469abf..ceb08c28c87 100644
  280. --- a/third_party/waf/waflib/Tools/javaw.py
  281. +++ b/third_party/waf/waflib/Tools/javaw.py
  282. @@ -246,7 +246,7 @@ def use_javac_files(self):
  283. self.javac_task.dep_nodes.extend(tg.jar_task.outputs)
  284. else:
  285. if hasattr(tg, 'outdir'):
  286. - base_node = tg.outdir.abspath()
  287. + base_node = tg.outdir
  288. else:
  289. base_node = tg.path.get_bld()
  290. diff --git a/third_party/waf/waflib/Tools/nasm.py b/third_party/waf/waflib/Tools/nasm.py
  291. index 411d5826b5d..9c51c18de18 100644
  292. --- a/third_party/waf/waflib/Tools/nasm.py
  293. +++ b/third_party/waf/waflib/Tools/nasm.py
  294. @@ -24,3 +24,8 @@ def configure(conf):
  295. conf.env.ASLNK_TGT_F = ['-o']
  296. conf.load('asm')
  297. conf.env.ASMPATH_ST = '-I%s' + os.sep
  298. + txt = conf.cmd_and_log(conf.env.AS + ['--version'])
  299. + if 'yasm' in txt.lower():
  300. + conf.env.ASM_NAME = 'yasm'
  301. + else:
  302. + conf.env.ASM_NAME = 'nasm'
  303. diff --git a/third_party/waf/waflib/Tools/python.py b/third_party/waf/waflib/Tools/python.py
  304. index 63a8917d7c1..7c45a76ffd2 100644
  305. --- a/third_party/waf/waflib/Tools/python.py
  306. +++ b/third_party/waf/waflib/Tools/python.py
  307. @@ -79,14 +79,19 @@ def process_py(self, node):
  308. """
  309. Add signature of .py file, so it will be byte-compiled when necessary
  310. """
  311. - assert(hasattr(self, 'install_path')), 'add features="py"'
  312. + assert(hasattr(self, 'install_path')), 'add features="py" for target "%s" in "%s/wscript".' % (self.target, self.path.nice_path())
  313. + self.install_from = getattr(self, 'install_from', None)
  314. + relative_trick = getattr(self, 'relative_trick', True)
  315. + if self.install_from:
  316. + assert isinstance(self.install_from, Node.Node), \
  317. + 'add features="py" for target "%s" in "%s/wscript" (%s).' % (self.target, self.path.nice_path(), type(self.install_from))
  318. # where to install the python file
  319. if self.install_path:
  320. if self.install_from:
  321. - self.add_install_files(install_to=self.install_path, install_from=node, cwd=self.install_from, relative_trick=True)
  322. + self.add_install_files(install_to=self.install_path, install_from=node, cwd=self.install_from, relative_trick=relative_trick)
  323. else:
  324. - self.add_install_files(install_to=self.install_path, install_from=node, relative_trick=True)
  325. + self.add_install_files(install_to=self.install_path, install_from=node, relative_trick=relative_trick)
  326. lst = []
  327. if self.env.PYC:
  328. @@ -96,9 +101,11 @@ def process_py(self, node):
  329. if self.install_path:
  330. if self.install_from:
  331. - pyd = Utils.subst_vars("%s/%s" % (self.install_path, node.path_from(self.install_from)), self.env)
  332. + target_dir = node.path_from(self.install_from) if relative_trick else node.name
  333. + pyd = Utils.subst_vars("%s/%s" % (self.install_path, target_dir), self.env)
  334. else:
  335. - pyd = Utils.subst_vars("%s/%s" % (self.install_path, node.path_from(self.path)), self.env)
  336. + target_dir = node.path_from(self.path) if relative_trick else node.name
  337. + pyd = Utils.subst_vars("%s/%s" % (self.install_path, target_dir), self.env)
  338. else:
  339. pyd = node.abspath()
  340. @@ -115,7 +122,7 @@ def process_py(self, node):
  341. tsk.pyd = pyd
  342. if self.install_path:
  343. - self.add_install_files(install_to=os.path.dirname(pyd), install_from=pyobj, cwd=node.parent.get_bld(), relative_trick=True)
  344. + self.add_install_files(install_to=os.path.dirname(pyd), install_from=pyobj, cwd=node.parent.get_bld(), relative_trick=relative_trick)
  345. class pyc(Task.Task):
  346. """
  347. @@ -433,11 +440,11 @@ def check_python_headers(conf, features='pyembed pyext'):
  348. # Code using the Python API needs to be compiled with -fno-strict-aliasing
  349. if env.CC_NAME == 'gcc':
  350. - env.append_value('CFLAGS_PYEMBED', ['-fno-strict-aliasing'])
  351. - env.append_value('CFLAGS_PYEXT', ['-fno-strict-aliasing'])
  352. + env.append_unique('CFLAGS_PYEMBED', ['-fno-strict-aliasing'])
  353. + env.append_unique('CFLAGS_PYEXT', ['-fno-strict-aliasing'])
  354. if env.CXX_NAME == 'gcc':
  355. - env.append_value('CXXFLAGS_PYEMBED', ['-fno-strict-aliasing'])
  356. - env.append_value('CXXFLAGS_PYEXT', ['-fno-strict-aliasing'])
  357. + env.append_unique('CXXFLAGS_PYEMBED', ['-fno-strict-aliasing'])
  358. + env.append_unique('CXXFLAGS_PYEXT', ['-fno-strict-aliasing'])
  359. if env.CC_NAME == "msvc":
  360. from distutils.msvccompiler import MSVCCompiler
  361. diff --git a/third_party/waf/waflib/extras/doxygen.py b/third_party/waf/waflib/extras/doxygen.py
  362. index 423d8455025..20cd9e1a852 100644
  363. --- a/third_party/waf/waflib/extras/doxygen.py
  364. +++ b/third_party/waf/waflib/extras/doxygen.py
  365. @@ -85,6 +85,12 @@ class doxygen(Task.Task):
  366. if not getattr(self, 'pars', None):
  367. txt = self.inputs[0].read()
  368. self.pars = parse_doxy(txt)
  369. +
  370. + # Override with any parameters passed to the task generator
  371. + if getattr(self.generator, 'pars', None):
  372. + for k, v in self.generator.pars.items():
  373. + self.pars[k] = v
  374. +
  375. if self.pars.get('OUTPUT_DIRECTORY'):
  376. # Use the path parsed from the Doxyfile as an absolute path
  377. output_node = self.inputs[0].parent.get_bld().make_node(self.pars['OUTPUT_DIRECTORY'])
  378. @@ -94,11 +100,6 @@ class doxygen(Task.Task):
  379. output_node.mkdir()
  380. self.pars['OUTPUT_DIRECTORY'] = output_node.abspath()
  381. - # Override with any parameters passed to the task generator
  382. - if getattr(self.generator, 'pars', None):
  383. - for k, v in self.generator.pars.items():
  384. - self.pars[k] = v
  385. -
  386. self.doxy_inputs = getattr(self, 'doxy_inputs', [])
  387. if not self.pars.get('INPUT'):
  388. self.doxy_inputs.append(self.inputs[0].parent)
  389. diff --git a/third_party/waf/waflib/extras/fast_partial.py b/third_party/waf/waflib/extras/fast_partial.py
  390. index 71b8318eecb..90a94723bb8 100644
  391. --- a/third_party/waf/waflib/extras/fast_partial.py
  392. +++ b/third_party/waf/waflib/extras/fast_partial.py
  393. @@ -18,6 +18,7 @@ Usage::
  394. opt.load('fast_partial')
  395. Assumptions:
  396. +* Start with a clean build (run "waf distclean" after enabling)
  397. * Mostly for C/C++/Fortran targets with link tasks (object-only targets are not handled)
  398. try it in the folder generated by utils/genbench.py
  399. * For full project builds: no --targets and no pruning from subfolders
  400. @@ -131,12 +132,18 @@ class bld_proxy(object):
  401. data[x] = getattr(self, x)
  402. db = os.path.join(self.variant_dir, Context.DBFILE + self.store_key)
  403. - try:
  404. - waflib.Node.pickle_lock.acquire()
  405. + with waflib.Node.pickle_lock:
  406. waflib.Node.Nod3 = self.node_class
  407. - x = Build.cPickle.dumps(data, Build.PROTOCOL)
  408. - finally:
  409. - waflib.Node.pickle_lock.release()
  410. + try:
  411. + x = Build.cPickle.dumps(data, Build.PROTOCOL)
  412. + except Build.cPickle.PicklingError:
  413. + root = data['root']
  414. + for node_deps in data['node_deps'].values():
  415. + for idx, node in enumerate(node_deps):
  416. + # there may be more cross-context Node objects to fix,
  417. + # but this should be the main source
  418. + node_deps[idx] = root.find_node(node.abspath())
  419. + x = Build.cPickle.dumps(data, Build.PROTOCOL)
  420. Logs.debug('rev_use: storing %s', db)
  421. Utils.writef(db + '.tmp', x, m='wb')
  422. @@ -393,12 +400,17 @@ def is_stale(self):
  423. Logs.debug('rev_use: must post %r because this is a clean build')
  424. return True
  425. - # 3. check if the configuration changed
  426. - if os.stat(self.bld.bldnode.find_node('c4che/build.config.py').abspath()).st_mtime > dbstat:
  427. + # 3.a check if the configuration exists
  428. + cache_node = self.bld.bldnode.find_node('c4che/build.config.py')
  429. + if not cache_node:
  430. + return True
  431. +
  432. + # 3.b check if the configuration changed
  433. + if os.stat(cache_node.abspath()).st_mtime > dbstat:
  434. Logs.debug('rev_use: must post %r because the configuration has changed', self.name)
  435. return True
  436. - # 3.a any tstamp data?
  437. + # 3.c any tstamp data?
  438. try:
  439. f_deps = self.bld.f_deps
  440. except AttributeError:
  441. diff --git a/third_party/waf/waflib/extras/genpybind.py b/third_party/waf/waflib/extras/genpybind.py
  442. new file mode 100644
  443. index 00000000000..ac206ee8a8b
  444. --- /dev/null
  445. +++ b/third_party/waf/waflib/extras/genpybind.py
  446. @@ -0,0 +1,194 @@
  447. +import os
  448. +import pipes
  449. +import subprocess
  450. +import sys
  451. +
  452. +from waflib import Logs, Task, Context
  453. +from waflib.Tools.c_preproc import scan as scan_impl
  454. +# ^-- Note: waflib.extras.gccdeps.scan does not work for us,
  455. +# due to its current implementation:
  456. +# The -MD flag is injected into the {C,CXX}FLAGS environment variable and
  457. +# dependencies are read out in a separate step after compiling by reading
  458. +# the .d file saved alongside the object file.
  459. +# As the genpybind task refers to a header file that is never compiled itself,
  460. +# gccdeps will not be able to extract the list of dependencies.
  461. +
  462. +from waflib.TaskGen import feature, before_method
  463. +
  464. +
  465. +def join_args(args):
  466. + return " ".join(pipes.quote(arg) for arg in args)
  467. +
  468. +
  469. +def configure(cfg):
  470. + cfg.load("compiler_cxx")
  471. + cfg.load("python")
  472. + cfg.check_python_version(minver=(2, 7))
  473. + if not cfg.env.LLVM_CONFIG:
  474. + cfg.find_program("llvm-config", var="LLVM_CONFIG")
  475. + if not cfg.env.GENPYBIND:
  476. + cfg.find_program("genpybind", var="GENPYBIND")
  477. +
  478. + # find clang reasource dir for builtin headers
  479. + cfg.env.GENPYBIND_RESOURCE_DIR = os.path.join(
  480. + cfg.cmd_and_log(cfg.env.LLVM_CONFIG + ["--libdir"]).strip(),
  481. + "clang",
  482. + cfg.cmd_and_log(cfg.env.LLVM_CONFIG + ["--version"]).strip())
  483. + if os.path.exists(cfg.env.GENPYBIND_RESOURCE_DIR):
  484. + cfg.msg("Checking clang resource dir", cfg.env.GENPYBIND_RESOURCE_DIR)
  485. + else:
  486. + cfg.fatal("Clang resource dir not found")
  487. +
  488. +
  489. +@feature("genpybind")
  490. +@before_method("process_source")
  491. +def generate_genpybind_source(self):
  492. + """
  493. + Run genpybind on the headers provided in `source` and compile/link the
  494. + generated code instead. This works by generating the code on the fly and
  495. + swapping the source node before `process_source` is run.
  496. + """
  497. + # name of module defaults to name of target
  498. + module = getattr(self, "module", self.target)
  499. +
  500. + # create temporary source file in build directory to hold generated code
  501. + out = "genpybind-%s.%d.cpp" % (module, self.idx)
  502. + out = self.path.get_bld().find_or_declare(out)
  503. +
  504. + task = self.create_task("genpybind", self.to_nodes(self.source), out)
  505. + # used to detect whether CFLAGS or CXXFLAGS should be passed to genpybind
  506. + task.features = self.features
  507. + task.module = module
  508. + # can be used to select definitions to include in the current module
  509. + # (when header files are shared by more than one module)
  510. + task.genpybind_tags = self.to_list(getattr(self, "genpybind_tags", []))
  511. + # additional include directories
  512. + task.includes = self.to_list(getattr(self, "includes", []))
  513. + task.genpybind = self.env.GENPYBIND
  514. +
  515. + # Tell waf to compile/link the generated code instead of the headers
  516. + # originally passed-in via the `source` parameter. (see `process_source`)
  517. + self.source = [out]
  518. +
  519. +
  520. +class genpybind(Task.Task): # pylint: disable=invalid-name
  521. + """
  522. + Runs genpybind on headers provided as input to this task.
  523. + Generated code will be written to the first (and only) output node.
  524. + """
  525. + quiet = True
  526. + color = "PINK"
  527. + scan = scan_impl
  528. +
  529. + @staticmethod
  530. + def keyword():
  531. + return "Analyzing"
  532. +
  533. + def run(self):
  534. + if not self.inputs:
  535. + return
  536. +
  537. + args = self.find_genpybind() + self._arguments(
  538. + resource_dir=self.env.GENPYBIND_RESOURCE_DIR)
  539. +
  540. + output = self.run_genpybind(args)
  541. +
  542. + # For debugging / log output
  543. + pasteable_command = join_args(args)
  544. +
  545. + # write generated code to file in build directory
  546. + # (will be compiled during process_source stage)
  547. + (output_node,) = self.outputs
  548. + output_node.write("// {}\n{}\n".format(
  549. + pasteable_command.replace("\n", "\n// "), output))
  550. +
  551. + def find_genpybind(self):
  552. + return self.genpybind
  553. +
  554. + def run_genpybind(self, args):
  555. + bld = self.generator.bld
  556. +
  557. + kwargs = dict(cwd=bld.variant_dir)
  558. + if hasattr(bld, "log_command"):
  559. + bld.log_command(args, kwargs)
  560. + else:
  561. + Logs.debug("runner: {!r}".format(args))
  562. + proc = subprocess.Popen(
  563. + args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)
  564. + stdout, stderr = proc.communicate()
  565. +
  566. + if not isinstance(stdout, str):
  567. + stdout = stdout.decode(sys.stdout.encoding, errors="replace")
  568. + if not isinstance(stderr, str):
  569. + stderr = stderr.decode(sys.stderr.encoding, errors="replace")
  570. +
  571. + if proc.returncode != 0:
  572. + bld.fatal(
  573. + "genpybind returned {code} during the following call:"
  574. + "\n{command}\n\n{stdout}\n\n{stderr}".format(
  575. + code=proc.returncode,
  576. + command=join_args(args),
  577. + stdout=stdout,
  578. + stderr=stderr,
  579. + ))
  580. +
  581. + if stderr.strip():
  582. + Logs.debug("non-fatal warnings during genpybind run:\n{}".format(stderr))
  583. +
  584. + return stdout
  585. +
  586. + def _include_paths(self):
  587. + return self.generator.to_incnodes(self.includes + self.env.INCLUDES)
  588. +
  589. + def _inputs_as_relative_includes(self):
  590. + include_paths = self._include_paths()
  591. + relative_includes = []
  592. + for node in self.inputs:
  593. + for inc in include_paths:
  594. + if node.is_child_of(inc):
  595. + relative_includes.append(node.path_from(inc))
  596. + break
  597. + else:
  598. + self.generator.bld.fatal("could not resolve {}".format(node))
  599. + return relative_includes
  600. +
  601. + def _arguments(self, genpybind_parse=None, resource_dir=None):
  602. + args = []
  603. + relative_includes = self._inputs_as_relative_includes()
  604. + is_cxx = "cxx" in self.features
  605. +
  606. + # options for genpybind
  607. + args.extend(["--genpybind-module", self.module])
  608. + if self.genpybind_tags:
  609. + args.extend(["--genpybind-tag"] + self.genpybind_tags)
  610. + if relative_includes:
  611. + args.extend(["--genpybind-include"] + relative_includes)
  612. + if genpybind_parse:
  613. + args.extend(["--genpybind-parse", genpybind_parse])
  614. +
  615. + args.append("--")
  616. +
  617. + # headers to be processed by genpybind
  618. + args.extend(node.abspath() for node in self.inputs)
  619. +
  620. + args.append("--")
  621. +
  622. + # options for clang/genpybind-parse
  623. + args.append("-D__GENPYBIND__")
  624. + args.append("-xc++" if is_cxx else "-xc")
  625. + has_std_argument = False
  626. + for flag in self.env["CXXFLAGS" if is_cxx else "CFLAGS"]:
  627. + flag = flag.replace("-std=gnu", "-std=c")
  628. + if flag.startswith("-std=c"):
  629. + has_std_argument = True
  630. + args.append(flag)
  631. + if not has_std_argument:
  632. + args.append("-std=c++14")
  633. + args.extend("-I{}".format(n.abspath()) for n in self._include_paths())
  634. + args.extend("-D{}".format(p) for p in self.env.DEFINES)
  635. +
  636. + # point to clang resource dir, if specified
  637. + if resource_dir:
  638. + args.append("-resource-dir={}".format(resource_dir))
  639. +
  640. + return args
  641. diff --git a/third_party/waf/waflib/extras/local_rpath.py b/third_party/waf/waflib/extras/local_rpath.py
  642. index b2507e17a10..e3923d9b9d4 100644
  643. --- a/third_party/waf/waflib/extras/local_rpath.py
  644. +++ b/third_party/waf/waflib/extras/local_rpath.py
  645. @@ -2,18 +2,20 @@
  646. # encoding: utf-8
  647. # Thomas Nagy, 2011 (ita)
  648. +import copy
  649. from waflib.TaskGen import after_method, feature
  650. @after_method('propagate_uselib_vars')
  651. @feature('cprogram', 'cshlib', 'cxxprogram', 'cxxshlib', 'fcprogram', 'fcshlib')
  652. def add_rpath_stuff(self):
  653. - all = self.to_list(getattr(self, 'use', []))
  654. + all = copy.copy(self.to_list(getattr(self, 'use', [])))
  655. while all:
  656. name = all.pop()
  657. try:
  658. tg = self.bld.get_tgen_by_name(name)
  659. except:
  660. continue
  661. - self.env.append_value('RPATH', tg.link_task.outputs[0].parent.abspath())
  662. - all.extend(self.to_list(getattr(tg, 'use', [])))
  663. + if hasattr(tg, 'link_task'):
  664. + self.env.append_value('RPATH', tg.link_task.outputs[0].parent.abspath())
  665. + all.extend(self.to_list(getattr(tg, 'use', [])))
  666. diff --git a/third_party/waf/waflib/extras/objcopy.py b/third_party/waf/waflib/extras/objcopy.py
  667. index 82d8359ecf7..bb7ca6ef224 100644
  668. --- a/third_party/waf/waflib/extras/objcopy.py
  669. +++ b/third_party/waf/waflib/extras/objcopy.py
  670. @@ -15,7 +15,7 @@ objcopy_flags Additional flags passed to objcopy.
  671. """
  672. from waflib.Utils import def_attrs
  673. -from waflib import Task
  674. +from waflib import Task, Options
  675. from waflib.TaskGen import feature, after_method
  676. class objcopy(Task.Task):
  677. @@ -46,5 +46,8 @@ def map_objcopy(self):
  678. self.add_install_files(install_to=self.objcopy_install_path, install_from=task.outputs[0])
  679. def configure(ctx):
  680. - ctx.find_program('objcopy', var='OBJCOPY', mandatory=True)
  681. -
  682. + program_name = 'objcopy'
  683. + prefix = getattr(Options.options, 'cross_prefix', None)
  684. + if prefix:
  685. + program_name = '{}-{}'.format(prefix, program_name)
  686. + ctx.find_program(program_name, var='OBJCOPY', mandatory=True)
  687. --
  688. 2.20.1