Example #1
0
def test_compilationerror_repr():
    # compilation error output/stdout may be large, but we don't want
    # repr to create a limited version
    c = CompilationError('', '*'*1000)
    assert repr(c) == 'CompilationError(err="""\n\t%s""")' % ('*'*1000,)
    c = CompilationError('*'*1000, '')
    assert repr(c) == 'CompilationError(out="""\n\t%s""")' % ('*'*1000,)
Example #2
0
def try_compile_cache(c_files, eci):
    "Try to compile a program.  Cache success, and error message on failure"
    # Import 'platform' every time, the compiler may have been changed
    from rpython.translator.platform import platform, CompilationError
    path = cache_file_path(c_files, eci, 'try_compile_cache')
    try:
        data = path.read()
        if data == 'True':
            return True
        else:
            raise CompilationError(data, '')
    except py.error.Error:
        pass
    #
    _previous = platform.log_errors
    try:
        platform.log_errors = False
        platform.compile(c_files, eci)
    except CompilationError as e:
        msg = e.out + e.err
        if msg != 'True':
            try_atomic_write(path, msg)
        raise
    finally:
        del platform.log_errors
        # ^^^remove from the instance --- needed so that it can
        # compare equal to another instance without it
        if platform.log_errors != _previous:
            platform.log_errors = _previous
    try_atomic_write(path, "True")
    return True
Example #3
0
 def _handle_error(self, returncode, stdout, stderr, outname):
     if returncode != 0:
         # Microsoft compilers write compilation errors to stdout
         stderr = stdout + stderr
         errorfile = outname.new(ext='errors')
         errorfile.write(stderr, mode='wb')
         if self.log_errors:
             stderrlines = stderr.splitlines()
             for line in stderrlines:
                 log.Error(line)
             # ^^^ don't use ERROR, because it might actually be fine.
             # Also, ERROR confuses lib-python/conftest.py.
         raise CompilationError(stdout, stderr)
Example #4
0
def configure_external_library(name,
                               eci,
                               configurations,
                               symbol=None,
                               _cache={}):
    """try to find the external library.
    On Unix, this simply tests and returns the given eci.

    On Windows, various configurations may be tried to compile the
    given eci object.  These configurations are a list of dicts,
    containing:

    - prefix: if an absolute path, will prefix each include and
              library directories.  If a relative path, the external
              directory is searched for directories which names start
              with the prefix.  The last one in alphabetical order
              chosen, and becomes the prefix.

    - include_dir: prefix + include_dir is added to the include directories

    - library_dir: prefix + library_dir is added to the library directories
    """

    if sys.platform != 'win32':
        configurations = []

    key = (name, eci)
    try:
        return _cache[key]
    except KeyError:
        last_error = None

        # Always try the default configuration
        if {} not in configurations:
            configurations.append({})

        for configuration in configurations:
            prefix = configuration.get('prefix', '')
            include_dir = configuration.get('include_dir', '')
            library_dir = configuration.get('library_dir', '')

            if prefix and not os.path.isabs(prefix):
                import glob

                entries = glob.glob(str(PYPY_EXTERNAL_DIR.join(prefix + '*')))
                if entries:
                    # Get last version
                    prefix = sorted(entries)[-1]
                else:
                    continue

            include_dir = os.path.join(prefix, include_dir)
            library_dir = os.path.join(prefix, library_dir)

            eci_lib = ExternalCompilationInfo(
                include_dirs=include_dir and [include_dir] or [],
                library_dirs=library_dir and [library_dir] or [],
            )
            eci_lib = eci_lib.merge(eci)

            # verify that this eci can be compiled
            try:
                verify_eci(eci_lib)
            except CompilationError as e:
                last_error = e
            else:
                _cache[key] = eci_lib
                return eci_lib

        # Nothing found
        if last_error:
            raise last_error
        else:
            raise CompilationError("Library %s is not installed" % (name, ))
Example #5
0
    def compile(self, cfilenames, eci, outputfilename=None, standalone=True):
        self._ensure_correct_math()
        self.cfilenames = cfilenames
        if standalone:
            ext = ''
        else:
            ext = so_ext
        self.standalone = standalone
        self.libraries = list(eci.libraries)
        self.include_dirs = list(eci.include_dirs)
        self.library_dirs = list(eci.library_dirs)
        self.compile_extra = list(eci.compile_extra)
        self.link_extra = list(eci.link_extra)
        self.frameworks = list(eci.frameworks)
        if not self.name in ('win32', 'darwin', 'cygwin'):  # xxx
            if 'm' not in self.libraries:
                self.libraries.append('m')
            self.compile_extra += CFLAGS + ['-fomit-frame-pointer']
            if 'pthread' not in self.libraries:
                self.libraries.append('pthread')
            if self.name != 'sunos5':
                self.compile_extra += ['-pthread']
                self.link_extra += ['-pthread']
            else:
                self.compile_extra += ['-pthreads']
                self.link_extra += ['-lpthread']
        if self.name == 'win32':
            self.link_extra += ['/DEBUG']  # generate .pdb file
        if self.name == 'darwin':
            # support Fink & Darwinports
            for s in ('/sw/', '/opt/local/'):
                if s + 'include' not in self.include_dirs and \
                   os.path.exists(s + 'include'):
                    self.include_dirs.append(s + 'include')
                if s + 'lib' not in self.library_dirs and \
                   os.path.exists(s + 'lib'):
                    self.library_dirs.append(s + 'lib')
            self.compile_extra += CFLAGS + ['-fomit-frame-pointer']
            for framework in self.frameworks:
                self.link_extra += ['-framework', framework]

        if outputfilename is None:
            self.outputfilename = py.path.local(cfilenames[0]).new(ext=ext)
        else:
            self.outputfilename = py.path.local(outputfilename)
        self.eci = eci
        import distutils.errors
        basename = self.outputfilename.new(ext='')
        data = ''
        try:
            saved_environ = os.environ.copy()
            c = stdoutcapture.Capture(mixed_out_err=True)
            try:
                self._build()
            finally:
                # workaround for a distutils bugs where some env vars can
                # become longer and longer every time it is used
                for key, value in saved_environ.items():
                    if os.environ.get(key) != value:
                        os.environ[key] = value
                foutput, foutput = c.done()
                data = foutput.read()
                if data:
                    fdump = basename.new(ext='errors').open("wb")
                    fdump.write(data)
                    fdump.close()
        except (distutils.errors.CompileError, distutils.errors.LinkError):
            raise CompilationError('', data)
        except:
            print >> sys.stderr, data
            raise
        return self.outputfilename