1414import tempfile
1515
1616import cffi
17+ import packaging .tags
1718
1819HERE = os .path .abspath (os .path .dirname (__file__ ))
1920
2223]
2324
2425# 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+ HEADERS = [os .path .join (HERE , "zstd" , p ) for p in ("zstd_errors.h" , " zstd.h" , "zdict.h" )]
2627
2728INCLUDE_DIRS = [
2829 os .path .join (HERE , "zstd" ),
@@ -76,8 +77,8 @@ def preprocess(path):
7677 # boilerplate. This can lead to duplicate declarations. So we strip
7778 # this include from the preprocessor invocation.
7879 #
79- # The same things happens for including zstd.h, so give it the same
80- # treatment.
80+ # The same things happens for including zstd.h and zstd_errors.h, so
81+ # give them the same treatment.
8182 #
8283 # We define ZSTD_STATIC_LINKING_ONLY, which is redundant with the inline
8384 # #define in zstdmt_compress.h and results in a compiler warning. So drop
@@ -86,11 +87,17 @@ def preprocess(path):
8687 (
8788 b"#include <stddef.h>" ,
8889 b'#include "zstd.h"' ,
90+ b'#include "zstd_errors.h"' ,
8991 b"#define ZSTD_STATIC_LINKING_ONLY" ,
9092 )
9193 ):
9294 continue
9395
96+ # There's a naked `static` before the declaration of ZSTD_customMem that
97+ # confuses the cffi parser. Strip it.
98+ if line == b'static\n ' :
99+ continue
100+
94101 # The preprocessor environment on Windows doesn't define include
95102 # paths, so the #include of limits.h fails. We work around this
96103 # by removing that import and defining INT_MAX ourselves. This is
@@ -157,19 +164,25 @@ def normalize_output(output):
157164
158165 return b"\n " .join (lines )
159166
167+ # musl 1.1 doesn't define qsort_r. We need to force using the C90
168+ # variant.
169+ musl_defines = ""
170+ for tag in packaging .tags .platform_tags ():
171+ if tag .startswith ("musllinux_1_1_" ):
172+ musl_defines = "#define ZDICT_QSORT ZDICT_QSORT_C90"
173+
160174
161175ffi = cffi .FFI ()
162- # zstd.h uses a possible undefined MIN(). Define it until
163- # https://github.com/facebook/zstd/issues/976 is fixed.
164176# *_DISABLE_DEPRECATE_WARNINGS prevents the compiler from emitting a warning
165177# when cffi uses the function. Since we statically link against zstd, even
166178# if we use the deprecated functions it shouldn't be a huge problem.
167179ffi .set_source (
168180 "zstandard._cffi" ,
169- """
170- #define MIN(a,b) ((a)<(b) ? (a) : (b))
181+ f"""
171182#define ZSTD_STATIC_LINKING_ONLY
172183#define ZSTD_DISABLE_DEPRECATE_WARNINGS
184+ { musl_defines }
185+ #include <zstd_errors.h>
173186#include <zstd.h>
174187#define ZDICT_STATIC_LINKING_ONLY
175188#define ZDICT_DISABLE_DEPRECATE_WARNINGS
@@ -179,7 +192,7 @@ def normalize_output(output):
179192 include_dirs = INCLUDE_DIRS ,
180193)
181194
182- DEFINE = re .compile (b"^ \\ #define ([a-zA-Z0-9_]+) " )
195+ DEFINE = re .compile (rb"^ #define\s+ ([a-zA-Z0-9_]+)\s+(\S+) " )
183196
184197sources = []
185198
@@ -204,9 +217,14 @@ def normalize_output(output):
204217 if m .group (1 ) in (b"ZSTD_LIB_VERSION" , b"ZSTD_VERSION_STRING" ):
205218 continue
206219
220+ # These defines create aliases from old (camelCase) type names
221+ # to the new PascalCase names, which breaks CFFI.
222+ if m .group (1 ).lower () == m .group (2 ).lower ():
223+ continue
224+
207225 # The ... is magic syntax by the cdef parser to resolve the
208226 # value at compile time.
209- sources .append (m .group (0 ) + b" ..." )
227+ sources .append (b"#define " + m .group (1 ) + b" ..." )
210228
211229cdeflines = b"\n " .join (sources ).splitlines ()
212230cdeflines = [line for line in cdeflines if line .strip ()]
0 commit comments