Python setuptools/distutils packaging #1455

Closed
wants to merge 7 commits into
from
View
6 .gitignore
@@ -52,3 +52,9 @@ demo/viewer/ui_about.h
demo/viewer/ui_info.h
demo/viewer/ui_layer_info.h
tests/cpp_tests/*-bin
+
+# Setuptools artifacts
+dist/
+build/
+*.egg-info
+*.egg
View
15 MANIFEST.in
@@ -0,0 +1,15 @@
+global-exclude *
+
+include setup.py
+include COPYING
+include AUTHORS.md
+include MANIFEST.in
+include bindings/python/*.rst
+
+recursive-include bindings/python *.cpp *.hpp
+recursive-include bindings/python/mapnik *.py
+recursive-include bindings/python/mapnik2 *.py
+recursive-include deps/agg/include *.h
+recursive-include tests/python_tests *.py
+recursive-include tests/python_tests/images *.png
+recursive-include bindings/python *.cpp
View
38 bindings/python/CHANGELOG.rst
@@ -0,0 +1,38 @@
+Changelog
+=========
+This the PyPI Python bindings only changelog.
+For a full changelog see `the official Mapnik changelog <https://github.com/mapnik/mapnik/blob/master/CHANGELOG.md>`_.
+
+2.1.0
+-----
+
+- Updated for mapnik 2.1.0
+- No more separate bindings repository.
+- New Pypi package name: mapnik instead of mapnik2
+
+
+2.0.1.3 (2012-08-05)
+--------------------
+
+- Nothing changed yet.
+
+
+2.0.1.1 (2012-08-05)
+--------------------
+
+- renaming release
+
+
+2.0.2 (2012-08-04)
+------------------
+
+- Multi Arch Support, thx to noirbizarre. [kiorky]
+ See https://github.com/mapnik/pymapnik2/pull/4
+
+
+2.0.1 (2012-05-06)
+------------------
+
+- First public release of mapnik2 eggified python bindings
+
+
View
137 bindings/python/README.rst
@@ -0,0 +1,137 @@
+======================
+Mapnik Python Bindings
+======================
+
+Official `Mapnik`_ python bindings.
+
+.. image:: https://secure.travis-ci.org/mapnik/mapnik.png
+ :target: http://travis-ci.org/mapnik/mapnik
+
+.. contents::
+
+
+Installation
+============
+
+Prerequisites
+-------------
+
+Before installing, you need:
+
+* the ``mapnik-config`` utility in your ``$PATH``
+* ``Boost.Python`` linked to your python interpreter (see `Boost notes`_)
+* ``cairo`` / ``cairomm`` (optionnal but enabled if you compiled mapnik with cairo support)
+* mapnik
+* The current python interpreter
+
+
+Version notes
+-------------
+
+The python bindings are tied to the mapnik library version.
+
+======================== ====================
+ Mapnik library version Python package
+======================== ====================
+2.0.x mapnik2 (==2.0.1.3)
+2.1.0 mapnik (==2.1.0)
+======================== ====================
+
+You can find your installed version with:
+
+.. code-block:: bash
+
+ $ mapnik-config -v
+
+
+Boost notes
+-----------
+
+To specify which ``boost_python`` lib to link against, you can use:
+
+.. code-block:: bash
+
+ $ export MAPNIK2_BOOST_PYTHON="libboost_python.so.1"
+
+Where you have on your filesystem
+
+.. code-block:: bash
+
+ /usr/lib/libboost_python.so.1
+
+Don't forget that you can play with ``LDFLAGS``/``CFLAGS``/``LD_LIBRARY_PATH`` to indicate non standart locations for the requirements if it applies.
+
+
+Standard installation
+---------------------
+You can use either ``easy_install`` or ``pip``.
+Choose the one you prefer into:
+
+.. code-block:: bash
+
+ $ easy_install mapnik # to use the last known version
+ $ easy_install mapnik==2.1.0 # to pin the version
+ $ pip install mapnik # to use the last known version
+ $ pip install mapnik==2.1.0 # to pin the version
+
+Standard installation works with virtualenv too.
+
+If an error occurs, please read carefully `Prerequisites`_, `Version notes`_ and `Boost notes`_ sections before submitting an issue to the `Mapnik tracker`_.
+
+
+Buildout
+--------
+
+Some developers use buildout_ to ease deployments.
+
+* Add ``mapnik`` to the list of eggs to install, e.g.
+
+.. code-block:: ini
+
+ [buildout]
+ parts = somepart
+
+ [somepart]
+ recipe = minitage.recipe.scripts
+ ...
+ # (options like include dirs)
+ ...
+ eggs =
+ ...
+ mapnik
+
+* Re-run buildout, e.g. with:
+
+.. code-block:: bash
+
+ $ ./bin/buildout
+
+
+Credits
+=======
+
+Companies
+---------
+
+|makinacom|_
+
+* `Planet Makina Corpus <http://www.makina-corpus.org>`_
+* `Contact us <mailto:python@makina-corpus.org>`_
+
+.. |makinacom| image:: http://depot.makina-corpus.org/public/logo.gif
+.. _makinacom: http://www.makina-corpus.com
+
+
+Authors
+-------
+
+Contributors
+------------
+
+* kiorky <kiorky@cryptelium.net>
+* noirbizarre <noirbizarre+mapnik@gmail.com>
+
+
+.. _buildout: http://buildout.org
+.. _Mapnik: http://www.mapnik.org
+.. _Mapnik tracker: https://github.com/mapnik/mapnik/issues
View
144 setup.py
@@ -0,0 +1,144 @@
+import os
+import re
+import sys
+import glob
+
+from setuptools import setup, find_packages, Extension
+from subprocess import Popen, PIPE, check_output
+from ctypes import CDLL
+
+
+def rst(filename):
+ '''
+ Load an rst file and sanitize it for PyPI.
+ Remove unsupported github tags:
+ - code-block directive
+ '''
+ content = open(filename).read()
+ return re.sub(r'\.\.\s? code-block::\s*\w+', '::', content)
+
+
+def mapnik_config(key):
+ cmd = 'mapnik-config --%s' % key
+ try:
+ ret = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)
+ except OSError as e:
+ if e.errno == os.errno.ENOENT:
+ raise Exception('mapnik-config not found') # handle file not found error.
+ else:
+ raise
+ if ret.wait() != 0:
+ raise Exception(
+ '%s error: %s\n%s' % (
+ cmd,
+ ret.stdout.read(),
+ ret.stderr.read(),
+ )
+ )
+ return ret.stdout.read().strip()
+
+
+bindings_dir = os.path.join('bindings', 'python')
+include_dirs = [
+ bindings_dir,
+ os.path.join('deps', 'agg', 'include'),
+]
+libraries = ['jpeg', 'png', 'boost_thread', 'python%s.%s' % sys.version_info[:2]]
+extra_compile_args = mapnik_config('cflags').split()
+extra_link_args = mapnik_config('libs').split()
+
+
+if sys.platform.startswith("linux"):
+ # Multiarch support
+ try:
+ arch = check_output(['dpkg-architecture', '-qDEB_HOST_MULTIARCH']).strip()
+ extra_compile_args.append('-I/usr/lib/%s/sigc++-2.0/include' % arch)
+ extra_link_args.append('-L/usr/lib/%s' % arch)
+ except:
+ pass
+
+
+if sys.platform == "win32":
+ libraries.extend(
+ "boost_python-mgw",
+ )
+else:
+ prefix = 'cyg' if sys.platform == 'cygwin' else 'lib'
+ if sys.platform == 'darwin':
+ suffix = 'dylib'
+ elif os.name == 'nt':
+ suffix = 'dll'
+ else:
+ suffix = 'so'
+
+ for lib in ["boost_python", "boost_python-gcc"]:
+ try:
+ if ".%s" % suffix in lib:
+ lib = re.sub(".%s.*" % suffix, '', lib)
+ if lib.startswith(prefix):
+ lib = lib[len(prefix):]
+ CDLL('%s%s.%s' % (prefix, lib, suffix))
+ libraries.append(lib)
+ break
+ except OSError:
+ pass
+ except IndexError:
+ raise Exception('Cant find boost_python lib!')
+
+
+long_description = '\n'.join((
+ rst(os.path.join(bindings_dir, 'README.rst')),
+ rst(os.path.join(bindings_dir, 'CHANGELOG.rst')),
+ ''
+))
+
+files = glob.glob(os.path.join(bindings_dir, '*.cpp'))
+
+install_requires = ['setuptools', ]
+for lib in extra_link_args:
+ if 'cairo' in lib:
+ dep = 'pycairo'
+ if sys.version_info[0] < 3:
+ dep = 'py2cairo'
+ install_requires.append(dep)
+ break
+
+version = mapnik_config('version')
+
+# nosetests configuration
+os.environ['NOSE_WHERE'] = 'tests/python_tests'
+
+setup(
+ name='mapnik',
+ version=version,
+ description="Python bindings for mapnik",
+ long_description=long_description,
+ keywords='',
+ author='Mathieu Le Marec - Pasquet & the mapnik community',
+ author_email='kiorky@cryptelium.net',
+ url='http://pypi.python.org/pypi/mapnik',
+ license='LGPL',
+ include_package_data=True,
+ zip_safe=False,
+ packages=find_packages(bindings_dir),
+ package_dir={'': bindings_dir},
+ ext_modules=[
+ Extension(
+ "_mapnik", files,
+ include_dirs=include_dirs,
+ extra_compile_args=extra_compile_args,
+ libraries=libraries,
+ extra_link_args=extra_link_args
+ ),
+ ],
+ install_requires=install_requires,
+ tests_require=['nose>=1.0'],
+ test_suite='nose.collector',
+ entry_points={},
+ classifiers=[
+ "Programming Language :: Python",
+ "Topic :: Software Development :: Libraries :: Python Modules",
+ "Topic :: Scientific/Engineering :: GIS",
+ "License :: OSI Approved :: GNU Lesser General Public License v2 (LGPLv2)",
+ ],
+)