init
This commit is contained in:
311
scons-local-3.0.0/SCons/Tool/packaging/__init__.py
Normal file
311
scons-local-3.0.0/SCons/Tool/packaging/__init__.py
Normal file
@@ -0,0 +1,311 @@
|
||||
"""SCons.Tool.Packaging
|
||||
|
||||
SCons Packaging Tool.
|
||||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/packaging/__init__.py rel_3.0.0:4395:8972f6a2f699 2017/09/18 12:59:24 bdbaddog"
|
||||
|
||||
import SCons.Environment
|
||||
from SCons.Variables import *
|
||||
from SCons.Errors import *
|
||||
from SCons.Util import is_List, make_path_relative
|
||||
from SCons.Warnings import warn, Warning
|
||||
|
||||
import os, imp
|
||||
import SCons.Defaults
|
||||
|
||||
__all__ = [ 'src_targz', 'src_tarbz2', 'src_zip', 'tarbz2', 'targz', 'zip', 'rpm', 'msi', 'ipk' ]
|
||||
|
||||
#
|
||||
# Utility and Builder function
|
||||
#
|
||||
def Tag(env, target, source, *more_tags, **kw_tags):
|
||||
""" Tag a file with the given arguments, just sets the accordingly named
|
||||
attribute on the file object.
|
||||
|
||||
TODO: FIXME
|
||||
"""
|
||||
if not target:
|
||||
target=source
|
||||
first_tag=None
|
||||
else:
|
||||
first_tag=source
|
||||
|
||||
if first_tag:
|
||||
kw_tags[first_tag[0]] = ''
|
||||
|
||||
if len(kw_tags) == 0 and len(more_tags) == 0:
|
||||
raise UserError("No tags given.")
|
||||
|
||||
# XXX: sanity checks
|
||||
for x in more_tags:
|
||||
kw_tags[x] = ''
|
||||
|
||||
if not SCons.Util.is_List(target):
|
||||
target=[target]
|
||||
else:
|
||||
# hmm, sometimes the target list, is a list of a list
|
||||
# make sure it is flattened prior to processing.
|
||||
# TODO: perhaps some bug ?!?
|
||||
target=env.Flatten(target)
|
||||
|
||||
for t in target:
|
||||
for (k,v) in kw_tags.items():
|
||||
# all file tags have to start with PACKAGING_, so we can later
|
||||
# differentiate between "normal" object attributes and the
|
||||
# packaging attributes. As the user should not be bothered with
|
||||
# that, the prefix will be added here if missing.
|
||||
if k[:10] != 'PACKAGING_':
|
||||
k='PACKAGING_'+k
|
||||
t.Tag(k, v)
|
||||
|
||||
def Package(env, target=None, source=None, **kw):
|
||||
""" Entry point for the package tool.
|
||||
"""
|
||||
# check if we need to find the source files ourself
|
||||
if not source:
|
||||
source = env.FindInstalledFiles()
|
||||
|
||||
if len(source)==0:
|
||||
raise UserError("No source for Package() given")
|
||||
|
||||
# decide which types of packages shall be built. Can be defined through
|
||||
# four mechanisms: command line argument, keyword argument,
|
||||
# environment argument and default selection( zip or tar.gz ) in that
|
||||
# order.
|
||||
try: kw['PACKAGETYPE']=env['PACKAGETYPE']
|
||||
except KeyError: pass
|
||||
|
||||
if not kw.get('PACKAGETYPE'):
|
||||
from SCons.Script import GetOption
|
||||
kw['PACKAGETYPE'] = GetOption('package_type')
|
||||
|
||||
if kw['PACKAGETYPE'] == None:
|
||||
if 'Tar' in env['BUILDERS']:
|
||||
kw['PACKAGETYPE']='targz'
|
||||
elif 'Zip' in env['BUILDERS']:
|
||||
kw['PACKAGETYPE']='zip'
|
||||
else:
|
||||
raise UserError("No type for Package() given")
|
||||
|
||||
PACKAGETYPE=kw['PACKAGETYPE']
|
||||
if not is_List(PACKAGETYPE):
|
||||
PACKAGETYPE=PACKAGETYPE.split(',')
|
||||
|
||||
# load the needed packagers.
|
||||
def load_packager(type):
|
||||
try:
|
||||
file,path,desc=imp.find_module(type, __path__)
|
||||
return imp.load_module(type, file, path, desc)
|
||||
except ImportError as e:
|
||||
raise EnvironmentError("packager %s not available: %s"%(type,str(e)))
|
||||
|
||||
packagers=list(map(load_packager, PACKAGETYPE))
|
||||
|
||||
# set up targets and the PACKAGEROOT
|
||||
try:
|
||||
# fill up the target list with a default target name until the PACKAGETYPE
|
||||
# list is of the same size as the target list.
|
||||
if not target: target = []
|
||||
|
||||
size_diff = len(PACKAGETYPE)-len(target)
|
||||
default_name = "%(NAME)s-%(VERSION)s"
|
||||
|
||||
if size_diff>0:
|
||||
default_target = default_name%kw
|
||||
target.extend( [default_target]*size_diff )
|
||||
|
||||
if 'PACKAGEROOT' not in kw:
|
||||
kw['PACKAGEROOT'] = default_name%kw
|
||||
|
||||
except KeyError as e:
|
||||
raise SCons.Errors.UserError( "Missing Packagetag '%s'"%e.args[0] )
|
||||
|
||||
# setup the source files
|
||||
source=env.arg2nodes(source, env.fs.Entry)
|
||||
|
||||
# call the packager to setup the dependencies.
|
||||
targets=[]
|
||||
try:
|
||||
for packager in packagers:
|
||||
t=[target.pop(0)]
|
||||
t=packager.package(env,t,source, **kw)
|
||||
targets.extend(t)
|
||||
|
||||
assert( len(target) == 0 )
|
||||
|
||||
except KeyError as e:
|
||||
raise SCons.Errors.UserError( "Missing Packagetag '%s' for %s packager"\
|
||||
% (e.args[0],packager.__name__) )
|
||||
except TypeError as e:
|
||||
# this exception means that a needed argument for the packager is
|
||||
# missing. As our packagers get their "tags" as named function
|
||||
# arguments we need to find out which one is missing.
|
||||
from inspect import getargspec
|
||||
args,varargs,varkw,defaults=getargspec(packager.package)
|
||||
if defaults!=None:
|
||||
args=args[:-len(defaults)] # throw away arguments with default values
|
||||
args.remove('env')
|
||||
args.remove('target')
|
||||
args.remove('source')
|
||||
# now remove any args for which we have a value in kw.
|
||||
args=[x for x in args if x not in kw]
|
||||
|
||||
if len(args)==0:
|
||||
raise # must be a different error, so re-raise
|
||||
elif len(args)==1:
|
||||
raise SCons.Errors.UserError( "Missing Packagetag '%s' for %s packager"\
|
||||
% (args[0],packager.__name__) )
|
||||
else:
|
||||
raise SCons.Errors.UserError( "Missing Packagetags '%s' for %s packager"\
|
||||
% (", ".join(args),packager.__name__) )
|
||||
|
||||
target=env.arg2nodes(target, env.fs.Entry)
|
||||
targets.extend(env.Alias( 'package', targets ))
|
||||
return targets
|
||||
|
||||
#
|
||||
# SCons tool initialization functions
|
||||
#
|
||||
|
||||
added = None
|
||||
|
||||
def generate(env):
|
||||
from SCons.Script import AddOption
|
||||
global added
|
||||
if not added:
|
||||
added = 1
|
||||
AddOption('--package-type',
|
||||
dest='package_type',
|
||||
default=None,
|
||||
type="string",
|
||||
action="store",
|
||||
help='The type of package to create.')
|
||||
|
||||
try:
|
||||
env['BUILDERS']['Package']
|
||||
env['BUILDERS']['Tag']
|
||||
except KeyError:
|
||||
env['BUILDERS']['Package'] = Package
|
||||
env['BUILDERS']['Tag'] = Tag
|
||||
|
||||
def exists(env):
|
||||
return 1
|
||||
|
||||
# XXX
|
||||
def options(opts):
|
||||
opts.AddVariables(
|
||||
EnumVariable( 'PACKAGETYPE',
|
||||
'the type of package to create.',
|
||||
None, allowed_values=list(map( str, __all__ )),
|
||||
ignorecase=2
|
||||
)
|
||||
)
|
||||
|
||||
#
|
||||
# Internal utility functions
|
||||
#
|
||||
|
||||
def copy_attr(f1, f2):
|
||||
""" copies the special packaging file attributes from f1 to f2.
|
||||
"""
|
||||
copyit = lambda x: not hasattr(f2, x) and x[:10] == 'PACKAGING_'
|
||||
if f1._tags:
|
||||
pattrs = [tag for tag in f1._tags if copyit(tag)]
|
||||
for attr in pattrs:
|
||||
f2.Tag(attr, f1.GetTag(attr))
|
||||
|
||||
def putintopackageroot(target, source, env, pkgroot, honor_install_location=1):
|
||||
""" Uses the CopyAs builder to copy all source files to the directory given
|
||||
in pkgroot.
|
||||
|
||||
If honor_install_location is set and the copied source file has an
|
||||
PACKAGING_INSTALL_LOCATION attribute, the PACKAGING_INSTALL_LOCATION is
|
||||
used as the new name of the source file under pkgroot.
|
||||
|
||||
The source file will not be copied if it is already under the the pkgroot
|
||||
directory.
|
||||
|
||||
All attributes of the source file will be copied to the new file.
|
||||
"""
|
||||
# make sure the packageroot is a Dir object.
|
||||
if SCons.Util.is_String(pkgroot): pkgroot=env.Dir(pkgroot)
|
||||
if not SCons.Util.is_List(source): source=[source]
|
||||
|
||||
new_source = []
|
||||
for file in source:
|
||||
if SCons.Util.is_String(file): file = env.File(file)
|
||||
|
||||
if file.is_under(pkgroot):
|
||||
new_source.append(file)
|
||||
else:
|
||||
if file.GetTag('PACKAGING_INSTALL_LOCATION') and\
|
||||
honor_install_location:
|
||||
new_name=make_path_relative(file.GetTag('PACKAGING_INSTALL_LOCATION'))
|
||||
else:
|
||||
new_name=make_path_relative(file.get_path())
|
||||
|
||||
new_file=pkgroot.File(new_name)
|
||||
new_file=env.CopyAs(new_file, file)[0]
|
||||
copy_attr(file, new_file)
|
||||
new_source.append(new_file)
|
||||
|
||||
return (target, new_source)
|
||||
|
||||
def stripinstallbuilder(target, source, env):
|
||||
""" Strips the install builder action from the source list and stores
|
||||
the final installation location as the "PACKAGING_INSTALL_LOCATION" of
|
||||
the source of the source file. This effectively removes the final installed
|
||||
files from the source list while remembering the installation location.
|
||||
|
||||
It also warns about files which have no install builder attached.
|
||||
"""
|
||||
def has_no_install_location(file):
|
||||
return not (file.has_builder() and\
|
||||
hasattr(file.builder, 'name') and\
|
||||
(file.builder.name=="InstallBuilder" or\
|
||||
file.builder.name=="InstallAsBuilder"))
|
||||
|
||||
if len([src for src in source if has_no_install_location(src)]):
|
||||
warn(Warning, "there are files to package which have no\
|
||||
InstallBuilder attached, this might lead to irreproducible packages")
|
||||
|
||||
n_source=[]
|
||||
for s in source:
|
||||
if has_no_install_location(s):
|
||||
n_source.append(s)
|
||||
else:
|
||||
for ss in s.sources:
|
||||
n_source.append(ss)
|
||||
copy_attr(s, ss)
|
||||
ss.Tag('PACKAGING_INSTALL_LOCATION', s.get_path())
|
||||
|
||||
return (target, n_source)
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=4 shiftwidth=4:
|
185
scons-local-3.0.0/SCons/Tool/packaging/ipk.py
Normal file
185
scons-local-3.0.0/SCons/Tool/packaging/ipk.py
Normal file
@@ -0,0 +1,185 @@
|
||||
"""SCons.Tool.Packaging.ipk
|
||||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/packaging/ipk.py rel_3.0.0:4395:8972f6a2f699 2017/09/18 12:59:24 bdbaddog"
|
||||
|
||||
import SCons.Builder
|
||||
import SCons.Node.FS
|
||||
import os
|
||||
|
||||
from SCons.Tool.packaging import stripinstallbuilder, putintopackageroot
|
||||
|
||||
def package(env, target, source, PACKAGEROOT, NAME, VERSION, DESCRIPTION,
|
||||
SUMMARY, X_IPK_PRIORITY, X_IPK_SECTION, SOURCE_URL,
|
||||
X_IPK_MAINTAINER, X_IPK_DEPENDS, **kw):
|
||||
""" This function prepares the packageroot directory for packaging with the
|
||||
ipkg builder.
|
||||
"""
|
||||
SCons.Tool.Tool('ipkg').generate(env)
|
||||
|
||||
# setup the Ipkg builder
|
||||
bld = env['BUILDERS']['Ipkg']
|
||||
target, source = stripinstallbuilder(target, source, env)
|
||||
target, source = putintopackageroot(target, source, env, PACKAGEROOT)
|
||||
|
||||
# This should be overrideable from the construction environment,
|
||||
# which it is by using ARCHITECTURE=.
|
||||
# Guessing based on what os.uname() returns at least allows it
|
||||
# to work for both i386 and x86_64 Linux systems.
|
||||
archmap = {
|
||||
'i686' : 'i386',
|
||||
'i586' : 'i386',
|
||||
'i486' : 'i386',
|
||||
}
|
||||
|
||||
buildarchitecture = os.uname()[4]
|
||||
buildarchitecture = archmap.get(buildarchitecture, buildarchitecture)
|
||||
|
||||
if 'ARCHITECTURE' in kw:
|
||||
buildarchitecture = kw['ARCHITECTURE']
|
||||
|
||||
# setup the kw to contain the mandatory arguments to this function.
|
||||
# do this before calling any builder or setup function
|
||||
loc=locals()
|
||||
del loc['kw']
|
||||
kw.update(loc)
|
||||
del kw['source'], kw['target'], kw['env']
|
||||
|
||||
# generate the specfile
|
||||
specfile = gen_ipk_dir(PACKAGEROOT, source, env, kw)
|
||||
|
||||
# override the default target.
|
||||
if str(target[0])=="%s-%s"%(NAME, VERSION):
|
||||
target=[ "%s_%s_%s.ipk"%(NAME, VERSION, buildarchitecture) ]
|
||||
|
||||
# now apply the Ipkg builder
|
||||
return bld(env, target, specfile, **kw)
|
||||
|
||||
def gen_ipk_dir(proot, source, env, kw):
|
||||
# make sure the packageroot is a Dir object.
|
||||
if SCons.Util.is_String(proot): proot=env.Dir(proot)
|
||||
|
||||
# create the specfile builder
|
||||
s_bld=SCons.Builder.Builder(
|
||||
action = build_specfiles,
|
||||
)
|
||||
|
||||
# create the specfile targets
|
||||
spec_target=[]
|
||||
control=proot.Dir('CONTROL')
|
||||
spec_target.append(control.File('control'))
|
||||
spec_target.append(control.File('conffiles'))
|
||||
spec_target.append(control.File('postrm'))
|
||||
spec_target.append(control.File('prerm'))
|
||||
spec_target.append(control.File('postinst'))
|
||||
spec_target.append(control.File('preinst'))
|
||||
|
||||
# apply the builder to the specfile targets
|
||||
s_bld(env, spec_target, source, **kw)
|
||||
|
||||
# the packageroot directory does now contain the specfiles.
|
||||
return proot
|
||||
|
||||
def build_specfiles(source, target, env):
|
||||
""" Filter the targets for the needed files and use the variables in env
|
||||
to create the specfile.
|
||||
"""
|
||||
#
|
||||
# At first we care for the CONTROL/control file, which is the main file for ipk.
|
||||
#
|
||||
# For this we need to open multiple files in random order, so we store into
|
||||
# a dict so they can be easily accessed.
|
||||
#
|
||||
#
|
||||
opened_files={}
|
||||
def open_file(needle, haystack):
|
||||
try:
|
||||
return opened_files[needle]
|
||||
except KeyError:
|
||||
file=filter(lambda x: x.get_path().rfind(needle)!=-1, haystack)[0]
|
||||
opened_files[needle]=open(file.get_abspath(), 'w')
|
||||
return opened_files[needle]
|
||||
|
||||
control_file=open_file('control', target)
|
||||
|
||||
if 'X_IPK_DESCRIPTION' not in env:
|
||||
env['X_IPK_DESCRIPTION']="%s\n %s"%(env['SUMMARY'],
|
||||
env['DESCRIPTION'].replace('\n', '\n '))
|
||||
|
||||
|
||||
content = """
|
||||
Package: $NAME
|
||||
Version: $VERSION
|
||||
Priority: $X_IPK_PRIORITY
|
||||
Section: $X_IPK_SECTION
|
||||
Source: $SOURCE_URL
|
||||
Architecture: $ARCHITECTURE
|
||||
Maintainer: $X_IPK_MAINTAINER
|
||||
Depends: $X_IPK_DEPENDS
|
||||
Description: $X_IPK_DESCRIPTION
|
||||
"""
|
||||
|
||||
control_file.write(env.subst(content))
|
||||
|
||||
#
|
||||
# now handle the various other files, which purpose it is to set post-,
|
||||
# pre-scripts and mark files as config files.
|
||||
#
|
||||
# We do so by filtering the source files for files which are marked with
|
||||
# the "config" tag and afterwards we do the same for x_ipk_postrm,
|
||||
# x_ipk_prerm, x_ipk_postinst and x_ipk_preinst tags.
|
||||
#
|
||||
# The first one will write the name of the file into the file
|
||||
# CONTROL/configfiles, the latter add the content of the x_ipk_* variable
|
||||
# into the same named file.
|
||||
#
|
||||
for f in [x for x in source if 'PACKAGING_CONFIG' in dir(x)]:
|
||||
config=open_file('conffiles')
|
||||
config.write(f.PACKAGING_INSTALL_LOCATION)
|
||||
config.write('\n')
|
||||
|
||||
for str in 'POSTRM PRERM POSTINST PREINST'.split():
|
||||
name="PACKAGING_X_IPK_%s"%str
|
||||
for f in [x for x in source if name in dir(x)]:
|
||||
file=open_file(name)
|
||||
file.write(env[str])
|
||||
|
||||
#
|
||||
# close all opened files
|
||||
for f in list(opened_files.values()):
|
||||
f.close()
|
||||
|
||||
# call a user specified function
|
||||
if 'CHANGE_SPECFILE' in env:
|
||||
content += env['CHANGE_SPECFILE'](target)
|
||||
|
||||
return 0
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=4 shiftwidth=4:
|
527
scons-local-3.0.0/SCons/Tool/packaging/msi.py
Normal file
527
scons-local-3.0.0/SCons/Tool/packaging/msi.py
Normal file
@@ -0,0 +1,527 @@
|
||||
"""SCons.Tool.packaging.msi
|
||||
|
||||
The msi packager.
|
||||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/packaging/msi.py rel_3.0.0:4395:8972f6a2f699 2017/09/18 12:59:24 bdbaddog"
|
||||
|
||||
import os
|
||||
import SCons
|
||||
from SCons.Action import Action
|
||||
from SCons.Builder import Builder
|
||||
|
||||
from xml.dom.minidom import *
|
||||
from xml.sax.saxutils import escape
|
||||
|
||||
from SCons.Tool.packaging import stripinstallbuilder
|
||||
|
||||
#
|
||||
# Utility functions
|
||||
#
|
||||
def convert_to_id(s, id_set):
|
||||
""" Some parts of .wxs need an Id attribute (for example: The File and
|
||||
Directory directives. The charset is limited to A-Z, a-z, digits,
|
||||
underscores, periods. Each Id must begin with a letter or with a
|
||||
underscore. Google for "CNDL0015" for information about this.
|
||||
|
||||
Requirements:
|
||||
* the string created must only contain chars from the target charset.
|
||||
* the string created must have a minimal editing distance from the
|
||||
original string.
|
||||
* the string created must be unique for the whole .wxs file.
|
||||
|
||||
Observation:
|
||||
* There are 62 chars in the charset.
|
||||
|
||||
Idea:
|
||||
* filter out forbidden characters. Check for a collision with the help
|
||||
of the id_set. Add the number of the number of the collision at the
|
||||
end of the created string. Furthermore care for a correct start of
|
||||
the string.
|
||||
"""
|
||||
charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYabcdefghijklmnopqrstuvwxyz0123456789_.'
|
||||
if s[0] in '0123456789.':
|
||||
s += '_'+s
|
||||
id = [c for c in s if c in charset]
|
||||
|
||||
# did we already generate an id for this file?
|
||||
try:
|
||||
return id_set[id][s]
|
||||
except KeyError:
|
||||
# no we did not, so initialize with the id
|
||||
if id not in id_set: id_set[id] = { s : id }
|
||||
# there is a collision, generate an id which is unique by appending
|
||||
# the collision number
|
||||
else: id_set[id][s] = id + str(len(id_set[id]))
|
||||
|
||||
return id_set[id][s]
|
||||
|
||||
def is_dos_short_file_name(file):
|
||||
""" Examine if the given file is in the 8.3 form.
|
||||
"""
|
||||
fname, ext = os.path.splitext(file)
|
||||
proper_ext = len(ext) == 0 or (2 <= len(ext) <= 4) # the ext contains the dot
|
||||
proper_fname = file.isupper() and len(fname) <= 8
|
||||
|
||||
return proper_ext and proper_fname
|
||||
|
||||
def gen_dos_short_file_name(file, filename_set):
|
||||
""" See http://support.microsoft.com/default.aspx?scid=kb;en-us;Q142982
|
||||
|
||||
These are no complete 8.3 dos short names. The ~ char is missing and
|
||||
replaced with one character from the filename. WiX warns about such
|
||||
filenames, since a collision might occur. Google for "CNDL1014" for
|
||||
more information.
|
||||
"""
|
||||
# guard this to not confuse the generation
|
||||
if is_dos_short_file_name(file):
|
||||
return file
|
||||
|
||||
fname, ext = os.path.splitext(file) # ext contains the dot
|
||||
|
||||
# first try if it suffices to convert to upper
|
||||
file = file.upper()
|
||||
if is_dos_short_file_name(file):
|
||||
return file
|
||||
|
||||
# strip forbidden characters.
|
||||
forbidden = '."/[]:;=, '
|
||||
fname = [c for c in fname if c not in forbidden]
|
||||
|
||||
# check if we already generated a filename with the same number:
|
||||
# thisis1.txt, thisis2.txt etc.
|
||||
duplicate, num = not None, 1
|
||||
while duplicate:
|
||||
shortname = "%s%s" % (fname[:8-len(str(num))].upper(),\
|
||||
str(num))
|
||||
if len(ext) >= 2:
|
||||
shortname = "%s%s" % (shortname, ext[:4].upper())
|
||||
|
||||
duplicate, num = shortname in filename_set, num+1
|
||||
|
||||
assert( is_dos_short_file_name(shortname) ), 'shortname is %s, longname is %s' % (shortname, file)
|
||||
filename_set.append(shortname)
|
||||
return shortname
|
||||
|
||||
def create_feature_dict(files):
|
||||
""" X_MSI_FEATURE and doc FileTag's can be used to collect files in a
|
||||
hierarchy. This function collects the files into this hierarchy.
|
||||
"""
|
||||
dict = {}
|
||||
|
||||
def add_to_dict( feature, file ):
|
||||
if not SCons.Util.is_List( feature ):
|
||||
feature = [ feature ]
|
||||
|
||||
for f in feature:
|
||||
if f not in dict:
|
||||
dict[ f ] = [ file ]
|
||||
else:
|
||||
dict[ f ].append( file )
|
||||
|
||||
for file in files:
|
||||
if hasattr( file, 'PACKAGING_X_MSI_FEATURE' ):
|
||||
add_to_dict(file.PACKAGING_X_MSI_FEATURE, file)
|
||||
elif hasattr( file, 'PACKAGING_DOC' ):
|
||||
add_to_dict( 'PACKAGING_DOC', file )
|
||||
else:
|
||||
add_to_dict( 'default', file )
|
||||
|
||||
return dict
|
||||
|
||||
def generate_guids(root):
|
||||
""" generates globally unique identifiers for parts of the xml which need
|
||||
them.
|
||||
|
||||
Component tags have a special requirement. Their UUID is only allowed to
|
||||
change if the list of their contained resources has changed. This allows
|
||||
for clean removal and proper updates.
|
||||
|
||||
To handle this requirement, the uuid is generated with an md5 hashing the
|
||||
whole subtree of a xml node.
|
||||
"""
|
||||
from hashlib import md5
|
||||
|
||||
# specify which tags need a guid and in which attribute this should be stored.
|
||||
needs_id = { 'Product' : 'Id',
|
||||
'Package' : 'Id',
|
||||
'Component' : 'Guid',
|
||||
}
|
||||
|
||||
# find all XMl nodes matching the key, retrieve their attribute, hash their
|
||||
# subtree, convert hash to string and add as a attribute to the xml node.
|
||||
for (key,value) in needs_id.items():
|
||||
node_list = root.getElementsByTagName(key)
|
||||
attribute = value
|
||||
for node in node_list:
|
||||
hash = md5(node.toxml()).hexdigest()
|
||||
hash_str = '%s-%s-%s-%s-%s' % ( hash[:8], hash[8:12], hash[12:16], hash[16:20], hash[20:] )
|
||||
node.attributes[attribute] = hash_str
|
||||
|
||||
|
||||
|
||||
def string_wxsfile(target, source, env):
|
||||
return "building WiX file %s"%( target[0].path )
|
||||
|
||||
def build_wxsfile(target, source, env):
|
||||
""" Compiles a .wxs file from the keywords given in env['msi_spec'] and
|
||||
by analyzing the tree of source nodes and their tags.
|
||||
"""
|
||||
file = open(target[0].get_abspath(), 'w')
|
||||
|
||||
try:
|
||||
# Create a document with the Wix root tag
|
||||
doc = Document()
|
||||
root = doc.createElement( 'Wix' )
|
||||
root.attributes['xmlns']='http://schemas.microsoft.com/wix/2003/01/wi'
|
||||
doc.appendChild( root )
|
||||
|
||||
filename_set = [] # this is to circumvent duplicates in the shortnames
|
||||
id_set = {} # this is to circumvent duplicates in the ids
|
||||
|
||||
# Create the content
|
||||
build_wxsfile_header_section(root, env)
|
||||
build_wxsfile_file_section(root, source, env['NAME'], env['VERSION'], env['VENDOR'], filename_set, id_set)
|
||||
generate_guids(root)
|
||||
build_wxsfile_features_section(root, source, env['NAME'], env['VERSION'], env['SUMMARY'], id_set)
|
||||
build_wxsfile_default_gui(root)
|
||||
build_license_file(target[0].get_dir(), env)
|
||||
|
||||
# write the xml to a file
|
||||
file.write( doc.toprettyxml() )
|
||||
|
||||
# call a user specified function
|
||||
if 'CHANGE_SPECFILE' in env:
|
||||
env['CHANGE_SPECFILE'](target, source)
|
||||
|
||||
except KeyError as e:
|
||||
raise SCons.Errors.UserError( '"%s" package field for MSI is missing.' % e.args[0] )
|
||||
|
||||
#
|
||||
# setup function
|
||||
#
|
||||
def create_default_directory_layout(root, NAME, VERSION, VENDOR, filename_set):
|
||||
""" Create the wix default target directory layout and return the innermost
|
||||
directory.
|
||||
|
||||
We assume that the XML tree delivered in the root argument already contains
|
||||
the Product tag.
|
||||
|
||||
Everything is put under the PFiles directory property defined by WiX.
|
||||
After that a directory with the 'VENDOR' tag is placed and then a
|
||||
directory with the name of the project and its VERSION. This leads to the
|
||||
following TARGET Directory Layout:
|
||||
C:\<PFiles>\<Vendor>\<Projectname-Version>\
|
||||
Example: C:\Programme\Company\Product-1.2\
|
||||
"""
|
||||
doc = Document()
|
||||
d1 = doc.createElement( 'Directory' )
|
||||
d1.attributes['Id'] = 'TARGETDIR'
|
||||
d1.attributes['Name'] = 'SourceDir'
|
||||
|
||||
d2 = doc.createElement( 'Directory' )
|
||||
d2.attributes['Id'] = 'ProgramFilesFolder'
|
||||
d2.attributes['Name'] = 'PFiles'
|
||||
|
||||
d3 = doc.createElement( 'Directory' )
|
||||
d3.attributes['Id'] = 'VENDOR_folder'
|
||||
d3.attributes['Name'] = escape( gen_dos_short_file_name( VENDOR, filename_set ) )
|
||||
d3.attributes['LongName'] = escape( VENDOR )
|
||||
|
||||
d4 = doc.createElement( 'Directory' )
|
||||
project_folder = "%s-%s" % ( NAME, VERSION )
|
||||
d4.attributes['Id'] = 'MY_DEFAULT_FOLDER'
|
||||
d4.attributes['Name'] = escape( gen_dos_short_file_name( project_folder, filename_set ) )
|
||||
d4.attributes['LongName'] = escape( project_folder )
|
||||
|
||||
d1.childNodes.append( d2 )
|
||||
d2.childNodes.append( d3 )
|
||||
d3.childNodes.append( d4 )
|
||||
|
||||
root.getElementsByTagName('Product')[0].childNodes.append( d1 )
|
||||
|
||||
return d4
|
||||
|
||||
#
|
||||
# mandatory and optional file tags
|
||||
#
|
||||
def build_wxsfile_file_section(root, files, NAME, VERSION, VENDOR, filename_set, id_set):
|
||||
""" Builds the Component sections of the wxs file with their included files.
|
||||
|
||||
Files need to be specified in 8.3 format and in the long name format, long
|
||||
filenames will be converted automatically.
|
||||
|
||||
Features are specficied with the 'X_MSI_FEATURE' or 'DOC' FileTag.
|
||||
"""
|
||||
root = create_default_directory_layout( root, NAME, VERSION, VENDOR, filename_set )
|
||||
components = create_feature_dict( files )
|
||||
factory = Document()
|
||||
|
||||
def get_directory( node, dir ):
|
||||
""" Returns the node under the given node representing the directory.
|
||||
|
||||
Returns the component node if dir is None or empty.
|
||||
"""
|
||||
if dir == '' or not dir:
|
||||
return node
|
||||
|
||||
Directory = node
|
||||
dir_parts = dir.split(os.path.sep)
|
||||
|
||||
# to make sure that our directory ids are unique, the parent folders are
|
||||
# consecutively added to upper_dir
|
||||
upper_dir = ''
|
||||
|
||||
# walk down the xml tree finding parts of the directory
|
||||
dir_parts = [d for d in dir_parts if d != '']
|
||||
for d in dir_parts[:]:
|
||||
already_created = [c for c in Directory.childNodes
|
||||
if c.nodeName == 'Directory'
|
||||
and c.attributes['LongName'].value == escape(d)]
|
||||
|
||||
if already_created != []:
|
||||
Directory = already_created[0]
|
||||
dir_parts.remove(d)
|
||||
upper_dir += d
|
||||
else:
|
||||
break
|
||||
|
||||
for d in dir_parts:
|
||||
nDirectory = factory.createElement( 'Directory' )
|
||||
nDirectory.attributes['LongName'] = escape( d )
|
||||
nDirectory.attributes['Name'] = escape( gen_dos_short_file_name( d, filename_set ) )
|
||||
upper_dir += d
|
||||
nDirectory.attributes['Id'] = convert_to_id( upper_dir, id_set )
|
||||
|
||||
Directory.childNodes.append( nDirectory )
|
||||
Directory = nDirectory
|
||||
|
||||
return Directory
|
||||
|
||||
for file in files:
|
||||
drive, path = os.path.splitdrive( file.PACKAGING_INSTALL_LOCATION )
|
||||
filename = os.path.basename( path )
|
||||
dirname = os.path.dirname( path )
|
||||
|
||||
h = {
|
||||
# tagname : default value
|
||||
'PACKAGING_X_MSI_VITAL' : 'yes',
|
||||
'PACKAGING_X_MSI_FILEID' : convert_to_id(filename, id_set),
|
||||
'PACKAGING_X_MSI_LONGNAME' : filename,
|
||||
'PACKAGING_X_MSI_SHORTNAME' : gen_dos_short_file_name(filename, filename_set),
|
||||
'PACKAGING_X_MSI_SOURCE' : file.get_path(),
|
||||
}
|
||||
|
||||
# fill in the default tags given above.
|
||||
for k,v in [ (k, v) for (k,v) in h.items() if not hasattr(file, k) ]:
|
||||
setattr( file, k, v )
|
||||
|
||||
File = factory.createElement( 'File' )
|
||||
File.attributes['LongName'] = escape( file.PACKAGING_X_MSI_LONGNAME )
|
||||
File.attributes['Name'] = escape( file.PACKAGING_X_MSI_SHORTNAME )
|
||||
File.attributes['Source'] = escape( file.PACKAGING_X_MSI_SOURCE )
|
||||
File.attributes['Id'] = escape( file.PACKAGING_X_MSI_FILEID )
|
||||
File.attributes['Vital'] = escape( file.PACKAGING_X_MSI_VITAL )
|
||||
|
||||
# create the <Component> Tag under which this file should appear
|
||||
Component = factory.createElement('Component')
|
||||
Component.attributes['DiskId'] = '1'
|
||||
Component.attributes['Id'] = convert_to_id( filename, id_set )
|
||||
|
||||
# hang the component node under the root node and the file node
|
||||
# under the component node.
|
||||
Directory = get_directory( root, dirname )
|
||||
Directory.childNodes.append( Component )
|
||||
Component.childNodes.append( File )
|
||||
|
||||
#
|
||||
# additional functions
|
||||
#
|
||||
def build_wxsfile_features_section(root, files, NAME, VERSION, SUMMARY, id_set):
|
||||
""" This function creates the <features> tag based on the supplied xml tree.
|
||||
|
||||
This is achieved by finding all <component>s and adding them to a default target.
|
||||
|
||||
It should be called after the tree has been built completly. We assume
|
||||
that a MY_DEFAULT_FOLDER Property is defined in the wxs file tree.
|
||||
|
||||
Furthermore a top-level with the name and VERSION of the software will be created.
|
||||
|
||||
An PACKAGING_X_MSI_FEATURE can either be a string, where the feature
|
||||
DESCRIPTION will be the same as its title or a Tuple, where the first
|
||||
part will be its title and the second its DESCRIPTION.
|
||||
"""
|
||||
factory = Document()
|
||||
Feature = factory.createElement('Feature')
|
||||
Feature.attributes['Id'] = 'complete'
|
||||
Feature.attributes['ConfigurableDirectory'] = 'MY_DEFAULT_FOLDER'
|
||||
Feature.attributes['Level'] = '1'
|
||||
Feature.attributes['Title'] = escape( '%s %s' % (NAME, VERSION) )
|
||||
Feature.attributes['Description'] = escape( SUMMARY )
|
||||
Feature.attributes['Display'] = 'expand'
|
||||
|
||||
for (feature, files) in create_feature_dict(files).items():
|
||||
SubFeature = factory.createElement('Feature')
|
||||
SubFeature.attributes['Level'] = '1'
|
||||
|
||||
if SCons.Util.is_Tuple(feature):
|
||||
SubFeature.attributes['Id'] = convert_to_id( feature[0], id_set )
|
||||
SubFeature.attributes['Title'] = escape(feature[0])
|
||||
SubFeature.attributes['Description'] = escape(feature[1])
|
||||
else:
|
||||
SubFeature.attributes['Id'] = convert_to_id( feature, id_set )
|
||||
if feature=='default':
|
||||
SubFeature.attributes['Description'] = 'Main Part'
|
||||
SubFeature.attributes['Title'] = 'Main Part'
|
||||
elif feature=='PACKAGING_DOC':
|
||||
SubFeature.attributes['Description'] = 'Documentation'
|
||||
SubFeature.attributes['Title'] = 'Documentation'
|
||||
else:
|
||||
SubFeature.attributes['Description'] = escape(feature)
|
||||
SubFeature.attributes['Title'] = escape(feature)
|
||||
|
||||
# build the componentrefs. As one of the design decision is that every
|
||||
# file is also a component we walk the list of files and create a
|
||||
# reference.
|
||||
for f in files:
|
||||
ComponentRef = factory.createElement('ComponentRef')
|
||||
ComponentRef.attributes['Id'] = convert_to_id( os.path.basename(f.get_path()), id_set )
|
||||
SubFeature.childNodes.append(ComponentRef)
|
||||
|
||||
Feature.childNodes.append(SubFeature)
|
||||
|
||||
root.getElementsByTagName('Product')[0].childNodes.append(Feature)
|
||||
|
||||
def build_wxsfile_default_gui(root):
|
||||
""" This function adds a default GUI to the wxs file
|
||||
"""
|
||||
factory = Document()
|
||||
Product = root.getElementsByTagName('Product')[0]
|
||||
|
||||
UIRef = factory.createElement('UIRef')
|
||||
UIRef.attributes['Id'] = 'WixUI_Mondo'
|
||||
Product.childNodes.append(UIRef)
|
||||
|
||||
UIRef = factory.createElement('UIRef')
|
||||
UIRef.attributes['Id'] = 'WixUI_ErrorProgressText'
|
||||
Product.childNodes.append(UIRef)
|
||||
|
||||
def build_license_file(directory, spec):
|
||||
""" Creates a License.rtf file with the content of "X_MSI_LICENSE_TEXT"
|
||||
in the given directory
|
||||
"""
|
||||
name, text = '', ''
|
||||
|
||||
try:
|
||||
name = spec['LICENSE']
|
||||
text = spec['X_MSI_LICENSE_TEXT']
|
||||
except KeyError:
|
||||
pass # ignore this as X_MSI_LICENSE_TEXT is optional
|
||||
|
||||
if name!='' or text!='':
|
||||
file = open( os.path.join(directory.get_path(), 'License.rtf'), 'w' )
|
||||
file.write('{\\rtf')
|
||||
if text!='':
|
||||
file.write(text.replace('\n', '\\par '))
|
||||
else:
|
||||
file.write(name+'\\par\\par')
|
||||
file.write('}')
|
||||
file.close()
|
||||
|
||||
#
|
||||
# mandatory and optional package tags
|
||||
#
|
||||
def build_wxsfile_header_section(root, spec):
|
||||
""" Adds the xml file node which define the package meta-data.
|
||||
"""
|
||||
# Create the needed DOM nodes and add them at the correct position in the tree.
|
||||
factory = Document()
|
||||
Product = factory.createElement( 'Product' )
|
||||
Package = factory.createElement( 'Package' )
|
||||
|
||||
root.childNodes.append( Product )
|
||||
Product.childNodes.append( Package )
|
||||
|
||||
# set "mandatory" default values
|
||||
if 'X_MSI_LANGUAGE' not in spec:
|
||||
spec['X_MSI_LANGUAGE'] = '1033' # select english
|
||||
|
||||
# mandatory sections, will throw a KeyError if the tag is not available
|
||||
Product.attributes['Name'] = escape( spec['NAME'] )
|
||||
Product.attributes['Version'] = escape( spec['VERSION'] )
|
||||
Product.attributes['Manufacturer'] = escape( spec['VENDOR'] )
|
||||
Product.attributes['Language'] = escape( spec['X_MSI_LANGUAGE'] )
|
||||
Package.attributes['Description'] = escape( spec['SUMMARY'] )
|
||||
|
||||
# now the optional tags, for which we avoid the KeyErrror exception
|
||||
if 'DESCRIPTION' in spec:
|
||||
Package.attributes['Comments'] = escape( spec['DESCRIPTION'] )
|
||||
|
||||
if 'X_MSI_UPGRADE_CODE' in spec:
|
||||
Package.attributes['X_MSI_UPGRADE_CODE'] = escape( spec['X_MSI_UPGRADE_CODE'] )
|
||||
|
||||
# We hardcode the media tag as our current model cannot handle it.
|
||||
Media = factory.createElement('Media')
|
||||
Media.attributes['Id'] = '1'
|
||||
Media.attributes['Cabinet'] = 'default.cab'
|
||||
Media.attributes['EmbedCab'] = 'yes'
|
||||
root.getElementsByTagName('Product')[0].childNodes.append(Media)
|
||||
|
||||
# this builder is the entry-point for .wxs file compiler.
|
||||
wxs_builder = Builder(
|
||||
action = Action( build_wxsfile, string_wxsfile ),
|
||||
ensure_suffix = '.wxs' )
|
||||
|
||||
def package(env, target, source, PACKAGEROOT, NAME, VERSION,
|
||||
DESCRIPTION, SUMMARY, VENDOR, X_MSI_LANGUAGE, **kw):
|
||||
# make sure that the Wix Builder is in the environment
|
||||
SCons.Tool.Tool('wix').generate(env)
|
||||
|
||||
# get put the keywords for the specfile compiler. These are the arguments
|
||||
# given to the package function and all optional ones stored in kw, minus
|
||||
# the the source, target and env one.
|
||||
loc = locals()
|
||||
del loc['kw']
|
||||
kw.update(loc)
|
||||
del kw['source'], kw['target'], kw['env']
|
||||
|
||||
# strip the install builder from the source files
|
||||
target, source = stripinstallbuilder(target, source, env)
|
||||
|
||||
# put the arguments into the env and call the specfile builder.
|
||||
env['msi_spec'] = kw
|
||||
specfile = wxs_builder(* [env, target, source], **kw)
|
||||
|
||||
# now call the WiX Tool with the built specfile added as a source.
|
||||
msifile = env.WiX(target, specfile)
|
||||
|
||||
# return the target and source tuple.
|
||||
return (msifile, source+[specfile])
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=4 shiftwidth=4:
|
349
scons-local-3.0.0/SCons/Tool/packaging/rpm.py
Normal file
349
scons-local-3.0.0/SCons/Tool/packaging/rpm.py
Normal file
@@ -0,0 +1,349 @@
|
||||
"""SCons.Tool.Packaging.rpm
|
||||
|
||||
The rpm packager.
|
||||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/packaging/rpm.py rel_3.0.0:4395:8972f6a2f699 2017/09/18 12:59:24 bdbaddog"
|
||||
|
||||
import os
|
||||
|
||||
import SCons.Builder
|
||||
import SCons.Tool.rpmutils
|
||||
|
||||
from SCons.Environment import OverrideEnvironment
|
||||
from SCons.Tool.packaging import stripinstallbuilder, src_targz
|
||||
from SCons.Errors import UserError
|
||||
|
||||
def package(env, target, source, PACKAGEROOT, NAME, VERSION,
|
||||
PACKAGEVERSION, DESCRIPTION, SUMMARY, X_RPM_GROUP, LICENSE,
|
||||
**kw):
|
||||
# initialize the rpm tool
|
||||
SCons.Tool.Tool('rpm').generate(env)
|
||||
|
||||
bld = env['BUILDERS']['Rpm']
|
||||
|
||||
# Generate a UserError whenever the target name has been set explicitly,
|
||||
# since rpm does not allow for controlling it. This is detected by
|
||||
# checking if the target has been set to the default by the Package()
|
||||
# Environment function.
|
||||
if str(target[0])!="%s-%s"%(NAME, VERSION):
|
||||
raise UserError( "Setting target is not supported for rpm." )
|
||||
else:
|
||||
# This should be overridable from the construction environment,
|
||||
# which it is by using ARCHITECTURE=.
|
||||
buildarchitecture = SCons.Tool.rpmutils.defaultMachine()
|
||||
|
||||
if 'ARCHITECTURE' in kw:
|
||||
buildarchitecture = kw['ARCHITECTURE']
|
||||
|
||||
fmt = '%s-%s-%s.%s.rpm'
|
||||
srcrpm = fmt % (NAME, VERSION, PACKAGEVERSION, 'src')
|
||||
binrpm = fmt % (NAME, VERSION, PACKAGEVERSION, buildarchitecture)
|
||||
|
||||
target = [ srcrpm, binrpm ]
|
||||
|
||||
# get the correct arguments into the kw hash
|
||||
loc=locals()
|
||||
del loc['kw']
|
||||
kw.update(loc)
|
||||
del kw['source'], kw['target'], kw['env']
|
||||
|
||||
# if no "SOURCE_URL" tag is given add a default one.
|
||||
if 'SOURCE_URL' not in kw:
|
||||
kw['SOURCE_URL']=(str(target[0])+".tar.gz").replace('.rpm', '')
|
||||
|
||||
# mangle the source and target list for the rpmbuild
|
||||
env = OverrideEnvironment(env, kw)
|
||||
target, source = stripinstallbuilder(target, source, env)
|
||||
target, source = addspecfile(target, source, env)
|
||||
target, source = collectintargz(target, source, env)
|
||||
|
||||
# now call the rpm builder to actually build the packet.
|
||||
return bld(env, target, source, **kw)
|
||||
|
||||
def collectintargz(target, source, env):
|
||||
""" Puts all source files into a tar.gz file. """
|
||||
# the rpm tool depends on a source package, until this is changed
|
||||
# this hack needs to be here that tries to pack all sources in.
|
||||
sources = env.FindSourceFiles()
|
||||
|
||||
# filter out the target we are building the source list for.
|
||||
sources = [s for s in sources if s not in target]
|
||||
|
||||
# find the .spec file for rpm and add it since it is not necessarily found
|
||||
# by the FindSourceFiles function.
|
||||
sources.extend( [s for s in source if str(s).rfind('.spec')!=-1] )
|
||||
# sort to keep sources from changing order across builds
|
||||
sources.sort()
|
||||
|
||||
# as the source contains the url of the source package this rpm package
|
||||
# is built from, we extract the target name
|
||||
tarball = (str(target[0])+".tar.gz").replace('.rpm', '')
|
||||
try:
|
||||
tarball = env['SOURCE_URL'].split('/')[-1]
|
||||
except KeyError as e:
|
||||
raise SCons.Errors.UserError( "Missing PackageTag '%s' for RPM packager" % e.args[0] )
|
||||
|
||||
tarball = src_targz.package(env, source=sources, target=tarball,
|
||||
PACKAGEROOT=env['PACKAGEROOT'], )
|
||||
|
||||
return (target, tarball)
|
||||
|
||||
def addspecfile(target, source, env):
|
||||
specfile = "%s-%s" % (env['NAME'], env['VERSION'])
|
||||
|
||||
bld = SCons.Builder.Builder(action = build_specfile,
|
||||
suffix = '.spec',
|
||||
target_factory = SCons.Node.FS.File)
|
||||
|
||||
source.extend(bld(env, specfile, source))
|
||||
|
||||
return (target,source)
|
||||
|
||||
def build_specfile(target, source, env):
|
||||
""" Builds a RPM specfile from a dictionary with string metadata and
|
||||
by analyzing a tree of nodes.
|
||||
"""
|
||||
file = open(target[0].get_abspath(), 'w')
|
||||
|
||||
try:
|
||||
file.write( build_specfile_header(env) )
|
||||
file.write( build_specfile_sections(env) )
|
||||
file.write( build_specfile_filesection(env, source) )
|
||||
file.close()
|
||||
|
||||
# call a user specified function
|
||||
if 'CHANGE_SPECFILE' in env:
|
||||
env['CHANGE_SPECFILE'](target, source)
|
||||
|
||||
except KeyError as e:
|
||||
raise SCons.Errors.UserError( '"%s" package field for RPM is missing.' % e.args[0] )
|
||||
|
||||
|
||||
#
|
||||
# mandatory and optional package tag section
|
||||
#
|
||||
def build_specfile_sections(spec):
|
||||
""" Builds the sections of a rpm specfile.
|
||||
"""
|
||||
str = ""
|
||||
|
||||
mandatory_sections = {
|
||||
'DESCRIPTION' : '\n%%description\n%s\n\n', }
|
||||
|
||||
str = str + SimpleTagCompiler(mandatory_sections).compile( spec )
|
||||
|
||||
optional_sections = {
|
||||
'DESCRIPTION_' : '%%description -l %s\n%s\n\n',
|
||||
'CHANGELOG' : '%%changelog\n%s\n\n',
|
||||
'X_RPM_PREINSTALL' : '%%pre\n%s\n\n',
|
||||
'X_RPM_POSTINSTALL' : '%%post\n%s\n\n',
|
||||
'X_RPM_PREUNINSTALL' : '%%preun\n%s\n\n',
|
||||
'X_RPM_POSTUNINSTALL' : '%%postun\n%s\n\n',
|
||||
'X_RPM_VERIFY' : '%%verify\n%s\n\n',
|
||||
|
||||
# These are for internal use but could possibly be overridden
|
||||
'X_RPM_PREP' : '%%prep\n%s\n\n',
|
||||
'X_RPM_BUILD' : '%%build\n%s\n\n',
|
||||
'X_RPM_INSTALL' : '%%install\n%s\n\n',
|
||||
'X_RPM_CLEAN' : '%%clean\n%s\n\n',
|
||||
}
|
||||
|
||||
# Default prep, build, install and clean rules
|
||||
# TODO: optimize those build steps, to not compile the project a second time
|
||||
if 'X_RPM_PREP' not in spec:
|
||||
spec['X_RPM_PREP'] = '[ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf "$RPM_BUILD_ROOT"' + '\n%setup -q'
|
||||
|
||||
if 'X_RPM_BUILD' not in spec:
|
||||
spec['X_RPM_BUILD'] = '[ ! -e "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && mkdir "$RPM_BUILD_ROOT"'
|
||||
|
||||
if 'X_RPM_INSTALL' not in spec:
|
||||
spec['X_RPM_INSTALL'] = 'scons --install-sandbox="$RPM_BUILD_ROOT" "$RPM_BUILD_ROOT"'
|
||||
|
||||
if 'X_RPM_CLEAN' not in spec:
|
||||
spec['X_RPM_CLEAN'] = '[ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf "$RPM_BUILD_ROOT"'
|
||||
|
||||
str = str + SimpleTagCompiler(optional_sections, mandatory=0).compile( spec )
|
||||
|
||||
return str
|
||||
|
||||
def build_specfile_header(spec):
|
||||
""" Builds all sections but the %file of a rpm specfile
|
||||
"""
|
||||
str = ""
|
||||
|
||||
# first the mandatory sections
|
||||
mandatory_header_fields = {
|
||||
'NAME' : '%%define name %s\nName: %%{name}\n',
|
||||
'VERSION' : '%%define version %s\nVersion: %%{version}\n',
|
||||
'PACKAGEVERSION' : '%%define release %s\nRelease: %%{release}\n',
|
||||
'X_RPM_GROUP' : 'Group: %s\n',
|
||||
'SUMMARY' : 'Summary: %s\n',
|
||||
'LICENSE' : 'License: %s\n', }
|
||||
|
||||
str = str + SimpleTagCompiler(mandatory_header_fields).compile( spec )
|
||||
|
||||
# now the optional tags
|
||||
optional_header_fields = {
|
||||
'VENDOR' : 'Vendor: %s\n',
|
||||
'X_RPM_URL' : 'Url: %s\n',
|
||||
'SOURCE_URL' : 'Source: %s\n',
|
||||
'SUMMARY_' : 'Summary(%s): %s\n',
|
||||
'X_RPM_DISTRIBUTION' : 'Distribution: %s\n',
|
||||
'X_RPM_ICON' : 'Icon: %s\n',
|
||||
'X_RPM_PACKAGER' : 'Packager: %s\n',
|
||||
'X_RPM_GROUP_' : 'Group(%s): %s\n',
|
||||
|
||||
'X_RPM_REQUIRES' : 'Requires: %s\n',
|
||||
'X_RPM_PROVIDES' : 'Provides: %s\n',
|
||||
'X_RPM_CONFLICTS' : 'Conflicts: %s\n',
|
||||
'X_RPM_BUILDREQUIRES' : 'BuildRequires: %s\n',
|
||||
|
||||
'X_RPM_SERIAL' : 'Serial: %s\n',
|
||||
'X_RPM_EPOCH' : 'Epoch: %s\n',
|
||||
'X_RPM_AUTOREQPROV' : 'AutoReqProv: %s\n',
|
||||
'X_RPM_EXCLUDEARCH' : 'ExcludeArch: %s\n',
|
||||
'X_RPM_EXCLUSIVEARCH' : 'ExclusiveArch: %s\n',
|
||||
'X_RPM_PREFIX' : 'Prefix: %s\n',
|
||||
|
||||
# internal use
|
||||
'X_RPM_BUILDROOT' : 'BuildRoot: %s\n', }
|
||||
|
||||
# fill in default values:
|
||||
# Adding a BuildRequires renders the .rpm unbuildable under System, which
|
||||
# are not managed by rpm, since the database to resolve this dependency is
|
||||
# missing (take Gentoo as an example)
|
||||
# if not s.has_key('x_rpm_BuildRequires'):
|
||||
# s['x_rpm_BuildRequires'] = 'scons'
|
||||
|
||||
if 'X_RPM_BUILDROOT' not in spec:
|
||||
spec['X_RPM_BUILDROOT'] = '%{_tmppath}/%{name}-%{version}-%{release}'
|
||||
|
||||
str = str + SimpleTagCompiler(optional_header_fields, mandatory=0).compile( spec )
|
||||
return str
|
||||
|
||||
#
|
||||
# mandatory and optional file tags
|
||||
#
|
||||
def build_specfile_filesection(spec, files):
|
||||
""" builds the %file section of the specfile
|
||||
"""
|
||||
str = '%files\n'
|
||||
|
||||
if 'X_RPM_DEFATTR' not in spec:
|
||||
spec['X_RPM_DEFATTR'] = '(-,root,root)'
|
||||
|
||||
str = str + '%%defattr %s\n' % spec['X_RPM_DEFATTR']
|
||||
|
||||
supported_tags = {
|
||||
'PACKAGING_CONFIG' : '%%config %s',
|
||||
'PACKAGING_CONFIG_NOREPLACE' : '%%config(noreplace) %s',
|
||||
'PACKAGING_DOC' : '%%doc %s',
|
||||
'PACKAGING_UNIX_ATTR' : '%%attr %s',
|
||||
'PACKAGING_LANG_' : '%%lang(%s) %s',
|
||||
'PACKAGING_X_RPM_VERIFY' : '%%verify %s',
|
||||
'PACKAGING_X_RPM_DIR' : '%%dir %s',
|
||||
'PACKAGING_X_RPM_DOCDIR' : '%%docdir %s',
|
||||
'PACKAGING_X_RPM_GHOST' : '%%ghost %s', }
|
||||
|
||||
for file in files:
|
||||
# build the tagset
|
||||
tags = {}
|
||||
for k in list(supported_tags.keys()):
|
||||
try:
|
||||
v = file.GetTag(k)
|
||||
if v:
|
||||
tags[k] = v
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
# compile the tagset
|
||||
str = str + SimpleTagCompiler(supported_tags, mandatory=0).compile( tags )
|
||||
|
||||
str = str + ' '
|
||||
str = str + file.GetTag('PACKAGING_INSTALL_LOCATION')
|
||||
str = str + '\n\n'
|
||||
|
||||
return str
|
||||
|
||||
class SimpleTagCompiler(object):
|
||||
""" This class is a simple string substition utility:
|
||||
the replacement specfication is stored in the tagset dictionary, something
|
||||
like:
|
||||
{ "abc" : "cdef %s ",
|
||||
"abc_" : "cdef %s %s" }
|
||||
|
||||
the compile function gets a value dictionary, which may look like:
|
||||
{ "abc" : "ghij",
|
||||
"abc_gh" : "ij" }
|
||||
|
||||
The resulting string will be:
|
||||
"cdef ghij cdef gh ij"
|
||||
"""
|
||||
def __init__(self, tagset, mandatory=1):
|
||||
self.tagset = tagset
|
||||
self.mandatory = mandatory
|
||||
|
||||
def compile(self, values):
|
||||
""" Compiles the tagset and returns a str containing the result
|
||||
"""
|
||||
def is_international(tag):
|
||||
return tag.endswith('_')
|
||||
|
||||
def get_country_code(tag):
|
||||
return tag[-2:]
|
||||
|
||||
def strip_country_code(tag):
|
||||
return tag[:-2]
|
||||
|
||||
replacements = list(self.tagset.items())
|
||||
|
||||
str = ""
|
||||
domestic = [t for t in replacements if not is_international(t[0])]
|
||||
for key, replacement in domestic:
|
||||
try:
|
||||
str = str + replacement % values[key]
|
||||
except KeyError as e:
|
||||
if self.mandatory:
|
||||
raise e
|
||||
|
||||
international = [t for t in replacements if is_international(t[0])]
|
||||
for key, replacement in international:
|
||||
try:
|
||||
x = [t for t in values.items() if strip_country_code(t[0]) == key]
|
||||
int_values_for_key = [(get_country_code(t[0]),t[1]) for t in x]
|
||||
for v in int_values_for_key:
|
||||
str = str + replacement % v
|
||||
except KeyError as e:
|
||||
if self.mandatory:
|
||||
raise e
|
||||
|
||||
return str
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=4 shiftwidth=4:
|
43
scons-local-3.0.0/SCons/Tool/packaging/src_tarbz2.py
Normal file
43
scons-local-3.0.0/SCons/Tool/packaging/src_tarbz2.py
Normal file
@@ -0,0 +1,43 @@
|
||||
"""SCons.Tool.Packaging.tarbz2
|
||||
|
||||
The tarbz2 SRC packager.
|
||||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/packaging/src_tarbz2.py rel_3.0.0:4395:8972f6a2f699 2017/09/18 12:59:24 bdbaddog"
|
||||
|
||||
from SCons.Tool.packaging import putintopackageroot
|
||||
|
||||
def package(env, target, source, PACKAGEROOT, **kw):
|
||||
bld = env['BUILDERS']['Tar']
|
||||
bld.set_suffix('.tar.bz2')
|
||||
target, source = putintopackageroot(target, source, env, PACKAGEROOT, honor_install_location=0)
|
||||
return bld(env, target, source, TARFLAGS='-jc')
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=4 shiftwidth=4:
|
43
scons-local-3.0.0/SCons/Tool/packaging/src_targz.py
Normal file
43
scons-local-3.0.0/SCons/Tool/packaging/src_targz.py
Normal file
@@ -0,0 +1,43 @@
|
||||
"""SCons.Tool.Packaging.targz
|
||||
|
||||
The targz SRC packager.
|
||||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/packaging/src_targz.py rel_3.0.0:4395:8972f6a2f699 2017/09/18 12:59:24 bdbaddog"
|
||||
|
||||
from SCons.Tool.packaging import putintopackageroot
|
||||
|
||||
def package(env, target, source, PACKAGEROOT, **kw):
|
||||
bld = env['BUILDERS']['Tar']
|
||||
bld.set_suffix('.tar.gz')
|
||||
target, source = putintopackageroot(target, source, env, PACKAGEROOT, honor_install_location=0)
|
||||
return bld(env, target, source, TARFLAGS='-zc')
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=4 shiftwidth=4:
|
43
scons-local-3.0.0/SCons/Tool/packaging/src_zip.py
Normal file
43
scons-local-3.0.0/SCons/Tool/packaging/src_zip.py
Normal file
@@ -0,0 +1,43 @@
|
||||
"""SCons.Tool.Packaging.zip
|
||||
|
||||
The zip SRC packager.
|
||||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/packaging/src_zip.py rel_3.0.0:4395:8972f6a2f699 2017/09/18 12:59:24 bdbaddog"
|
||||
|
||||
from SCons.Tool.packaging import putintopackageroot
|
||||
|
||||
def package(env, target, source, PACKAGEROOT, **kw):
|
||||
bld = env['BUILDERS']['Zip']
|
||||
bld.set_suffix('.zip')
|
||||
target, source = putintopackageroot(target, source, env, PACKAGEROOT, honor_install_location=0)
|
||||
return bld(env, target, source)
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=4 shiftwidth=4:
|
44
scons-local-3.0.0/SCons/Tool/packaging/tarbz2.py
Normal file
44
scons-local-3.0.0/SCons/Tool/packaging/tarbz2.py
Normal file
@@ -0,0 +1,44 @@
|
||||
"""SCons.Tool.Packaging.tarbz2
|
||||
|
||||
The tarbz2 SRC packager.
|
||||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/packaging/tarbz2.py rel_3.0.0:4395:8972f6a2f699 2017/09/18 12:59:24 bdbaddog"
|
||||
|
||||
from SCons.Tool.packaging import stripinstallbuilder, putintopackageroot
|
||||
|
||||
def package(env, target, source, PACKAGEROOT, **kw):
|
||||
bld = env['BUILDERS']['Tar']
|
||||
bld.set_suffix('.tar.gz')
|
||||
target, source = putintopackageroot(target, source, env, PACKAGEROOT)
|
||||
target, source = stripinstallbuilder(target, source, env)
|
||||
return bld(env, target, source, TARFLAGS='-jc')
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=4 shiftwidth=4:
|
44
scons-local-3.0.0/SCons/Tool/packaging/targz.py
Normal file
44
scons-local-3.0.0/SCons/Tool/packaging/targz.py
Normal file
@@ -0,0 +1,44 @@
|
||||
"""SCons.Tool.Packaging.targz
|
||||
|
||||
The targz SRC packager.
|
||||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/packaging/targz.py rel_3.0.0:4395:8972f6a2f699 2017/09/18 12:59:24 bdbaddog"
|
||||
|
||||
from SCons.Tool.packaging import stripinstallbuilder, putintopackageroot
|
||||
|
||||
def package(env, target, source, PACKAGEROOT, **kw):
|
||||
bld = env['BUILDERS']['Tar']
|
||||
bld.set_suffix('.tar.gz')
|
||||
target, source = stripinstallbuilder(target, source, env)
|
||||
target, source = putintopackageroot(target, source, env, PACKAGEROOT)
|
||||
return bld(env, target, source, TARFLAGS='-zc')
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=4 shiftwidth=4:
|
44
scons-local-3.0.0/SCons/Tool/packaging/zip.py
Normal file
44
scons-local-3.0.0/SCons/Tool/packaging/zip.py
Normal file
@@ -0,0 +1,44 @@
|
||||
"""SCons.Tool.Packaging.zip
|
||||
|
||||
The zip SRC packager.
|
||||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/packaging/zip.py rel_3.0.0:4395:8972f6a2f699 2017/09/18 12:59:24 bdbaddog"
|
||||
|
||||
from SCons.Tool.packaging import stripinstallbuilder, putintopackageroot
|
||||
|
||||
def package(env, target, source, PACKAGEROOT, **kw):
|
||||
bld = env['BUILDERS']['Zip']
|
||||
bld.set_suffix('.zip')
|
||||
target, source = stripinstallbuilder(target, source, env)
|
||||
target, source = putintopackageroot(target, source, env, PACKAGEROOT)
|
||||
return bld(env, target, source)
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=4 shiftwidth=4:
|
Reference in New Issue
Block a user