|
1 | 1 | import os
|
2 | 2 | import sys
|
| 3 | +import subprocess |
3 | 4 |
|
4 |
| -# This dequote() business is required for some older versions |
5 |
| -# of mysql_config |
6 | 5 |
|
7 |
| - |
8 |
| -def dequote(s): |
9 |
| - if not s: |
10 |
| - raise Exception( |
11 |
| - "Wrong MySQL configuration: maybe https://bugs.mysql.com/bug.php?id=86971 ?" |
12 |
| - ) |
13 |
| - if s[0] in "\"'" and s[0] == s[-1]: |
14 |
| - s = s[1:-1] |
15 |
| - return s |
16 |
| - |
17 |
| - |
18 |
| -_mysql_config_path = "mysql_config" |
19 |
| - |
20 |
| - |
21 |
| -def mysql_config(what): |
22 |
| - cmd = "{} --{}".format(_mysql_config_path, what) |
23 |
| - print(cmd) |
24 |
| - f = os.popen(cmd) |
25 |
| - data = f.read().strip().split() |
26 |
| - ret = f.close() |
27 |
| - if ret: |
28 |
| - if ret / 256: |
29 |
| - data = [] |
30 |
| - if ret / 256 > 1: |
31 |
| - raise OSError("{} not found".format(_mysql_config_path)) |
32 |
| - print(data) |
33 |
| - return data |
| 6 | +def find_package_name(): |
| 7 | + """Get available pkg-config package name""" |
| 8 | + packages = ["mysqlclient", "mariadb"] |
| 9 | + for pkg in packages: |
| 10 | + try: |
| 11 | + cmd = f"pkg-config --exists {pkg}" |
| 12 | + print(f"Trying {cmd}") |
| 13 | + subprocess.check_call(cmd, shell=True) |
| 14 | + except subprocess.CalledProcessError as err: |
| 15 | + print(err) |
| 16 | + else: |
| 17 | + return pkg |
| 18 | + raise Exception("Can not find valid pkg-config") |
34 | 19 |
|
35 | 20 |
|
36 | 21 | def get_config():
|
37 | 22 | from setup_common import get_metadata_and_options, enabled, create_release_file
|
38 | 23 |
|
39 |
| - global _mysql_config_path |
40 |
| - |
41 | 24 | metadata, options = get_metadata_and_options()
|
42 | 25 |
|
43 |
| - if "mysql_config" in options: |
44 |
| - _mysql_config_path = options["mysql_config"] |
45 |
| - else: |
46 |
| - try: |
47 |
| - mysql_config("version") |
48 |
| - except OSError: |
49 |
| - # try mariadb_config |
50 |
| - _mysql_config_path = "mariadb_config" |
51 |
| - try: |
52 |
| - mysql_config("version") |
53 |
| - except OSError: |
54 |
| - _mysql_config_path = "mysql_config" |
55 |
| - |
56 |
| - extra_objects = [] |
57 | 26 | static = enabled(options, "static")
|
58 |
| - |
59 | 27 | # allow a command-line option to override the base config file to permit
|
60 | 28 | # a static build to be created via requirements.txt
|
61 | 29 | #
|
62 | 30 | if "--static" in sys.argv:
|
63 | 31 | static = True
|
64 | 32 | sys.argv.remove("--static")
|
65 | 33 |
|
66 |
| - libs = os.environ.get("MYSQLCLIENT_LDFLAGS") |
67 |
| - if libs: |
68 |
| - libs = libs.strip().split() |
69 |
| - else: |
70 |
| - libs = mysql_config("libs") |
71 |
| - library_dirs = [dequote(i[2:]) for i in libs if i.startswith("-L")] |
72 |
| - libraries = [dequote(i[2:]) for i in libs if i.startswith("-l")] |
73 |
| - extra_link_args = [x for x in libs if not x.startswith(("-l", "-L"))] |
74 |
| - |
| 34 | + ldflags = os.environ.get("MYSQLCLIENT_LDFLAGS") |
75 | 35 | cflags = os.environ.get("MYSQLCLIENT_CFLAGS")
|
76 |
| - if cflags: |
77 |
| - use_mysqlconfig_cflags = False |
78 |
| - cflags = cflags.strip().split() |
79 |
| - else: |
80 |
| - use_mysqlconfig_cflags = True |
81 |
| - cflags = mysql_config("cflags") |
82 |
| - |
83 |
| - include_dirs = [] |
84 |
| - extra_compile_args = ["-std=c99"] |
85 | 36 |
|
86 |
| - for a in cflags: |
87 |
| - if a.startswith("-I"): |
88 |
| - include_dirs.append(dequote(a[2:])) |
89 |
| - elif a.startswith(("-L", "-l")): # This should be LIBS. |
90 |
| - pass |
91 |
| - else: |
92 |
| - extra_compile_args.append(a.replace("%", "%%")) |
93 |
| - |
94 |
| - # Copy the arch flags for linking as well |
95 |
| - try: |
96 |
| - i = extra_compile_args.index("-arch") |
97 |
| - if "-arch" not in extra_link_args: |
98 |
| - extra_link_args += ["-arch", extra_compile_args[i + 1]] |
99 |
| - except ValueError: |
100 |
| - pass |
| 37 | + pkg_name = None |
| 38 | + static_opt = " --static" if static else "" |
| 39 | + if not (cflags and ldflags): |
| 40 | + pkg_name = find_package_name() |
| 41 | + if not cflags: |
| 42 | + cflags = subprocess.check_output( |
| 43 | + f"pkg-config{static_opt} --cflags {pkg_name}", encoding="utf-8", shell=True |
| 44 | + ) |
| 45 | + if not ldflags: |
| 46 | + ldflags = subprocess.check_output( |
| 47 | + f"pkg-config{static_opt} --libs {pkg_name}", encoding="utf-8", shell=True |
| 48 | + ) |
101 | 49 |
|
102 |
| - if static: |
103 |
| - # properly handle mysql client libraries that are not called libmysqlclient |
104 |
| - client = None |
105 |
| - CLIENT_LIST = [ |
106 |
| - "mysqlclient", |
107 |
| - "mysqlclient_r", |
108 |
| - "mysqld", |
109 |
| - "mariadb", |
110 |
| - "mariadbclient", |
111 |
| - "perconaserverclient", |
112 |
| - "perconaserverclient_r", |
113 |
| - ] |
114 |
| - for c in CLIENT_LIST: |
115 |
| - if c in libraries: |
116 |
| - client = c |
117 |
| - break |
118 |
| - |
119 |
| - if client == "mariadb": |
120 |
| - client = "mariadbclient" |
121 |
| - if client is None: |
122 |
| - raise ValueError("Couldn't identify mysql client library") |
123 |
| - |
124 |
| - extra_objects.append(os.path.join(library_dirs[0], "lib%s.a" % client)) |
125 |
| - if client in libraries: |
126 |
| - libraries.remove(client) |
| 50 | + cflags = cflags.split() |
| 51 | + for f in cflags: |
| 52 | + if f.startswith("-std="): |
| 53 | + break |
127 | 54 | else:
|
128 |
| - if use_mysqlconfig_cflags: |
129 |
| - # mysql_config may have "-lmysqlclient -lz -lssl -lcrypto", but zlib and |
130 |
| - # ssl is not used by _mysql. They are needed only for static build. |
131 |
| - for L in ("crypto", "ssl", "z", "zstd"): |
132 |
| - if L in libraries: |
133 |
| - libraries.remove(L) |
| 55 | + cflags += ["-std=c99"] |
134 | 56 |
|
135 |
| - name = "mysqlclient" |
136 |
| - metadata["name"] = name |
| 57 | + ldflags = ldflags.split() |
137 | 58 |
|
138 | 59 | define_macros = [
|
139 | 60 | ("version_info", metadata["version_info"]),
|
140 | 61 | ("__version__", metadata["version"]),
|
141 | 62 | ]
|
142 |
| - create_release_file(metadata) |
143 |
| - del metadata["version_info"] |
| 63 | + |
| 64 | + # print(f"{cflags = }") |
| 65 | + # print(f"{ldflags = }") |
| 66 | + # print(f"{define_macros = }") |
| 67 | + |
144 | 68 | ext_options = dict(
|
145 |
| - library_dirs=library_dirs, |
146 |
| - libraries=libraries, |
147 |
| - extra_compile_args=extra_compile_args, |
148 |
| - extra_link_args=extra_link_args, |
149 |
| - include_dirs=include_dirs, |
150 |
| - extra_objects=extra_objects, |
| 69 | + extra_compile_args=cflags, |
| 70 | + extra_link_args=ldflags, |
151 | 71 | define_macros=define_macros,
|
152 | 72 | )
|
153 |
| - |
154 | 73 | # newer versions of gcc require libstdc++ if doing a static build
|
155 | 74 | if static:
|
156 | 75 | ext_options["language"] = "c++"
|
157 | 76 |
|
158 |
| - print("ext_options:") |
| 77 | + print("Options for building extention module:") |
159 | 78 | for k, v in ext_options.items():
|
160 |
| - print(" {}: {}".format(k, v)) |
| 79 | + print(f" {k}: {v}") |
| 80 | + |
| 81 | + create_release_file(metadata) |
| 82 | + del metadata["version_info"] |
161 | 83 |
|
162 | 84 | return metadata, ext_options
|
163 | 85 |
|
164 | 86 |
|
165 | 87 | if __name__ == "__main__":
|
166 |
| - sys.stderr.write( |
167 |
| - """You shouldn't be running this directly; it is used by setup.py.""" |
168 |
| - ) |
| 88 | + from pprint import pprint |
| 89 | + |
| 90 | + metadata, config = get_config() |
| 91 | + print("# Metadata") |
| 92 | + pprint(metadata, sort_dicts=False, compact=True) |
| 93 | + print("\n# Extention options") |
| 94 | + pprint(config, sort_dicts=False, compact=True) |
0 commit comments