setup.py revision 2523
1516N/A#!/usr/bin/python2.6
290N/A#
290N/A# CDDL HEADER START
290N/A#
290N/A# The contents of this file are subject to the terms of the
290N/A# Common Development and Distribution License (the "License").
290N/A# You may not use this file except in compliance with the License.
290N/A#
290N/A# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
290N/A# or http://www.opensolaris.org/os/licensing.
290N/A# See the License for the specific language governing permissions
290N/A# and limitations under the License.
290N/A#
290N/A# When distributing Covered Code, include this CDDL HEADER in each
290N/A# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
290N/A# If applicable, add the following below this CDDL HEADER, with the
290N/A# fields enclosed by brackets "[]" replaced with your own identifying
290N/A# information: Portions Copyright [yyyy] [name of copyright owner]
290N/A#
290N/A# CDDL HEADER END
290N/A#
3026N/A# Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
395N/A#
290N/A
3143N/Aimport errno
883N/Aimport fnmatch
454N/Aimport os
290N/Aimport platform
448N/Aimport stat
290N/Aimport sys
290N/Aimport shutil
290N/Aimport re
383N/Aimport subprocess
290N/Aimport tarfile
395N/Aimport tempfile
290N/Aimport urllib
395N/Aimport py_compile
849N/Aimport hashlib
1516N/Aimport time
2508N/A
2826N/Afrom distutils.errors import DistutilsError
290N/Afrom distutils.core import setup, Extension
2535N/Afrom distutils.cmd import Command
2698N/Afrom distutils.command.install import install as _install
290N/Afrom distutils.command.build import build as _build
290N/Afrom distutils.command.build_ext import build_ext as _build_ext
2535N/Afrom distutils.command.build_py import build_py as _build_py
2561N/Afrom distutils.command.bdist import bdist as _bdist
290N/Afrom distutils.command.clean import clean as _clean
2508N/Afrom distutils.dist import Distribution
383N/A
290N/Afrom distutils.sysconfig import get_python_inc
290N/Aimport distutils.file_util as file_util
2339N/Aimport distutils.dir_util as dir_util
2535N/Aimport distutils.util as util
290N/Aimport distutils.ccompiler
290N/Afrom distutils.unixccompiler import UnixCCompiler
2535N/A
2535N/Aosname = platform.uname()[0].lower()
290N/Aostype = arch = 'unknown'
290N/Aif osname == 'sunos':
2508N/A arch = platform.processor()
2508N/A ostype = "posix"
290N/Aelif osname == 'linux':
1660N/A arch = "linux_" + platform.machine()
1660N/A ostype = "posix"
1660N/Aelif osname == 'windows':
1660N/A arch = osname
1660N/A ostype = "windows"
1660N/Aelif osname == 'darwin':
1660N/A arch = osname
1660N/A ostype = "posix"
1660N/Aelif osname == 'aix':
1660N/A arch = "aix"
1660N/A ostype = "posix"
1660N/A
1660N/Apwd = os.path.normpath(sys.path[0])
1660N/A
1660N/A#
1660N/A# Unbuffer stdout and stderr. This helps to ensure that subprocess output
1660N/A# is properly interleaved with output from this program.
1660N/A#
448N/Asys.stdout = os.fdopen(sys.stdout.fileno(), "w", 0)
448N/Asys.stderr = os.fdopen(sys.stderr.fileno(), "w", 0)
2828N/A
2828N/Adist_dir = os.path.normpath(os.path.join(pwd, os.pardir, "proto", "dist_" + arch))
2828N/Abuild_dir = os.path.normpath(os.path.join(pwd, os.pardir, "proto", "build_" + arch))
534N/Aif "ROOT" in os.environ and os.environ["ROOT"] != "":
534N/A root_dir = os.environ["ROOT"]
534N/Aelse:
534N/A root_dir = os.path.normpath(os.path.join(pwd, os.pardir, "proto", "root_" + arch))
534N/Apkgs_dir = os.path.normpath(os.path.join(pwd, os.pardir, "packages", arch))
534N/Aextern_dir = os.path.normpath(os.path.join(pwd, "extern"))
534N/A
290N/Apy_install_dir = 'usr/lib/python2.6/vendor-packages'
290N/A
954N/Ascripts_dir = 'usr/bin'
954N/Alib_dir = 'usr/lib'
954N/Asvc_method_dir = 'lib/svc/method'
954N/A
534N/Aman1_dir = 'usr/share/man/man1'
1099N/Aman1m_dir = 'usr/share/man/man1m'
290N/Aman5_dir = 'usr/share/man/man5'
3117N/Aman1_ja_JP_dir = 'usr/share/man/ja_JP.UTF-8/man1'
3117N/Aman1m_ja_JP_dir = 'usr/share/man/ja_JP.UTF-8/man1m'
3117N/Aman5_ja_JP_dir = 'usr/share/man/ja_JP.UTF-8/man5'
3117N/Aman1_zh_CN_dir = 'usr/share/man/zh_CN.UTF-8/man1'
290N/Aman1m_zh_CN_dir = 'usr/share/man/zh_CN.UTF-8/man1m'
290N/Aman5_zh_CN_dir = 'usr/share/man/zh_CN.UTF-8/man5'
290N/A
661N/Aresource_dir = 'usr/share/lib/pkg'
2867N/Atransform_dir = 'usr/share/pkg/transforms'
290N/Asmf_app_dir = 'lib/svc/manifest/application/pkg'
2494N/Aexecattrd_dir = 'etc/security/exec_attr.d'
2494N/Aauthattrd_dir = 'etc/security/auth_attr.d'
2494N/Asysrepo_dir = 'etc/pkg/sysrepo'
2516N/Asysrepo_logs_dir = 'var/log/pkg/sysrepo'
2516N/Asysrepo_cache_dir = 'var/cache/pkg/sysrepo'
2516N/A
2516N/A
2516N/A# A list of source, destination tuples of modules which should be hardlinked
2516N/A# together if the os supports it and otherwise copied.
2516N/Ahardlink_modules = []
290N/A
2523N/Ascripts_sunos = {
3138N/A scripts_dir: [
2390N/A ['client.py', 'pkg'],
1498N/A ['pkgdep.py', 'pkgdepend'],
1498N/A ['pkgrepo.py', 'pkgrepo'],
2867N/A ['util/publish/pkgdiff.py', 'pkgdiff'],
2310N/A ['util/publish/pkgfmt.py', 'pkgfmt'],
2310N/A ['util/publish/pkglint.py', 'pkglint'],
2310N/A ['util/publish/pkgmerge.py', 'pkgmerge'],
2852N/A ['util/publish/pkgmogrify.py', 'pkgmogrify'],
2852N/A ['publish.py', 'pkgsend'],
2852N/A ['pull.py', 'pkgrecv'],
2852N/A ['sign.py', 'pkgsign'],
2535N/A ['packagemanager.py', 'packagemanager'],
2867N/A ['updatemanager.py', 'pm-updatemanager'],
2867N/A ],
2310N/A lib_dir: [
290N/A ['depot.py', 'pkg.depotd'],
1674N/A ['checkforupdates.py', 'pm-checkforupdates'],
1674N/A ['updatemanagernotifier.py', 'updatemanagernotifier'],
2262N/A ['launch.py', 'pm-launch'],
1674N/A ['sysrepo.py', 'pkg.sysrepo'],
395N/A ],
430N/A svc_method_dir: [
395N/A ['svc/svc-pkg-depot', 'svc-pkg-depot'],
1544N/A ['svc/svc-pkg-mdns', 'svc-pkg-mdns'],
1968N/A ['svc/svc-pkg-sysrepo', 'svc-pkg-sysrepo'],
1557N/A ],
1903N/A }
2046N/A
2240N/Ascripts_windows = {
1506N/A scripts_dir: [
2928N/A ['client.py', 'client.py'],
395N/A ['pkgrepo.py', 'pkgrepo.py'],
395N/A ['publish.py', 'publish.py'],
2026N/A ['pull.py', 'pull.py'],
395N/A ['scripts/pkg.bat', 'pkg.bat'],
395N/A ['scripts/pkgsend.bat', 'pkgsend.bat'],
395N/A ['scripts/pkgrecv.bat', 'pkgrecv.bat'],
2310N/A ],
2852N/A lib_dir: [
395N/A ['depot.py', 'depot.py'],
661N/A ['scripts/pkg.depotd.bat', 'pkg.depotd.bat'],
2867N/A ],
2867N/A }
2867N/A
2867N/Ascripts_other_unix = {
2867N/A scripts_dir: [
2852N/A ['client.py', 'client.py'],
2310N/A ['pkgdep.py', 'pkgdep'],
2867N/A ['util/publish/pkgdiff.py', 'pkgdiff'],
2867N/A ['util/publish/pkgfmt.py', 'pkgfmt'],
2867N/A ['util/publish/pkgmogrify.py', 'pkgmogrify'],
661N/A ['pull.py', 'pull.py'],
395N/A ['publish.py', 'publish.py'],
849N/A ['scripts/pkg.sh', 'pkg'],
290N/A ['scripts/pkgsend.sh', 'pkgsend'],
395N/A ['scripts/pkgrecv.sh', 'pkgrecv'],
395N/A ],
1968N/A lib_dir: [
395N/A ['depot.py', 'depot.py'],
395N/A ['scripts/pkg.depotd.sh', 'pkg.depotd'],
395N/A ],
395N/A }
395N/A
395N/A# indexed by 'osname'
395N/Ascripts = {
395N/A "sunos": scripts_sunos,
395N/A "linux": scripts_other_unix,
395N/A "windows": scripts_windows,
395N/A "darwin": scripts_other_unix,
290N/A "aix" : scripts_other_unix,
290N/A "unknown": scripts_sunos,
395N/A }
395N/A
1231N/Aman1_files = [
1557N/A 'man/packagemanager.1',
1903N/A 'man/pkg.1',
1557N/A 'man/pkgdepend.1',
395N/A 'man/pkgdiff.1',
395N/A 'man/pkgfmt.1',
395N/A 'man/pkglint.1',
395N/A 'man/pkgmerge.1',
395N/A 'man/pkgmogrify.1',
395N/A 'man/pkgsend.1',
395N/A 'man/pkgsign.1',
395N/A 'man/pkgrecv.1',
395N/A 'man/pkgrepo.1',
395N/A 'man/pm-updatemanager.1',
395N/A ]
290N/Aman1m_files = [
290N/A 'man/pkg.depotd.1m',
430N/A 'man/pkg.sysrepo.1m'
395N/A ]
395N/Aman5_files = [
395N/A 'man/pkg.5'
395N/A ]
1302N/A
395N/Aman1_ja_files = [
395N/A 'man/ja_JP/packagemanager.1',
290N/A 'man/ja_JP/pkg.1',
3139N/A 'man/ja_JP/pkgdepend.1',
3139N/A 'man/ja_JP/pkgdiff.1',
395N/A 'man/ja_JP/pkgfmt.1',
3139N/A 'man/ja_JP/pkglint.1',
3139N/A 'man/ja_JP/pkgmerge.1',
3139N/A 'man/ja_JP/pkgmogrify.1',
3139N/A 'man/ja_JP/pkgsend.1',
3139N/A 'man/ja_JP/pkgsign.1',
3139N/A 'man/ja_JP/pkgrecv.1',
3139N/A 'man/ja_JP/pkgrepo.1',
3139N/A 'man/ja_JP/pm-updatemanager.1',
3139N/A ]
3139N/Aman1m_ja_files = [
3139N/A 'man/ja_JP/pkg.depotd.1m',
3139N/A 'man/ja_JP/pkg.sysrepo.1m'
3139N/A ]
3139N/Aman5_ja_files = [
3139N/A 'man/ja_JP/pkg.5'
3139N/A ]
395N/A
3139N/Aman1_zh_CN_files = [
3139N/A 'man/zh_CN/packagemanager.1',
3139N/A 'man/zh_CN/pkg.1',
3139N/A 'man/zh_CN/pkgdepend.1',
3139N/A 'man/zh_CN/pkgdiff.1',
3139N/A 'man/zh_CN/pkgfmt.1',
3139N/A 'man/zh_CN/pkglint.1',
395N/A 'man/zh_CN/pkgmerge.1',
3139N/A 'man/zh_CN/pkgmogrify.1',
3139N/A 'man/zh_CN/pkgsend.1',
3139N/A 'man/zh_CN/pkgsign.1',
3139N/A 'man/zh_CN/pkgrecv.1',
3139N/A 'man/zh_CN/pkgrepo.1',
2516N/A 'man/zh_CN/pm-updatemanager.1',
2516N/A ]
3139N/Aman1m_zh_CN_files = [
3139N/A 'man/zh_CN/pkg.depotd.1m',
3139N/A 'man/zh_CN/pkg.sysrepo.1m'
3139N/A ]
3139N/Aman5_zh_CN_files = [
3139N/A 'man/zh_CN/pkg.5'
3139N/A ]
3139N/A
3139N/Apackages = [
3139N/A 'pkg',
3139N/A 'pkg.actions',
3139N/A 'pkg.bundle',
3139N/A 'pkg.client',
3139N/A 'pkg.client.linkedimage',
3139N/A 'pkg.client.transport',
2516N/A 'pkg.file_layout',
3139N/A 'pkg.flavor',
3139N/A 'pkg.lint',
3139N/A 'pkg.portable',
3139N/A 'pkg.publish',
3139N/A 'pkg.server'
3139N/A ]
2516N/A
3139N/Apylint_targets = [
3139N/A 'pkg.altroot',
3139N/A 'pkg.client.linkedimage',
3139N/A 'pkg.client.pkgdefs',
3139N/A ]
2516N/A
2516N/Aweb_files = []
3139N/Afor entry in os.walk("web"):
3139N/A web_dir, dirs, files = entry
3139N/A if not files:
3139N/A continue
3139N/A web_files.append((os.path.join(resource_dir, web_dir), [
3139N/A os.path.join(web_dir, f) for f in files
3139N/A if f != "Makefile"
3139N/A ]))
3139N/A
3139N/Asmf_app_files = [
3139N/A 'svc/pkg-mdns.xml',
3139N/A 'svc/pkg-server.xml',
3139N/A 'svc/pkg-update.xml',
3139N/A 'svc/pkg-system-repository.xml',
3139N/A 'svc/zoneproxy-client.xml',
2516N/A 'svc/zoneproxyd.xml'
3139N/A ]
3139N/Aresource_files = [
3139N/A 'util/opensolaris.org.sections',
3139N/A 'util/pkglintrc',
3139N/A ]
3139N/Atransform_files = [
2516N/A 'util/publish/transforms/developer',
3139N/A 'util/publish/transforms/documentation',
3139N/A 'util/publish/transforms/locale',
3139N/A 'util/publish/transforms/smf-manifests'
3139N/A ]
3139N/Asysrepo_files = [
2516N/A 'util/apache2/sysrepo/sysrepo_httpd.conf.mako',
395N/A 'util/apache2/sysrepo/sysrepo_publisher_response.mako',
395N/A ]
395N/Asysrepo_log_stubs = [
395N/A 'util/apache2/sysrepo/logs/access_log',
395N/A 'util/apache2/sysrepo/logs/error_log',
2339N/A ]
1191N/Aexecattrd_files = [
1452N/A 'util/misc/exec_attr.d/package:pkg',
1231N/A 'util/misc/exec_attr.d/package:pkg:package-manager'
2046N/A]
395N/Aauthattrd_files = ['util/misc/auth_attr.d/package:pkg']
395N/Asyscallat_srcs = [
424N/A 'modules/syscallat.c'
395N/A ]
742N/Apspawn_srcs = [
2339N/A 'modules/pspawn.c'
2339N/A ]
2693N/Aelf_srcs = [
2690N/A 'modules/elf.c',
2339N/A 'modules/elfextract.c',
3094N/A 'modules/liblist.c',
2339N/A ]
2690N/Aarch_srcs = [
2690N/A 'modules/arch.c'
2693N/A ]
2693N/A_actions_srcs = [
2690N/A 'modules/actions/_actions.c'
2690N/A ]
2339N/Asolver_srcs = [
2339N/A 'modules/solver/solver.c',
742N/A 'modules/solver/py_solver.c'
742N/A ]
742N/Asolver_link_args = ["-lm", "-lc"]
742N/Aif osname == 'sunos':
742N/A solver_link_args = ["-ztext"] + solver_link_args
742N/A
742N/A# Runs lint on the extension module source code
742N/Aclass pylint_func(Command):
742N/A description = "Runs pylint tools over IPS python source code"
3136N/A user_options = []
2688N/A
2688N/A def initialize_options(self):
2688N/A pass
2688N/A
2688N/A def finalize_options(self):
2688N/A pass
2688N/A
2688N/A # Make string shell-friendly
2688N/A @staticmethod
742N/A def escape(astring):
2310N/A return astring.replace(' ', '\\ ')
2852N/A
1902N/A def run(self, quiet=False):
2867N/A proto = os.path.join(root_dir, py_install_dir)
2867N/A sys.path.insert(0, proto)
1099N/A
2867N/A # Insert tests directory onto sys.path so any custom checkers
2338N/A # can be found.
2338N/A sys.path.insert(0, os.path.join(pwd, 'tests'))
2310N/A # assumes pylint is accessible on the sys.path
2046N/A from pylint import lint
2223N/A
2046N/A #
2046N/A # For some reason, the load-plugins option, when used in the
2523N/A # rcfile, does not work, so we put it here instead, to load
2523N/A # our custom checkers.
2523N/A #
2523N/A # Unfortunately, pylint seems pretty fragile and will crash if
2523N/A # we try to run it over all the current pkg source. Hence for
2523N/A # now we only run it over a subset of the source. As source
2310N/A # files are made pylint clean they should be added to the
2677N/A # pylint_targets list.
2310N/A #
2310N/A args = ['--load-plugins=multiplatform']
2310N/A if quiet:
2310N/A args += ['--reports=no']
2310N/A args += ['--rcfile', os.path.join(pwd, 'tests', 'pylintrc')]
2310N/A args += pylint_targets
2858N/A lint.Run(args)
2310N/A
2852N/A
2852N/Aclass pylint_func_quiet(pylint_func):
2852N/A
2852N/A def run(self, quiet=False):
3136N/A pylint_func.run(self, quiet=True)
2852N/A
2852N/A
2852N/Ainclude_dirs = [ 'modules' ]
2852N/Alint_flags = [ '-u', '-axms', '-erroff=E_NAME_DEF_NOT_USED2' ]
2858N/A
2852N/A# Runs lint on the extension module source code
3138N/Aclass clint_func(Command):
3138N/A description = "Runs lint tools over IPS C extension source code"
2852N/A user_options = []
2852N/A
2852N/A def initialize_options(self):
2508N/A pass
2508N/A
2508N/A def finalize_options(self):
2508N/A pass
2867N/A
2535N/A # Make string shell-friendly
2535N/A @staticmethod
2535N/A def escape(astring):
3053N/A return astring.replace(' ', '\\ ')
3053N/A
3053N/A def run(self):
3026N/A # assumes lint is on the $PATH
3026N/A if osname == 'sunos' or osname == "linux":
3026N/A archcmd = ['lint'] + lint_flags + ['-D_FILE_OFFSET_BITS=64'] + \
2339N/A ["%s%s" % ("-I", k) for k in include_dirs] + \
2339N/A ['-I' + self.escape(get_python_inc())] + \
2339N/A arch_srcs
691N/A elfcmd = ['lint'] + lint_flags + \
691N/A ["%s%s" % ("-I", k) for k in include_dirs] + \
691N/A ['-I' + self.escape(get_python_inc())] + \
395N/A ["%s%s" % ("-l", k) for k in elf_libraries] + \
395N/A elf_srcs
395N/A _actionscmd = ['lint'] + lint_flags + \
395N/A ["%s%s" % ("-I", k) for k in include_dirs] + \
395N/A ['-I' + self.escape(get_python_inc())] + \
290N/A _actions_srcs
395N/A pspawncmd = ['lint'] + lint_flags + ['-D_FILE_OFFSET_BITS=64'] + \
395N/A ["%s%s" % ("-I", k) for k in include_dirs] + \
591N/A ['-I' + self.escape(get_python_inc())] + \
591N/A pspawn_srcs
591N/A syscallatcmd = ['lint'] + lint_flags + ['-D_FILE_OFFSET_BITS=64'] + \
2639N/A ["%s%s" % ("-I", k) for k in include_dirs] + \
2639N/A ['-I' + self.escape(get_python_inc())] + \
2639N/A syscallat_srcs
2639N/A
2639N/A print(" ".join(archcmd))
2639N/A os.system(" ".join(archcmd))
1505N/A print(" ".join(elfcmd))
2516N/A os.system(" ".join(elfcmd))
1505N/A print(" ".join(_actionscmd))
1505N/A os.system(" ".join(_actionscmd))
1632N/A print(" ".join(pspawncmd))
1632N/A os.system(" ".join(pspawncmd))
1632N/A print(" ".join(syscallatcmd))
1632N/A os.system(" ".join(syscallatcmd))
2339N/A
2339N/A
2339N/A# Runs both C and Python lint
2339N/Aclass lint_func(Command):
2339N/A description = "Runs C and Python lint checkers"
2339N/A user_options = []
2339N/A
2339N/A def initialize_options(self):
2339N/A pass
2339N/A
2339N/A def finalize_options(self):
2339N/A pass
2339N/A
2339N/A # Make string shell-friendly
2339N/A @staticmethod
2339N/A def escape(astring):
2364N/A return astring.replace(' ', '\\ ')
2828N/A
2828N/A def run(self):
2828N/A clint_func(Distribution()).run()
2828N/A pylint_func(Distribution()).run()
2828N/A
2828N/Aclass install_func(_install):
2828N/A def initialize_options(self):
2828N/A _install.initialize_options(self)
2828N/A
2828N/A # PRIVATE_BUILD set in the environment tells us to put the build
2828N/A # directory into the .pyc files, rather than the final
2828N/A # installation directory.
2828N/A private_build = os.getenv("PRIVATE_BUILD", None)
2828N/A
2828N/A if private_build is None:
2828N/A self.install_lib = py_install_dir
2828N/A self.install_data = os.path.sep
2828N/A self.root = root_dir
2828N/A else:
2828N/A self.install_lib = os.path.join(root_dir, py_install_dir)
2828N/A self.install_data = root_dir
2828N/A
2828N/A # This is used when installing scripts, below, but it isn't a
2828N/A # standard distutils variable.
2828N/A self.root_dir = root_dir
2828N/A
2828N/A def run(self):
2828N/A """
2892N/A At the end of the install function, we need to rename some files
2892N/A because distutils provides no way to rename files as they are
2828N/A placed in their install locations.
2828N/A Also, make sure that cherrypy and other external dependencies
2828N/A are installed.
2828N/A """
2828N/A
2828N/A _install.run(self)
2828N/A
2828N/A for o_src, o_dest in hardlink_modules:
2828N/A for e in [".py", ".pyc"]:
2828N/A src = util.change_root(self.root_dir, o_src + e)
2828N/A dest = util.change_root(
2828N/A self.root_dir, o_dest + e)
2339N/A if ostype == "posix":
2339N/A if os.path.exists(dest) and \
2339N/A os.stat(src)[stat.ST_INO] != \
2339N/A os.stat(dest)[stat.ST_INO]:
2339N/A os.remove(dest)
2339N/A file_util.copy_file(src, dest,
2339N/A link="hard", update=1)
2339N/A else:
2339N/A file_util.copy_file(src, dest, update=1)
2339N/A
2339N/A for d, files in scripts[osname].iteritems():
2339N/A for (srcname, dstname) in files:
2339N/A dst_dir = util.change_root(self.root_dir, d)
2339N/A dst_path = util.change_root(self.root_dir,
2339N/A os.path.join(d, dstname))
2339N/A dir_util.mkpath(dst_dir, verbose = True)
2339N/A file_util.copy_file(srcname, dst_path, update = True)
2339N/A # make scripts executable
2339N/A os.chmod(dst_path,
2339N/A os.stat(dst_path).st_mode
2364N/A | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
2364N/A
2364N/Adef hash_sw(swname, swarc, swhash):
2364N/A if swhash == None:
2364N/A return True
2364N/A
2364N/A print "checksumming %s" % swname
2364N/A hash = hashlib.sha1()
2364N/A f = open(swarc, "rb")
2364N/A while True:
2364N/A data = f.read(65536)
2364N/A if data == "":
2364N/A break
2339N/A hash.update(data)
395N/A f.close()
395N/A
290N/A if hash.hexdigest() == swhash:
290N/A return True
2339N/A else:
2339N/A print >> sys.stderr, "bad checksum! %s != %s" % \
290N/A (swhash, hash.hexdigest())
290N/A return False
290N/A
290N/Adef prep_sw(swname, swarc, swdir, swurl, swhash):
290N/A swarc = os.path.join(extern_dir, swarc)
290N/A swdir = os.path.join(extern_dir, swdir)
290N/A if not os.path.exists(extern_dir):
290N/A os.mkdir(extern_dir)
290N/A
290N/A if not os.path.exists(swarc):
395N/A print "downloading %s" % swname
395N/A try:
290N/A fname, hdr = urllib.urlretrieve(swurl, swarc)
290N/A except IOError:
2674N/A pass
2674N/A if not os.path.exists(swarc):
2674N/A print >> sys.stderr, "Unable to retrieve %s.\n" \
2674N/A "Please retrieve the file " \
290N/A "and place it at: %s\n" % (swurl, swarc)
2674N/A # remove a partial download or error message from proxy
2674N/A remove_sw(swname)
395N/A sys.exit(1)
395N/A if not os.path.exists(swdir):
395N/A if not hash_sw(swname, swarc, swhash):
2674N/A sys.exit(1)
395N/A
395N/A print "unpacking %s" % swname
395N/A tar = tarfile.open(swarc)
395N/A # extractall doesn't exist until python 2.5
2674N/A for m in tar.getmembers():
591N/A tar.extract(m, extern_dir)
591N/A tar.close()
591N/A
2674N/A # If there are patches, apply them now.
2639N/A patchdir = os.path.join("patch", swname)
2639N/A already_patched = os.path.join(swdir, ".patched")
2639N/A if os.path.exists(patchdir) and not os.path.exists(already_patched):
2674N/A patches = os.listdir(patchdir)
2639N/A for p in patches:
2639N/A patchpath = os.path.join(os.path.pardir,
2639N/A os.path.pardir, patchdir, p)
2674N/A print "Applying %s to %s" % (p, swname)
2674N/A args = ["patch", "-d", swdir, "-i", patchpath, "-p0"]
691N/A if osname == "windows":
691N/A args.append("--binary")
691N/A ret = subprocess.Popen(args).wait()
2674N/A if ret != 0:
2674N/A print >> sys.stderr, \
2339N/A "patch failed and returned %d." % ret
2339N/A print >> sys.stderr, \
2339N/A "Command was: %s" % " ".join(args)
3026N/A sys.exit(1)
3026N/A file(already_patched, "w").close()
3026N/A
3026N/Adef run_cmd(args, swdir, env=None):
3026N/A if env is None:
3026N/A env = os.environ
3053N/A ret = subprocess.Popen(args, cwd=swdir, env=env).wait()
3053N/A if ret != 0:
3053N/A print >> sys.stderr, \
3053N/A "install failed and returned %d." % ret
3053N/A print >> sys.stderr, \
3053N/A "Command was: %s" % " ".join(args)
290N/A sys.exit(1)
290N/A
290N/Adef remove_sw(swname):
290N/A print("deleting %s" % swname)
290N/A for file in os.listdir(extern_dir):
591N/A if fnmatch.fnmatch(file, "%s*" % swname):
591N/A fpath = os.path.join(extern_dir, file)
2639N/A if os.path.isfile(fpath):
2639N/A os.unlink(fpath)
2639N/A else:
2639N/A shutil.rmtree(fpath, True)
691N/A
691N/Aclass build_func(_build):
2339N/A def initialize_options(self):
2339N/A _build.initialize_options(self)
3026N/A self.build_base = build_dir
3026N/A
3053N/Adef get_hg_version():
3053N/A try:
290N/A p = subprocess.Popen(['hg', 'id', '-i'], stdout = subprocess.PIPE)
290N/A return p.communicate()[0].strip()
2339N/A except OSError:
2339N/A print >> sys.stderr, "ERROR: unable to obtain mercurial version"
2339N/A return "unknown"
2339N/A
2339N/Adef syntax_check(filename):
2339N/A """ Run python's compiler over the file, and discard the results.
2339N/A Arrange to generate an exception if the file does not compile.
290N/A This is needed because distutil's own use of pycompile (in the
2339N/A distutils.utils module) is broken, and doesn't stop on error. """
2339N/A try:
290N/A py_compile.compile(filename, os.devnull, doraise=True)
2339N/A except py_compile.PyCompileError, e:
2339N/A res = ""
2339N/A for err in e.exc_value:
2339N/A if isinstance(err, basestring):
2339N/A res += err + "\n"
2339N/A continue
2339N/A
2339N/A # Assume it's a tuple of (filename, lineno, col, code)
290N/A fname, line, col, code = err
395N/A res += "line %d, column %s, in %s:\n%s" % (line,
290N/A col or "unknown", fname, code)
395N/A
506N/A raise DistutilsError(res)
506N/A
506N/A# On Solaris, ld inserts the full argument to the -o option into the symbol
506N/A# table. This means that the resulting object will be different depending on
506N/A# the path at which the workspace lives, and not just on the interesting content
506N/A# of the object.
506N/A#
506N/A# In order to work around that bug (7076871), we create a new compiler class
834N/A# that looks at the argument indicating the output file, chdirs to its
506N/A# directory, and runs the real link with the output file set to just the base
506N/A# name of the file.
506N/A#
513N/A# Unfortunately, distutils isn't too customizable in this regard, so we have to
506N/A# twiddle with a couple of the names in the distutils.ccompiler namespace: we
506N/A# have to add a new entry to the compiler_class dict, and we have to override
506N/A# the new_compiler() function to point to our own. Luckily, our copy of
506N/A# new_compiler() gets to be very simple, since we always know what we want to
290N/A# return.
290N/Aclass MyUnixCCompiler(UnixCCompiler):
2535N/A
2535N/A def link(self, *args, **kwargs):
2535N/A
395N/A output_filename = args[2]
413N/A output_dir = kwargs.get('output_dir')
395N/A cwd = os.getcwd()
290N/A
1674N/A assert(not output_dir)
1674N/A output_dir = os.path.join(cwd, os.path.dirname(output_filename))
1674N/A output_filename = os.path.basename(output_filename)
1674N/A nargs = args[:2] + (output_filename,) + args[3:]
1674N/A os.chdir(output_dir)
1674N/A
1674N/A UnixCCompiler.link(self, *nargs, **kwargs)
1674N/A
1674N/A os.chdir(cwd)
1674N/A
1674N/Adistutils.ccompiler.compiler_class['myunix'] = (
1674N/A 'unixccompiler', 'MyUnixCCompiler',
1674N/A 'standard Unix-style compiler with a link stage modified for Solaris'
1674N/A)
1674N/A
3117N/Adef my_new_compiler(plat=None, compiler=None, verbose=0, dry_run=0, force=0):
3117N/A return MyUnixCCompiler(None, dry_run, force)
3117N/A
395N/Aif osname == 'sunos':
395N/A distutils.ccompiler.new_compiler = my_new_compiler
506N/A
506N/Aclass build_ext_func(_build_ext):
395N/A
2535N/A def initialize_options(self):
2535N/A _build_ext.initialize_options(self)
395N/A if osname == 'sunos':
430N/A self.compiler = 'myunix'
849N/A
834N/Aclass build_py_func(_build_py):
290N/A
2561N/A def __init__(self, dist):
2561N/A ret = _build_py.__init__(self, dist)
2561N/A
2561N/A # Gather the timestamps of the .py files in the gate, so we can
2561N/A # force the mtimes of the built and delivered copies to be
2561N/A # consistent across builds, causing their corresponding .pyc
2561N/A # files to be unchanged unless the .py file content changed.
2561N/A
2561N/A self.timestamps = {}
2561N/A
2561N/A p = subprocess.Popen(
2561N/A [sys.executable, os.path.join(pwd, "pydates")],
2561N/A stdout=subprocess.PIPE)
2561N/A
2561N/A for line in p.stdout:
2561N/A stamp, path = line.split()
2561N/A stamp = float(stamp)
2561N/A self.timestamps[path] = stamp
2561N/A
2561N/A if p.wait() != 0:
2535N/A print >> sys.stderr, "ERROR: unable to gather .py " \
2535N/A "timestamps"
2535N/A sys.exit(1)
2535N/A
2535N/A return ret
1099N/A
2535N/A # override the build_module method to do VERSION substitution on pkg/__init__.py
2535N/A def build_module (self, module, module_file, package):
2535N/A
2535N/A if module == "__init__" and package == "pkg":
2535N/A versionre = '(?m)^VERSION[^"]*"([^"]*)"'
2535N/A # Grab the previously-built version out of the build
2535N/A # tree.
2535N/A try:
2535N/A ocontent = \
2535N/A file(self.get_module_outfile(self.build_lib,
1099N/A [package], module)).read()
2535N/A ov = re.search(versionre, ocontent).group(1)
2535N/A except IOError:
2535N/A ov = None
2535N/A v = get_hg_version()
2535N/A vstr = 'VERSION = "%s"' % v
2535N/A # If the versions haven't changed, there's no need to
2535N/A # recompile.
2535N/A if v == ov:
2535N/A return
2535N/A
2535N/A mcontent = file(module_file).read()
2535N/A mcontent = re.sub(versionre, vstr, mcontent)
2535N/A tmpfd, tmp_file = tempfile.mkstemp()
2535N/A os.write(tmpfd, mcontent)
2535N/A os.close(tmpfd)
2535N/A print "doing version substitution: ", v
2535N/A rv = _build_py.build_module(self, module, tmp_file, package)
1099N/A os.unlink(tmp_file)
2826N/A return rv
2688N/A
2688N/A # Will raise a DistutilsError on failure.
2688N/A syntax_check(module_file)
2688N/A
2688N/A return _build_py.build_module(self, module, module_file, package)
2688N/A
1660N/A def copy_file(self, infile, outfile, preserve_mode=1, preserve_times=1,
2688N/A link=None, level=1):
2688N/A
2688N/A # If the timestamp on the source file (coming from mercurial if
2826N/A # unchanged, or from the filesystem if changed) doesn't match
2826N/A # the filesystem timestamp on the destination, then force the
2688N/A # copy to make sure the right data is in place.
2688N/A
2688N/A try:
2688N/A dst_mtime = os.stat(outfile).st_mtime
2688N/A except OSError, e:
849N/A if e.errno != errno.ENOENT:
2688N/A raise
2688N/A dst_mtime = time.time()
3143N/A
3143N/A # The timestamp for __init__.py is the timestamp for the
3143N/A # workspace itself.
3143N/A if outfile.endswith("/pkg/__init__.py"):
849N/A src_mtime = self.timestamps["."]
2688N/A else:
2688N/A src_mtime = self.timestamps[os.path.join("src", infile)]
290N/A
2535N/A if dst_mtime != src_mtime:
2535N/A f = self.force
2597N/A self.force = True
2597N/A dst, copied = _build_py.copy_file(self, infile, outfile,
2597N/A preserve_mode, preserve_times, link, level)
2535N/A self.force = f
2535N/A else:
2535N/A dst, copied = outfile, 0
2535N/A
2535N/A # If we copied the file, then we need to go and readjust the
2535N/A # timestamp on the file to match what we have in our database.
2535N/A if copied and dst.endswith(".py"):
2535N/A os.utime(dst, (src_mtime, src_mtime))
2535N/A
2535N/A return dst, copied
2535N/A
2535N/Aclass clean_func(_clean):
2535N/A def initialize_options(self):
2535N/A _clean.initialize_options(self)
2535N/A self.build_base = build_dir
2535N/A
2535N/Aclass clobber_func(Command):
2535N/A user_options = []
2535N/A description = "Deletes any and all files created by setup"
2597N/A
2597N/A def initialize_options(self):
2597N/A pass
2597N/A def finalize_options(self):
2597N/A pass
2597N/A def run(self):
2597N/A # nuke everything
2597N/A print("deleting " + dist_dir)
2597N/A shutil.rmtree(dist_dir, True)
2597N/A print("deleting " + build_dir)
2597N/A shutil.rmtree(build_dir, True)
2597N/A print("deleting " + root_dir)
2597N/A shutil.rmtree(root_dir, True)
2597N/A print("deleting " + pkgs_dir)
2597N/A shutil.rmtree(pkgs_dir, True)
2597N/A print("deleting " + extern_dir)
2535N/A shutil.rmtree(extern_dir, True)
2535N/A
2535N/Aclass test_func(Command):
2535N/A # NOTE: these options need to be in sync with tests/run.py and the
2535N/A # list of options stored in initialize_options below. The first entry
2688N/A # in each tuple must be the exact name of a member variable.
2688N/A user_options = [
2688N/A ("archivedir=", 'a', "archive failed tests <dir>"),
2688N/A ("baselinefile=", 'b', "baseline file <file>"),
2688N/A ("coverage", "c", "collect code coverage data"),
2688N/A ("genbaseline", 'g', "generate test baseline"),
2688N/A ("only=", "o", "only <regex>"),
2688N/A ("parseable", 'p', "parseable output"),
2688N/A ("port=", "z", "lowest port to start a depot on"),
2688N/A ("timing", "t", "timing file <file>"),
2688N/A ("verbosemode", 'v', "run tests in verbose mode"),
3143N/A ("enableguitests", 'u', "enable IPS GUI tests, disabled by default"),
2688N/A ("stoponerr", 'x', "stop when a baseline mismatch occurs"),
2688N/A ("debugoutput", 'd', "emit debugging output"),
2688N/A ("showonexpectedfail", 'f',
2688N/A "show all failure info, even for expected fails"),
3143N/A ("startattest=", 's', "start at indicated test"),
3143N/A ("jobs=", 'j', "number of parallel processes to use"),
2688N/A ("quiet", "q", "use the dots as the output format"),
3143N/A ]
2688N/A description = "Runs unit and functional tests"
3143N/A
3143N/A def initialize_options(self):
2688N/A self.only = ""
3143N/A self.baselinefile = ""
3143N/A self.verbosemode = 0
3136N/A self.parseable = 0
3136N/A self.genbaseline = 0
3143N/A self.timing = 0
2688N/A self.coverage = 0
2688N/A self.stoponerr = 0
2688N/A self.debugoutput = 0
3143N/A self.showonexpectedfail = 0
3143N/A self.startattest = ""
3143N/A self.archivedir = ""
2688N/A self.port = 12001
3143N/A self.jobs = 1
2688N/A self.quiet = False
3143N/A
3143N/A def finalize_options(self):
2688N/A pass
3143N/A
3143N/A def run(self):
2688N/A
2688N/A os.putenv('PYEXE', sys.executable)
2688N/A os.chdir(os.path.join(pwd, "tests"))
2688N/A
2688N/A # Reconstruct the cmdline and send that to run.py
2688N/A cmd = [sys.executable, "run.py"]
2688N/A args = ""
2688N/A if "test" in sys.argv:
2688N/A args = sys.argv[sys.argv.index("test")+1:]
2688N/A cmd.extend(args)
2688N/A subprocess.call(cmd)
3143N/A
2688N/Aclass dist_func(_bdist):
2688N/A def initialize_options(self):
2688N/A _bdist.initialize_options(self)
2688N/A self.dist_dir = dist_dir
2688N/A
3143N/A# These are set to real values based on the platform, down below
2688N/Acompile_args = None
2688N/Aif osname in ("sunos", "linux", "darwin"):
2535N/A compile_args = [ "-O3" ]
2535N/Aif osname == "sunos":
2535N/A link_args = [ "-zstrip-class=nonalloc" ]
2535N/Aelse:
2535N/A link_args = []
2535N/Aext_modules = [
2535N/A Extension(
2535N/A 'actions._actions',
3143N/A _actions_srcs,
2688N/A include_dirs = include_dirs,
2535N/A extra_compile_args = compile_args,
2826N/A extra_link_args = link_args
2826N/A ),
2826N/A Extension(
2826N/A 'solver',
2826N/A solver_srcs,
2826N/A include_dirs = include_dirs + ["."],
2826N/A extra_compile_args = compile_args,
2826N/A extra_link_args = link_args + solver_link_args,
2826N/A define_macros = [('_FILE_OFFSET_BITS', '64')]
2826N/A ),
2826N/A ]
2826N/Aelf_libraries = None
2826N/Adata_files = web_files
2826N/Acmdclasses = {
2826N/A 'install': install_func,
2826N/A 'build': build_func,
2826N/A 'build_ext': build_ext_func,
2826N/A 'build_py': build_py_func,
2826N/A 'bdist': dist_func,
2826N/A 'lint': lint_func,
2826N/A 'clint': clint_func,
2826N/A 'pylint': pylint_func,
2826N/A 'pylint_quiet': pylint_func_quiet,
2826N/A 'clean': clean_func,
2826N/A 'clobber': clobber_func,
2826N/A 'test': test_func,
2826N/A }
2826N/A
2826N/A# all builds of IPS should have manpages
2826N/Adata_files += [
2826N/A (man1_dir, man1_files),
2826N/A (man1m_dir, man1m_files),
2826N/A (man5_dir, man5_files),
2826N/A (man1_ja_JP_dir, man1_ja_files),
2826N/A (man1m_ja_JP_dir, man1m_ja_files),
2826N/A (man5_ja_JP_dir, man5_ja_files),
3143N/A (man1_zh_CN_dir, man1_zh_CN_files),
3143N/A (man1m_zh_CN_dir, man1m_zh_CN_files),
3143N/A (man5_zh_CN_dir, man5_zh_CN_files),
3143N/A (resource_dir, resource_files),
2826N/A ]
3143N/A# add transforms
2826N/Adata_files += [
2826N/A (transform_dir, transform_files)
2826N/A ]
2535N/Aif osname == 'sunos':
2535N/A # Solaris-specific extensions are added here
2535N/A data_files += [
2535N/A (smf_app_dir, smf_app_files),
2535N/A (execattrd_dir, execattrd_files),
3143N/A (authattrd_dir, authattrd_files),
2535N/A (sysrepo_dir, sysrepo_files),
2535N/A (sysrepo_logs_dir, sysrepo_log_stubs),
2688N/A (sysrepo_cache_dir, {})
2688N/A ]
2688N/A
2688N/Aif osname == 'sunos' or osname == "linux":
2688N/A # Unix platforms which the elf extension has been ported to
2688N/A # are specified here, so they are built automatically
2688N/A elf_libraries = ['elf']
2688N/A ext_modules += [
2688N/A Extension(
2688N/A 'elf',
2688N/A elf_srcs,
2688N/A include_dirs = include_dirs,
2688N/A libraries = elf_libraries,
2688N/A extra_compile_args = compile_args,
2688N/A extra_link_args = link_args
2688N/A ),
2688N/A ]
3143N/A
2688N/A # Solaris has built-in md library and Solaris-specific arch extension
2688N/A # All others use OpenSSL and cross-platform arch module
2688N/A if osname == 'sunos':
2688N/A elf_libraries += [ 'md' ]
2688N/A ext_modules += [
2688N/A Extension(
3143N/A 'arch',
3136N/A arch_srcs,
2688N/A include_dirs = include_dirs,
2688N/A extra_compile_args = compile_args,
2688N/A extra_link_args = link_args,
2688N/A define_macros = [('_FILE_OFFSET_BITS', '64')]
2688N/A ),
2688N/A Extension(
2688N/A 'pspawn',
2688N/A pspawn_srcs,
2688N/A include_dirs = include_dirs,
2688N/A extra_compile_args = compile_args,
2688N/A extra_link_args = link_args,
3143N/A define_macros = [('_FILE_OFFSET_BITS', '64')]
2688N/A ),
2688N/A Extension(
2688N/A 'syscallat',
2688N/A syscallat_srcs,
2688N/A include_dirs = include_dirs,
2688N/A extra_compile_args = compile_args,
2535N/A extra_link_args = link_args,
2535N/A define_macros = [('_FILE_OFFSET_BITS', '64')]
2535N/A ),
2535N/A ]
2535N/A else:
2535N/A elf_libraries += [ 'ssl' ]
2535N/A
2535N/Asetup(cmdclass = cmdclasses,
2535N/A name = 'pkg',
3143N/A version = '0.1',
2535N/A package_dir = {'pkg':'modules'},
2535N/A packages = packages,
2535N/A data_files = data_files,
2535N/A ext_package = 'pkg',
2535N/A ext_modules = ext_modules,
2535N/A )
2535N/A