bpo-45774: Autoconfiscate SQLite detection (GH-29507)

Co-authored-by: Christian Heimes <christian@python.org>
This commit is contained in:
Erlend Egeberg Aasland 2021-11-19 15:10:41 +01:00 committed by GitHub
parent 036fead695
commit 29e5874d5a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 355 additions and 106 deletions

113
setup.py
View file

@ -1371,108 +1371,17 @@ class PyBuildExt(build_ext):
self.missing.append('_gdbm')
def detect_sqlite(self):
# The sqlite interface
sqlite_setup_debug = False # verbose debug prints from this script?
# We hunt for #define SQLITE_VERSION "n.n.n"
sqlite_incdir = sqlite_libdir = None
sqlite_inc_paths = [ '/usr/include',
'/usr/include/sqlite',
'/usr/include/sqlite3',
'/usr/local/include',
'/usr/local/include/sqlite',
'/usr/local/include/sqlite3',
]
if CROSS_COMPILING:
sqlite_inc_paths = []
MIN_SQLITE_VERSION_NUMBER = (3, 7, 15) # Issue 40810
MIN_SQLITE_VERSION = ".".join([str(x)
for x in MIN_SQLITE_VERSION_NUMBER])
# Scan the default include directories before the SQLite specific
# ones. This allows one to override the copy of sqlite on OSX,
# where /usr/include contains an old version of sqlite.
if MACOS:
sysroot = macosx_sdk_root()
for d_ in self.inc_dirs + sqlite_inc_paths:
d = d_
if MACOS and is_macosx_sdk_path(d):
d = os.path.join(sysroot, d[1:])
f = os.path.join(d, "sqlite3.h")
if os.path.exists(f):
if sqlite_setup_debug: print("sqlite: found %s"%f)
with open(f) as file:
incf = file.read()
m = re.search(
r'\s*.*#\s*.*define\s.*SQLITE_VERSION\W*"([\d\.]*)"', incf)
if m:
sqlite_version = m.group(1)
sqlite_version_tuple = tuple([int(x)
for x in sqlite_version.split(".")])
if sqlite_version_tuple >= MIN_SQLITE_VERSION_NUMBER:
# we win!
if sqlite_setup_debug:
print("%s/sqlite3.h: version %s"%(d, sqlite_version))
sqlite_incdir = d
break
else:
if sqlite_setup_debug:
print("%s: version %s is too old, need >= %s"%(d,
sqlite_version, MIN_SQLITE_VERSION))
elif sqlite_setup_debug:
print("sqlite: %s had no SQLITE_VERSION"%(f,))
if sqlite_incdir:
sqlite_dirs_to_check = [
os.path.join(sqlite_incdir, '..', 'lib64'),
os.path.join(sqlite_incdir, '..', 'lib'),
os.path.join(sqlite_incdir, '..', '..', 'lib64'),
os.path.join(sqlite_incdir, '..', '..', 'lib'),
]
sqlite_libfile = self.compiler.find_library_file(
sqlite_dirs_to_check + self.lib_dirs, 'sqlite3')
if sqlite_libfile:
sqlite_libdir = [os.path.abspath(os.path.dirname(sqlite_libfile))]
if sqlite_incdir and sqlite_libdir:
sqlite_srcs = [
'_sqlite/connection.c',
'_sqlite/cursor.c',
'_sqlite/microprotocols.c',
'_sqlite/module.c',
'_sqlite/prepare_protocol.c',
'_sqlite/row.c',
'_sqlite/statement.c',
'_sqlite/util.c', ]
sqlite_defines = []
# Enable support for loadable extensions in the sqlite3 module
# if --enable-loadable-sqlite-extensions configure option is used.
if (
MACOS and
sqlite_incdir == os.path.join(MACOS_SDK_ROOT, "usr/include") and
sysconfig.get_config_var("PY_SQLITE_ENABLE_LOAD_EXTENSION")
):
raise DistutilsError("System version of SQLite does not support loadable extensions")
include_dirs = ["Modules/_sqlite"]
# Only include the directory where sqlite was found if it does
# not already exist in set include directories, otherwise you
# can end up with a bad search path order.
if sqlite_incdir not in self.compiler.include_dirs:
include_dirs.append(sqlite_incdir)
# avoid a runtime library path for a system library dir
if sqlite_libdir and sqlite_libdir[0] in self.lib_dirs:
sqlite_libdir = None
self.add(Extension('_sqlite3', sqlite_srcs,
define_macros=sqlite_defines,
include_dirs=include_dirs,
library_dirs=sqlite_libdir,
libraries=["sqlite3",]))
else:
self.missing.append('_sqlite3')
sources = [
"_sqlite/connection.c",
"_sqlite/cursor.c",
"_sqlite/microprotocols.c",
"_sqlite/module.c",
"_sqlite/prepare_protocol.c",
"_sqlite/row.c",
"_sqlite/statement.c",
"_sqlite/util.c",
]
self.addext(Extension("_sqlite3", sources=sources))
def detect_platform_specific_exts(self):
# Unix-only modules