summaryrefslogtreecommitdiff
path: root/setup.py
blob: fb6b59aa69d4dcc9e6bcafd1578ea4af540eab03 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
#!/usr/bin/env python
# -*- encoding: utf8 -*-
__revision__ = "$Id$"
import sys
import os
import re

from distutils2 import __version__ as VERSION
from distutils2 import log
from distutils2.core import setup, Extension
from distutils2.compiler.ccompiler import new_compiler
from distutils2.command.sdist import sdist
from distutils2.command.install import install
from distutils2.util import find_packages

f = open('README.txt')
try:
    README = f.read()
finally:
    f.close()

def get_tip_revision(path=os.getcwd()):
    from subprocess import Popen, PIPE
    try:
        cmd = Popen(['hg', 'tip', '--template', '{rev}', '-R', path],
                    stdout=PIPE, stderr=PIPE)
    except OSError:
        return 0
    rev = cmd.stdout.read()
    if rev == '':
        # there has been an error in the command
        return 0
    return int(rev)

DEV_SUFFIX = '.dev%d' % get_tip_revision('..')


class install_hg(install):

    user_options = install.user_options + [
            ('dev', None, "Add a dev marker")
            ]

    def initialize_options(self):
        install.initialize_options(self)
        self.dev = 0

    def run(self):
        if self.dev:
            self.distribution.metadata.version += DEV_SUFFIX
        install.run(self)


class sdist_hg(sdist):

    user_options = sdist.user_options + [
            ('dev', None, "Add a dev marker")
            ]

    def initialize_options(self):
        sdist.initialize_options(self)
        self.dev = 0

    def run(self):
        if self.dev:
            self.distribution.metadata.version += DEV_SUFFIX
        sdist.run(self)


# additional paths to check, set from the command line
SSL_INCDIR = ''   # --openssl-incdir=
SSL_LIBDIR = ''   # --openssl-libdir=
SSL_DIR = ''      # --openssl-prefix=

def add_dir_to_list(dirlist, dir):
    """Add the directory 'dir' to the list 'dirlist' (at the front) if
    'dir' actually exists and is a directory.  If 'dir' is already in
    'dirlist' it is moved to the front.
    """
    if dir is not None and os.path.isdir(dir) and dir not in dirlist:
        if dir in dirlist:
            dirlist.remove(dir)
        dirlist.insert(0, dir)


