File: ccompiler.py

package info (click to toggle)
pymssql 2.3.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 972 kB
  • sloc: python: 3,801; sh: 152; makefile: 151; ansic: 1
file content (129 lines) | stat: -rw-r--r-- 3,577 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# -*- coding: utf-8 -*-

import contextlib
from distutils import ccompiler
from distutils.errors import *
import os
import sys
import types


def _has_function(self, funcname, includes=None, include_dirs=None,
                 libraries=None, library_dirs=None):
    """Return a boolean indicating whether funcname is supported on
    the current platform.  The optional arguments can be used to
    augment the compilation environment.
    """
    # this can't be included at module scope because it tries to
    # import math which might not be available at that point - maybe
    # the necessary logic should just be inlined?
    import tempfile
    if includes is None:
        includes = []
    if include_dirs is None:
        include_dirs = []
    if libraries is None:
        libraries = []
    if library_dirs is None:
        library_dirs = []
    fd, fname = tempfile.mkstemp(".c", funcname, text=True)
    f = os.fdopen(fd, "w")
    try:
        for incl in includes:
            f.write("""#include "%s"\n""" % incl)
        f.write("""\
int main (int argc, char **argv) {
%s;
return 0;
}
""" % funcname)
    finally:
        f.close()
    try:
        objects = self.compile([fname], include_dirs=include_dirs)
    except CompileError:
        return False
    finally:
        os.remove(fname)

    try:
        self.link_executable(objects, "a.out",
                             libraries=libraries,
                             library_dirs=library_dirs)
    except (LinkError, TypeError):
        return False
    else:
        os.remove("a.out")
    finally:
        for fn in objects:
            os.remove(fn)

    return True


@contextlib.contextmanager
def stdchannel_redirected(stdchannel, dest_filename):
    """
    A context manager to temporarily redirect stdout or stderr

    e.g.:

    with stdchannel_redirected(sys.stderr, os.devnull):
        ...
    """

    try:
        oldstdchannel = os.dup(stdchannel.fileno())
        dest_file = open(dest_filename, 'w')
        os.dup2(dest_file.fileno(), stdchannel.fileno())

        yield
    finally:
        if oldstdchannel is not None:
            os.dup2(oldstdchannel, stdchannel.fileno())
        if dest_file is not None:
            dest_file.close()


def has_function(*args, **kw):

        with stdchannel_redirected(sys.stderr, os.devnull):
            return _has_function(*args, **kw)


def new_compiler():

    compiler = ccompiler.new_compiler()
    compiler.has_function = types.MethodType(has_function, compiler)
    return compiler


def find_compiler():

    from subprocess import run, STDOUT, PIPE

    for cc in ['cc', 'gcc']:
        x = run("which %s" % cc, stdout=PIPE, stderr=STDOUT, shell=True)
        if x.returncode == 0:
            return True
    return False


def check_clock_gettime(libraries):
    """
        check for clock_gettime, link with librt for glibc<2.17
    """
    compiler = new_compiler()
    try:
        if not compiler.has_function('clock_gettime(0,NULL)', includes=['time.h']):
            if compiler.has_function('clock_gettime(0,NULL)', includes=['time.h'], libraries=['rt']):
                libraries.append('rt')
            else:
                if find_compiler():
                    print("setup.py: could not locate 'clock_gettime' function required by FreeTDS.", file=sys.stderr)
                else:
                    print("setup.py: ERROR: Could not find C compiler", file=sys.stderr)
                sys.exit(1)
    except Exception as exc:
        print(f"setup.py: ERROR: {exc}", file=sys.stderr)
        sys.exit(1)