diff options
author | Luo Jinghua <sunmoon1997@gmail.com> | 2010-01-08 10:33:24 +0800 |
---|---|---|
committer | Luo Jinghua <sunmoon1997@gmail.com> | 2010-01-08 10:33:24 +0800 |
commit | a41d5a24a0cc12dd7af1daac2dd55ccfcadf3a09 (patch) | |
tree | bd9df94d33ed062089b1769fb5f35d2f8e794867 | |
parent | c3ceab0a38283f77f75f0e7ebda80fc097282858 (diff) |
build: add some tools
-rw-r--r-- | site_scons/site_tools/archive.py | 196 | ||||
-rw-r--r-- | site_scons/site_tools/convlib.py | 30 | ||||
-rw-r--r-- | site_scons/site_tools/convlib.pyc | bin | 0 -> 1397 bytes | |||
-rw-r--r-- | site_scons/site_tools/gettext.py | 39 | ||||
-rw-r--r-- | site_scons/site_tools/md5sum.py | 45 | ||||
-rw-r--r-- | site_scons/site_tools/scanreplace.py | 27 |
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 Binary files differnew file mode 100644 index 0000000..8edcec5 --- /dev/null +++ b/site_scons/site_tools/convlib.pyc 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 + |