1
from string import Template
4
import tarfile, zipfile
7
def register_builders(env):
8
register_template_builder(env)
9
register_archive_builder(env)
10
register_localsymlink_builder(env)
12
def get_configure_tests():
13
return { 'CheckPKGConfig' : CheckPKGConfig,
14
'CheckPKG' : CheckPKG }
16
class AtTemplate(Template):
19
# A builder that replaces variables in a file
20
# Adapted from http://www.scons.org/wiki/ReplacementBuilder
21
def register_template_builder(env):
22
action = env.Action(template_action, template_string)
23
env['BUILDERS']['Template'] = env.Builder(action=action, src_suffix='.in',
24
emitter=template_emitter, single_source=True)
26
def template_emitter(target, source, env):
27
"""this emitter adds all the variables referenced in the target file as
28
dependencies for this target"""
29
text = open(str(source[0]), 'r').read()
31
r = re.compile('@\{?(\w*)\}?')
33
for match in re.findall(r, text):
34
dep_str += '${' + match + '}'
36
env.Depends(target[0], env.Value(env.subst(dep_str)))
38
return (target, source)
40
def template_action(target, source, env):
41
fin = open(str(source[0]), 'r')
42
fout = open(str(target[0]), 'w')
43
fout.write(AtTemplate(fin.read()).safe_substitute(env))
46
def template_string(target, source, env):
47
return "Creating '%s' from '%s'" % (str(target[0]), str(source[0]))
49
def accept_pattern(name, include, exclude):
52
for pattern in include:
53
if fnmatch.fnmatch (name, pattern):
55
for pattern in exclude:
56
if fnmatch.fnmatch (name, pattern):
61
return included and not excluded
63
def get_files(path, include = ['*'], exclude= []):
64
""" Recursively find files in path matching include patterns list
65
and not matching exclude patterns
69
for root, dirs, files in os.walk(path):
71
for filename in files:
72
if accept_pattern(filename, include, exclude):
73
fullname = os.path.join (root, filename)
74
ret_files.append(fullname)
76
dirs[:] = [d for d in dirs if accept_pattern(d, include, exclude)]
81
# A builder that creates a rooted archive
82
# Adapted from http://www.scons.org/wiki/ArchiveBuilder
83
def register_archive_builder(env):
84
action = env.Action(archive_action, archive_string)
85
env['BUILDERS']['Archive'] = env.Builder(action=action)
87
def archive_action (target, source, env):
88
""" Make an archive from sources """
91
base = os.path.basename(path)
93
if path.endswith('.tgz'):
94
archive = tarfile.open (path, 'w:gz')
95
prefix = base[:-len('.tgz')]
96
elif path.endswith('.tar.gz'):
97
archive = tarfile.open (path, 'w:gz')
98
prefix = base[:-len('.tar.gz')]
99
elif path.endswith('.tar.bz2'):
100
archive = tarfile.open (path, 'w:bz2')
101
prefix = base[:-len('.tar.bz2')]
102
elif path.endswith('.zip'):
103
archive = zipfile.ZipFile (path, 'w')
104
archive.add = archive.write
105
prefix = base[:-len('.zip')]
107
print "Unknown archive type (%s)" % type
110
src = [str(s) for s in source if str(s) != path]
112
archive.add (s, os.path.join (prefix, s))
115
def archive_string (target, source, env):
116
""" Information string for Archive """
117
return 'Making archive %s' % os.path.basename (str (target[0]))
119
# A symbolic link builder that creates a symlink to a file in the
120
# same directory as that source file
121
def register_localsymlink_builder(env):
122
action = env.Action(localsymlink_action, localsymlink_string)
123
env['BUILDERS']['LocalSymlink'] = env.Builder(action=action,
124
emitter = localsymlink_emitter)
126
def localsymlink_emitter(target, source, env):
127
t_base = os.path.basename(str(target[0]))
128
s_dir = os.path.dirname(str(source[0]))
130
return ([os.path.join(s_dir, t_base)], source)
132
def localsymlink_action (target, source, env):
133
""" Make an symlink target pointing to source"""
135
if os.path.lexists(t):
136
if os.path.islink(t):
139
os.symlink(os.path.basename(str(source[0])), str(target[0]))
142
def localsymlink_string (target, source, env):
143
""" Information string for symlink """
144
return 'Creating symlink %s -> %s' % (str(target[0]), str(source[0]))
146
def create_library_links(lib, soname, env):
147
# Dummy builders for links
148
lnk1 = env.Command(None, None, "")
149
lnk2 = env.Command(None, None, "")
151
if env['SHLIBSUFFIX'] == '.so':
153
lib_base = os.path.basename(lib)
155
lnk1_base = os.path.basename(lnk1_name)
157
if lnk1_base != lib_base:
158
lnk1 = env.LocalSymlink(lnk1_name, lib)
159
env.Depends(lnk1, lib)
161
so_index = soname.rfind('.so')
162
lnk2_name = soname[:so_index + 3]
163
lnk2_base = os.path.basename(lnk2_name)
165
if lnk2_base != lib_base and lnk2_base != lnk1_base:
166
lnk2 = env.LocalSymlink(lnk2_name, lib)
167
env.Depends(lnk2, lib)
171
# Helper function to create a versioned library and related symlinks
172
def versioned_library(target, source, soname, env):
173
"""Creates the shared library named 'target' from Nodes 'source'
174
using the specified 'soname' and the scons 'env'"""
176
env_lib = env.Clone()
178
if env.subst('$SHLIBSUFFIX') == '.so':
179
env_lib.Append(SHLINKFLAGS = '-Wl,-soname=%s' % soname)
180
so_index = target.rfind('.so')
181
env_lib['SHLIBSUFFIX'] = target[so_index:]
182
env_lib.Append(LIBSUFFIXES=['$SHLIBSUFFIX'])
184
suffix_index = target.rfind(env_lib.subst('$SHLIBSUFFIX'))
185
prefix_length = len(env_lib.subst('$SHLIBPREFIX'))
187
lib_name = target[prefix_length:suffix_index]
189
lib = env_lib.SharedLibrary(lib_name, source)
191
lnk1, lnk2 = create_library_links(str(lib[0]), soname, env)
193
return [lib, lnk1, lnk2]
195
def install_versioned_library(target_dir, source, soname, env):
197
lib = env.Install(target_dir, source)
199
lnk1, lnk2 = create_library_links(str(lib[0]), soname, env)
201
return [lib, lnk1, lnk2]
203
def CheckPKGConfig(context, version):
204
context.Message( 'Checking for pkg-config... ' )
205
ret = context.TryAction('pkg-config --atleast-pkgconfig-version=%s' % version)[0]
206
context.Result( ret )
209
def CheckPKG(context, name):
210
context.Message( 'Checking for %s... ' % name )
211
ret = context.TryAction('pkg-config --exists \'%s\'' % name)[0]
212
context.Result( ret )