mirror of
https://github.com/PyMySQL/mysqlclient.git
synced 2025-08-06 17:28:45 +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)
|
||||
|
||||
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.
|
||||
|
||||
You can use `MYSQLCLIENT_CFLAGS` and `MYSQLCLIENT_LDFLAGS` environment
|
||||
|
@ -1,6 +1,7 @@
|
||||
[metadata]
|
||||
version: 2.1.1
|
||||
version_info: (2,1,1,'final',0)
|
||||
name: mysqlclient
|
||||
version: 2.1.2
|
||||
version_info: (2,1,2,'dev',0)
|
||||
description: Python interface to MySQL
|
||||
author: Inada Naoki
|
||||
author_email: songofacandy@gmail.com
|
||||
|
@ -1,8 +1,8 @@
|
||||
from configparser import ConfigParser as SafeConfigParser
|
||||
from configparser import ConfigParser
|
||||
|
||||
|
||||
def get_metadata_and_options():
|
||||
config = SafeConfigParser()
|
||||
config = ConfigParser()
|
||||
config.read(["metadata.cfg", "site.cfg"])
|
||||
|
||||
metadata = dict(config.items("metadata"))
|
||||
|
182
setup_posix.py
182
setup_posix.py
@ -1,61 +1,29 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
# This dequote() business is required for some older versions
|
||||
# of mysql_config
|
||||
import subprocess
|
||||
|
||||
|
||||
def dequote(s):
|
||||
if not s:
|
||||
raise Exception(
|
||||
"Wrong MySQL configuration: maybe https://bugs.mysql.com/bug.php?id=86971 ?"
|
||||
)
|
||||
if s[0] in "\"'" and s[0] == s[-1]:
|
||||
s = s[1:-1]
|
||||
return s
|
||||
|
||||
|
||||
_mysql_config_path = "mysql_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 find_package_name():
|
||||
"""Get available pkg-config package name"""
|
||||
packages = ["mysqlclient", "mariadb"]
|
||||
for pkg in packages:
|
||||
try:
|
||||
cmd = f"pkg-config --exists {pkg}"
|
||||
print(f"Trying {cmd}")
|
||||
subprocess.check_call(cmd, shell=True)
|
||||
except subprocess.CalledProcessError as err:
|
||||
print(err)
|
||||
else:
|
||||
return pkg
|
||||
raise Exception("Can not find valid pkg-config")
|
||||
|
||||
|
||||
def get_config():
|
||||
from setup_common import get_metadata_and_options, enabled, create_release_file
|
||||
|
||||
global _mysql_config_path
|
||||
|
||||
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")
|
||||
|
||||
# allow a command-line option to override the base config file to permit
|
||||
# a static build to be created via requirements.txt
|
||||
#
|
||||
@ -63,106 +31,64 @@ def get_config():
|
||||
static = True
|
||||
sys.argv.remove("--static")
|
||||
|
||||
libs = 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"))]
|
||||
|
||||
ldflags = os.environ.get("MYSQLCLIENT_LDFLAGS")
|
||||
cflags = os.environ.get("MYSQLCLIENT_CFLAGS")
|
||||
if cflags:
|
||||
use_mysqlconfig_cflags = False
|
||||
cflags = cflags.strip().split()
|
||||
|
||||
pkg_name = None
|
||||
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:
|
||||
use_mysqlconfig_cflags = True
|
||||
cflags = mysql_config("cflags")
|
||||
cflags += ["-std=c99"]
|
||||
|
||||
include_dirs = []
|
||||
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
|
||||
ldflags = ldflags.split()
|
||||
|
||||
define_macros = [
|
||||
("version_info", metadata["version_info"]),
|
||||
("__version__", metadata["version"]),
|
||||
]
|
||||
create_release_file(metadata)
|
||||
del metadata["version_info"]
|
||||
|
||||
# print(f"{cflags = }")
|
||||
# print(f"{ldflags = }")
|
||||
# print(f"{define_macros = }")
|
||||
|
||||
ext_options = dict(
|
||||
library_dirs=library_dirs,
|
||||
libraries=libraries,
|
||||
extra_compile_args=extra_compile_args,
|
||||
extra_link_args=extra_link_args,
|
||||
include_dirs=include_dirs,
|
||||
extra_objects=extra_objects,
|
||||
extra_compile_args=cflags,
|
||||
extra_link_args=ldflags,
|
||||
define_macros=define_macros,
|
||||
)
|
||||
|
||||
# newer versions of gcc require libstdc++ if doing a static build
|
||||
if static:
|
||||
ext_options["language"] = "c++"
|
||||
|
||||
print("ext_options:")
|
||||
print("Options for building extention module:")
|
||||
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
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.stderr.write(
|
||||
"""You shouldn't be running this directly; it is used by setup.py."""
|
||||
)
|
||||
from pprint import pprint
|
||||
|
||||
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 sys
|
||||
|
||||
|
||||
def get_config():
|
||||
@ -38,9 +37,6 @@ def get_config():
|
||||
|
||||
extra_link_args = ["/MANIFEST"]
|
||||
|
||||
name = "mysqlclient"
|
||||
metadata["name"] = name
|
||||
|
||||
define_macros = [
|
||||
("version_info", metadata["version_info"]),
|
||||
("__version__", metadata["version"]),
|
||||
@ -59,6 +55,10 @@ def get_config():
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.stderr.write(
|
||||
"""You shouldn't be running this directly; it is used by setup.py."""
|
||||
)
|
||||
from pprint import pprint
|
||||
|
||||
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 = 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
|
||||
# Windows connector libs for MySQL. You need a 32-bit connector for your 32-bit Python build.
|
||||
connector =
|
||||
|
Reference in New Issue
Block a user