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