Exemple #1
0
    def test_build(self, contents, link=True, execute=False, libraries=None,
                   include_dirs=None, library_dirs=None):
        name = os.path.join(self.build_temp, 'conftest-%s.c' % self.conftestidx)
        self.conftestidx += 1
        if os.path.exists(name):
            os.unlink(name)
        thefile = open(name, 'w')
        print_(contents, file=thefile)
        thefile.close()

        sys.stdout.flush()
        sys.stderr.flush()
        mystdout = os.dup(1)
        mystderr = os.dup(2)
        result = True
        try:
            os.dup2(self.ctout, 1)
            os.dup2(self.ctout, 2)
            try:
                objects = self.compiler.compile([name],
                                                output_dir=self.build_temp,
                                                include_dirs=include_dirs,
                                                debug=self.debug)
                if link:
                    self.compiler.link_executable(objects,
                                                  'conftest',
                                                  output_dir=self.build_temp,
                                                  library_dirs=library_dirs,
                                                  libraries=libraries,
                                                  debug=self.debug)
                    if execute:
                        abspath = os.path.abspath(os.path.join(self.build_temp,
                                                               'conftest'))
                        pipe = os.popen(abspath, 'r')
                        result = pipe.read().strip()
                        status = pipe.close()
                        if status is None:
                            status = 0
                        if result == '':
                            result = True
                        if status != 0:
                            result = False
                        
            finally:
                os.dup2(mystdout, 1)
                os.dup2(mystderr, 2)
        except CompileError:
            return False
        except DistutilsExecError:
            return False
        return result
