mirror of
https://github.com/PyMySQL/mysqlclient.git
synced 2025-08-14 01:44:04 +08:00
Use pkg-config instead of mysql_config (#586)
MySQL breaks mysql_config often. Use pkg-config instead. Fixes #584
This commit is contained in:
@ -83,7 +83,7 @@ $ pip install mysqlclient
|
|||||||
|
|
||||||
### Customize build (POSIX)
|
### Customize build (POSIX)
|
||||||
|
|
||||||
mysqlclient uses `mysql_config` or `mariadb_config` by default for finding
|
mysqlclient uses `pkg-config --clfags --ldflags mysqlclient` by default for finding
|
||||||
compiler/linker flags.
|
compiler/linker flags.
|
||||||
|
|
||||||
You can use `MYSQLCLIENT_CFLAGS` and `MYSQLCLIENT_LDFLAGS` environment
|
You can use `MYSQLCLIENT_CFLAGS` and `MYSQLCLIENT_LDFLAGS` environment
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
[metadata]
|
[metadata]
|
||||||
version: 2.1.1
|
name: mysqlclient
|
||||||
version_info: (2,1,1,'final',0)
|
version: 2.1.2
|
||||||
|
version_info: (2,1,2,'dev',0)
|
||||||
description: Python interface to MySQL
|
description: Python interface to MySQL
|
||||||
author: Inada Naoki
|
author: Inada Naoki
|
||||||
author_email: songofacandy@gmail.com
|
author_email: songofacandy@gmail.com
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
from configparser import ConfigParser as SafeConfigParser
|
from configparser import ConfigParser
|
||||||
|
|
||||||
|
|
||||||
def get_metadata_and_options():
|
def get_metadata_and_options():
|
||||||
config = SafeConfigParser()
|
config = ConfigParser()
|
||||||
config.read(["metadata.cfg", "site.cfg"])
|
config.read(["metadata.cfg", "site.cfg"])
|
||||||
|
|
||||||
metadata = dict(config.items("metadata"))
|
metadata = dict(config.items("metadata"))
|
||||||
|
182
setup_posix.py
182
setup_posix.py
@ -1,61 +1,29 @@
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
import subprocess
|
||||||
# This dequote() business is required for some older versions
|
|
||||||
# of mysql_config
|
|
||||||
|
|
||||||
|
|
||||||
def dequote(s):
|
def find_package_name():
|
||||||
if not s:
|
"""Get available pkg-config package name"""
|
||||||
raise Exception(
|
packages = ["mysqlclient", "mariadb"]
|
||||||
"Wrong MySQL configuration: maybe https://bugs.mysql.com/bug.php?id=86971 ?"
|
for pkg in packages:
|
||||||
)
|
try:
|
||||||
if s[0] in "\"'" and s[0] == s[-1]:
|
cmd = f"pkg-config --exists {pkg}"
|
||||||
s = s[1:-1]
|
print(f"Trying {cmd}")
|
||||||
return s
|
subprocess.check_call(cmd, shell=True)
|
||||||
|
except subprocess.CalledProcessError as err:
|
||||||
|
print(err)
|
||||||
_mysql_config_path = "mysql_config"
|
else:
|
||||||
|
return pkg
|
||||||
|
raise Exception("Can not find valid pkg-config")
|
||||||
def mysql_config(what):
|
|
||||||
cmd = "{} --{}".format(_mysql_config_path, what)
|
|
||||||
print(cmd)
|
|
||||||
f = os.popen(cmd)
|
|
||||||
data = f.read().strip().split()
|
|
||||||
ret = f.close()
|
|
||||||
if ret:
|
|
||||||
if ret / 256:
|
|
||||||
data = []
|
|
||||||
if ret / 256 > 1:
|
|
||||||
raise OSError("{} not found".format(_mysql_config_path))
|
|
||||||
print(data)
|
|
||||||
return data
|
|
||||||
|
|
||||||
|
|
||||||
def get_config():
|
def get_config():
|
||||||
from setup_common import get_metadata_and_options, enabled, create_release_file
|
from setup_common import get_metadata_and_options, enabled, create_release_file
|
||||||
|
|
||||||
global _mysql_config_path
|
|
||||||
|
|
||||||
metadata, options = get_metadata_and_options()
|
metadata, options = get_metadata_and_options()
|
||||||
|
|
||||||
if "mysql_config" in options:
|
|
||||||
_mysql_config_path = options["mysql_config"]
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
mysql_config("version")
|
|
||||||
except OSError:
|
|
||||||
# try mariadb_config
|
|
||||||
_mysql_config_path = "mariadb_config"
|
|
||||||
try:
|
|
||||||
mysql_config("version")
|
|
||||||
except OSError:
|
|
||||||
_mysql_config_path = "mysql_config"
|
|
||||||
|
|
||||||
extra_objects = []
|
|
||||||
static = enabled(options, "static")
|
static = enabled(options, "static")
|
||||||
|
|
||||||
# allow a command-line option to override the base config file to permit
|
# allow a command-line option to override the base config file to permit
|
||||||
# a static build to be created via requirements.txt
|
# a static build to be created via requirements.txt
|
||||||
#
|
#
|
||||||
@ -63,106 +31,64 @@ def get_config():
|
|||||||
static = True
|
static = True
|
||||||
sys.argv.remove("--static")
|
sys.argv.remove("--static")
|
||||||
|
|
||||||
libs = os.environ.get("MYSQLCLIENT_LDFLAGS")
|
ldflags = os.environ.get("MYSQLCLIENT_LDFLAGS")
|
||||||
if libs:
|
|
||||||
libs = libs.strip().split()
|
|
||||||
else:
|
|
||||||
libs = mysql_config("libs")
|
|
||||||
library_dirs = [dequote(i[2:]) for i in libs if i.startswith("-L")]
|
|
||||||
libraries = [dequote(i[2:]) for i in libs if i.startswith("-l")]
|
|
||||||
extra_link_args = [x for x in libs if not x.startswith(("-l", "-L"))]
|
|
||||||
|
|
||||||
cflags = os.environ.get("MYSQLCLIENT_CFLAGS")
|
cflags = os.environ.get("MYSQLCLIENT_CFLAGS")
|
||||||
if cflags:
|
|
||||||
use_mysqlconfig_cflags = False
|
pkg_name = None
|
||||||
cflags = cflags.strip().split()
|
static_opt = " --static" if static else ""
|
||||||
|
if not (cflags and ldflags):
|
||||||
|
pkg_name = find_package_name()
|
||||||
|
if not cflags:
|
||||||
|
cflags = subprocess.check_output(
|
||||||
|
f"pkg-config{static_opt} --cflags {pkg_name}", encoding="utf-8", shell=True
|
||||||
|
)
|
||||||
|
if not ldflags:
|
||||||
|
ldflags = subprocess.check_output(
|
||||||
|
f"pkg-config{static_opt} --libs {pkg_name}", encoding="utf-8", shell=True
|
||||||
|
)
|
||||||
|
|
||||||
|
cflags = cflags.split()
|
||||||
|
for f in cflags:
|
||||||
|
if f.startswith("-std="):
|
||||||
|
break
|
||||||
else:
|
else:
|
||||||
use_mysqlconfig_cflags = True
|
cflags += ["-std=c99"]
|
||||||
cflags = mysql_config("cflags")
|
|
||||||
|
|
||||||
include_dirs = []
|
ldflags = ldflags.split()
|
||||||
extra_compile_args = ["-std=c99"]
|
|
||||||
|
|
||||||
for a in cflags:
|
|
||||||
if a.startswith("-I"):
|
|
||||||
include_dirs.append(dequote(a[2:]))
|
|
||||||
elif a.startswith(("-L", "-l")): # This should be LIBS.
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
extra_compile_args.append(a.replace("%", "%%"))
|
|
||||||
|
|
||||||
# Copy the arch flags for linking as well
|
|
||||||
try:
|
|
||||||
i = extra_compile_args.index("-arch")
|
|
||||||
if "-arch" not in extra_link_args:
|
|
||||||
extra_link_args += ["-arch", extra_compile_args[i + 1]]
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if static:
|
|
||||||
# properly handle mysql client libraries that are not called libmysqlclient
|
|
||||||
client = None
|
|
||||||
CLIENT_LIST = [
|
|
||||||
"mysqlclient",
|
|
||||||
"mysqlclient_r",
|
|
||||||
"mysqld",
|
|
||||||
"mariadb",
|
|
||||||
"mariadbclient",
|
|
||||||
"perconaserverclient",
|
|
||||||
"perconaserverclient_r",
|
|
||||||
]
|
|
||||||
for c in CLIENT_LIST:
|
|
||||||
if c in libraries:
|
|
||||||
client = c
|
|
||||||
break
|
|
||||||
|
|
||||||
if client == "mariadb":
|
|
||||||
client = "mariadbclient"
|
|
||||||
if client is None:
|
|
||||||
raise ValueError("Couldn't identify mysql client library")
|
|
||||||
|
|
||||||
extra_objects.append(os.path.join(library_dirs[0], "lib%s.a" % client))
|
|
||||||
if client in libraries:
|
|
||||||
libraries.remove(client)
|
|
||||||
else:
|
|
||||||
if use_mysqlconfig_cflags:
|
|
||||||
# mysql_config may have "-lmysqlclient -lz -lssl -lcrypto", but zlib and
|
|
||||||
# ssl is not used by _mysql. They are needed only for static build.
|
|
||||||
for L in ("crypto", "ssl", "z", "zstd"):
|
|
||||||
if L in libraries:
|
|
||||||
libraries.remove(L)
|
|
||||||
|
|
||||||
name = "mysqlclient"
|
|
||||||
metadata["name"] = name
|
|
||||||
|
|
||||||
define_macros = [
|
define_macros = [
|
||||||
("version_info", metadata["version_info"]),
|
("version_info", metadata["version_info"]),
|
||||||
("__version__", metadata["version"]),
|
("__version__", metadata["version"]),
|
||||||
]
|
]
|
||||||
create_release_file(metadata)
|
|
||||||
del metadata["version_info"]
|
# print(f"{cflags = }")
|
||||||
|
# print(f"{ldflags = }")
|
||||||
|
# print(f"{define_macros = }")
|
||||||
|
|
||||||
ext_options = dict(
|
ext_options = dict(
|
||||||
library_dirs=library_dirs,
|
extra_compile_args=cflags,
|
||||||
libraries=libraries,
|
extra_link_args=ldflags,
|
||||||
extra_compile_args=extra_compile_args,
|
|
||||||
extra_link_args=extra_link_args,
|
|
||||||
include_dirs=include_dirs,
|
|
||||||
extra_objects=extra_objects,
|
|
||||||
define_macros=define_macros,
|
define_macros=define_macros,
|
||||||
)
|
)
|
||||||
|
|
||||||
# newer versions of gcc require libstdc++ if doing a static build
|
# newer versions of gcc require libstdc++ if doing a static build
|
||||||
if static:
|
if static:
|
||||||
ext_options["language"] = "c++"
|
ext_options["language"] = "c++"
|
||||||
|
|
||||||
print("ext_options:")
|
print("Options for building extention module:")
|
||||||
for k, v in ext_options.items():
|
for k, v in ext_options.items():
|
||||||
print(" {}: {}".format(k, v))
|
print(f" {k}: {v}")
|
||||||
|
|
||||||
|
create_release_file(metadata)
|
||||||
|
del metadata["version_info"]
|
||||||
|
|
||||||
return metadata, ext_options
|
return metadata, ext_options
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
sys.stderr.write(
|
from pprint import pprint
|
||||||
"""You shouldn't be running this directly; it is used by setup.py."""
|
|
||||||
)
|
metadata, config = get_config()
|
||||||
|
print("# Metadata")
|
||||||
|
pprint(metadata, sort_dicts=False, compact=True)
|
||||||
|
print("\n# Extention options")
|
||||||
|
pprint(config, sort_dicts=False, compact=True)
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import os
|
import os
|
||||||
import sys
|
|
||||||
|
|
||||||
|
|
||||||
def get_config():
|
def get_config():
|
||||||
@ -38,9 +37,6 @@ def get_config():
|
|||||||
|
|
||||||
extra_link_args = ["/MANIFEST"]
|
extra_link_args = ["/MANIFEST"]
|
||||||
|
|
||||||
name = "mysqlclient"
|
|
||||||
metadata["name"] = name
|
|
||||||
|
|
||||||
define_macros = [
|
define_macros = [
|
||||||
("version_info", metadata["version_info"]),
|
("version_info", metadata["version_info"]),
|
||||||
("__version__", metadata["version"]),
|
("__version__", metadata["version"]),
|
||||||
@ -59,6 +55,10 @@ def get_config():
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
sys.stderr.write(
|
from pprint import pprint
|
||||||
"""You shouldn't be running this directly; it is used by setup.py."""
|
|
||||||
)
|
metadata, config = get_config()
|
||||||
|
print("# Metadata")
|
||||||
|
pprint(metadata)
|
||||||
|
print("\n# Extention options")
|
||||||
|
pprint(config)
|
||||||
|
5
site.cfg
5
site.cfg
@ -2,11 +2,6 @@
|
|||||||
# static: link against a static library
|
# static: link against a static library
|
||||||
static = False
|
static = False
|
||||||
|
|
||||||
# The path to mysql_config.
|
|
||||||
# Only use this if mysql_config is not on your PATH, or you have some weird
|
|
||||||
# setup that requires it.
|
|
||||||
#mysql_config = /usr/local/bin/mysql_config
|
|
||||||
|
|
||||||
# http://stackoverflow.com/questions/1972259/mysql-python-install-problem-using-virtualenv-windows-pip
|
# http://stackoverflow.com/questions/1972259/mysql-python-install-problem-using-virtualenv-windows-pip
|
||||||
# Windows connector libs for MySQL. You need a 32-bit connector for your 32-bit Python build.
|
# Windows connector libs for MySQL. You need a 32-bit connector for your 32-bit Python build.
|
||||||
connector =
|
connector =
|
||||||
|
Reference in New Issue
Block a user