Advertisement
Guest User

Untitled

a guest
Feb 3rd, 2017
356
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 11.06 KB | None | 0 0
  1. #! /usr/bin/env python
  2.  
  3. import os
  4. import os.path
  5. import re
  6. import shutil
  7. import subprocess
  8. import sys
  9. import glob
  10. from distutils import sysconfig
  11. from ctypes.util import find_library
  12.  
  13. from setuptools import Command, Extension, setup
  14.  
  15. PYTHON3 = sys.version_info.major == 3
  16.  
  17.  
  18. # Utils
  19. def check_output(args):
  20.     output = subprocess.check_output(args)
  21.     if PYTHON3:
  22.         # check_output returns bytes in PYTHON3.
  23.         output = output.decode()
  24.     return output.rstrip('\n')
  25.  
  26.  
  27. def clean_boost_name(name):
  28.     name = name.split('.')[0]
  29.     if name.startswith('lib'):
  30.         name = name[3:]
  31.     return name
  32.  
  33.  
  34. def find_boost_library(_id):
  35.     suffixes = [
  36.         "",  # standard naming
  37.         "-mt"  # former naming schema for multithreading build
  38.     ]
  39.     if "python" in _id:
  40.         # Debian naming convention for versions installed in parallel
  41.         suffixes.insert(0, "-py%d%d" % (sys.version_info.major,
  42.                                         sys.version_info.minor))
  43.         # standard suffix for Python3
  44.         suffixes.insert(1, sys.version_info.major)
  45.     for suf in suffixes:
  46.         name = "%s%s" % (_id, suf)
  47.         lib = find_library(name)
  48.         if lib is not None:
  49.             return name
  50.  
  51.  
  52. def get_boost_library_names():
  53.     wanted = ['boost_python', 'boost_thread', 'boost_system']
  54.     found = []
  55.     missing = []
  56.     for _id in wanted:
  57.         name = os.environ.get("%s_LIB" % _id.upper(), find_boost_library(_id))
  58.         if name:
  59.             found.append(name)
  60.         else:
  61.             missing.append(_id)
  62.     if missing:
  63.         msg = ""
  64.         for name in missing:
  65.             msg += ("\nMissing {} boost library, try to add its name with "
  66.                     "{}_LIB environment var.").format(name, name.upper())
  67.         raise EnvironmentError(msg)
  68.     return found
  69.  
  70.  
  71. class WhichBoostCommand(Command):
  72.     description = 'Output found boost names. Useful for debug.'
  73.     user_options = []
  74.  
  75.     def initialize_options(self):
  76.         pass
  77.  
  78.     def finalize_options(self):
  79.         pass
  80.  
  81.     def run(self):
  82.         print("\n".join(get_boost_library_names()))
  83.  
  84.  
  85. cflags = sysconfig.get_config_var('CFLAGS')
  86. sysconfig._config_vars['CFLAGS'] = re.sub(
  87.     ' +', ' ', cflags.replace('-g ', '').replace('-Os', '').replace('-arch i386', ''))
  88. opt = sysconfig.get_config_var('OPT')
  89. sysconfig._config_vars['OPT'] = re.sub(
  90.     ' +', ' ', opt.replace('-g ', '').replace('-Os', ''))
  91. ldshared = sysconfig.get_config_var('LDSHARED')
  92. sysconfig._config_vars['LDSHARED'] = re.sub(
  93.     ' +', ' ', ldshared.replace('-g ', '').replace('-Os', '').replace('-arch i386', ''))
  94. ldflags = sysconfig.get_config_var('LDFLAGS')
  95. sysconfig._config_vars['LDFLAGS'] = re.sub(
  96.     ' +', ' ', ldflags.replace('-g ', '').replace('-Os', '').replace('-arch i386', ''))
  97. pycflags = sysconfig.get_config_var('PY_CFLAGS')
  98. sysconfig._config_vars['PY_CFLAGS'] = re.sub(
  99.     ' +', ' ', pycflags.replace('-g ', '').replace('-Os', '').replace('-arch i386', ''))
  100. sysconfig._config_vars['CFLAGSFORSHARED'] = ''
  101. os.environ['ARCHFLAGS'] = ''
  102.  
  103. if os.environ.get("MASON_BUILD", "false") == "true":
  104.     # run bootstrap.sh to get mason builds
  105.     subprocess.call(['./bootstrap.sh'])
  106.     mapnik_config = 'mason_packages/.link/bin/mapnik-config'
  107.     mason_build = True
  108. else:
  109.     mapnik_config = 'mapnik-config'
  110.     mason_build = False
  111.  
  112.  
  113. linkflags = []
  114. lib_path = os.path.join(check_output([mapnik_config, '--prefix']),'lib')
  115. linkflags.extend(check_output([mapnik_config, '--libs']).split(' '))
  116. linkflags.extend(check_output([mapnik_config, '--ldflags']).split(' '))
  117. linkflags.extend(check_output([mapnik_config, '--dep-libs']).split(' '))
  118. linkflags.extend([
  119. '-lmapnik-wkt',
  120. '-lmapnik-json',
  121. ] + ['-l%s' % i for i in get_boost_library_names()])
  122.  
  123. # Dynamically make the mapnik/paths.py file if it doesn't exist.
  124. if os.path.isfile('mapnik/paths.py'):
  125.     create_paths = False
  126. else:
  127.     create_paths = True
  128.     f_paths = open('mapnik/paths.py', 'w')
  129.     f_paths.write('import os\n')
  130.     f_paths.write('\n')
  131.  
  132. input_plugin_path = check_output([mapnik_config, '--input-plugins'])
  133. font_path = check_output([mapnik_config, '--fonts'])
  134.  
  135. if mason_build:
  136.     try:
  137.         if sys.platform == 'darwin':
  138.             base_f = 'libmapnik.dylib'
  139.         else:
  140.             base_f = 'libmapnik.so.3.0'
  141.         f = os.path.join(lib_path, base_f)
  142.         if not os.path.exists(os.path.join('mapnik', 'lib')):
  143.             os.makedirs(os.path.join('mapnik', 'lib'))
  144.         shutil.copyfile(f, os.path.join('mapnik', 'lib', base_f))
  145.     except shutil.Error:
  146.         pass
  147.     input_plugin_files = os.listdir(input_plugin_path)
  148.     input_plugin_files = [os.path.join(
  149.         input_plugin_path, f) for f in input_plugin_files]
  150.     if not os.path.exists(os.path.join('mapnik', 'plugins', 'input')):
  151.         os.makedirs(os.path.join('mapnik', 'plugins', 'input'))
  152.     for f in input_plugin_files:
  153.         try:
  154.             shutil.copyfile(f, os.path.join(
  155.                 'mapnik', 'plugins', 'input', os.path.basename(f)))
  156.         except shutil.Error:
  157.             pass
  158.     font_files = os.listdir(font_path)
  159.     font_files = [os.path.join(font_path, f) for f in font_files]
  160.     if not os.path.exists(os.path.join('mapnik', 'plugins', 'fonts')):
  161.         os.makedirs(os.path.join('mapnik', 'plugins', 'fonts'))
  162.     for f in font_files:
  163.         try:
  164.             shutil.copyfile(f, os.path.join(
  165.                 'mapnik', 'plugins', 'fonts', os.path.basename(f)))
  166.         except shutil.Error:
  167.             pass
  168.     if create_paths:
  169.         f_paths.write(
  170.             'mapniklibpath = os.path.join(os.path.dirname(os.path.realpath(__file__)), "plugins")\n')
  171.         f_paths.write("inputpluginspath = os.path.join(mapniklibpath,'input')\n")
  172.         f_paths.write("fontscollectionpath = os.path.join(mapniklibpath,'fonts')\n")
  173. elif create_paths:
  174.     if os.environ.get('LIB_DIR_NAME'):
  175.         mapnik_lib_path = lib_path + os.environ.get('LIB_DIR_NAME')
  176.     else:
  177.         mapnik_lib_path = lib_path + "/mapnik"
  178.     f_paths.write("mapniklibpath = '{path}'\n".format(path=mapnik_lib_path))
  179.     f_paths.write('mapniklibpath = os.path.normpath(mapniklibpath)\n')
  180.     f_paths.write(
  181.         "inputpluginspath = '{path}'\n".format(path=input_plugin_path))
  182.     f_paths.write(
  183.         "fontscollectionpath = '{path}'\n".format(path=font_path))
  184.  
  185. if create_paths:
  186.     f_paths.write(
  187.         "__all__ = [mapniklibpath,inputpluginspath,fontscollectionpath]\n")
  188.     f_paths.close()
  189.  
  190.  
  191. if mason_build:
  192.  
  193.     share_dir = 'share'
  194.  
  195.     for dep in ['icu','gdal','proj']:
  196.         share_path = os.path.join('mapnik', share_dir, dep)
  197.         if not os.path.exists(share_path):
  198.             os.makedirs(share_path)
  199.  
  200.     icu_path = 'mason_packages/.link/share/icu/*/*.dat'
  201.     icu_files = glob.glob(icu_path)
  202.     if len(icu_files) != 1:
  203.         raise Exception("Failed to find icu dat file at "+ icu_path)
  204.     for f in icu_files:
  205.         shutil.copyfile(f, os.path.join(
  206.             'mapnik', share_dir, 'icu', os.path.basename(f)))
  207.  
  208.     gdal_path = 'mason_packages/.link/share/gdal/'
  209.     gdal_files = os.listdir(gdal_path)
  210.     gdal_files = [os.path.join(gdal_path, f) for f in gdal_files]
  211.     for f in gdal_files:
  212.         try:
  213.             shutil.copyfile(f, os.path.join(
  214.                 'mapnik', share_dir, 'gdal', os.path.basename(f)))
  215.         except shutil.Error:
  216.             pass
  217.  
  218.     proj_path = 'mason_packages/.link/share/proj/'
  219.     proj_files = os.listdir(proj_path)
  220.     proj_files = [os.path.join(proj_path, f) for f in proj_files]
  221.     for f in proj_files:
  222.         try:
  223.             shutil.copyfile(f, os.path.join(
  224.                 'mapnik', share_dir, 'proj', os.path.basename(f)))
  225.         except shutil.Error:
  226.             pass
  227.  
  228. extra_comp_args = check_output([mapnik_config, '--cflags']).split(' ')
  229.  
  230. if os.environ.get("PYCAIRO", "false") == "true":
  231.     try:
  232.         extra_comp_args.append('-DHAVE_PYCAIRO')
  233.         print("-I%s/include/pycairo".format(sys.exec_prefix))
  234.         extra_comp_args.append("-I{0}/include/pycairo".format(sys.exec_prefix))
  235.         #extra_comp_args.extend(check_output(["pkg-config", '--cflags', 'pycairo']).strip().split(' '))
  236.         #linkflags.extend(check_output(["pkg-config", '--libs', 'pycairo']).strip().split(' '))
  237.     except:
  238.         raise Exception("Failed to find compiler options for pycairo")
  239.  
  240. if sys.platform == 'darwin':
  241.     extra_comp_args.append('-mmacosx-version-min=10.11')
  242.     # silence warning coming from boost python macros which
  243.     # would is hard to silence via pragma
  244.     extra_comp_args.append('-Wno-parentheses-equality')
  245.     linkflags.append('-mmacosx-version-min=10.11')
  246. else:
  247.     linkflags.append('-lrt')
  248.     linkflags.append('-Wl,-z,origin')
  249.     linkflags.append('-Wl,-rpath=$ORIGIN/lib')
  250.  
  251. if os.environ.get("CC", False) == False:
  252.     os.environ["CC"] = check_output([mapnik_config, '--cxx'])
  253. if os.environ.get("CXX", False) == False:
  254.     os.environ["CXX"] = check_output([mapnik_config, '--cxx'])
  255.  
  256. setup(
  257.     name="mapnik",
  258.     version="0.1",
  259.     packages=['mapnik','mapnik.printing'],
  260.     author="Blake Thompson",
  261.     author_email="[email protected]",
  262.     description="Python bindings for Mapnik",
  263.     license="GNU LESSER GENERAL PUBLIC LICENSE",
  264.     keywords="mapnik mapbox mapping cartography",
  265.     url="http://mapnik.org/",
  266.     tests_require=[
  267.         'nose',
  268.     ],
  269.     package_data={
  270.         'mapnik': ['lib/*', 'plugins/*/*', 'share/*/*'],
  271.     },
  272.     test_suite='nose.collector',
  273.     cmdclass={
  274.         'whichboost': WhichBoostCommand,
  275.     },
  276.     ext_modules=[
  277.         Extension('mapnik._mapnik', [
  278.             'src/mapnik_color.cpp',
  279.             'src/mapnik_coord.cpp',
  280.             'src/mapnik_datasource.cpp',
  281.             'src/mapnik_datasource_cache.cpp',
  282.             'src/mapnik_envelope.cpp',
  283.             'src/mapnik_expression.cpp',
  284.             'src/mapnik_feature.cpp',
  285.             'src/mapnik_featureset.cpp',
  286.             'src/mapnik_font_engine.cpp',
  287.             'src/mapnik_fontset.cpp',
  288.             'src/mapnik_gamma_method.cpp',
  289.             'src/mapnik_geometry.cpp',
  290.             'src/mapnik_grid.cpp',
  291.             'src/mapnik_grid_view.cpp',
  292.             'src/mapnik_image.cpp',
  293.             'src/mapnik_image_view.cpp',
  294.             'src/mapnik_label_collision_detector.cpp',
  295.             'src/mapnik_layer.cpp',
  296.             'src/mapnik_logger.cpp',
  297.             'src/mapnik_map.cpp',
  298.             'src/mapnik_palette.cpp',
  299.             'src/mapnik_parameters.cpp',
  300.             'src/mapnik_proj_transform.cpp',
  301.             'src/mapnik_projection.cpp',
  302.             'src/mapnik_python.cpp',
  303.             'src/mapnik_query.cpp',
  304.             'src/mapnik_raster_colorizer.cpp',
  305.             'src/mapnik_rule.cpp',
  306.             'src/mapnik_scaling_method.cpp',
  307.             'src/mapnik_style.cpp',
  308.             'src/mapnik_svg_generator_grammar.cpp',
  309.             'src/mapnik_symbolizer.cpp',
  310.             'src/mapnik_view_transform.cpp',
  311.             'src/python_grid_utils.cpp',
  312.         ],
  313.             language='c++',
  314.             extra_compile_args=extra_comp_args,
  315.             extra_link_args=linkflags,
  316.         )
  317.     ]
  318. )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement