setup.py revision 395
1516N/A#
20N/A# CDDL HEADER START
20N/A#
20N/A# The contents of this file are subject to the terms of the
20N/A# Common Development and Distribution License (the "License").
20N/A# You may not use this file except in compliance with the License.
20N/A#
20N/A# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
20N/A# or http://www.opensolaris.org/os/licensing.
20N/A# See the License for the specific language governing permissions
20N/A# and limitations under the License.
20N/A#
20N/A# When distributing Covered Code, include this CDDL HEADER in each
20N/A# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
20N/A# If applicable, add the following below this CDDL HEADER, with the
20N/A# fields enclosed by brackets "[]" replaced with your own identifying
20N/A# information: Portions Copyright [yyyy] [name of copyright owner]
20N/A#
20N/A# CDDL HEADER END
20N/A#
20N/A# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
2230N/A# Use is subject to license terms.
20N/A#
20N/A
22N/Aimport os
0N/Aimport stat
50N/Aimport sys
50N/Aimport platform
50N/Aimport shutil
50N/Aimport re
50N/Aimport subprocess
50N/Aimport tarfile
50N/Aimport tempfile
50N/Aimport urllib
50N/A
50N/Afrom distutils.core import setup, Extension
50N/Afrom distutils.cmd import Command
50N/Afrom distutils.command.install import install as _install
50N/Afrom distutils.command.build import build as _build
50N/Afrom distutils.command.build_py import build_py as _build_py
589N/Afrom distutils.command.bdist import bdist as _bdist
589N/Afrom distutils.command.clean import clean as _clean
965N/A
965N/Afrom distutils.sysconfig import get_python_inc
965N/Aimport distutils.file_util as file_util
965N/Aimport distutils.dir_util as dir_util
965N/Aimport distutils.util as util
965N/A
1836N/Apwd = os.path.normpath(sys.path[0])
1836N/A
382N/Aosname = platform.uname()[0].lower()
812N/Aostype = arch = 'unknown'
382N/Aif osname == 'sunos':
382N/A arch = platform.processor()
382N/A ostype = "posix"
1963N/Aelif osname == 'linux':
382N/A arch = "linux_" + platform.machine()
1963N/A ostype = "posix"
382N/Aelif osname == 'windows':
382N/A arch = osname
382N/A ostype = "windows"
382N/Aelif osname == 'darwin':
382N/A arch = osname
26N/A ostype = "posix"
689N/A
689N/Adist_dir = os.path.normpath(os.path.join(pwd, os.pardir, "proto", "dist_" + arch))
466N/Abuild_dir = os.path.normpath(os.path.join(pwd, os.pardir, "proto", "build_" + arch))
0N/Aroot_dir = os.path.normpath(os.path.join(pwd, os.pardir, "proto", "root_" + arch))
468N/A
812N/Apy_install_dir = 'usr/lib/python2.4/vendor-packages'
812N/A
52N/Ascripts_dir = 'usr/bin'
812N/Alib_dir = 'usr/lib'
451N/A
0N/Aman1_dir = 'usr/share/man/cat1'
382N/Aman1m_dir = 'usr/share/man/cat1m'
382N/Aman5_dir = 'usr/share/man/cat5'
382N/Aresource_dir = 'usr/share/lib/pkg'
452N/Asmf_dir = 'var/svc/manifest/application'
382N/Azones_dir = 'etc/zones'
452N/Abrand_dir = 'usr/lib/brand/ipkg'
382N/A
382N/Ascripts_sunos = {
751N/A scripts_dir: [
751N/A ['client.py', 'pkg'],
382N/A ['publish.py', 'pkgsend'],
22N/A ['pull.py', 'pkgrecv'],
1836N/A ],
1836N/A lib_dir: [
1836N/A ['depot.py', 'pkg.depotd'],
1431N/A ],
1968N/A }
873N/A
812N/Ascripts_windows = {
1431N/A scripts_dir: [
873N/A ['client.py', 'client.py'],
1431N/A ['publish.py', 'publish.py'],
466N/A ['pull.py', 'pull.py'],
1431N/A ['scripts/pkg.bat', 'pkg.bat'],
466N/A ['scripts/pkgsend.bat', 'pkgsend.bat'],
466N/A ['scripts/pkgrecv.bat', 'pkgrecv.bat'],
466N/A ],
23N/A lib_dir: [
466N/A ['depot.py', 'depot.py'],
466N/A ['scripts/pkg.depotd.bat', 'pkg.depotd.bat'],
466N/A ],
466N/A }
466N/A
466N/Ascripts_other_unix = {
466N/A scripts_dir: [
466N/A ['client.py', 'client.py'],
1431N/A ['pull.py', 'pull.py'],
1633N/A ['publish.py', 'publish.py'],
1633N/A ['scripts/pkg.sh', 'pkg'],
1633N/A ['scripts/pkgsend.sh', 'pkgsend'],
1633N/A ['scripts/pkgrecv.sh', 'pkgrecv'],
466N/A ],
466N/A lib_dir: [
466N/A ['depot.py', 'depot.py'],
1633N/A ['scripts/pkg.depotd.sh', 'pkg.depotd'],
1633N/A ],
1633N/A }
1633N/A
1633N/A# indexed by 'osname'
1633N/Ascripts = {
26N/A "sunos": scripts_sunos,
2230N/A "linux": scripts_other_unix,
1968N/A "windows": scripts_windows,
1633N/A "darwin": scripts_other_unix,
1902N/A "unknown": scripts_sunos,
1968N/A }
2100N/A
1937N/Aman1_files = [
382N/A 'man/pkg.1.txt',
2230N/A 'man/pkgsend.1.txt',
2230N/A 'man/pkgrecv.1.txt',
2230N/A ]
2230N/Aman1m_files = [
2028N/A 'man/pkg.depotd.1m.txt'
1968N/A ]
1968N/Aman5_files = [
2028N/A 'man/pkg.5.txt'
1968N/A ]
1968N/Apackages = [
1968N/A 'pkg',
2028N/A 'pkg.actions',
2028N/A 'pkg.bundle',
2028N/A 'pkg.client',
1968N/A 'pkg.portable',
1968N/A 'pkg.publish',
1968N/A 'pkg.server',
1968N/A ]
1968N/Aweb_files = [
1968N/A 'web/pkg-block-icon.png',
589N/A 'web/pkg-block-logo.png',
589N/A 'web/pkg.css',
589N/A 'web/robots.txt',
589N/A ]
1431N/Azones_files = [
1431N/A 'brand/SUNWipkg.xml',
1431N/A ]
1431N/Abrand_files = [
1431N/A 'brand/config.xml',
858N/A 'brand/platform.xml',
1633N/A 'brand/pkgcreatezone',
1633N/A ]
1902N/Asmf_files = [
1902N/A 'pkg-server.xml',
2028N/A ]
466N/Aelf_srcs = [
466N/A 'modules/elf.c',
466N/A 'modules/elfextract.c',
466N/A 'modules/liblist.c',
466N/A ]
466N/Aarch_srcs = [
466N/A 'modules/arch.c'
466N/A ]
466N/Ainclude_dirs = [ 'modules' ]
589N/Alint_flags = [ '-u', '-axms', '-erroff=E_NAME_DEF_NOT_USED2' ]
589N/A
589N/A# Runs lint on the extension module source code
1191N/Aclass lint_func(Command):
1191N/A description = "Runs various lint tools over IPS extension source code"
1191N/A user_options = []
1191N/A
1191N/A def initialize_options(self):
589N/A pass
589N/A
589N/A def finalize_options(self):
589N/A pass
812N/A
812N/A # Make string shell-friendly
812N/A @staticmethod
812N/A def escape(astring):
812N/A return astring.replace(' ', '\\ ')
812N/A
812N/A def run(self):
1968N/A # assumes lint is on the $PATH
1968N/A if osname == 'sunos' or osname == "linux":
1968N/A archcmd = ['lint'] + lint_flags + ['-D_FILE_OFFSET_BITS=64'] + \
812N/A ["%s%s" % ("-I", k) for k in include_dirs] + \
812N/A ['-I' + self.escape(get_python_inc())] + \
812N/A arch_srcs
812N/A elfcmd = ['lint'] + lint_flags + \
1475N/A ["%s%s" % ("-I", k) for k in include_dirs] + \
1475N/A ['-I' + self.escape(get_python_inc())] + \
1475N/A ["%s%s" % ("-l", k) for k in elf_libraries] + \
1475N/A elf_srcs
975N/A
975N/A print(" ".join(archcmd))
975N/A os.system(" ".join(archcmd))
975N/A print(" ".join(elfcmd))
1633N/A os.system(" ".join(elfcmd))
1633N/A
1633N/A proto = os.path.join(root_dir, py_install_dir)
1633N/A sys.path.insert(0, proto)
2028N/A
1633N/A # Insert tests directory onto sys.path so any custom checkers
1633N/A # can be found.
1633N/A sys.path.insert(0, os.path.join(pwd, 'tests'))
14N/A print(sys.path)
382N/A
429N/A # assumes pylint is accessible on the sys.path
14N/A from pylint import lint
404N/A scriptlist = [ 'setup.py' ]
404N/A for d, m in scripts_sunos.items():
30N/A for a in m:
382N/A # specify the filenames of the scripts, in addition
30N/A # to the package names themselves
791N/A scriptlist.append(os.path.join(root_dir, d, a[1]))
689N/A
689N/A # For some reason, the load-plugins option, when used in the
1968N/A # rcfile, does not work, so we put it here instead, to load
1968N/A # our custom checkers.
1968N/A lint.Run(['--load-plugins=multiplatform', '--rcfile',
1968N/A os.path.join(pwd, 'tests', 'pylintrc')] +
1191N/A scriptlist + packages)
1191N/A
258N/Aclass install_func(_install):
1968N/A def initialize_options(self):
1968N/A _install.initialize_options(self)
382N/A # It's OK to have /'s here, python figures it out when writing files
1968N/A self.install_purelib = py_install_dir
30N/A self.install_platlib = py_install_dir
589N/A self.root = root_dir
589N/A self.prefix = '.'
1968N/A
589N/A def run(self):
589N/A """
589N/A At the end of the install function, we need to rename some files
589N/A because distutils provides no way to rename files as they are
1968N/A placed in their install locations.
589N/A Also, make sure that cherrypy is installed.
1968N/A """
466N/A _install.run(self)
466N/A if ostype == 'posix':
2230N/A # only rename manpages if building for unix-derived OS
1968N/A for (d, files) in [(man1_dir, man1_files), (man1m_dir,
1968N/A man1m_files), (man5_dir, man5_files)]:
1431N/A for f in files:
1968N/A src = util.change_root(self.root,
1968N/A os.path.join(d, os.path.basename(f)))
54N/A if src.endswith('.txt'):
1968N/A dst = src[:-4]
1968N/A os.rename(src, dst)
1968N/A
1968N/A for d, files in scripts[osname].iteritems():
2100N/A for (srcname, dstname) in files:
1968N/A dst_dir = util.change_root(self.root, d)
1968N/A dst_path = util.change_root(self.root,
1475N/A os.path.join(d, dstname))
2230N/A dir_util.mkpath(dst_dir, verbose = True)
466N/A file_util.copy_file(srcname, dst_path, update = True)
1633N/A # make scripts executable
1633N/A os.chmod(dst_path,
135N/A os.stat(dst_path).st_mode | stat.S_IEXEC)
2230N/A
2230N/A install_cherrypy()
2230N/A
135N/ACP = 'CherryPy'
135N/ACPVER = '3.0.3'
1968N/ACPARC = '%s-%s.tar.gz' % (CP, CPVER)
135N/ACPDIR = '%s-%s' % (CP, CPVER)
1968N/ACPURL = 'http://download.cherrypy.org/cherrypy/%s/%s' % (CPVER, CPARC)
382N/Adef install_cherrypy():
382N/A if not os.path.exists(CPARC):
382N/A print "downloading CherryPy"
382N/A try:
382N/A fname, hdr = urllib.urlretrieve(CPURL, CPARC)
382N/A except IOError:
382N/A pass
382N/A if not os.path.exists(CPARC) or \
1968N/A hdr.gettype() != "application/x-gzip":
382N/A print "Unable to retrieve %s.\nPlease retrieve the file " \
1968N/A "and place it at: %s\n" % (CPURL, CPARC)
1542N/A # remove a partial download or error message from proxy
1542N/A remove_cherrypy()
1968N/A sys.exit(1)
1968N/A if not os.path.exists(CPDIR):
812N/A print "unpacking CherryPy"
1968N/A tar = tarfile.open(CPARC)
589N/A # extractall doesn't exist until python 2.5
1968N/A for m in tar.getmembers():
858N/A tar.extract(m)
858N/A tar.close()
1968N/A cherrypy_dir = os.path.join(root_dir, py_install_dir, "cherrypy")
858N/A if not os.path.exists(cherrypy_dir):
858N/A print "installing CherryPy"
858N/A subprocess.Popen(['python', 'setup.py', 'install',
858N/A '--install-lib=%s' % os.path.join(root_dir, py_install_dir),
858N/A '--install-data=%s' % os.path.join(root_dir, py_install_dir)],
858N/A cwd = CPDIR).wait()
858N/A
1968N/Adef remove_cherrypy():
1431N/A if os.path.exists(CPARC):
1431N/A os.unlink(CPARC)
1431N/A shutil.rmtree(CPDIR, True)
1431N/A
1431N/Aclass build_func(_build):
1431N/A def initialize_options(self):
1431N/A _build.initialize_options(self)
1431N/A self.build_base = build_dir
1431N/A
1431N/Adef get_hg_version():
1431N/A try:
1431N/A p = subprocess.Popen(['hg', 'id', '-i'], stdout = subprocess.PIPE)
1431N/A return p.communicate()[0].strip()
1431N/A except OSError:
1431N/A print >> sys.stderr, "ERROR: unable to obtain mercurial version"
1431N/A return "unknown"
1431N/A
1431N/Aclass build_py_func(_build_py):
1968N/A # override the build_module method to do VERSION substitution on pkg/__init__.py
1542N/A def build_module (self, module, module_file, package):
1542N/A if module == "__init__" and package == "pkg":
1968N/A mcontent = file(module_file).read()
1968N/A v = 'VERSION = "%s"' % get_hg_version()
1968N/A mcontent = re.sub('(?m)^VERSION[^"]*"([^"]*)"', v, mcontent)
1968N/A tmpfd, tmp_file = tempfile.mkstemp()
1968N/A os.write(tmpfd, mcontent)
1633N/A os.close(tmpfd)
1633N/A print "doing version substitution: ", v
589N/A rv = _build_py.build_module(self, module, tmp_file, package)
1968N/A os.unlink(tmp_file)
1902N/A return rv
1968N/A return _build_py.build_module(self, module, module_file, package)
1968N/A
1968N/Aclass clean_func(_clean):
1191N/A def initialize_options(self):
1191N/A _clean.initialize_options(self)
1191N/A self.build_base = build_dir
1191N/A
1191N/Aclass clobber_func(Command):
1191N/A user_options = []
1191N/A description = "Deletes any and all files created by setup"
1191N/A
1191N/A def initialize_options(self):
1191N/A pass
1191N/A def finalize_options(self):
1191N/A pass
1191N/A def run(self):
589N/A # nuke everything
589N/A print("deleting " + dist_dir)
589N/A shutil.rmtree(dist_dir, True)
589N/A print("deleting " + build_dir)
589N/A shutil.rmtree(build_dir, True)
589N/A print("deleting " + root_dir)
589N/A shutil.rmtree(root_dir, True)
765N/A print("deleting cherrypy")
765N/A remove_cherrypy()
765N/A
765N/Aclass test_func(Command):
765N/A user_options = []
765N/A description = "Runs unit and functional tests"
765N/A
589N/A def initialize_options(self):
765N/A pass
765N/A def finalize_options(self):
765N/A pass
765N/A def run(self):
765N/A os.putenv('PYEXE', sys.executable)
765N/A os.chdir(os.path.join(pwd, "tests"))
765N/A testlogfd, testlogpath = tempfile.mkstemp(suffix = '.pkg-test.log')
1968N/A testlogfp = os.fdopen(testlogfd, "w")
1968N/A print "logging to %s" % testlogpath
1968N/A
135N/A subprocess.call([sys.executable, "api-complete.py"],
1968N/A stdout = testlogfp)
157N/A
382N/A if ostype == 'posix':
429N/A subprocess.call([sys.executable, "cli-complete.py"],
429N/A stdout = testlogfp)
2028N/A if osname == 'sunos':
2028N/A subprocess.call(["/bin/ksh", "memleaks.ksh"],
429N/A stdout = testlogfp)
429N/A testlogfp.close()
429N/A
429N/Aclass dist_func(_bdist):
429N/A def initialize_options(self):
429N/A _bdist.initialize_options(self)
429N/A self.dist_dir = dist_dir
2028N/A
1968N/A
1968N/A# These are set to real values based on the platform, down below
1968N/Aext_modules = None
1968N/Acompile_args = None
1968N/Alink_args = None
1968N/Aelf_libraries = None
1968N/Adata_files = [ (resource_dir, web_files) ]
1968N/Acmdclasses = {
1968N/A 'install': install_func,
1968N/A 'build': build_func,
812N/A 'build_py': build_py_func,
1968N/A 'bdist': dist_func,
1968N/A 'lint': lint_func,
1968N/A 'clean': clean_func,
1968N/A 'clobber': clobber_func,
1968N/A 'test': test_func,
812N/A }
812N/A
812N/A# all builds of IPS should have manpages
1968N/Adata_files += [
812N/A (man1_dir, man1_files),
812N/A (man1m_dir, man1m_files),
1968N/A (man5_dir, man5_files),
812N/A ]
812N/A
1968N/Aif osname == 'sunos':
812N/A # Solaris-specific extensions are added here
1968N/A data_files += [
1968N/A (zones_dir, zones_files),
1968N/A (brand_dir, brand_files),
1968N/A (smf_dir, smf_files),
1968N/A ]
812N/A
812N/Aif osname == 'sunos' or osname == "linux":
812N/A # Unix platforms which the elf extension has been ported to
1968N/A # are specified here, so they are built automatically
812N/A elf_libraries = ['elf']
812N/A ext_modules = [
1968N/A Extension(
812N/A 'elf',
812N/A elf_srcs,
1968N/A include_dirs = include_dirs,
812N/A libraries = elf_libraries,
1968N/A extra_compile_args = compile_args,
1968N/A extra_link_args = link_args
812N/A ),
1968N/A ]
812N/A
812N/A # Solaris has built-in md library and Solaris-specific arch extension
1968N/A # All others use OpenSSL and cross-platform arch module
1968N/A if osname == 'sunos':
812N/A elf_libraries += [ 'md' ]
1968N/A ext_modules += [
812N/A Extension(
812N/A 'arch',
873N/A arch_srcs,
873N/A include_dirs = include_dirs,
873N/A extra_compile_args = compile_args,
873N/A extra_link_args = link_args,
873N/A define_macros = [('_FILE_OFFSET_BITS', '64')]
873N/A ),
873N/A ]
812N/A else:
1968N/A elf_libraries += [ 'ssl' ]
812N/A
812N/Asetup(cmdclass = cmdclasses,
812N/A name = 'ips',
812N/A version = '1.0',
812N/A package_dir = {'pkg':'modules'},
1968N/A packages = packages,
1475N/A data_files = data_files,
1968N/A ext_package = 'pkg',
975N/A ext_modules = ext_modules,
1968N/A )
1968N/A