188 lines
6.3 KiB
Python
188 lines
6.3 KiB
Python
# -*- coding: ISO-8859-1 -*-
|
|
# setup.py: the distutils script
|
|
#
|
|
import os
|
|
import setuptools
|
|
import shutil
|
|
import sys
|
|
|
|
from distutils import log
|
|
from distutils.command.build_ext import build_ext
|
|
from setuptools import Extension
|
|
|
|
# If you need to change anything, it should be enough to change setup.cfg.
|
|
|
|
PACKAGE_NAME = 'sqlcipher3'
|
|
VERSION = '0.4.4'
|
|
|
|
# define sqlite sources
|
|
sources = [os.path.join('src', source)
|
|
for source in ["module.c", "connection.c", "cursor.c", "cache.c",
|
|
"microprotocols.c", "prepare_protocol.c",
|
|
"statement.c", "util.c", "row.c", "blob.c"]]
|
|
|
|
# define packages
|
|
packages = [PACKAGE_NAME]
|
|
EXTENSION_MODULE_NAME = "._sqlite3"
|
|
|
|
# Work around clang raising hard error for unused arguments
|
|
if sys.platform == "darwin":
|
|
os.environ['CFLAGS'] = "-Qunused-arguments"
|
|
log.info("CFLAGS: " + os.environ['CFLAGS'])
|
|
|
|
|
|
def quote_argument(arg):
|
|
quote = '"' if sys.platform != 'win32' else '\\"'
|
|
return quote + arg + quote
|
|
|
|
define_macros = [('MODULE_NAME', quote_argument(PACKAGE_NAME + '.dbapi2'))]
|
|
|
|
|
|
class SystemLibSqliteBuilder(build_ext):
|
|
description = "Builds a C extension linking against libsqlcipher library"
|
|
|
|
def build_extension(self, ext):
|
|
log.info(self.description)
|
|
ext.libraries.append('sqlcipher')
|
|
build_ext.build_extension(self, ext)
|
|
|
|
|
|
class AmalgationLibSqliteBuilder(build_ext):
|
|
description = "Builds a C extension using a sqlcipher amalgamation"
|
|
|
|
amalgamation_root = "."
|
|
amalgamation_header = os.path.join(amalgamation_root, 'sqlite3.h')
|
|
amalgamation_source = os.path.join(amalgamation_root, 'sqlite3.c')
|
|
|
|
header_dir = os.path.join(amalgamation_root, 'sqlcipher')
|
|
header_file = os.path.join(header_dir, 'sqlite3.h')
|
|
|
|
amalgamation_message = ('Sqlcipher amalgamation not found. Please download'
|
|
' or build the amalgamation and make sure the '
|
|
'following files are present in the sqlcipher3 '
|
|
'folder: sqlite3.h, sqlite3.c')
|
|
|
|
def check_amalgamation(self):
|
|
header_exists = os.path.exists(self.amalgamation_header)
|
|
source_exists = os.path.exists(self.amalgamation_source)
|
|
if not header_exists or not source_exists:
|
|
raise RuntimeError(self.amalgamation_message)
|
|
|
|
if not os.path.exists(self.header_dir):
|
|
os.mkdir(self.header_dir)
|
|
if not os.path.exists(self.header_file):
|
|
shutil.copy(self.amalgamation_header, self.header_file)
|
|
|
|
def build_extension(self, ext):
|
|
log.info(self.description)
|
|
|
|
# it is responsibility of user to provide amalgamation
|
|
self.check_amalgamation()
|
|
|
|
# Feature-ful library.
|
|
features = (
|
|
'ENABLE_FTS3',
|
|
'ENABLE_FTS3_PARENTHESIS',
|
|
'ENABLE_FTS4',
|
|
'ENABLE_FTS5',
|
|
'ENABLE_JSON1',
|
|
'ENABLE_LOAD_EXTENSION',
|
|
'ENABLE_RTREE',
|
|
'ENABLE_STAT4',
|
|
'ENABLE_UPDATE_DELETE_LIMIT',
|
|
'HAS_CODEC', # Required for SQLCipher.
|
|
'SOUNDEX',
|
|
'USE_URI',
|
|
)
|
|
for feature in features:
|
|
ext.define_macros.append(('SQLITE_%s' % feature, '1'))
|
|
|
|
# Required for SQLCipher.
|
|
ext.define_macros.append(("SQLITE_TEMP_STORE", "2"))
|
|
|
|
# Increase the maximum number of "host parameters".
|
|
ext.define_macros.append(("SQLITE_MAX_VARIABLE_NUMBER", "250000"))
|
|
|
|
# Additional nice-to-have.
|
|
ext.define_macros.extend((
|
|
('SQLITE_DEFAULT_PAGE_SIZE', '4096'),
|
|
('SQLITE_DEFAULT_CACHE_SIZE', '-8000'))) # 8MB.
|
|
|
|
ext.include_dirs.append(self.amalgamation_root)
|
|
ext.sources.append(os.path.join(self.amalgamation_root, "sqlite3.c"))
|
|
|
|
if sys.platform != "win32":
|
|
# Include math library, required for fts5, and crypto.
|
|
ext.extra_link_args.extend(["-lm", "-lcrypto"])
|
|
else:
|
|
# Try to locate openssl.
|
|
openssl_conf = os.environ.get('OPENSSL_CONF')
|
|
if not openssl_conf:
|
|
error_message = 'Fatal error: OpenSSL could not be detected!'
|
|
raise RuntimeError(error_message)
|
|
|
|
openssl = os.path.dirname(os.path.dirname(openssl_conf))
|
|
openssl_lib_path = os.path.join(openssl, "lib")
|
|
|
|
# Configure the compiler
|
|
ext.include_dirs.append(os.path.join(openssl, "include"))
|
|
ext.define_macros.append(("inline", "__inline"))
|
|
|
|
# Configure the linker
|
|
ext.extra_link_args.append("libeay32.lib")
|
|
ext.extra_link_args.append('/LIBPATH:' + openssl_lib_path)
|
|
|
|
build_ext.build_extension(self, ext)
|
|
|
|
def __setattr__(self, k, v):
|
|
# Make sure we don't link against the SQLite
|
|
# library, no matter what setup.cfg says
|
|
if k == "libraries":
|
|
v = None
|
|
self.__dict__[k] = v
|
|
|
|
|
|
def get_setup_args():
|
|
return dict(
|
|
name=PACKAGE_NAME,
|
|
version=VERSION,
|
|
description="DB-API 2.0 interface for SQLCipher 3.x",
|
|
long_description='',
|
|
author="Charles Leifer",
|
|
author_email="coleifer@gmail.com",
|
|
license="zlib/libpng",
|
|
platforms="ALL",
|
|
url="https://github.com/coleifer/sqlcipher3",
|
|
package_dir={PACKAGE_NAME: "sqlcipher3"},
|
|
packages=packages,
|
|
ext_modules=[Extension(
|
|
name=PACKAGE_NAME + EXTENSION_MODULE_NAME,
|
|
sources=sources,
|
|
define_macros=define_macros)
|
|
],
|
|
classifiers=[
|
|
"Development Status :: 4 - Beta",
|
|
"Intended Audience :: Developers",
|
|
"License :: OSI Approved :: zlib/libpng License",
|
|
"Operating System :: MacOS :: MacOS X",
|
|
"Operating System :: Microsoft :: Windows",
|
|
"Operating System :: POSIX",
|
|
"Programming Language :: C",
|
|
"Programming Language :: Python",
|
|
"Topic :: Database :: Database Engines/Servers",
|
|
"Topic :: Software Development :: Libraries :: Python Modules"],
|
|
cmdclass={
|
|
"build_static": AmalgationLibSqliteBuilder,
|
|
"build_ext": SystemLibSqliteBuilder
|
|
}
|
|
)
|
|
|
|
|
|
def main():
|
|
try:
|
|
setuptools.setup(**get_setup_args())
|
|
except BaseException as ex:
|
|
log.info(str(ex))
|
|
|
|
if __name__ == "__main__":
|
|
main()
|