summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuo Jinghua <sunmoon1997@gmail.com>2010-01-08 10:33:24 +0800
committerLuo Jinghua <sunmoon1997@gmail.com>2010-01-08 10:33:24 +0800
commita41d5a24a0cc12dd7af1daac2dd55ccfcadf3a09 (patch)
treebd9df94d33ed062089b1769fb5f35d2f8e794867
parentc3ceab0a38283f77f75f0e7ebda80fc097282858 (diff)
build: add some tools
-rw-r--r--site_scons/site_tools/archive.py196
-rw-r--r--site_scons/site_tools/convlib.py30
-rw-r--r--site_scons/site_tools/convlib.pycbin0 -> 1397 bytes
-rw-r--r--site_scons/site_tools/gettext.py39
-rw-r--r--site_scons/site_tools/md5sum.py45
-rw-r--r--site_scons/site_tools/scanreplace.py27
6 files changed, 337 insertions, 0 deletions
diff --git a/site_scons/site_tools/archive.py b/site_scons/site_tools/archive.py
new file mode 100644
index 0000000..5718ae9
--- /dev/null
+++ b/site_scons/site_tools/archive.py
@@ -0,0 +1,196 @@
+import SCons.Action
+import SCons.Builder
+import SCons.Defaults
+import SCons.Node.FS
+import SCons.Util
+import os
+import fnmatch
+
+SUFFIX = {
+ 'gztar': '.tar.gz',
+ 'bztar': '.tar.bz2',
+ 'tar': '.tar',
+ 'zip': '.zip'
+ }
+
+def MakeZipfile (env, file_name, format, root_dir, base_dir):
+ """Create a zip file from all the files under 'base_dir'. The output
+ zip file will be named 'base_dir' + ".zip". Uses either the "zipfile"
+ Python module (if available) or the InfoZIP "zip" utility (if installed
+ and found on the default search path).
+ """
+ try:
+ import zipfile
+ except ImportError:
+ return 1
+
+ zip_filename = file_name
+
+ z = zipfile.ZipFile(zip_filename, "w",
+ compression = zipfile.ZIP_DEFLATED)
+
+ src_dir = os.path.join(root_dir, base_dir)
+ for dirpath, dirnames, filenames in os.walk(src_dir):
+ for name in filenames:
+ path = os.path.normpath(os.path.join(dirpath, name))
+ arch_path = path[len(root_dir):]
+ if os.path.isfile(path):
+ z.write(path, arch_path)
+ z.close()
+
+ return 0
+
+def MakeTarball (env, file_name, format, root_dir, base_dir):
+ """Create a (possibly compressed) tar file from all the files under
+ 'root_dir/basedir'. 'compress' must be "gzip" (the default), "bzip2",
+ or None. Both "tar" and the compression utility named by
+ 'compress' must be on the default program search path, so this is
+ probably Unix-specific. The output tar file will be named 'base_dir' +
+ ".tar", possibly plus the appropriate compression extension (".gz",
+ ".bz2").
+ """
+ mode = {
+ 'gztar': 'w|gz',
+ 'bztar': 'w|bz2',
+ 'tar': 'w|',
+ }
+ try:
+ import tarfile
+ except ImportError:
+ return 1
+
+ tarball = tarfile.open(file_name, mode[format])
+ src_dir = os.path.join(root_dir, base_dir)
+ for dirpath, dirnames, filenames in os.walk(src_dir):
+ for name in filenames:
+ path = os.path.normpath(os.path.join(dirpath, name))
+ arch_path = path[len(root_dir):]
+ tarball.add(path, arch_path, False)
+ tarball.close()
+ return 0;
+
+def MakeTarballCmd (env, file_name, format, root_dir, base_dir):
+ """Create a (possibly compressed) tar file from all the files under
+ 'root_dir/basedir'. 'compress' must be "gzip" (the default), "compress",
+ "bzip2", or None. Both "tar" and the compression utility named by
+ 'compress' must be on the default program search path, so this is
+ probably Unix-specific. The output tar file will be named 'base_dir' +
+ ".tar", possibly plus the appropriate compression extension (".gz",
+ ".bz2" or ".Z").
+ """
+ compress = {
+ 'gztar': 'z',
+ 'bztar': 'j',
+ 'tar': '',
+ }
+ if root_dir:
+ return env.Execute ('$TAR -C %s -c%sf %s %s' % (root_dir, compress[format],
+ file_name, base_dir))
+ return env.Execute ('$TAR -c%sf %s %s -C %s' % (compress[format], file_name, base_dir))
+
+ARCHIVER = {
+ 'gztar': MakeTarball,
+ 'bztar': MakeTarball,
+ 'tar': MakeTarball,
+ 'zip': MakeZipfile
+ }
+
+def MakeArchive(env, file_name, format, root_dir, base_dir):
+ root_dir = os.path.normpath(root_dir)
+ base_dir = os.path.normpath(base_dir)
+ return ARCHIVER[format](env, file_name, format, root_dir, base_dir)
+
+def Archive (target, source, env):
+ name = source[0].value
+ rootdir = env.Dir(source[1].value).abspath
+ basedir = source[2].value
+ format = source[3].value
+
+ for i in range(len(format)):
+ status = MakeArchive(env, target[i].path, format[i], rootdir, basedir)
+ if status:
+ return status
+ return 0
+
+ArchiveAction = SCons.Action.Action (Archive, '$ARCHIVESTR')
+ArchiveBuilder = SCons.Builder.Builder (action = ArchiveAction,
+ target_factory = SCons.Node.FS.default_fs.Entry)
+def generate (env):
+ """Add Builders and construction variables for Archive to an Environment."""
+
+ def Archive (env, target = None, source = None, **kwargs):
+ for arg in ['rootdir', 'basedir']:
+ if not kwargs.has_key(arg):
+ raise SCons.Errors.UserError, "Missing tag %s" % arg
+
+ ### archive name
+ if kwargs.has_key('name'):
+ name = kwargs['name']
+ else:
+ name = os.path.basename(basedir)
+
+ ### archive format
+ if kwargs.has_key('format'):
+ format = kwargs['format']
+ else:
+ format = 'zip'
+
+ if not SCons.Util.is_List(format):
+ format = [format]
+ for f in format:
+ if not SUFFIX.has_key(f):
+ raise SCons.Errors.UserError, "Unsupported archive format: %s" % f
+
+ rootdir = kwargs['rootdir']
+ basedir = kwargs['basedir']
+
+ ### archive format
+ if kwargs.has_key('depends'):
+ depends = kwargs['depends']
+ else:
+ depends = []
+
+ ### depends
+ if not depends:
+ depends = []
+ if not SCons.Util.is_List(depends):
+ depends = [depends]
+
+ ### fixup the target list
+ if not target:
+ target = []
+ if not SCons.Util.is_List(target):
+ target = [target]
+
+ ### pad the target list
+ if len(target) < len(format):
+ base = len(target)
+ for i in range(len(format) - base):
+ target += [env.File(str(name) + SUFFIX[format[i + base]])]
+
+ ### this is the really source what we used
+ source = [env.Value(name), env.Value(rootdir), env.Value(basedir),
+ env.Value(format)]
+
+ ### put source files, directroies in source, let scons track
+ ### target dependences correctly.
+ if not depends:
+ depends = [os.path.join(rootdir, basedir)]
+ source += depends
+ return env._Archive(target = target, source = source)
+
+ try:
+ bld = env['BUILDERS']['_Archive']
+ except KeyError:
+ bld = ArchiveBuilder
+ env['BUILDERS']['_Archive'] = bld
+ env['ARCHIVESTR'] = "Compressing: $TARGETS"
+ env['BUILDERS']['Archive'] = Archive
+
+def exists (env):
+ try:
+ import zipfile
+ import tarfile
+ return True
+ except:
+ return False
diff --git a/site_scons/site_tools/convlib.py b/site_scons/site_tools/convlib.py
new file mode 100644
index 0000000..3c174e2
--- /dev/null
+++ b/site_scons/site_tools/convlib.py
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+# -*- python -*-
+import SCons
+
+def generate(env, **kwargs):
+ """This is a utility function that creates the ConvenienceLibrary
+ Builder in an Environment if it is not there already.
+
+ If it is already there, we return the existing one.
+
+ Based on the stock StaticLibrary and SharedLibrary builders.
+ """
+ try:
+ convenience_lib = env['BUILDERS']['ConvenienceLibrary']
+ except KeyError:
+ action_list = [ SCons.Action.Action ("$ARCOM", "$ARCOMSTR") ]
+ if env['BUILDERS'].has_key('RANLIB'):
+ ranlib_action = SCons.Action.Action("$RANLIBCOM", "$RANLIBCOMSTR")
+ action_list.append(ranlib_action)
+
+ convenience_lib = SCons.Builder.Builder (action = action_list,
+ emitter = '$LIBEMITTER',
+ prefix = '$LIBPREFIX',
+ suffix = '$LIBSUFFIX',
+ src_suffix = '$SHOBJSUFFIX',
+ src_builder = 'SharedObject')
+ env['BUILDERS']['ConvenienceLibrary'] = convenience_lib
+
+def exists(env):
+ return True
diff --git a/site_scons/site_tools/convlib.pyc b/site_scons/site_tools/convlib.pyc
new file mode 100644
index 0000000..8edcec5
--- /dev/null
+++ b/site_scons/site_tools/convlib.pyc
Binary files differ
diff --git a/site_scons/site_tools/gettext.py b/site_scons/site_tools/gettext.py
new file mode 100644
index 0000000..3571706
--- /dev/null
+++ b/site_scons/site_tools/gettext.py
@@ -0,0 +1,39 @@
+from SCons.Builder import Builder
+from SCons.Util import WhereIs, is_List
+
+def generate(env):
+ try:
+ env["MSGFMT"]
+ except KeyError:
+ env["XGETTEXT"] = WhereIs("xgettext") or 'xgettext'
+ env["MSGFMT"] = WhereIs("msgfmt")
+ msgfmt = Builder(action = "$MSGFMT -c --statistics -o $TARGET $SOURCE",
+ src_suffix = ".po",
+ suffix = ".mo",
+ single_source = True)
+ env["BUILDERS"]["Msgfmt"] = msgfmt
+
+ env["MSGMERGE"] = WhereIs("msgmerge") or 'msgmerge'
+ msgmerge = Builder(action = "$MSGMERGE $TARGET $SOURCE -o $TARGET",
+ src_suffix = ".pot",
+ suffix = ".po",
+ single_source = True)
+ env["BUILDERS"]["MsgMerge"] = msgmerge
+
+ env["MSGINIT"] = WhereIs("msginit") or 'msginit'
+ msginit = Builder(action = "$MSGINIT -i $SOURCE -o $TARGET --no-translator",
+ src_suffix = ".pot",
+ suffix = ".po",
+ single_source = True)
+ env["BUILDERS"]["MsgInit"] = msginit
+
+ def MsgInitMerge(env, target, source):
+ #print target[0].path, os.path.exists(target[0].abspath)
+ if os.path.exists(target[0].abspath):
+ return env.MsgMerge(target, source)
+ else:
+ return env.MsgInit(target, source)
+ env["BUILDERS"]["MsgInitMerge"] = MsgInitMerge
+
+def exists():
+ return True
diff --git a/site_scons/site_tools/md5sum.py b/site_scons/site_tools/md5sum.py
new file mode 100644
index 0000000..3be71f1
--- /dev/null
+++ b/site_scons/site_tools/md5sum.py
@@ -0,0 +1,45 @@
+#!/usr/bin/python
+
+from string import Template
+import stat
+import SCons
+
+def md5sum(filename):
+ import hashlib
+ f = file(filename,'rb')
+ return hashlib.md5(f.read()).hexdigest()
+
+def md5sum_action(target, source, env):
+ for i in range(len(source)):
+ digest = md5sum(source[i].abspath)
+ content = digest + ' ' + source[i].name + '\n'
+ file(target[i].abspath, 'w').write(content)
+ return 0
+
+def md5sum_emitter(target, source, env):
+ if len(target) < len(source):
+ diff = len(source) - len(target)
+ offset = len(target)
+ for i in range(diff):
+ s = source[offset + i]
+ target.append(env.File(s.abspath + '.md5sum'))
+ return (target, source)
+
+def generate(env, **kw):
+ try:
+ env['BUILDERS']['MD5SUMSTR']
+ env['BUILDERS']['MD5SUM']
+ except KeyError:
+ md5str = "Caculating md5sum: $TARGETS"
+ action = SCons.Action.Action(md5sum_action, '$MD5SUMSTR')
+ env['MD5SUMSTR'] = md5str
+ env['BUILDERS']['MD5SUM'] = env.Builder(action = action,
+ emitter = md5sum_emitter,
+ suffix = '.md5sum')
+
+def exists(env):
+ try:
+ import hashlib
+ return True
+ except:
+ return False
diff --git a/site_scons/site_tools/scanreplace.py b/site_scons/site_tools/scanreplace.py
new file mode 100644
index 0000000..949dd2f
--- /dev/null
+++ b/site_scons/site_tools/scanreplace.py
@@ -0,0 +1,27 @@
+#!/usr/bin/python
+
+from string import Template
+import stat
+
+def replace_action(target, source, env):
+ if len(source) > 1:
+ d = source[1].value
+ else:
+ d = env
+ open(str(target[0]), 'w').write(Template(open(str(source[0]), 'r').read()).safe_substitute(d))
+ st = env.fs.stat(source[0].path)
+ env.fs.chmod(target[0].path, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE)
+
+ return 0
+
+def replace_string(target, source, env):
+ return "building '%s' from '%s'" % (str(target[0]), str(source[0]))
+
+def generate(env, **kw):
+ action = env.Action(replace_action, replace_string)
+ env['BUILDERS']['ScanReplace'] = env.Builder(action = action,
+ src_suffix = '.in')
+
+def exists(env):
+ return True
+