0
This repository has been archived on 2025-04-25. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Minecraft-Overviewer/setup.py
Nicolas F 04ea4eb3ff setup: ugly hack to include our AWOL CI python lib path
This is wrong bad bad bad, but it makes the Win64 build work again
for now, which is what matters.
2022-06-08 13:40:10 +02:00

328 lines
11 KiB
Python
Executable File

#!/usr/bin/env python3
import sys
import traceback
# quick version check
if sys.version_info[0] == 2 or (sys.version_info[0] == 3 and sys.version_info[1] < 4):
print("Sorry, the Overviewer requires at least Python 3.4 to run.")
sys.exit(1)
from distutils.core import setup
from distutils.extension import Extension
from distutils.command.build import build
from distutils.command.clean import clean
from distutils.command.build_ext import build_ext
from distutils.command.sdist import sdist
from distutils.cmd import Command
from distutils.dir_util import remove_tree
from distutils.sysconfig import get_python_inc, get_python_lib
from distutils import log
import os, os.path
import glob
import platform
import time
import overviewer_core.util as util
import numpy
try:
import py2exe
except ImportError:
py2exe = None
try:
import py2app
from setuptools.extension import Extension
except ImportError:
py2app = None
# make sure our current working directory is the same directory
# setup.py is in
curdir = os.path.split(sys.argv[0])[0]
if curdir:
os.chdir(curdir)
# now, setup the keyword arguments for setup
# (because we don't know until runtime if py2exe/py2app is available)
setup_kwargs = {}
setup_kwargs['ext_modules'] = []
setup_kwargs['cmdclass'] = {}
setup_kwargs['options'] = {}
#
# metadata
#
# Utility function to read the README file.
# Used for the long_description. It's nice, because now 1) we have a top level
# README file and 2) it's easier to type in the README file than to put a raw
# string in below ...
def read(fname):
return open(fname).read()
setup_kwargs['name'] = 'Minecraft-Overviewer'
setup_kwargs['version'] = util.findGitVersion()
setup_kwargs['description'] = 'Generates large resolution images of a Minecraft map.'
setup_kwargs['url'] = 'http://overviewer.org/'
setup_kwargs['author'] = 'Andrew Brown'
setup_kwargs['author_email'] = 'brownan@gmail.com'
setup_kwargs['license'] = 'GNU General Public License v3'
setup_kwargs['long_description'] = read('README.rst')
# top-level files that should be included as documentation
doc_files = ['COPYING.txt', 'README.rst', 'CONTRIBUTORS.rst', 'sample_config.py']
# helper to create a 'data_files'-type sequence recursively for a given dir
def recursive_data_files(src, dest=None):
if dest is None:
dest = src
ret = []
for dirpath, dirnames, filenames in os.walk(src):
current_dest = os.path.relpath(dirpath, src)
if current_dest == '.':
current_dest = dest
else:
current_dest = os.path.join(dest, current_dest)
current_sources = map(lambda p: os.path.join(dirpath, p), filenames)
ret.append((current_dest, current_sources))
return ret
# helper to create a 'package_data'-type sequence recursively for a given dir
def recursive_package_data(src, package_dir='overviewer_core'):
full_src = os.path.join(package_dir, src)
ret = []
for dirpath, dirnames, filenames in os.walk(full_src, topdown=False):
current_path = os.path.relpath(dirpath, package_dir)
for filename in filenames:
ret.append(os.path.join(current_path, filename))
return ret
#
# py2exe options
#
if py2exe is not None:
setup_kwargs['comments'] = "http://overviewer.org"
# py2exe likes a very particular type of version number:
setup_kwargs['version'] = util.findGitVersion().replace("-",".")
setup_kwargs['console'] = ['overviewer.py', 'contribManager.py']
setup_kwargs['data_files'] = [('', doc_files)]
setup_kwargs['data_files'] += recursive_data_files('overviewer_core/data/textures', 'textures')
setup_kwargs['data_files'] += recursive_data_files('overviewer_core/data/web_assets', 'web_assets')
setup_kwargs['data_files'] += recursive_data_files('overviewer_core/data/js_src', 'js_src')
setup_kwargs['data_files'] += recursive_data_files('contrib', 'contrib')
setup_kwargs['zipfile'] = None
if platform.system() == 'Windows' and '64bit' in platform.architecture():
b = 3
else:
b = 1
setup_kwargs['options']['py2exe'] = {'bundle_files' : b, 'excludes': 'Tkinter', 'includes':
['fileinput', 'overviewer_core.items', 'overviewer_core.aux_files.genPOI']}
#
# py2app options
#
if py2app is not None:
setup_kwargs['app'] = ['overviewer.py']
setup_kwargs['options']['py2app'] = {'argv_emulation' : False}
setup_kwargs['setup_requires'] = ['py2app']
#
# script, package, and data
#
setup_kwargs['packages'] = ['overviewer_core', 'overviewer_core/aux_files']
setup_kwargs['scripts'] = ['overviewer.py']
setup_kwargs['package_data'] = {'overviewer_core': recursive_package_data('data/textures') + recursive_package_data('data/web_assets') + recursive_package_data('data/js_src')}
if py2exe is None:
setup_kwargs['data_files'] = [('share/doc/minecraft-overviewer', doc_files)]
#
# c_overviewer extension
#
# Third-party modules - we depend on numpy for everything
# Obtain the numpy include directory. This logic works across numpy versions.
try:
numpy_include = numpy.get_include()
except AttributeError:
numpy_include = numpy.get_numpy_include()
try:
pil_include = os.environ['PIL_INCLUDE_DIR'].split(os.pathsep)
except Exception:
pil_include = [ os.path.join(get_python_inc(plat_specific=1), 'Imaging') ]
if not os.path.exists(pil_include[0]):
pil_include = [ ]
# used to figure out what files to compile
# auto-created from files in primitives/, but we need the raw names so
# we can use them later.
primitives = []
for name in glob.glob("overviewer_core/src/primitives/*.c"):
name = os.path.split(name)[-1]
name = os.path.splitext(name)[0]
primitives.append(name)
c_overviewer_files = ['main.c', 'composite.c', 'iterate.c', 'endian.c', 'rendermodes.c', 'block_class.c']
c_overviewer_files += ['primitives/%s.c' % (mode) for mode in primitives]
c_overviewer_files += ['Draw.c']
c_overviewer_includes = ['overviewer.h', 'rendermodes.h']
c_overviewer_files = ['overviewer_core/src/' + s for s in c_overviewer_files]
c_overviewer_includes = ['overviewer_core/src/' + s for s in c_overviewer_includes]
setup_kwargs['ext_modules'].append(Extension(
'overviewer_core.c_overviewer',
c_overviewer_files,
include_dirs=['.', numpy_include] + pil_include,
depends=c_overviewer_includes,
extra_link_args=[]
))
# tell build_ext to build the extension in-place
# (NOT in build/)
setup_kwargs['options']['build_ext'] = {'inplace' : 1}
# custom clean command to remove in-place extension
# and the version file, primitives header
class CustomClean(clean):
def run(self):
# do the normal cleanup
clean.run(self)
# try to remove '_composite.{so,pyd,...}' extension,
# regardless of the current system's extension name convention
build_ext = self.get_finalized_command('build_ext')
ext_fname = build_ext.get_ext_filename('overviewer_core.c_overviewer')
versionpath = os.path.join("overviewer_core", "overviewer_version.py")
primspath = os.path.join("overviewer_core", "src", "primitives.h")
for fname in [ext_fname, primspath]:
if os.path.exists(fname):
try:
log.info("removing '%s'", fname)
if not self.dry_run:
os.remove(fname)
except OSError:
log.warning("'%s' could not be cleaned -- permission denied",
fname)
else:
log.debug("'%s' does not exist -- can't clean it",
fname)
# now try to purge all *.pyc files
for root, dirs, files in os.walk(os.path.join(os.path.dirname(__file__), ".")):
for f in files:
if f.endswith(".pyc"):
if self.dry_run:
log.warning("Would remove %s", os.path.join(root,f))
else:
os.remove(os.path.join(root, f))
def generate_version_py():
try:
outstr = ""
outstr += "VERSION=%r\n" % util.findGitVersion()
outstr += "HASH=%r\n" % util.findGitHash()
outstr += "BUILD_DATE=%r\n" % time.asctime()
outstr += "BUILD_PLATFORM=%r\n" % platform.processor()
outstr += "BUILD_OS=%r\n" % platform.platform()
f = open("overviewer_core/overviewer_version.py", "w")
f.write(outstr)
f.close()
except Exception:
print("WARNING: failed to build overviewer_version file")
def generate_primitives_h():
global primitives
prims = [p.lower().replace('-', '_') for p in primitives]
outstr = "/* this file is auto-generated by setup.py */\n"
for p in prims:
outstr += "extern RenderPrimitiveInterface primitive_{0};\n".format(p)
outstr += "static RenderPrimitiveInterface *render_primitives[] = {\n"
for p in prims:
outstr += " &primitive_{0},\n".format(p)
outstr += " NULL\n"
outstr += "};\n"
with open("overviewer_core/src/primitives.h", "w") as f:
f.write(outstr)
class CustomSDist(sdist):
def run(self):
# generate the version file
generate_version_py()
generate_primitives_h()
sdist.run(self)
class CustomBuild(build):
def run(self):
# generate the version file
try:
generate_version_py()
generate_primitives_h()
build.run(self)
print("\nBuild Complete")
except Exception:
traceback.print_exc(limit=1)
print("\nFailed to build Overviewer!")
print("Please review the errors printed above and the build instructions")
print("at <http://docs.overviewer.org/en/latest/building/>. If you are")
print("still having build problems, file an incident on the github tracker")
print("or find us in IRC.")
sys.exit(1)
class CustomBuildExt(build_ext):
def build_extensions(self):
c = self.compiler.compiler_type
if c == "msvc":
# customize the build options for this compilier
for e in self.extensions:
e.extra_link_args.append("/MANIFEST")
e.extra_link_args.append("/DWINVER=0x060")
e.extra_link_args.append("/D_WIN32_WINNT=0x060")
# workaround for our extremely shitty build system
# yeet this into a fire once we move to github actions
e.extra_link_args.append("/LIBPATH:C:\Python37\Libs")
if c == "unix":
# customize the build options for this compilier
for e in self.extensions:
e.extra_compile_args.append("-Wno-unused-variable") # quell some annoying warnings
e.extra_compile_args.append("-Wno-unused-function") # quell some annoying warnings
e.extra_compile_args.append("-Wdeclaration-after-statement")
e.extra_compile_args.append("-Werror=declaration-after-statement")
e.extra_compile_args.append("-O3")
e.extra_compile_args.append("-std=gnu99")
# build in place, and in the build/ tree
self.inplace = False
build_ext.build_extensions(self)
self.inplace = True
build_ext.build_extensions(self)
setup_kwargs['cmdclass']['clean'] = CustomClean
setup_kwargs['cmdclass']['sdist'] = CustomSDist
setup_kwargs['cmdclass']['build'] = CustomBuild
setup_kwargs['cmdclass']['build_ext'] = CustomBuildExt
###
setup(**setup_kwargs)