def prepare_hashlib_extensions():
    """Decide which C extensions to build and create the appropriate
    Extension objects to build them.  Return a list of Extensions.
    """
    # this CCompiler object is only used to locate include files
    compiler = new_compiler()

    # Ensure that these paths are always checked
    if os.name == 'posix':
        add_dir_to_list(compiler.library_dirs, '/usr/local/lib')
        add_dir_to_list(compiler.include_dirs, '/usr/local/include')

        add_dir_to_list(compiler.library_dirs, '/usr/local/ssl/lib')
        add_dir_to_list(compiler.include_dirs, '/usr/local/ssl/include')

        add_dir_to_list(compiler.library_dirs, '/usr/contrib/ssl/lib')
        add_dir_to_list(compiler.include_dirs, '/usr/contrib/ssl/include')

        add_dir_to_list(compiler.library_dirs, '/usr/lib')
        add_dir_to_list(compiler.include_dirs, '/usr/include')

    # look in paths supplied on the command line
    if SSL_LIBDIR:
        add_dir_to_list(compiler.library_dirs, SSL_LIBDIR)
    if SSL_INCDIR:
        add_dir_to_list(compiler.include_dirs, SSL_INCDIR)
    if SSL_DIR:
        if os.name == 'nt':
            add_dir_to_list(compiler.library_dirs, os.path.join(SSL_DIR, 'out32dll'))
            # prefer the static library
            add_dir_to_list(compiler.library_dirs, os.path.join(SSL_DIR, 'out32'))
        else:
            add_dir_to_list(compiler.library_dirs, os.path.join(SSL_DIR, 'lib'))
        add_dir_to_list(compiler.include_dirs, os.path.join(SSL_DIR, 'include'))

    oslibs = {'posix': ['ssl', 'crypto'],
              'nt': ['libeay32',  'gdi32', 'advapi32', 'user32']}

    if os.name not in oslibs:
        sys.stderr.write(
            'unknown operating system, impossible to compile _hashlib')
        sys.exit(1)

    exts = []

    ssl_inc_dirs = []
    ssl_incs = []
    for inc_dir in compiler.include_dirs:
        f = os.path.join(inc_dir, 'openssl', 'ssl.h')
        if os.path.exists(f):
            ssl_incs.append(f)
            ssl_inc_dirs.append(inc_dir)

    ssl_lib = compiler.find_library_file(compiler.library_dirs, oslibs[os.name][0])

    # find out which version of OpenSSL we have
    openssl_ver = 0
    openssl_ver_re = re.compile(
        '^\s*#\s*define\s+OPENSSL_VERSION_NUMBER\s+(0x[0-9a-fA-F]+)' )
    ssl_inc_dir = ''
    for ssl_inc_dir in ssl_inc_dirs:
        name = os.path.join(ssl_inc_dir, 'openssl', 'opensslv.h')
        if os.path.isfile(name):
            try:
                incfile = open(name, 'r')
                for line in incfile:
                    m = openssl_ver_re.match(line)
                    if m:
                        openssl_ver = int(m.group(1), 16)
                        break
            except IOError:
                pass

        # first version found is what we'll use
        if openssl_ver:
            break

    if (ssl_inc_dir and ssl_lib is not None and openssl_ver >= 0x00907000):

        log.info('Using OpenSSL version 0x%08x from', openssl_ver)
        log.info(' Headers:\t%s', ssl_inc_dir)
        log.info(' Library:\t%s', ssl_lib)

        # The _hashlib module wraps optimized implementations
        # of hash functions from the OpenSSL library.
        exts.append(Extension('distutils2._backport._hashlib',
                              ['distutils2/_backport/_hashopenssl.c'],
                              include_dirs = [ssl_inc_dir],
                              library_dirs = [os.path.dirname(ssl_lib)],
                              libraries = oslibs[os.name]))
    else:
        exts.append(Extension('distutils2._backport._sha',
                              ['distutils2/_backport/shamodule.c']))
        exts.append(Extension('distutils2._backport._md5',
                              sources=['distutils2/_backport/md5module.c',
                                       'distutils2/_backport/md5.c'],
                              depends=['distutils2/_backport/md5.h']) )

    if (not ssl_lib or openssl_ver < 0x00908000):
        # OpenSSL doesn't do these until 0.9.8 so we'll bring our own
        exts.append(Extension('distutils2._backport._sha256',
                              ['distutils2/_backport/sha256module.c']))
        exts.append(Extension('distutils2._backport._sha512',
                              ['distutils2/_backport/sha512module.c']))

    return exts

setup_kwargs = {}
if sys.version < '2.6':
    setup_kwargs['scripts'] = ['distutils2/mkpkg.py']

if sys.version < '2.5':
    setup_kwargs['ext_modules'] = prepare_hashlib_extensions()

_CLASSIFIERS = """\
Development Status :: 3 - Alpha
Intended Audience :: Developers
License :: OSI Approved :: Python Software Foundation License
Operating System :: OS Independent
Programming Language :: Python
Topic :: Software Development :: Libraries :: Python Modules
Topic :: System :: Archiving :: Packaging
Topic :: System :: Systems Administration
Topic :: Utilities"""

setup(name="Distutils2",
      version=VERSION,
      summary="Python Distribution Utilities",
      keywords=['packaging', 'distutils'],
      author="Tarek Ziade",
      author_email="tarek@ziade.org",
      home_page="http://bitbucket.org/tarek/distutils2/wiki/Home",
      license="PSF",
      description=README,
      classifier=_CLASSIFIERS.split('\n'),
      packages=find_packages(),
      cmdclass={'sdist_hg': sdist_hg, 'install_hg': install_hg},
      package_data={'distutils2._backport': ['sysconfig.cfg']},
      project_url=[('Mailing list',
                    'http://mail.python.org/mailman/listinfo/distutils-sig/'),
                   ('Documentation',
                    'http://packages.python.org/Distutils2'),
                   ('Repository', 'http://hg.python.org/distutils2'),
                   ('Bug tracker', 'http://bugs.python.org')],
      **setup_kwargs)