Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
pkgconfig.py122 linesDownload Raw Back to cffi
1# pkg-config, https://www.freedesktop.org/wiki/Software/pkg-config/ integration for cffi2import sys, os, subprocess3 4from .error import PkgConfigError5 6 7def merge_flags(cfg1, cfg2):8    """Merge values from cffi config flags cfg2 to cf19 10    Example:11        merge_flags({"libraries": ["one"]}, {"libraries": ["two"]})12        {"libraries": ["one", "two"]}13    """14    for key, value in cfg2.items():15        if key not in cfg1:16            cfg1[key] = value17        else:18            if not isinstance(cfg1[key], list):19                raise TypeError("cfg1[%r] should be a list of strings" % (key,))20            if not isinstance(value, list):21                raise TypeError("cfg2[%r] should be a list of strings" % (key,))22            cfg1[key].extend(value)23    return cfg124 25 26def call(libname, flag, encoding=sys.getfilesystemencoding()):27    """Calls pkg-config and returns the output if found28    """29    a = ["pkg-config", "--print-errors"]30    a.append(flag)31    a.append(libname)32    try:33        pc = subprocess.Popen(a, stdout=subprocess.PIPE, stderr=subprocess.PIPE)34    except EnvironmentError as e:35        raise PkgConfigError("cannot run pkg-config: %s" % (str(e).strip(),))36 37    bout, berr = pc.communicate()38    if pc.returncode != 0:39        try:40            berr = berr.decode(encoding)41        except Exception:42            pass43        raise PkgConfigError(berr.strip())44 45    if sys.version_info >= (3,) and not isinstance(bout, str):   # Python 3.x46        try:47            bout = bout.decode(encoding)48        except UnicodeDecodeError:49            raise PkgConfigError("pkg-config %s %s returned bytes that cannot "50                                 "be decoded with encoding %r:\n%r" %51                                 (flag, libname, encoding, bout))52 53    if os.altsep != '\\' and '\\' in bout:54        raise PkgConfigError("pkg-config %s %s returned an unsupported "55                             "backslash-escaped output:\n%r" %56                             (flag, libname, bout))57    return bout58 59 60def flags_from_pkgconfig(libs):61    r"""Return compiler line flags for FFI.set_source based on pkg-config output62 63    Usage64        ...65        ffibuilder.set_source("_foo", pkgconfig = ["libfoo", "libbar >= 1.8.3"])66 67    If pkg-config is installed on build machine, then arguments include_dirs,68    library_dirs, libraries, define_macros, extra_compile_args and69    extra_link_args are extended with an output of pkg-config for libfoo and70    libbar.71 72    Raises PkgConfigError in case the pkg-config call fails.73    """74 75    def get_include_dirs(string):76        return [x[2:] for x in string.split() if x.startswith("-I")]77 78    def get_library_dirs(string):79        return [x[2:] for x in string.split() if x.startswith("-L")]80 81    def get_libraries(string):82        return [x[2:] for x in string.split() if x.startswith("-l")]83 84    # convert -Dfoo=bar to list of tuples [("foo", "bar")] expected by distutils85    def get_macros(string):86        def _macro(x):87            x = x[2:]    # drop "-D"88            if '=' in x:89                return tuple(x.split("=", 1))  # "-Dfoo=bar" => ("foo", "bar")90            else:91                return (x, None)               # "-Dfoo" => ("foo", None)92        return [_macro(x) for x in string.split() if x.startswith("-D")]93 94    def get_other_cflags(string):95        return [x for x in string.split() if not x.startswith("-I") and96                                             not x.startswith("-D")]97 98    def get_other_libs(string):99        return [x for x in string.split() if not x.startswith("-L") and100                                             not x.startswith("-l")]101 102    # return kwargs for given libname103    def kwargs(libname):104        fse = sys.getfilesystemencoding()105        all_cflags = call(libname, "--cflags")106        all_libs = call(libname, "--libs")107        return {108            "include_dirs": get_include_dirs(all_cflags),109            "library_dirs": get_library_dirs(all_libs),110            "libraries": get_libraries(all_libs),111            "define_macros": get_macros(all_cflags),112            "extra_compile_args": get_other_cflags(all_cflags),113            "extra_link_args": get_other_libs(all_libs),114            }115 116    # merge all arguments together117    ret = {}118    for libname in libs:119        lib_flags = kwargs(libname)120        merge_flags(ret, lib_flags)121    return ret122 
codekingpro/portable-devtools · Team Ai