You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
3.6 KiB
Python
128 lines
3.6 KiB
Python
#! /usr/bin/env python
|
|
|
|
import os, sys, imp
|
|
from waflib import Context, Options, Configure, Utils, Logs, TaskGen, Task
|
|
import waflib.Tools.c
|
|
|
|
"""
|
|
Compile main.c and dependent object files into a single target (program/shlib/stlib or just object files)
|
|
|
|
- no build directory and no script files
|
|
- just a c4che directory for the configuration files
|
|
- configure, clean or build
|
|
|
|
Uses the task signatures and the dependency calculation results to avoid
|
|
rescanning/rebuilding the files all the time
|
|
"""
|
|
|
|
def options(opt):
|
|
opt.add_option('--type', action='store', default='program', help='type: program, shlib, stlib, objects', dest='progtype')
|
|
opt.add_option('--source', action='store', default='main.c', help='space-separated list of source files', dest='source')
|
|
opt.add_option('--app', action='store', default='app', help='name of the binary file to create', dest='app')
|
|
opt.load('compiler_c')
|
|
|
|
def configure(conf):
|
|
conf.options = Options.options
|
|
conf.load('compiler_c')
|
|
|
|
def build(bld):
|
|
tp = Options.options.progtype
|
|
features = 'c cprogram'
|
|
if tp == 'shlib':
|
|
features = 'c cshlib'
|
|
elif tp == 'stlib':
|
|
features = 'c cstlib'
|
|
elif tp == 'objects':
|
|
features = 'c'
|
|
|
|
app = Options.options.app
|
|
bld(features=features, source=Options.options.source, target=app)
|
|
|
|
def recurse_rep(x, y):
|
|
f = getattr(Context.g_module, x.cmd or x.fun, Utils.nada)
|
|
return f(x)
|
|
|
|
def start(cwd, version, wafdir):
|
|
# this is the entry point of our small build system
|
|
# no script file here
|
|
Logs.init_log()
|
|
Context.waf_dir = wafdir
|
|
Context.out_dir = Context.top_dir = Context.run_dir = cwd
|
|
Context.g_module = imp.new_module('wscript')
|
|
Context.g_module.root_path = cwd
|
|
Context.Context.recurse = recurse_rep
|
|
|
|
Context.g_module.configure = configure
|
|
Context.g_module.build = build
|
|
Context.g_module.options = options
|
|
Context.g_module.top = Context.g_module.out = '.'
|
|
|
|
Options.OptionsContext().execute()
|
|
|
|
do_config = 'configure' in sys.argv
|
|
try:
|
|
os.stat(cwd + os.sep + 'c4che')
|
|
except:
|
|
do_config = True
|
|
if do_config:
|
|
Context.create_context('configure').execute()
|
|
|
|
if 'clean' in sys.argv:
|
|
Context.create_context('clean').execute()
|
|
|
|
if 'build' in sys.argv:
|
|
Context.create_context('build').execute()
|
|
|
|
|
|
class c2(waflib.Tools.c.c):
|
|
# Make a subclass of the default c task, and bind the .c extension to it
|
|
|
|
def runnable_status(self):
|
|
ret = super(waflib.Tools.c.c, self).runnable_status()
|
|
self.more_tasks = []
|
|
|
|
# use a cache to avoid creating the same tasks
|
|
# for example, truc.cpp might be compiled twice
|
|
try:
|
|
shared = self.generator.bld.shared_tasks
|
|
except AttributeError:
|
|
shared = self.generator.bld.shared_tasks = {}
|
|
|
|
if ret != Task.ASK_LATER:
|
|
for x in self.generator.bld.node_deps[self.uid()]:
|
|
node = x.parent.get_src().find_resource(x.name.replace('.h', '.c'))
|
|
if node:
|
|
try:
|
|
tsk = shared[node]
|
|
except:
|
|
tsk = shared[node] = self.generator.c_hook(node)
|
|
|
|
self.more_tasks.append(tsk)
|
|
|
|
# add the node created to the link task outputs
|
|
try:
|
|
link = self.generator.link_task
|
|
except AttributeError:
|
|
pass
|
|
else:
|
|
if not tsk.outputs[0] in link.inputs:
|
|
link.inputs.append(tsk.outputs[0])
|
|
link.set_run_after(tsk)
|
|
|
|
# any change in the order of the input nodes may cause a recompilation
|
|
link.inputs.sort(key=lambda x: x.abspath())
|
|
|
|
# if you want to modify some flags
|
|
# you *must* have the task recompute the signature
|
|
self.env.append_value('CXXFLAGS', '-O2')
|
|
delattr(self, 'cache_sig')
|
|
return super(waflib.Tools.c.c, self).runnable_status()
|
|
|
|
return ret
|
|
|
|
@TaskGen.extension('.c')
|
|
def c_hook(self, node):
|
|
# re-bind the extension to this new class
|
|
return self.create_compiled_task('c2', node)
|
|
|