Exemple #2
0
    def check_requirements(self):
        # Load the cached config data from a previous run if possible; compiling
        # things to test for features is slow
        cache_file = os.path.join(self.build_temp, 'config.cache')
        if os.path.exists(cache_file):
            myfile = open(cache_file, 'rb')
            try:
                results = pickle.load(myfile)
            finally:
                myfile.close()
        else:
            results = {}

        self.conftestidx = 0
        
        print_("checking for getifaddrs...", end=' ')

        result = results.get('have_getifaddrs', None)
        if result is not None:
            cached = '(cached)'
        else:
            cached = ''

            if not os.path.exists(self.build_temp):
                os.makedirs(self.build_temp)
            outname = os.path.join(self.build_temp, 'conftest.out')
            self.ctout = os.open(outname, os.O_RDWR | os.O_CREAT | os.O_TRUNC)
            testrig = """
            #include <sys/types.h>
            #include <sys/socket.h>
            #include <ifaddrs.h>
            int main(void) {
              struct ifaddrs *addrs;
              int ret;
              ret = getifaddrs(&addrs);
              freeifaddrs (addrs);
              return 0;
            }
            """
            if self.test_build(testrig):
                result = True
            else:
                result = False

        if result:
            print("found. %s" % cached)
            self.compiler.define_macro('HAVE_GETIFADDRS', 1)
        else:
            print("not found. %s" % cached)

        results['have_getifaddrs'] = result

        print_("checking for getnameinfo...", end=' ')

        result = results.get('have_getnameinfo', None)
        if result is not None:
            cached = '(cached)'
        else:
            cached = ''

            if not os.path.exists(self.build_temp):
                os.makedirs(self.build_temp)
            outname = os.path.join(self.build_temp, 'conftest2.out')
            self.ctout = os.open(outname, os.O_RDWR | os.O_CREAT | os.O_TRUNC)
            testrig = """
            #include <sys/types.h>
            #include <sys/socket.h>
            #include <arpa/inet.h>
            #include <netdb.h>
            #include <stdlib.h>
            int main(void) {
              struct sockaddr_in sin;
              char buffer[256];
              int ret;

              sin.sin_family = AF_INET;
              sin.sin_port = 0;
              sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
              
              ret = getnameinfo ((struct sockaddr *)&sin, sizeof (sin),
                                 buffer, sizeof (buffer),
                                 NULL, 0,
                                 NI_NUMERICHOST);

              return 0;
            }
            """
            if self.test_build(testrig,libraries=libraries):
                result = True
            else:
                result = False

        if result:
            print("found. %s" % cached)
            self.compiler.define_macro('HAVE_GETNAMEINFO', 1)
        else:
            print("not found. %s" % cached)

        results['have_getnameinfo'] = result

        if not results['have_getifaddrs']:
            print_("checking for socket IOCTLs...", end=' ')

            result = results.get('have_socket_ioctls', None)
            if result is not None:
                cached = '(cached)'
            else:
                cached = ''

                if not os.path.exists(self.build_temp):
                    os.makedirs(self.build_temp)
                outname = os.path.join(self.build_temp, 'conftest3.out')
                self.ctout = os.open(outname, os.O_RDWR | os.O_CREAT | os.O_TRUNC)

                result = []
                ioctls = ('SIOCGIFCONF',
                          'SIOCGSIZIFCONF',
                          'SIOCGIFHWADDR',
                          'SIOCGIFADDR',
                          'SIOCGIFFLAGS',
                          'SIOCGIFDSTADDR',
                          'SIOCGIFBRDADDR',
                          'SIOCGIFNETMASK',
                          'SIOCGLIFNUM',
                          'SIOCGLIFCONF',
                          'SIOCGLIFFLAGS')
                added_includes = ""
                if mos.startswith('sunos'):
                    added_includes = """
                     #include <unistd.h>
                     #include <stropts.h>
                     #include <sys/sockio.h>
                    """

                for ioctl in ioctls:
                    testrig = """
                    #include <sys/types.h>
                    #include <sys/socket.h>
                    #include <sys/ioctl.h>
                    #include <net/if.h>
                    #include <netinet/in.h>
                    #include <arpa/inet.h>
                    %(addedinc)s
                    int main(void) {
                        int fd = socket (AF_INET, SOCK_DGRAM, IPPROTO_IP);
                        struct ifreq ifreq;

                        ioctl(fd, %(ioctl)s, &ifreq);

                        return 0;
                    }
                    """ % { 'ioctl': ioctl , 'addedinc': added_includes}

                    if self.test_build(testrig,libraries=libraries):
                        result.append(ioctl)

            if result:
                print("%r. %s" % (result, cached))
                for ioctl in result:
                    self.compiler.define_macro('HAVE_%s' % ioctl, 1)
                self.compiler.define_macro('HAVE_SOCKET_IOCTLS', 1)
            else:
                print("not found. %s" % cached)

            results['have_socket_ioctls'] = result

        print_("checking for optional header files...", end=' ')

        result = results.get('have_headers', None)
        if result is not None:
            cached = '(cached)'
        else:
            cached = ''

            result =[]
            headers = ('net/if_dl.h', 'netash/ash.h',
                       'netatalk/at.h', 'netax25/ax25.h',
                       'neteconet/ec.h', 'netipx/ipx.h',
                       'netpacket/packet.h', 'netrose/rose.h',
                       'linux/irda.h', 'linux/atm.h',
                       'linux/llc.h', 'linux/tipc.h',
                       'linux/dn.h')

            for header in headers:
                testrig = """
                #include <sys/types.h>
                #include <sys/socket.h>
                #include <net/if.h>
                #include <%s>
                int main (void) { return 0; }
                """ % header

                if self.test_build(testrig, link=False):
                    result.append(header)

        if result:
            print("%s. %s" % (' '.join(result), cached))
            for header in result:
                macro = header.upper().replace('.', '_').replace('/', '_')
                self.compiler.define_macro('HAVE_%s' % macro, 1)
        else:
            print("none found. %s" % cached)

        optional_headers = result
        results['have_headers'] = result

        print_("checking whether struct sockaddr has a length field...", end=' ')

        result = results.get('have_sockaddr_sa_len', None)
        if result is not None:
            cached = '(cached)'
        else:
            cached = ''

            testrig = """
            #include <sys/types.h>
            #include <sys/socket.h>
            #include <net/if.h>

            int main (void) {
              struct sockaddr sa;
              sa.sa_len = 5;
              return 0;
            }
            """

            result = self.test_build(testrig)

        if result:
            print('yes. %s' % cached)
            self.compiler.define_macro('HAVE_SOCKADDR_SA_LEN', 1)
        else:
            print('no. %s' % cached)

        results['have_sockaddr_sa_len'] = result

        if not results['have_sockaddr_sa_len']:
            # GAK! On certain stupid platforms (Linux), there's no sa_len.
            # Macho Linux programmers apparently think that it's not needed,
            # however, unfortunately, getifaddrs() doesn't return the
            # lengths, because they're in the sa_len field on just about
            # everything but Linux.
            print_("checking which sockaddr_xxx structs are defined...", end=' ')
            
            result = results.get('have_sockaddrs', None)
            if result is not None:
                cached = '(cached)'
            else:
                cached = ''

                if not os.path.exists(self.build_temp):
                    os.makedirs(self.build_temp)
                outname = os.path.join(self.build_temp, 'conftest4.out')
                self.ctout = os.open(outname, os.O_RDWR | os.O_CREAT | os.O_TRUNC)

                sockaddrs = ('at', 'ax25', 'dl', 'eon', 'in', 'in6',
                             'inarp', 'ipx', 'iso', 'ns', 'un', 'x25',
                             'rose', 'ash', 'ec', 'll', 'atmpvc', 'atmsvc',
                             'dn', 'irda', 'llc')
                result = []
                for sockaddr in sockaddrs:
                    testrig = """
                    #include <sys/types.h>
                    #include <sys/socket.h>
                    #include <sys/un.h>
                    #include <net/if.h>
                    #include <netinet/in.h>
                    %(includes)s
                    
                    int main (void) {
                      struct sockaddr_%(sockaddr)s sa;
                      return 0;
                    }
                    """ % { 'includes': '\n'.join(["#include <%s>" % header
                                                   for header
                                                   in optional_headers]),
                            'sockaddr': sockaddr }

                    if self.test_build(testrig):
                        result.append(sockaddr)
                
            if result:
                print('%s. %s' % (' '.join(result), cached))
                for sockaddr in result:
                    self.compiler.define_macro('HAVE_SOCKADDR_%s' \
                                               % sockaddr.upper(), 1)
            else:
                print('none! %s' % cached)

            results['have_sockaddrs'] = result

       # Save the results to our config.cache file
        myfile = open(cache_file, 'wb')
        try:
            pickle.dump(results, myfile)
        finally:
            myfile.close()