1#! /usr/bin/env python
2# per rosengren 2011
3
4from os import sep, readlink
5from waflib import Logs
6from waflib.TaskGen import feature, after_method
7from waflib.Task import Task, always_run
8
9def options(opt):
10	grp = opt.add_option_group('Bjam Options')
11	grp.add_option('--bjam_src', default=None, help='You can find it in <boost root>/tools/jam/src')
12	grp.add_option('--bjam_uname', default='linuxx86_64', help='bjam is built in <src>/bin.<uname>/bjam')
13	grp.add_option('--bjam_config', default=None)
14	grp.add_option('--bjam_toolset', default=None)
15
16def configure(cnf):
17	if not cnf.env.BJAM_SRC:
18		cnf.env.BJAM_SRC = cnf.options.bjam_src
19	if not cnf.env.BJAM_UNAME:
20		cnf.env.BJAM_UNAME = cnf.options.bjam_uname
21	try:
22		cnf.find_program('bjam', path_list=[
23			cnf.env.BJAM_SRC + sep + 'bin.' + cnf.env.BJAM_UNAME
24		])
25	except Exception:
26		cnf.env.BJAM = None
27	if not cnf.env.BJAM_CONFIG:
28		cnf.env.BJAM_CONFIG = cnf.options.bjam_config
29	if not cnf.env.BJAM_TOOLSET:
30		cnf.env.BJAM_TOOLSET = cnf.options.bjam_toolset
31
32@feature('bjam')
33@after_method('process_rule')
34def process_bjam(self):
35	if not self.bld.env.BJAM:
36		self.create_task('bjam_creator')
37	self.create_task('bjam_build')
38	self.create_task('bjam_installer')
39	if getattr(self, 'always', False):
40		always_run(bjam_creator)
41		always_run(bjam_build)
42	always_run(bjam_installer)
43
44class bjam_creator(Task):
45	ext_out = 'bjam_exe'
46	vars=['BJAM_SRC', 'BJAM_UNAME']
47	def run(self):
48		env = self.env
49		gen = self.generator
50		bjam = gen.bld.root.find_dir(env.BJAM_SRC)
51		if not bjam:
52			Logs.error('Can not find bjam source')
53			return -1
54		bjam_exe_relpath = 'bin.' + env.BJAM_UNAME + '/bjam'
55		bjam_exe = bjam.find_resource(bjam_exe_relpath)
56		if bjam_exe:
57			env.BJAM = bjam_exe.srcpath()
58			return 0
59		bjam_cmd = ['./build.sh']
60		Logs.debug('runner: ' + bjam.srcpath() + '> ' + str(bjam_cmd))
61		result = self.exec_command(bjam_cmd, cwd=bjam.srcpath())
62		if not result == 0:
63			Logs.error('bjam failed')
64			return -1
65		bjam_exe = bjam.find_resource(bjam_exe_relpath)
66		if bjam_exe:
67			env.BJAM = bjam_exe.srcpath()
68			return 0
69		Logs.error('bjam failed')
70		return -1
71
72class bjam_build(Task):
73	ext_in = 'bjam_exe'
74	ext_out = 'install'
75	vars = ['BJAM_TOOLSET']
76	def run(self):
77		env = self.env
78		gen = self.generator
79		path = gen.path
80		bld = gen.bld
81		if hasattr(gen, 'root'):
82			build_root = path.find_node(gen.root)
83		else:
84			build_root = path
85		jam = bld.srcnode.find_resource(env.BJAM_CONFIG)
86		if jam:
87			Logs.debug('bjam: Using jam configuration from ' + jam.srcpath())
88			jam_rel = jam.relpath_gen(build_root)
89		else:
90			Logs.warn('No build configuration in build_config/user-config.jam. Using default')
91			jam_rel = None
92		bjam_exe = bld.srcnode.find_node(env.BJAM)
93		if not bjam_exe:
94			Logs.error('env.BJAM is not set')
95			return -1
96		bjam_exe_rel = bjam_exe.relpath_gen(build_root)
97		cmd = ([bjam_exe_rel] +
98			(['--user-config=' + jam_rel] if jam_rel else []) +
99			['--stagedir=' + path.get_bld().path_from(build_root)] +
100			['--debug-configuration'] +
101			['--with-' + lib for lib in self.generator.target] +
102			(['toolset=' + env.BJAM_TOOLSET] if env.BJAM_TOOLSET else []) +
103			['link=' + 'shared'] +
104			['variant=' + 'release']
105		)
106		Logs.debug('runner: ' + build_root.srcpath() + '> ' + str(cmd))
107		ret = self.exec_command(cmd, cwd=build_root.srcpath())
108		if ret != 0:
109			return ret
110		self.set_outputs(path.get_bld().ant_glob('lib/*') + path.get_bld().ant_glob('bin/*'))
111		return 0
112
113class bjam_installer(Task):
114	ext_in = 'install'
115	def run(self):
116		gen = self.generator
117		path = gen.path
118		for idir, pat in (('${LIBDIR}', 'lib/*'), ('${BINDIR}', 'bin/*')):
119			files = []
120			for n in path.get_bld().ant_glob(pat):
121				try:
122					t = readlink(n.srcpath())
123					gen.bld.symlink_as(sep.join([idir, n.name]), t, postpone=False)
124				except OSError:
125					files.append(n)
126			gen.bld.install_files(idir, files, postpone=False)
127		return 0
128
129