dbdlib.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. #! /usr/bin/env python
  2. import os, sys, imp
  3. from waflib import Context, Options, Configure, Utils, Logs, TaskGen, Task
  4. import waflib.Tools.c
  5. """
  6. Compile main.c and dependent object files into a single target (program/shlib/stlib or just object files)
  7. - no build directory and no script files
  8. - just a c4che directory for the configuration files
  9. - configure, clean or build
  10. Uses the task signatures and the dependency calculation results to avoid
  11. rescanning/rebuilding the files all the time
  12. """
  13. def options(opt):
  14. opt.add_option('--type', action='store', default='program', help='type: program, shlib, stlib, objects', dest='progtype')
  15. opt.add_option('--source', action='store', default='main.c', help='space-separated list of source files', dest='source')
  16. opt.add_option('--app', action='store', default='app', help='name of the binary file to create', dest='app')
  17. opt.load('compiler_c')
  18. def configure(conf):
  19. conf.options = Options.options
  20. conf.load('compiler_c')
  21. def build(bld):
  22. tp = Options.options.progtype
  23. features = 'c cprogram'
  24. if tp == 'shlib':
  25. features = 'c cshlib'
  26. elif tp == 'stlib':
  27. features = 'c cstlib'
  28. elif tp == 'objects':
  29. features = 'c'
  30. app = Options.options.app
  31. bld(features=features, source=Options.options.source, target=app)
  32. def recurse_rep(x, y):
  33. f = getattr(Context.g_module, x.cmd or x.fun, Utils.nada)
  34. return f(x)
  35. def start(cwd, version, wafdir):
  36. # this is the entry point of our small build system
  37. # no script file here
  38. Logs.init_log()
  39. Context.waf_dir = wafdir
  40. Context.out_dir = Context.top_dir = Context.run_dir = cwd
  41. Context.g_module = imp.new_module('wscript')
  42. Context.g_module.root_path = cwd
  43. Context.Context.recurse = recurse_rep
  44. Context.g_module.configure = configure
  45. Context.g_module.build = build
  46. Context.g_module.options = options
  47. Context.g_module.top = Context.g_module.out = '.'
  48. Options.OptionsContext().execute()
  49. do_config = 'configure' in sys.argv
  50. try:
  51. os.stat(cwd + os.sep + 'c4che')
  52. except:
  53. do_config = True
  54. if do_config:
  55. Context.create_context('configure').execute()
  56. if 'clean' in sys.argv:
  57. Context.create_context('clean').execute()
  58. if 'build' in sys.argv:
  59. Context.create_context('build').execute()
  60. class c2(waflib.Tools.c.c):
  61. # Make a subclass of the default c task, and bind the .c extension to it
  62. def runnable_status(self):
  63. ret = super(waflib.Tools.c.c, self).runnable_status()
  64. self.more_tasks = []
  65. # use a cache to avoid creating the same tasks
  66. # for example, truc.cpp might be compiled twice
  67. try:
  68. shared = self.generator.bld.shared_tasks
  69. except AttributeError:
  70. shared = self.generator.bld.shared_tasks = {}
  71. if ret != Task.ASK_LATER:
  72. for x in self.generator.bld.node_deps[self.uid()]:
  73. node = x.parent.get_src().find_resource(x.name.replace('.h', '.c'))
  74. if node:
  75. try:
  76. tsk = shared[node]
  77. except:
  78. tsk = shared[node] = self.generator.c_hook(node)
  79. self.more_tasks.append(tsk)
  80. # add the node created to the link task outputs
  81. try:
  82. link = self.generator.link_task
  83. except AttributeError:
  84. pass
  85. else:
  86. if not tsk.outputs[0] in link.inputs:
  87. link.inputs.append(tsk.outputs[0])
  88. link.set_run_after(tsk)
  89. # any change in the order of the input nodes may cause a recompilation
  90. link.inputs.sort(key=lambda x: x.abspath())
  91. # if you want to modify some flags
  92. # you *must* have the task recompute the signature
  93. self.env.append_value('CXXFLAGS', '-O2')
  94. delattr(self, 'cache_sig')
  95. return super(waflib.Tools.c.c, self).runnable_status()
  96. return ret
  97. @TaskGen.extension('.c')
  98. def c_hook(self, node):
  99. # re-bind the extension to this new class
  100. return self.create_compiled_task('c2', node)