setup.py revision 498
1459N/A#!/usr/bin/python2.4
1459N/A#
1459N/A# CDDL HEADER START
1459N/A#
1459N/A# The contents of this file are subject to the terms of the
1459N/A# Common Development and Distribution License (the "License").
1459N/A# You may not use this file except in compliance with the License.
1459N/A#
1459N/A# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1459N/A# or http://www.opensolaris.org/os/licensing.
1459N/A# See the License for the specific language governing permissions
1459N/A# and limitations under the License.
1459N/A#
1459N/A# When distributing Covered Code, include this CDDL HEADER in each
1459N/A# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1459N/A# If applicable, add the following below this CDDL HEADER, with the
1459N/A# fields enclosed by brackets "[]" replaced with your own identifying
1459N/A# information: Portions Copyright [yyyy] [name of copyright owner]
1459N/A#
1459N/A# CDDL HEADER END
1459N/A#
1459N/A# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
1459N/A# Use is subject to license terms.
1459N/A#
3232N/A
1459N/Aimport fnmatch
1459N/Aimport os
1459N/Aimport platform
1459N/Aimport stat
1459N/Aimport sys
1459N/Aimport shutil
1459N/Aimport re
1459N/Aimport subprocess
1459N/Aimport tarfile
1459N/Aimport tempfile
1459N/Aimport urllib
1459N/A
1459N/Afrom distutils.core import setup, Extension
1459N/Afrom distutils.cmd import Command
1459N/Afrom distutils.command.install import install as _install
1459N/Afrom distutils.command.build import build as _build
1459N/Afrom distutils.command.build_py import build_py as _build_py
1459N/Afrom distutils.command.bdist import bdist as _bdist
1459N/Afrom distutils.command.clean import clean as _clean
1459N/A
1459N/Afrom distutils.sysconfig import get_python_inc
1459N/Aimport distutils.file_util as file_util
1459N/Aimport distutils.dir_util as dir_util
1459N/Aimport distutils.util as util
1459N/A
1459N/A# 3rd party software required for the build
1459N/ACP = 'CherryPy'
1459N/ACPIDIR = 'cherrypy'
1459N/ACPVER = '3.1.0'
1459N/ACPARC = '%s-%s.tar.gz' % (CP, CPVER)
1459N/ACPDIR = '%s-%s' % (CP, CPVER)
1459N/ACPURL = 'http://download.cherrypy.org/cherrypy/%s/%s' % (CPVER, CPARC)
1459N/A
1459N/APO = 'pyOpenSSL'
1459N/APOIDIR = 'OpenSSL'
1459N/APOVER = '0.7'
1459N/APOARC = '%s-%s.tar.gz' % (PO, POVER)
1459N/APODIR = '%s-%s' % (PO, POVER)
1459N/APOURL = 'http://downloads.sourceforge.net/pyopenssl/%s' % (POARC)
1459N/A
1459N/Aosname = platform.uname()[0].lower()
1459N/Aostype = arch = 'unknown'
1459N/Aif osname == 'sunos':
1459N/A arch = platform.processor()
1459N/A ostype = "posix"
1459N/Aelif osname == 'linux':
1459N/A arch = "linux_" + platform.machine()
1459N/A ostype = "posix"
1459N/Aelif osname == 'windows':
1459N/A arch = osname
1459N/A ostype = "windows"
1459N/Aelif osname == 'darwin':
1459N/A arch = osname
1459N/A ostype = "posix"
1459N/A
1459N/Apwd = os.path.normpath(sys.path[0])
1459N/A
1459N/Adist_dir = os.path.normpath(os.path.join(pwd, os.pardir, "proto", "dist_" + arch))
1459N/Abuild_dir = os.path.normpath(os.path.join(pwd, os.pardir, "proto", "build_" + arch))
1459N/Aroot_dir = os.path.normpath(os.path.join(pwd, os.pardir, "proto", "root_" + arch))
1459N/A
1459N/Apy_install_dir = 'usr/lib/python2.4/vendor-packages'
2342N/A
1459N/Ascripts_dir = 'usr/bin'
1459N/Alib_dir = 'usr/lib'
1459N/A
1459N/Aman1_dir = 'usr/share/man/cat1'
1459N/Aman1m_dir = 'usr/share/man/cat1m'
1459N/Aman5_dir = 'usr/share/man/cat5'
1459N/Aresource_dir = 'usr/share/lib/pkg'
1459N/Asmf_dir = 'var/svc/manifest/application'
1459N/Azones_dir = 'etc/zones'
1459N/Abrand_dir = 'usr/lib/brand/ipkg'
1459N/A
1459N/Ascripts_sunos = {
1459N/A scripts_dir: [
1459N/A ['client.py', 'pkg'],
1459N/A ['publish.py', 'pkgsend'],
1459N/A ['pull.py', 'pkgrecv'],
1459N/A ['packagemanager.py', 'packagemanager'],
1459N/A ],
1459N/A lib_dir: [
1459N/A ['depot.py', 'pkg.depotd'],
1459N/A ],
1459N/A }
1459N/A
1459N/Ascripts_windows = {
1459N/A scripts_dir: [
1459N/A ['client.py', 'client.py'],
1459N/A ['publish.py', 'publish.py'],
1459N/A ['pull.py', 'pull.py'],
1459N/A ['scripts/pkg.bat', 'pkg.bat'],
1459N/A ['scripts/pkgsend.bat', 'pkgsend.bat'],
1459N/A ['scripts/pkgrecv.bat', 'pkgrecv.bat'],
1459N/A ],
1459N/A lib_dir: [
1459N/A ['depot.py', 'depot.py'],
1459N/A ['scripts/pkg.depotd.bat', 'pkg.depotd.bat'],
1459N/A ],
1459N/A }
1459N/A
1459N/Ascripts_other_unix = {
1459N/A scripts_dir: [
1459N/A ['client.py', 'client.py'],
1459N/A ['pull.py', 'pull.py'],
1459N/A ['publish.py', 'publish.py'],
1459N/A ['scripts/pkg.sh', 'pkg'],
1459N/A ['scripts/pkgsend.sh', 'pkgsend'],
1459N/A ['scripts/pkgrecv.sh', 'pkgrecv'],
1459N/A ],
1459N/A lib_dir: [
1459N/A ['depot.py', 'depot.py'],
1459N/A ['scripts/pkg.depotd.sh', 'pkg.depotd'],
1459N/A ],
1459N/A }
1459N/A
1459N/A# indexed by 'osname'
1459N/Ascripts = {
1459N/A "sunos": scripts_sunos,
1459N/A "linux": scripts_other_unix,
1459N/A "windows": scripts_windows,
1459N/A "darwin": scripts_other_unix,
1459N/A "unknown": scripts_sunos,
1459N/A }
1459N/A
1459N/Aman1_files = [
1459N/A 'man/pkg.1',
1459N/A 'man/pkgsend.1',
1459N/A 'man/pkgrecv.1',
1459N/A ]
1459N/Aman1m_files = [
1459N/A 'man/pkg.depotd.1m'
1459N/A ]
1459N/Aman5_files = [
1459N/A 'man/pkg.5'
1459N/A ]
1459N/Apackages = [
1459N/A 'pkg',
1459N/A 'pkg.actions',
1459N/A 'pkg.bundle',
1459N/A 'pkg.client',
1459N/A 'pkg.portable',
1459N/A 'pkg.publish',
1459N/A 'pkg.server'
1459N/A ]
1459N/Aweb_files = [
1459N/A 'web/pkg-block-icon.png',
1459N/A 'web/pkg-block-logo.png',
1459N/A 'web/pkg.css',
1459N/A 'web/feed-icon-32x32.png',
1459N/A 'web/robots.txt',
1459N/A ]
1459N/Azones_files = [
1459N/A 'brand/SUNWipkg.xml',
1459N/A ]
1459N/Abrand_files = [
1459N/A 'brand/config.xml',
1459N/A 'brand/platform.xml',
1459N/A 'brand/pkgcreatezone',
1459N/A ]
1459N/Asmf_files = [
1459N/A 'pkg-server.xml',
1459N/A ]
1459N/Aelf_srcs = [
1459N/A 'modules/elf.c',
1459N/A 'modules/elfextract.c',
1459N/A 'modules/liblist.c',
1459N/A ]
1459N/Aarch_srcs = [
1459N/A 'modules/arch.c'
1459N/A ]
1459N/Ainclude_dirs = [ 'modules' ]
1459N/Alint_flags = [ '-u', '-axms', '-erroff=E_NAME_DEF_NOT_USED2' ]
1459N/A
1459N/A# Runs lint on the extension module source code
1459N/Aclass lint_func(Command):
1459N/A description = "Runs various lint tools over IPS extension source code"
1459N/A user_options = []
1459N/A
1459N/A def initialize_options(self):
1459N/A pass
1459N/A
1459N/A def finalize_options(self):
1459N/A pass
1459N/A
1459N/A # Make string shell-friendly
1459N/A @staticmethod
1459N/A def escape(astring):
1459N/A return astring.replace(' ', '\\ ')
1459N/A
1459N/A def run(self):
1459N/A # assumes lint is on the $PATH
1459N/A if osname == 'sunos' or osname == "linux":
1459N/A archcmd = ['lint'] + lint_flags + ['-D_FILE_OFFSET_BITS=64'] + \
1459N/A ["%s%s" % ("-I", k) for k in include_dirs] + \
1459N/A ['-I' + self.escape(get_python_inc())] + \
1459N/A arch_srcs
1459N/A elfcmd = ['lint'] + lint_flags + \
1459N/A ["%s%s" % ("-I", k) for k in include_dirs] + \
1459N/A ['-I' + self.escape(get_python_inc())] + \
1459N/A ["%s%s" % ("-l", k) for k in elf_libraries] + \
1459N/A elf_srcs
1459N/A
1459N/A print(" ".join(archcmd))
1459N/A os.system(" ".join(archcmd))
1459N/A print(" ".join(elfcmd))
1459N/A os.system(" ".join(elfcmd))
1459N/A
1459N/A proto = os.path.join(root_dir, py_install_dir)
1459N/A sys.path.insert(0, proto)
1459N/A
1459N/A # Insert tests directory onto sys.path so any custom checkers
1459N/A # can be found.
1459N/A sys.path.insert(0, os.path.join(pwd, 'tests'))
1459N/A print(sys.path)
1459N/A
1459N/A # assumes pylint is accessible on the sys.path
1459N/A from pylint import lint
1459N/A scriptlist = [ 'setup.py' ]
1459N/A for d, m in scripts_sunos.items():
1459N/A for a in m:
1459N/A # specify the filenames of the scripts, in addition
1459N/A # to the package names themselves
1459N/A scriptlist.append(os.path.join(root_dir, d, a[1]))
1459N/A
1459N/A # For some reason, the load-plugins option, when used in the
1459N/A # rcfile, does not work, so we put it here instead, to load
1459N/A # our custom checkers.
1459N/A lint.Run(['--load-plugins=multiplatform', '--rcfile',
1459N/A os.path.join(pwd, 'tests', 'pylintrc')] +
1459N/A scriptlist + packages)
1459N/A
1459N/Aclass install_func(_install):
1459N/A def initialize_options(self):
1459N/A _install.initialize_options(self)
1459N/A # It's OK to have /'s here, python figures it out when writing files
1459N/A self.install_purelib = py_install_dir
1459N/A self.install_platlib = py_install_dir
1459N/A self.root = root_dir
1459N/A self.prefix = '.'
1459N/A
1459N/A def run(self):
1459N/A """
1459N/A At the end of the install function, we need to rename some files
1459N/A because distutils provides no way to rename files as they are
1459N/A placed in their install locations.
1459N/A Also, make sure that cherrypy is installed.
1459N/A """
1459N/A for f in man1_files + man1m_files + man5_files:
1459N/A file_util.copy_file(f + ".txt", f, update=1)
1459N/A
1459N/A _install.run(self)
1459N/A
1459N/A for d, files in scripts[osname].iteritems():
1459N/A for (srcname, dstname) in files:
1459N/A dst_dir = util.change_root(self.root, d)
1459N/A dst_path = util.change_root(self.root,
1459N/A os.path.join(d, dstname))
1459N/A dir_util.mkpath(dst_dir, verbose = True)
1459N/A file_util.copy_file(srcname, dst_path, update = True)
1459N/A # make scripts executable
1459N/A os.chmod(dst_path,
os.stat(dst_path).st_mode | stat.S_IEXEC)
install_sw(CP, CPVER, CPARC, CPDIR, CPURL, CPIDIR)
install_sw(PO, POVER, POARC, PODIR, POURL, POIDIR)
def install_sw(swname, swver, swarc, swdir, swurl, swidir):
if not os.path.exists(swarc):
print "downloading %s" % swname
try:
fname, hdr = urllib.urlretrieve(swurl, swarc)
except IOError:
pass
if not os.path.exists(swarc) or \
(hdr.gettype() != "application/x-gzip" and
hdr.gettype() != "application/x-tar"):
print "Unable to retrieve %s.\nPlease retrieve the file " \
"and place it at: %s\n" % (swurl, swarc)
# remove a partial download or error message from proxy
remove_sw(swname)
sys.exit(1)
if not os.path.exists(swdir):
print "unpacking %s" % swname
tar = tarfile.open(swarc)
# extractall doesn't exist until python 2.5
for m in tar.getmembers():
tar.extract(m)
tar.close()
swinst_dir = os.path.join(root_dir, py_install_dir, swidir)
if not os.path.exists(swinst_dir):
print "installing %s" % swname
subprocess.Popen(['python', 'setup.py', 'install',
'--root=%s' % root_dir,
'--install-lib=%s' % py_install_dir,
'--install-data=%s' % py_install_dir],
cwd = swdir).wait()
def remove_sw(swname):
print("deleting %s" % swname)
for file in os.listdir("."):
if fnmatch.fnmatch(file, "%s*" % swname):
if os.path.isfile(file):
os.unlink(file)
else:
shutil.rmtree(file, True)
class build_func(_build):
def initialize_options(self):
_build.initialize_options(self)
self.build_base = build_dir
def get_hg_version():
try:
p = subprocess.Popen(['hg', 'id', '-i'], stdout = subprocess.PIPE)
return p.communicate()[0].strip()
except OSError:
print >> sys.stderr, "ERROR: unable to obtain mercurial version"
return "unknown"
class build_py_func(_build_py):
# override the build_module method to do VERSION substitution on pkg/__init__.py
def build_module (self, module, module_file, package):
if module == "__init__" and package == "pkg":
versionre = '(?m)^VERSION[^"]*"([^"]*)"'
# Grab the previously-built version out of the build
# tree.
try:
ocontent = \
file(self.get_module_outfile(self.build_lib,
[package], module)).read()
ov = re.search(versionre, ocontent).group(1)
except IOError:
ov = None
v = get_hg_version()
vstr = 'VERSION = "%s"' % v
# If the versions haven't changed, there's no need to
# recompile.
if v == ov:
return
mcontent = file(module_file).read()
mcontent = re.sub(versionre, vstr, mcontent)
tmpfd, tmp_file = tempfile.mkstemp()
os.write(tmpfd, mcontent)
os.close(tmpfd)
print "doing version substitution: ", v
rv = _build_py.build_module(self, module, tmp_file, package)
os.unlink(tmp_file)
return rv
return _build_py.build_module(self, module, module_file, package)
class clean_func(_clean):
def initialize_options(self):
_clean.initialize_options(self)
self.build_base = build_dir
class clobber_func(Command):
user_options = []
description = "Deletes any and all files created by setup"
def initialize_options(self):
pass
def finalize_options(self):
pass
def run(self):
# nuke everything
print("deleting " + dist_dir)
shutil.rmtree(dist_dir, True)
print("deleting " + build_dir)
shutil.rmtree(build_dir, True)
print("deleting " + root_dir)
shutil.rmtree(root_dir, True)
remove_sw(CP)
remove_sw(PO)
class test_func(Command):
# NOTE: these options need to be in sync with tests/run.py
user_options = [("verbosemode", 'v', "run tests in verbose mode"),
("genbaseline", 'g', "generate test baseline"),
("parseable", 'p', "parseable output"),
("baselinefile=", 'b', "baseline file <file>"),
("only=", "o", "only <regex>")]
description = "Runs unit and functional tests"
def initialize_options(self):
self.only = ""
self.baselinefile = ""
self.verbosemode = 0
self.parseable = 0
self.genbaseline = 0
def finalize_options(self):
pass
def run(self):
os.putenv('PYEXE', sys.executable)
os.chdir(os.path.join(pwd, "tests"))
# Reconstruct the cmdline and send that to run.py
cmd = [sys.executable, "run.py"]
args = ""
if "test" in sys.argv:
args = sys.argv[sys.argv.index("test")+1:]
cmd.extend(args)
subprocess.call(cmd)
class dist_func(_bdist):
def initialize_options(self):
_bdist.initialize_options(self)
self.dist_dir = dist_dir
# These are set to real values based on the platform, down below
ext_modules = None
compile_args = None
link_args = None
elf_libraries = None
data_files = [ (resource_dir, web_files) ]
cmdclasses = {
'install': install_func,
'build': build_func,
'build_py': build_py_func,
'bdist': dist_func,
'lint': lint_func,
'clean': clean_func,
'clobber': clobber_func,
'test': test_func,
}
# all builds of IPS should have manpages
data_files += [
(man1_dir, man1_files),
(man1m_dir, man1m_files),
(man5_dir, man5_files),
]
if osname == 'sunos':
# Solaris-specific extensions are added here
data_files += [
(zones_dir, zones_files),
(brand_dir, brand_files),
(smf_dir, smf_files),
]
if osname == 'sunos' or osname == "linux":
# Unix platforms which the elf extension has been ported to
# are specified here, so they are built automatically
elf_libraries = ['elf']
ext_modules = [
Extension(
'elf',
elf_srcs,
include_dirs = include_dirs,
libraries = elf_libraries,
extra_compile_args = compile_args,
extra_link_args = link_args
),
]
# Solaris has built-in md library and Solaris-specific arch extension
# All others use OpenSSL and cross-platform arch module
if osname == 'sunos':
elf_libraries += [ 'md' ]
ext_modules += [
Extension(
'arch',
arch_srcs,
include_dirs = include_dirs,
extra_compile_args = compile_args,
extra_link_args = link_args,
define_macros = [('_FILE_OFFSET_BITS', '64')]
),
]
else:
elf_libraries += [ 'ssl' ]
setup(cmdclass = cmdclasses,
name = 'ips',
version = '1.0',
package_dir = {'pkg':'modules'},
packages = packages,
data_files = data_files,
ext_package = 'pkg',
ext_modules = ext_modules,
)