4 from waflib
import Context
, Options
, Configure
, Utils
, Logs
, TaskGen
, Task
8 Compile main.c and dependent object files into a single target (program/shlib/stlib or just object files)
10 - no build directory and no script files
11 - just a c4che directory for the configuration files
12 - configure, clean or build
14 Uses the task signatures and the dependency calculation results to avoid
15 rescanning/rebuilding the files all the time
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')
25 conf
.options
= Options
.options
26 conf
.load('compiler_c')
29 tp
= Options
.options
.progtype
30 features
= 'c cprogram'
38 source
= Options
.options
.source
39 app
= Options
.options
.app
40 bld(features
=features
, source
=source
, target
=app
)
42 def recurse_rep(x
, y
):
43 f
= getattr(Context
.g_module
, x
.cmd
or x
.fun
, Utils
.nada
)
46 def start(cwd
, version
, wafdir
):
47 # this is the entry point of our small build system
50 Context
.waf_dir
= wafdir
51 Context
.out_dir
= Context
.top_dir
= Context
.run_dir
= cwd
52 Context
.g_module
= imp
.new_module('wscript')
53 Context
.g_module
.root_path
= cwd
54 Context
.Context
.recurse
= recurse_rep
56 Context
.g_module
.configure
= configure
57 Context
.g_module
.build
= build
58 Context
.g_module
.options
= options
59 Context
.g_module
.top
= Context
.g_module
.out
= '.'
61 Options
.OptionsContext().execute()
63 do_config
= 'configure' in sys
.argv
65 os
.stat(cwd
+ os
.sep
+ 'c4che')
69 Context
.create_context('configure').execute()
71 if 'clean' in sys
.argv
:
72 Context
.create_context('clean').execute()
74 if 'build' in sys
.argv
:
75 Context
.create_context('build').execute()
78 class c2(waflib
.Tools
.c
.c
):
79 # Make a subclass of the default c task, and bind the .c extension to it
81 def runnable_status(self
):
82 ret
= super(waflib
.Tools
.c
.c
, self
).runnable_status()
85 # use a cache to avoid creating the same tasks
86 # for example, truc.cpp might be compiled twice
88 shared
= self
.generator
.bld
.shared_tasks
89 except AttributeError:
90 shared
= self
.generator
.bld
.shared_tasks
= {}
92 if ret
!= Task
.ASK_LATER
:
93 for x
in self
.generator
.bld
.node_deps
[self
.uid()]:
94 node
= x
.parent
.get_src().find_resource(x
.name
.replace('.h', '.c'))
99 tsk
= shared
[node
] = self
.generator
.c_hook(node
)
101 self
.more_tasks
.append(tsk
)
103 # add the node created to the link task outputs
105 link
= self
.generator
.link_task
106 except AttributeError:
109 if not tsk
.outputs
[0] in link
.inputs
:
110 link
.inputs
.append(tsk
.outputs
[0])
111 link
.set_run_after(tsk
)
113 # any change in the order of the input nodes may cause a recompilation
114 link
.inputs
.sort(key
=lambda x
: x
.abspath())
116 # if you want to modify some flags
117 # you *must* have the task recompute the signature
118 self
.env
.append_value('CXXFLAGS', '-O2')
119 delattr(self
, 'cache_sig')
120 return super(waflib
.Tools
.c
.c
, self
).runnable_status()
124 @TaskGen.extension('.c')
125 def c_hook(self
, node
):
126 # re-bind the extension to this new class
127 return self
.create_compiled_task('c2', node
)
129 # modify the existing class to output the targets in the same directory as the original files
130 Task
.update_outputs(c2
)
131 Task
.update_outputs(waflib
.Tools
.c
.cprogram
)
132 Task
.update_outputs(waflib
.Tools
.c
.cshlib
)
133 Task
.update_outputs(waflib
.Tools
.c
.cstlib
)