|
15 | 15 |
|
16 | 16 | import cffi |
17 | 17 |
|
18 | | -HERE = os.path.abspath(os.path.dirname(__file__)) |
19 | | - |
20 | | -SOURCES = [ |
21 | | - "zstd/zstd.c", |
22 | | -] |
23 | | - |
24 | | -# Headers whose preprocessed output will be fed into cdef(). |
25 | | -HEADERS = [os.path.join(HERE, "zstd", p) for p in ("zstd.h", "zdict.h")] |
26 | | - |
27 | | -INCLUDE_DIRS = [ |
28 | | - os.path.join(HERE, "zstd"), |
29 | | -] |
30 | | - |
31 | 18 | # cffi can't parse some of the primitives in zstd.h. So we invoke the |
32 | 19 | # preprocessor and feed its output into cffi. |
33 | 20 | compiler = distutils.ccompiler.new_compiler() |
@@ -158,59 +145,75 @@ def normalize_output(output): |
158 | 145 | return b"\n".join(lines) |
159 | 146 |
|
160 | 147 |
|
161 | | -ffi = cffi.FFI() |
162 | | -# zstd.h uses a possible undefined MIN(). Define it until |
163 | | -# https://github.com/facebook/zstd/issues/976 is fixed. |
164 | | -# *_DISABLE_DEPRECATE_WARNINGS prevents the compiler from emitting a warning |
165 | | -# when cffi uses the function. Since we statically link against zstd, even |
166 | | -# if we use the deprecated functions it shouldn't be a huge problem. |
167 | | -ffi.set_source( |
168 | | - "zstandard._cffi", |
169 | | - """ |
170 | | -#define MIN(a,b) ((a)<(b) ? (a) : (b)) |
171 | | -#define ZSTD_STATIC_LINKING_ONLY |
172 | | -#define ZSTD_DISABLE_DEPRECATE_WARNINGS |
173 | | -#include <zstd.h> |
174 | | -#define ZDICT_STATIC_LINKING_ONLY |
175 | | -#define ZDICT_DISABLE_DEPRECATE_WARNINGS |
176 | | -#include <zdict.h> |
177 | | -""", |
178 | | - sources=SOURCES, |
179 | | - include_dirs=INCLUDE_DIRS, |
180 | | -) |
181 | | - |
182 | | -DEFINE = re.compile(b"^\\#define ([a-zA-Z0-9_]+) ") |
183 | | - |
184 | | -sources = [] |
185 | | - |
186 | | -# Feed normalized preprocessor output for headers into the cdef parser. |
187 | | -for header in HEADERS: |
188 | | - preprocessed = preprocess(header) |
189 | | - sources.append(normalize_output(preprocessed)) |
190 | | - |
191 | | - # #define's are effectively erased as part of going through preprocessor. |
192 | | - # So perform a manual pass to re-add those to the cdef source. |
193 | | - with open(header, "rb") as fh: |
194 | | - for line in fh: |
195 | | - line = line.strip() |
196 | | - m = DEFINE.match(line) |
197 | | - if not m: |
198 | | - continue |
| 148 | +def get_ffi(): |
| 149 | + here = os.path.abspath(os.path.dirname(__file__)) |
| 150 | + |
| 151 | + zstd_sources = [ |
| 152 | + "zstd/zstd.c", |
| 153 | + ] |
| 154 | + |
| 155 | + # Headers whose preprocessed output will be fed into cdef(). |
| 156 | + headers = [os.path.join(here, "zstd", p) for p in ("zstd.h", "zdict.h")] |
| 157 | + |
| 158 | + include_dirs = [ |
| 159 | + os.path.join(here, "zstd"), |
| 160 | + ] |
| 161 | + |
| 162 | + ffi = cffi.FFI() |
| 163 | + # zstd.h uses a possible undefined MIN(). Define it until |
| 164 | + # https://github.com/facebook/zstd/issues/976 is fixed. |
| 165 | + # *_DISABLE_DEPRECATE_WARNINGS prevents the compiler from emitting a warning |
| 166 | + # when cffi uses the function. Since we statically link against zstd, even |
| 167 | + # if we use the deprecated functions it shouldn't be a huge problem. |
| 168 | + ffi.set_source( |
| 169 | + "zstandard._cffi", |
| 170 | + """ |
| 171 | + #define MIN(a,b) ((a)<(b) ? (a) : (b)) |
| 172 | + #define ZSTD_STATIC_LINKING_ONLY |
| 173 | + #define ZSTD_DISABLE_DEPRECATE_WARNINGS |
| 174 | + #include <zstd.h> |
| 175 | + #define ZDICT_STATIC_LINKING_ONLY |
| 176 | + #define ZDICT_DISABLE_DEPRECATE_WARNINGS |
| 177 | + #include <zdict.h> |
| 178 | + """, |
| 179 | + sources=zstd_sources, |
| 180 | + include_dirs=include_dirs, |
| 181 | + ) |
199 | 182 |
|
200 | | - if m.group(1) == b"ZSTD_STATIC_LINKING_ONLY": |
201 | | - continue |
| 183 | + DEFINE = re.compile(b"^\\#define ([a-zA-Z0-9_]+) ") |
202 | 184 |
|
203 | | - # The parser doesn't like some constants with complex values. |
204 | | - if m.group(1) in (b"ZSTD_LIB_VERSION", b"ZSTD_VERSION_STRING"): |
205 | | - continue |
| 185 | + sources = [] |
| 186 | + |
| 187 | + # Feed normalized preprocessor output for headers into the cdef parser. |
| 188 | + for header in headers: |
| 189 | + preprocessed = preprocess(header) |
| 190 | + sources.append(normalize_output(preprocessed)) |
| 191 | + |
| 192 | + # #define's are effectively erased as part of going through preprocessor. |
| 193 | + # So perform a manual pass to re-add those to the cdef source. |
| 194 | + with open(header, "rb") as fh: |
| 195 | + for line in fh: |
| 196 | + line = line.strip() |
| 197 | + m = DEFINE.match(line) |
| 198 | + if not m: |
| 199 | + continue |
| 200 | + |
| 201 | + if m.group(1) == b"ZSTD_STATIC_LINKING_ONLY": |
| 202 | + continue |
| 203 | + |
| 204 | + # The parser doesn't like some constants with complex values. |
| 205 | + if m.group(1) in (b"ZSTD_LIB_VERSION", b"ZSTD_VERSION_STRING"): |
| 206 | + continue |
| 207 | + |
| 208 | + # The ... is magic syntax by the cdef parser to resolve the |
| 209 | + # value at compile time. |
| 210 | + sources.append(m.group(0) + b" ...") |
206 | 211 |
|
207 | | - # The ... is magic syntax by the cdef parser to resolve the |
208 | | - # value at compile time. |
209 | | - sources.append(m.group(0) + b" ...") |
| 212 | + cdeflines = b"\n".join(sources).splitlines() |
| 213 | + cdeflines = [line for line in cdeflines if line.strip()] |
| 214 | + ffi.cdef(b"\n".join(cdeflines).decode("latin1")) |
| 215 | + return ffi |
210 | 216 |
|
211 | | -cdeflines = b"\n".join(sources).splitlines() |
212 | | -cdeflines = [line for line in cdeflines if line.strip()] |
213 | | -ffi.cdef(b"\n".join(cdeflines).decode("latin1")) |
214 | 217 |
|
215 | 218 | if __name__ == "__main__": |
216 | | - ffi.compile() |
| 219 | + get_ffi().compile() |
0 commit comments