jack2 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

371 lines
11KB

  1. #! /usr/bin/env python
  2. # encoding: utf-8
  3. # Thomas Nagy, 2010 (ita)
  4. """
  5. This file is provided to enable compatibility with waf 1.5
  6. It was enabled by default in waf 1.6, but it is not used in waf 1.7
  7. """
  8. import sys
  9. from waflib import ConfigSet, Logs, Options, Scripting, Task, Build, Configure, Node, Runner, TaskGen, Utils, Errors, Context
  10. # the following is to bring some compatibility with waf 1.5 "import waflib.Configure → import Configure"
  11. sys.modules['Environment'] = ConfigSet
  12. ConfigSet.Environment = ConfigSet.ConfigSet
  13. sys.modules['Logs'] = Logs
  14. sys.modules['Options'] = Options
  15. sys.modules['Scripting'] = Scripting
  16. sys.modules['Task'] = Task
  17. sys.modules['Build'] = Build
  18. sys.modules['Configure'] = Configure
  19. sys.modules['Node'] = Node
  20. sys.modules['Runner'] = Runner
  21. sys.modules['TaskGen'] = TaskGen
  22. sys.modules['Utils'] = Utils
  23. from waflib.Tools import c_preproc
  24. sys.modules['preproc'] = c_preproc
  25. from waflib.Tools import c_config
  26. sys.modules['config_c'] = c_config
  27. ConfigSet.ConfigSet.copy = ConfigSet.ConfigSet.derive
  28. ConfigSet.ConfigSet.set_variant = Utils.nada
  29. Build.BuildContext.add_subdirs = Build.BuildContext.recurse
  30. Build.BuildContext.new_task_gen = Build.BuildContext.__call__
  31. Build.BuildContext.is_install = 0
  32. Node.Node.relpath_gen = Node.Node.path_from
  33. Utils.pproc = Utils.subprocess
  34. Utils.get_term_cols = Logs.get_term_cols
  35. def cmd_output(cmd, **kw):
  36. silent = False
  37. if 'silent' in kw:
  38. silent = kw['silent']
  39. del(kw['silent'])
  40. if 'e' in kw:
  41. tmp = kw['e']
  42. del(kw['e'])
  43. kw['env'] = tmp
  44. kw['shell'] = isinstance(cmd, str)
  45. kw['stdout'] = Utils.subprocess.PIPE
  46. if silent:
  47. kw['stderr'] = Utils.subprocess.PIPE
  48. try:
  49. p = Utils.subprocess.Popen(cmd, **kw)
  50. output = p.communicate()[0]
  51. except OSError as e:
  52. raise ValueError(str(e))
  53. if p.returncode:
  54. if not silent:
  55. msg = "command execution failed: %s -> %r" % (cmd, str(output))
  56. raise ValueError(msg)
  57. output = ''
  58. return output
  59. Utils.cmd_output = cmd_output
  60. def name_to_obj(self, s, env=None):
  61. if Logs.verbose:
  62. Logs.warn('compat: change "name_to_obj(name, env)" by "get_tgen_by_name(name)"')
  63. return self.get_tgen_by_name(s)
  64. Build.BuildContext.name_to_obj = name_to_obj
  65. def env_of_name(self, name):
  66. try:
  67. return self.all_envs[name]
  68. except KeyError:
  69. Logs.error('no such environment: '+name)
  70. return None
  71. Build.BuildContext.env_of_name = env_of_name
  72. def set_env_name(self, name, env):
  73. self.all_envs[name] = env
  74. return env
  75. Configure.ConfigurationContext.set_env_name = set_env_name
  76. def retrieve(self, name, fromenv=None):
  77. try:
  78. env = self.all_envs[name]
  79. except KeyError:
  80. env = ConfigSet.ConfigSet()
  81. self.prepare_env(env)
  82. self.all_envs[name] = env
  83. else:
  84. if fromenv:
  85. Logs.warn("The environment %s may have been configured already" % name)
  86. return env
  87. Configure.ConfigurationContext.retrieve = retrieve
  88. Configure.ConfigurationContext.sub_config = Configure.ConfigurationContext.recurse
  89. Configure.ConfigurationContext.check_tool = Configure.ConfigurationContext.load
  90. Configure.conftest = Configure.conf
  91. Configure.ConfigurationError = Errors.ConfigurationError
  92. Utils.WafError = Errors.WafError
  93. Options.OptionsContext.sub_options = Options.OptionsContext.recurse
  94. Options.OptionsContext.tool_options = Context.Context.load
  95. Options.Handler = Options.OptionsContext
  96. Task.simple_task_type = Task.task_type_from_func = Task.task_factory
  97. Task.TaskBase.classes = Task.classes
  98. def setitem(self, key, value):
  99. if key.startswith('CCFLAGS'):
  100. key = key[1:]
  101. self.table[key] = value
  102. ConfigSet.ConfigSet.__setitem__ = setitem
  103. @TaskGen.feature('d')
  104. @TaskGen.before('apply_incpaths')
  105. def old_importpaths(self):
  106. if getattr(self, 'importpaths', []):
  107. self.includes = self.importpaths
  108. from waflib import Context
  109. eld = Context.load_tool
  110. def load_tool(*k, **kw):
  111. ret = eld(*k, **kw)
  112. if 'set_options' in ret.__dict__:
  113. if Logs.verbose:
  114. Logs.warn('compat: rename "set_options" to options')
  115. ret.options = ret.set_options
  116. if 'detect' in ret.__dict__:
  117. if Logs.verbose:
  118. Logs.warn('compat: rename "detect" to "configure"')
  119. ret.configure = ret.detect
  120. return ret
  121. Context.load_tool = load_tool
  122. def get_curdir(self):
  123. return self.path.abspath()
  124. Context.Context.curdir = property(get_curdir, Utils.nada)
  125. rev = Context.load_module
  126. def load_module(path, encoding=None):
  127. ret = rev(path, encoding)
  128. if 'set_options' in ret.__dict__:
  129. if Logs.verbose:
  130. Logs.warn('compat: rename "set_options" to "options" (%r)' % path)
  131. ret.options = ret.set_options
  132. if 'srcdir' in ret.__dict__:
  133. if Logs.verbose:
  134. Logs.warn('compat: rename "srcdir" to "top" (%r)' % path)
  135. ret.top = ret.srcdir
  136. if 'blddir' in ret.__dict__:
  137. if Logs.verbose:
  138. Logs.warn('compat: rename "blddir" to "out" (%r)' % path)
  139. ret.out = ret.blddir
  140. return ret
  141. Context.load_module = load_module
  142. old_post = TaskGen.task_gen.post
  143. def post(self):
  144. self.features = self.to_list(self.features)
  145. if 'cc' in self.features:
  146. if Logs.verbose:
  147. Logs.warn('compat: the feature cc does not exist anymore (use "c")')
  148. self.features.remove('cc')
  149. self.features.append('c')
  150. if 'cstaticlib' in self.features:
  151. if Logs.verbose:
  152. Logs.warn('compat: the feature cstaticlib does not exist anymore (use "cstlib" or "cxxstlib")')
  153. self.features.remove('cstaticlib')
  154. self.features.append(('cxx' in self.features) and 'cxxstlib' or 'cstlib')
  155. if getattr(self, 'ccflags', None):
  156. if Logs.verbose:
  157. Logs.warn('compat: "ccflags" was renamed to "cflags"')
  158. self.cflags = self.ccflags
  159. return old_post(self)
  160. TaskGen.task_gen.post = post
  161. def waf_version(*k, **kw):
  162. Logs.warn('wrong version (waf_version was removed in waf 1.6)')
  163. Utils.waf_version = waf_version
  164. import os
  165. @TaskGen.feature('c', 'cxx', 'd')
  166. @TaskGen.before('apply_incpaths', 'propagate_uselib_vars')
  167. @TaskGen.after('apply_link', 'process_source')
  168. def apply_uselib_local(self):
  169. """
  170. process the uselib_local attribute
  171. execute after apply_link because of the execution order set on 'link_task'
  172. """
  173. env = self.env
  174. from waflib.Tools.ccroot import stlink_task
  175. # 1. the case of the libs defined in the project (visit ancestors first)
  176. # the ancestors external libraries (uselib) will be prepended
  177. self.uselib = self.to_list(getattr(self, 'uselib', []))
  178. self.includes = self.to_list(getattr(self, 'includes', []))
  179. names = self.to_list(getattr(self, 'uselib_local', []))
  180. get = self.bld.get_tgen_by_name
  181. seen = set([])
  182. seen_uselib = set([])
  183. tmp = Utils.deque(names) # consume a copy of the list of names
  184. if tmp:
  185. if Logs.verbose:
  186. Logs.warn('compat: "uselib_local" is deprecated, replace by "use"')
  187. while tmp:
  188. lib_name = tmp.popleft()
  189. # visit dependencies only once
  190. if lib_name in seen:
  191. continue
  192. y = get(lib_name)
  193. y.post()
  194. seen.add(lib_name)
  195. # object has ancestors to process (shared libraries): add them to the end of the list
  196. if getattr(y, 'uselib_local', None):
  197. for x in self.to_list(getattr(y, 'uselib_local', [])):
  198. obj = get(x)
  199. obj.post()
  200. if getattr(obj, 'link_task', None):
  201. if not isinstance(obj.link_task, stlink_task):
  202. tmp.append(x)
  203. # link task and flags
  204. if getattr(y, 'link_task', None):
  205. link_name = y.target[y.target.rfind(os.sep) + 1:]
  206. if isinstance(y.link_task, stlink_task):
  207. env.append_value('STLIB', [link_name])
  208. else:
  209. # some linkers can link against programs
  210. env.append_value('LIB', [link_name])
  211. # the order
  212. self.link_task.set_run_after(y.link_task)
  213. # for the recompilation
  214. self.link_task.dep_nodes += y.link_task.outputs
  215. # add the link path too
  216. tmp_path = y.link_task.outputs[0].parent.bldpath()
  217. if not tmp_path in env['LIBPATH']:
  218. env.prepend_value('LIBPATH', [tmp_path])
  219. # add ancestors uselib too - but only propagate those that have no staticlib defined
  220. for v in self.to_list(getattr(y, 'uselib', [])):
  221. if v not in seen_uselib:
  222. seen_uselib.add(v)
  223. if not env['STLIB_' + v]:
  224. if not v in self.uselib:
  225. self.uselib.insert(0, v)
  226. # if the library task generator provides 'export_includes', add to the include path
  227. # the export_includes must be a list of paths relative to the other library
  228. if getattr(y, 'export_includes', None):
  229. self.includes.extend(y.to_incnodes(y.export_includes))
  230. @TaskGen.feature('cprogram', 'cxxprogram', 'cstlib', 'cxxstlib', 'cshlib', 'cxxshlib', 'dprogram', 'dstlib', 'dshlib')
  231. @TaskGen.after('apply_link')
  232. def apply_objdeps(self):
  233. "add the .o files produced by some other object files in the same manner as uselib_local"
  234. names = getattr(self, 'add_objects', [])
  235. if not names:
  236. return
  237. names = self.to_list(names)
  238. get = self.bld.get_tgen_by_name
  239. seen = []
  240. while names:
  241. x = names[0]
  242. # visit dependencies only once
  243. if x in seen:
  244. names = names[1:]
  245. continue
  246. # object does not exist ?
  247. y = get(x)
  248. # object has ancestors to process first ? update the list of names
  249. if getattr(y, 'add_objects', None):
  250. added = 0
  251. lst = y.to_list(y.add_objects)
  252. lst.reverse()
  253. for u in lst:
  254. if u in seen: continue
  255. added = 1
  256. names = [u]+names
  257. if added: continue # list of names modified, loop
  258. # safe to process the current object
  259. y.post()
  260. seen.append(x)
  261. for t in getattr(y, 'compiled_tasks', []):
  262. self.link_task.inputs.extend(t.outputs)
  263. @TaskGen.after('apply_link')
  264. def process_obj_files(self):
  265. if not hasattr(self, 'obj_files'):
  266. return
  267. for x in self.obj_files:
  268. node = self.path.find_resource(x)
  269. self.link_task.inputs.append(node)
  270. @TaskGen.taskgen_method
  271. def add_obj_file(self, file):
  272. """Small example on how to link object files as if they were source
  273. obj = bld.create_obj('cc')
  274. obj.add_obj_file('foo.o')"""
  275. if not hasattr(self, 'obj_files'): self.obj_files = []
  276. if not 'process_obj_files' in self.meths: self.meths.append('process_obj_files')
  277. self.obj_files.append(file)
  278. old_define = Configure.ConfigurationContext.__dict__['define']
  279. @Configure.conf
  280. def define(self, key, val, quote=True):
  281. old_define(self, key, val, quote)
  282. if key.startswith('HAVE_'):
  283. self.env[key] = 1
  284. old_undefine = Configure.ConfigurationContext.__dict__['undefine']
  285. @Configure.conf
  286. def undefine(self, key):
  287. old_undefine(self, key)
  288. if key.startswith('HAVE_'):
  289. self.env[key] = 0
  290. # some people might want to use export_incdirs, but it was renamed
  291. def set_incdirs(self, val):
  292. Logs.warn('compat: change "export_incdirs" by "export_includes"')
  293. self.export_includes = val
  294. TaskGen.task_gen.export_incdirs = property(None, set_incdirs)
  295. def install_dir(self, path):
  296. if not path:
  297. return []
  298. destpath = Utils.subst_vars(path, self.env)
  299. if self.is_install > 0:
  300. Logs.info('* creating %s' % destpath)
  301. Utils.check_dir(destpath)
  302. elif self.is_install < 0:
  303. Logs.info('* removing %s' % destpath)
  304. try:
  305. os.remove(destpath)
  306. except OSError:
  307. pass
  308. Build.BuildContext.install_dir = install_dir