Beispiel #1
0
    def __init__(self, compiler):
        self.static_fftw_dir = os.environ.get('STATIC_FFTW_DIR', None)
        if not os.path.exists(self.static_fftw_dir):
            raise LinkError('STATIC_FFTW_DIR="%s" was specified but does not exist' % self.static_fftw_dir)

        # call parent init
        super(self.__class__, self).__init__(compiler)
Beispiel #2
0
    def link(
        self,
        target_desc,
        objects,
        output_filename,
        output_dir=None,
        libraries=None,
        library_dirs=None,
        runtime_library_dirs=None,
        export_symbols=None,
        debug=0,
        extra_preargs=None,
        extra_postargs=None,
        build_temp=None,
        target_lang=None,
    ):
        objects, output_dir = self._fix_object_args(objects, output_dir)
        libraries, library_dirs, runtime_library_dirs = self._fix_lib_args(
            libraries, library_dirs, runtime_library_dirs
        )

        lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries)
        if is_string(output_dir):
            output_filename = os.path.join(output_dir, output_filename)
        elif output_dir is not None:
            raise TypeError("'output_dir' must be a string or None")

        if self._need_link(objects, output_filename):
            if self.library_switch[-1] == " ":
                o_args = [self.library_switch.strip(), output_filename]
            else:
                o_args = [self.library_switch.strip() + output_filename]

            if is_string(self.objects):
                ld_args = objects + [self.objects]
            else:
                ld_args = objects + self.objects
            ld_args = ld_args + lib_opts + o_args
            if debug:
                ld_args[:0] = ["-g"]
            if extra_preargs:
                ld_args[:0] = extra_preargs
            if extra_postargs:
                ld_args.extend(extra_postargs)
            self.mkpath(os.path.dirname(output_filename))
            if target_desc == CCompiler.EXECUTABLE:
                linker = self.linker_exe[:]
            else:
                linker = self.linker_so[:]
            command = linker + ld_args
            try:
                self.spawn(command)
            except DistutilsExecError:
                msg = str(get_exception())
                raise LinkError(msg)
        else:
            log.debug("skipping %s (up-to-date)", output_filename)
Beispiel #3
0
    def link(self, target_desc, objects,
             output_filename, output_dir=None, libraries=None,
             library_dirs=None, runtime_library_dirs=None,
             export_symbols=None, debug=0, extra_preargs=None,
             extra_postargs=None, build_temp=None, target_lang=None):
        objects, output_dir = self._fix_object_args(objects, output_dir)
        fixed_args = self._fix_lib_args(libraries, library_dirs,
                                        runtime_library_dirs)
        libraries, library_dirs, runtime_library_dirs = fixed_args

        lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs,
                                   libraries)
        if not isinstance(output_dir, (str, type(None))):
            raise TypeError("'output_dir' must be a string or None")
        if output_dir is not None:
            output_filename = os.path.join(output_dir, output_filename)

        if self._need_link(objects, output_filename):
            ld_args = (objects + self.objects +
                       lib_opts + ['-o', output_filename])
            if debug:
                ld_args[:0] = ['-g']
            if extra_preargs:
                ld_args[:0] = extra_preargs
            if extra_postargs:
                ld_args.extend(extra_postargs)
            self.mkpath(os.path.dirname(output_filename))
            try:
                if target_desc == CCompiler.EXECUTABLE:
                    linker = self.linker_exe[:]
                else:
                    linker = self.linker_so[:]
                if target_lang == "c++" and self.compiler_cxx:
                    # skip over environment variable settings if /usr/bin/env
                    # is used to set up the linker's environment.
                    # This is needed on OSX. Note: this assumes that the
                    # normal and C++ compiler have the same environment
                    # settings.
                    i = 0
                    if os.path.basename(linker[0]) == "env":
                        i = 1
                        while '=' in linker[i]:
                            i += 1
                    linker[i] = self.compiler_cxx[i]

                if sys.platform == 'darwin':
                    linker = _osx_support.compiler_fixup(linker, ld_args)
                    ld_args = ['-arch', 'x86_64'] + ld_args

                self.spawn(linker + ld_args)
            except DistutilsExecError as msg:
                raise LinkError(msg)
        else:
            log.debug("skipping %s (up-to-date)", output_filename)
 def link(self,
          target_desc,
          objects,
          output_filename,
          output_dir=None,
          libraries=None,
          library_dirs=None,
          runtime_library_dirs=None,
          export_symbols=None,
          debug=0,
          extra_preargs=None,
          extra_postargs=None,
          build_temp=None,
          target_lang=None):
     objects, output_dir = self._fix_object_args(objects, output_dir)
     fixed_args = self._fix_lib_args(libraries, library_dirs,
                                     runtime_library_dirs)
     libraries, library_dirs, runtime_library_dirs = fixed_args
     lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs,
                                libraries)
     if not isinstance(output_dir, (str, type(None))):
         raise TypeError("'output_dir' must be a string or None")
     if output_dir is not None:
         output_filename = os.path.join(output_dir, output_filename)
     if self._need_link(objects, output_filename):
         ld_args = objects + self.objects + lib_opts + [
             '-o', output_filename
         ]
         if debug:
             ld_args[:0] = ['-g']
         if extra_preargs:
             ld_args[:0] = extra_preargs
         if extra_postargs:
             ld_args.extend(extra_postargs)
         self.mkpath(os.path.dirname(output_filename))
         try:
             if target_desc == CCompiler.EXECUTABLE:
                 linker = self.linker_exe[:]
             else:
                 linker = self.linker_so[:]
             if target_lang == 'c++' and self.compiler_cxx:
                 i = 0
                 if os.path.basename(linker[0]) == 'env':
                     i = 1
                     while '=' in linker[i]:
                         i += 1
                 linker[i] = self.compiler_cxx[i]
             if sys.platform == 'darwin':
                 linker = _osx_support.compiler_fixup(linker, ld_args)
             self.spawn(linker + ld_args)
         except DistutilsExecError as msg:
             raise LinkError(msg)
     else:
         log.debug('skipping %s (up-to-date)', output_filename)
Beispiel #5
0
def getlibraries():
    """Use system information to find lapack, blas libraries"""
    from distutils.errors import LinkError
    from numpy.distutils import system_info

    hasmkl = system_info.get_info("mkl")
    if hasmkl:
        return ["mkl_rt"]

    libraries = ["lapack", "blas"]
    for lib in libraries:
        if not system_info.get_info(lib):
            raise LinkError("Cannot find {} library".format(lib))
    return libraries
 def link(self, target_desc, objects, output_filename, output_dir=None,
     libraries=None, library_dirs=None, runtime_library_dirs=None,
     export_symbols=None, debug=0, extra_preargs=None, extra_postargs=
     None, build_temp=None, target_lang=None):
     if not self.initialized:
         self.initialize()
     objects, output_dir = self._fix_object_args(objects, output_dir)
     fixed_args = self._fix_lib_args(libraries, library_dirs,
         runtime_library_dirs)
     libraries, library_dirs, runtime_library_dirs = fixed_args
     if runtime_library_dirs:
         self.warn(
             "I don't know what to do with 'runtime_library_dirs': " +
             str(runtime_library_dirs))
     lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs,
         libraries)
     if output_dir is not None:
         output_filename = os.path.join(output_dir, output_filename)
     if self._need_link(objects, output_filename):
         if target_desc == CCompiler.EXECUTABLE:
             if debug:
                 ldflags = self.ldflags_shared_debug[1:]
             else:
                 ldflags = self.ldflags_shared[1:]
         elif debug:
             ldflags = self.ldflags_shared_debug
         else:
             ldflags = self.ldflags_shared
         export_opts = []
         for sym in (export_symbols or []):
             export_opts.append('/EXPORT:' + sym)
         ld_args = ldflags + lib_opts + export_opts + objects + ['/OUT:' +
             output_filename]
         if export_symbols is not None:
             dll_name, dll_ext = os.path.splitext(os.path.basename(
                 output_filename))
             implib_file = os.path.join(os.path.dirname(objects[0]),
                 self.library_filename(dll_name))
             ld_args.append('/IMPLIB:' + implib_file)
         if extra_preargs:
             ld_args[:0] = extra_preargs
         if extra_postargs:
             ld_args.extend(extra_postargs)
         self.mkpath(os.path.dirname(output_filename))
         try:
             self.spawn([self.linker] + ld_args)
         except DistutilsExecError as msg:
             raise LinkError(msg)
     else:
         log.debug('skipping %s (up-to-date)', output_filename)
Beispiel #7
0
 def link(self, *args, **kwargs):
     target_desc = args[0]
     if target_desc == cc.CCompiler.SHARED_OBJECT:
         self._binpath = self.executables['linker_so'][0]
         self._linkOpts = self._SharedLinkOpts
     elif target_desc == cc.CCompiler.EXECUTABLE:
         self._binpath = self.executables['linker_exe'][0]
         self._linkOpts = self._exeLinkOpts
         self._linkOutputOpts = self._outputOpts
     else:
         raise LinkError(
             'This CCompiler implementation does not know'
             ' how to link anything except an extension module (that is, a'
             ' shared object file).')
     return DCompiler.link(self, *args, **kwargs)
Beispiel #8
0
    def build_java2cpython(self):
        sources = self.java2cpython_sources
        distutils.log.info("building java2cpython library")


        # First, compile the source code to object files in the library
        # directory.  (This should probably change to putting object
        # files in a temporary build directory.)
        include_dirs = \
            [sysconfig.get_config_var("INCLUDEPY"), "java"] +\
            get_jvm_include_dirs()
        python_lib_dir, lib_name = self.get_java2cpython_libdest()
        library_dirs = [python_lib_dir]
        output_dir = os.path.join(os.path.dirname(
            self.get_ext_fullpath("javabridge.jars")), "jars")
        export_symbols = ['Java_org_cellprofiler_javabridge_CPython_exec']
        objects = self.compiler.compile(sources,
                                        output_dir=self.build_temp,
                                        include_dirs=include_dirs,
                                        debug=self.debug)
        ver = sys.version_info
        needs_manifest = sys.platform == 'win32' and ver.major == 2 and not is_mingw
        extra_postargs = ["/MANIFEST"] if needs_manifest else None
        libraries = ["python{}{}".format(ver.major, ver.minor)] if is_mingw else None
        self.compiler.link(
            CCompiler.SHARED_OBJECT,
            objects, lib_name,
            output_dir=output_dir,
            debug=self.debug,
            library_dirs=library_dirs,
	    libraries=libraries,
            export_symbols=export_symbols,
            extra_postargs=extra_postargs)
        if needs_manifest:
            temp_dir = os.path.dirname(objects[0])
            manifest_name = lib_name +".manifest"
            lib_path = os.path.join(output_dir, lib_name)
            manifest_file = os.path.join(temp_dir, manifest_name)
            lib_path = os.path.abspath(lib_path)
            manifest_file = os.path.abspath(manifest_file)
            out_arg = '-outputresource:%s;2' % lib_path
            try:
                self.compiler.spawn([
                    'mt.exe', '-nologo', '-manifest', manifest_file,
                    out_arg])
            except DistutilsExecError as msg:
                raise LinkError(msg)
Beispiel #9
0
    def link_osx(self,
                 target_desc,
                 objects,
                 output_filename,
                 output_dir=None,
                 libraries=None,
                 library_dirs=None,
                 runtime_library_dirs=None,
                 export_symbols=None,
                 debug=0,
                 extra_preargs=None,
                 extra_postargs=None,
                 build_temp=None,
                 target_lang=None):
        """Link the objects."""
        # use separate copies, so we can modify the lists
        libraries = copy.copy(libraries or [])
        libraries.extend(self.dll_libraries)

        # Copy of unix link so we can remove the darwin test
        #UnixCCompiler.link(self, target_desc, objects, output_filename,
        #    output_dir, libraries, library_dirs, runtime_library_dirs,
        #    None, # export_symbols, we do this in our def-file
        #    debug, extra_preargs, extra_postargs, build_temp, target_lang)

        objects, output_dir = self._fix_object_args(objects, output_dir)
        libraries, library_dirs, runtime_library_dirs = \
            self._fix_lib_args(libraries, library_dirs, runtime_library_dirs)

        lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs,
                                   libraries)
        #if type(output_dir) not in (StringType, NoneType):
        #    raise TypeError("'output_dir' must be a string or None")
        if output_dir is not None:
            output_filename = os.path.join(output_dir, output_filename)

        if self._need_link(objects, output_filename):
            ld_args = (objects + self.objects + lib_opts +
                       ['-o', output_filename])
            if debug:
                ld_args[:0] = ['-g']
            if extra_preargs:
                ld_args[:0] = extra_preargs
            if extra_postargs:
                ld_args.extend(extra_postargs)
            self.mkpath(os.path.dirname(output_filename))
            try:
                if target_desc == CCompiler.EXECUTABLE:
                    linker = self.linker_exe[:]
                else:
                    linker = self.linker_so[:]
                if target_lang == "c++" and self.compiler_cxx:
                    # skip over environment variable settings if /usr/bin/env
                    # is used to set up the linker's environment.
                    # This is needed on OSX. Note: this assumes that the
                    # normal and C++ compiler have the same environment
                    # settings.
                    i = 0
                    if os.path.basename(linker[0]) == "env":
                        i = 1
                        while '=' in linker[i]:
                            i = i + 1

                    linker[i] = self.compiler_cxx[i]

                #if sys.platform == 'darwin':
                #    linker = _osx_support.compiler_fixup(linker, ld_args)
                #    ld_args = ['-arch', 'x86_64'] + ld_args

                self.spawn(linker + ld_args)
            except DistutilsExecError as msg:
                raise LinkError(msg)
        else:
            log.debug("skipping %s (up-to-date)", output_filename)
Beispiel #10
0
    def link(self, target_desc, objects,
             output_filename, output_dir=None, libraries=None,
             library_dirs=None, runtime_library_dirs=None,
             export_symbols=None, debug=0, extra_preargs=None,
             extra_postargs=None, build_temp=None, target_lang=None):
        objects, output_dir = self._fix_object_args(objects, output_dir)
        fixed_args = self._fix_lib_args(libraries, library_dirs,
                                        runtime_library_dirs)
        libraries, library_dirs, runtime_library_dirs = fixed_args

        lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs,
                                   libraries)
        if not isinstance(output_dir, (str, type(None))):
            raise TypeError("'output_dir' must be a string or None")
        if output_dir is not None:
            output_filename = os.path.join(output_dir, output_filename)

        if self._need_link(objects, output_filename):
            ld_args = (objects + self.objects +
                       lib_opts + ['-o', output_filename])
            if debug:
                ld_args[:0] = ['-g']
            if extra_preargs:
                ld_args[:0] = extra_preargs
            if extra_postargs:
                ld_args.extend(extra_postargs)
            self.mkpath(os.path.dirname(output_filename))
            try:
                if target_desc == CCompiler.EXECUTABLE:
                    linker = self.linker_exe[:]
                else:
                    linker = self.linker_so[:]
                if target_lang == "c++" and self.compiler_cxx:
                    # skip over environment variable settings if /usr/bin/env
                    # is used to set up the linker's environment.
                    # This is needed on OSX. Note: this assumes that the
                    # normal and C++ compiler have the same environment
                    # settings.
                    i = 0
                    if os.path.basename(linker[0]) == "env":
                        i = 1
                        while '=' in linker[i]:
                            i += 1

                    if os.path.basename(linker[i]) == 'ld_so_aix':
                        # AIX platforms prefix the compiler with the ld_so_aix
                        # script, so we need to adjust our linker index
                        offset = 1
                    else:
                        offset = 0

                    linker[i+offset] = self.compiler_cxx[i]

                if sys.platform == 'darwin':
                    linker = _osx_support.compiler_fixup(linker, ld_args)

                # iOS: since clang is not available, we send a nicer error message:
                if (sys.platform == 'darwin' and os.uname().machine.startswith('iP')):
                    raise DistutilsExecError("There are no linkers available on iOS, sorry.")

                self.spawn(linker + ld_args)
            except DistutilsExecError as msg:
                raise LinkError(msg)
        else:
            log.debug("skipping %s (up-to-date)", output_filename)
Beispiel #11
0
    def search_dependencies(self):

        # lib_checks = {}
        data_types = ['DOUBLE', 'SINGLE', 'LONG']
        data_types_short = ['', 'f', 'l']
        lib_types = ['', 'THREADS', 'OMP']
        functions = ['plan_dft', 'init_threads', 'init_threads']
        if self.support_mpi:
            lib_types.append('MPI')
            functions.append('mpi_init')

        for d, s in zip(data_types, data_types_short):
            # first check for serial library...
            basic_lib = self.check('', 'plan_dft', d, s, True)
            self.add_library(basic_lib)

            # ...then multithreading: link check with threads requires
            # the serial library. Both omp and posix define the same
            # function names. Prefer openmp if linking dynamically,
            # else fall back to pthreads.  pthreads can be prioritized over
            # openmp by defining the environment variable PYFFTW_USE_PTHREADS
            if 'PYFFTW_USE_PTHREADS' not in os.environ:
                # openmp requires special linker treatment
                self.linker_flags.append(self.openmp_linker_flag())
                lib_omp = self.check(
                    'OMP', 'init_threads', d, s, basic_lib
                    and not hasattr(self, 'static_fftw_dir'))
                if lib_omp:
                    self.add_library(lib_omp)
                    # manually set flag because it won't be checked below
                    self.compile_time_env[self.HAVE(d, 'THREADS')] = False
                else:
                    self.linker_flags.pop()
            else:
                lib_omp = False
                self.compile_time_env[self.HAVE(d, 'OMP')] = False

            if lib_omp:
                self.compile_time_env[self.HAVE(d, 'THREADS')] = False

            if not lib_omp:
                # -pthread added for gcc/clang when checking for threads
                self.linker_flags.append(self.pthread_linker_flag())
                lib_pthread = self.check('THREADS', 'init_threads', d, s,
                                         basic_lib)
                if lib_pthread:
                    self.add_library(lib_pthread)
                else:
                    self.linker_flags.pop()

            # On windows, the serial and posix threading functions are
            # build into one library as released on fftw.org. openMP
            # and MPI are not supported in the releases
            if get_platform() in ('win32', 'win-amd64'):
                if basic_lib:
                    self.compile_time_env[self.HAVE(d, 'THREADS')] = True

            # check whatever multithreading is available
            self.compile_time_env[self.HAVE(
                d, 'MULTITHREADING')] = self.compile_time_env[self.HAVE(
                    d, 'OMP')] or self.compile_time_env[self.HAVE(
                        d, 'THREADS')]

            # check MPI only if headers were found
            self.add_library(
                self.check('MPI', 'mpi_init', d, s, basic_lib
                           and self.support_mpi))

        # compile only if mpi.h *and* one of the fftw mpi libraries are found
        if self.support_mpi:
            found_mpi_types = []
            for d in data_types:
                if self.compile_time_env['HAVE_' + d + '_MPI']:
                    found_mpi_types.append(d)
        else:
            self.compile_time_env['HAVE_MPI'] = False

        # Pretend FFTW precision not available, regardless if it was found or
        # not. Useful for testing that pyfftw still works without requiring all
        # precisions
        if 'PYFFTW_IGNORE_SINGLE' in os.environ:
            self.compile_time_env['HAVE_SINGLE'] = False
        if 'PYFFTW_IGNORE_DOUBLE' in os.environ:
            self.compile_time_env['HAVE_DOUBLE'] = False
        if 'PYFFTW_IGNORE_LONG' in os.environ:
            self.compile_time_env['HAVE_LONG'] = False

        log.debug(repr(self.compile_time_env))

        # required package: FFTW itself
        have_fftw = False
        for d in data_types:
            have_fftw |= self.compile_time_env['HAVE_' + d]

        if not have_fftw:
            raise LinkError("Could not find any of the FFTW libraries")

        log.info('Build pyFFTW with support for FFTW with')
        for d in data_types:
            if not self.compile_time_env[self.HAVE(d)]:
                continue
            s = d.lower() + ' precision'
            if self.compile_time_env[self.HAVE(d, 'OMP')]:
                s += ' + openMP'
            elif self.compile_time_env[self.HAVE(d, 'THREADS')]:
                s += ' + pthreads'
            if self.compile_time_env[self.HAVE(d, 'MPI')]:
                s += ' + MPI'
            log.info(s)
Beispiel #12
0
    def link(self,
             target_desc,
             objects,
             output_filename,
             output_dir=None,
             libraries=None,
             library_dirs=None,
             runtime_library_dirs=None,
             export_symbols=None,
             debug=0,
             extra_preargs=None,
             extra_postargs=None,
             build_temp=None,
             target_lang=None):
        objects, output_dir = self._fix_object_args(objects, output_dir)
        fixed_args = self._fix_lib_args(libraries, library_dirs,
                                        runtime_library_dirs)
        libraries, library_dirs, runtime_library_dirs = fixed_args

        # lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs,
        #                            libraries)

        if not isinstance(output_dir, (str, type(None))):
            raise TypeError("'output_dir' must be a string or None")
        if output_dir is not None:
            output_filename = os.path.join(output_dir, output_filename)

        if self._need_link(objects, output_filename):
            # ld_args = (objects + self.objects +
            #            lib_opts + [link_output_qualifier, output_filename])
            opt_file = tempfile.NamedTemporaryFile(suffix='.OPT', delete=False)
            opt_lines = []

            for obj_file in objects:
                obj_file_vms = vms.decc.to_vms(obj_file, 0, 0)[0]
                opt_lines.append(obj_file_vms)

            vms_libraries_set = set()

            verbose = False  # True # '_multiarray_umath' in output_filename

            for lib_file in libraries:
                lib_file_vms = None
                _, lib_file_ext = os.path.splitext(lib_file)
                if lib_file_ext:
                    # looks like full path
                    lib_file_ext = lib_file_ext.upper()
                    if lib_file_ext in ('.OLB', '.EXE'):
                        if re.search(r'[:\[\]]', lib_file):
                            lib_file_vms = lib_file
                        else:
                            lib_file_vms = vms.decc.to_vms(lib_file, 0, 0)[0]
                if not lib_file_vms:
                    # find the library in the library_dirs
                    for lib_dir in library_dirs:
                        for lib_ext in ['', '.OLB', '.EXE']:
                            try:
                                lib_path = os.path.join(
                                    lib_dir, lib_file + lib_ext)
                                st = os.stat(lib_path)
                                if not stat.S_ISDIR(st.st_mode):
                                    lib_file_ext = lib_ext
                                    lib_file_vms = vms.decc.to_vms(
                                        lib_path, 0, 0)[0]
                                    break
                            except:
                                pass
                        else:
                            continue
                        break
                if lib_file_vms and lib_file_vms.lower(
                ) not in vms_libraries_set:
                    # write it to the OPT
                    opt_line = lib_file_vms + ('/LIBRARY' if lib_file_ext
                                               == '.OLB' else '/SHAREABLE')
                    opt_lines.append(opt_line)
                    vms_libraries_set.add(lib_file_vms.lower())

            opt_lines.append('GSMATCH=LEQUAL,1,0')
            opt_lines.append('CASE_SENSITIVE=YES')

            proc_names = dict()
            try:
                repository = open('CXX_REPOSITORY/CXX$DEMANGLER_DB')
                for line in repository:
                    full_name = line[31:-1]
                    short_name = line[:31]
                    proc_names[full_name] = short_name
                repository.close()
            except:
                pass

            def shorten_name(name):
                if len(name) <= 31:
                    return name
                try:
                    return proc_names[name]
                except:
                    return name[:31]

            if export_symbols and len(export_symbols):
                opt_lines.append('SYMBOL_VECTOR=( -')
                for export_symbol in export_symbols[:-1]:
                    opt_lines.append(
                        shorten_name(export_symbol) + '=PROCEDURE, -')
                for export_symbol in export_symbols[-1:]:
                    opt_lines.append(
                        shorten_name(export_symbol) + '=PROCEDURE )')

            if verbose:
                print("--- OPT START\n")
                print('\n'.join(opt_lines))
                print("--- OPT END\n")

            opt_file.write(('\n'.join(opt_lines)).encode())
            opt_file.close()
            opt_name_vms = vms.decc.to_vms(opt_file.name, 0, 0)[0]

            link_output_qualifier = '/EXECUTABLE=' if target_desc == CCompiler.EXECUTABLE else '/SHAREABLE='
            output_filename_vms = vms.decc.to_vms(output_filename, 0, 0)[0]
            ld_args = [
                link_output_qualifier + output_filename_vms,
                opt_name_vms + "/OPTIONS"
            ]

            if debug:
                map_file, _ = os.path.splitext(output_filename)
                map_file_vms = vms.decc.to_vms(map_file + '.MAP', 0, 0)[0]
                ld_args[:0] = ['/DEBUG/MAP=' + map_file_vms]

            if extra_preargs:
                ld_args[:0] = extra_preargs

            if extra_postargs:
                ld_args.extend(extra_postargs)

            self.mkpath(os.path.dirname(output_filename))

            try:
                linker = self.linker[:]
                self.spawn(linker + ld_args)
            except DistutilsExecError as msg:
                raise LinkError(msg)
            finally:
                os.unlink(opt_file.name)
        else:
            log.debug("skipping %s (up-to-date)", output_filename)
    def link(
        self,
        target_desc,
        objects,
        output_filename,
        output_dir=None,
        libraries=None,
        library_dirs=None,
        runtime_library_dirs=None,
        export_symbols=None,
        debug=0,
        extra_preargs=None,
        extra_postargs=None,
        build_temp=None,
        target_lang=None,
    ):

        if not self.initialized:
            self.initialize()
        (objects, output_dir) = self._fix_object_args(objects, output_dir)
        fixed_args = self._fix_lib_args(libraries, library_dirs,
                                        runtime_library_dirs)
        (libraries, library_dirs, runtime_library_dirs) = fixed_args

        if runtime_library_dirs:
            self.warn("I don't know what to do with 'runtime_library_dirs': " +
                      str(runtime_library_dirs))

        lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs,
                                   libraries)
        if output_dir is not None:
            output_filename = os.path.join(output_dir, output_filename)

        if self._need_link(objects, output_filename):
            if target_desc == CCompiler.EXECUTABLE:
                if debug:
                    ldflags = self.ldflags_shared_debug[1:]
                else:
                    ldflags = self.ldflags_shared[1:]
            else:
                if debug:
                    ldflags = self.ldflags_shared_debug
                else:
                    ldflags = self.ldflags_shared

            export_opts = []
            for sym in export_symbols or []:
                export_opts.append("/EXPORT:" + sym)

            ld_args = (ldflags + lib_opts + export_opts + objects +
                       ["/OUT:" + output_filename])

            # The MSVC linker generates .lib and .exp files, which cannot be
            # suppressed by any linker switches. The .lib files may even be
            # needed! Make sure they are generated in the temporary build
            # directory. Since they have different names for debug and release
            # builds, they can go into the same directory.
            build_temp = os.path.dirname(objects[0])
            if export_symbols is not None:
                (dll_name,
                 dll_ext) = os.path.splitext(os.path.basename(output_filename))
                implib_file = os.path.join(build_temp,
                                           self.library_filename(dll_name))
                ld_args.append("/IMPLIB:" + implib_file)

            self.manifest_setup_ldargs(output_filename, build_temp, ld_args)

            if extra_preargs:
                ld_args[:0] = extra_preargs
            if extra_postargs:
                ld_args.extend(extra_postargs)

            self.mkpath(os.path.dirname(output_filename))
            try:
                self.spawn([self.linker] + ld_args)
            except DistutilsExecError as msg:
                raise LinkError(msg)

            # embed the manifest
            # XXX - this is somewhat fragile - if mt.exe fails, distutils
            # will still consider the DLL up-to-date, but it will not have a
            # manifest.  Maybe we should link to a temp file?  OTOH, that
            # implies a build environment error that shouldn't go undetected.
            mfinfo = self.manifest_get_embed_info(target_desc, ld_args)
            if mfinfo is not None:
                mffilename, mfid = mfinfo
                out_arg = "-outputresource:%s;%s" % (output_filename, mfid)
                try:
                    self.spawn([
                        "mt.exe", "-nologo", "-manifest", mffilename, out_arg
                    ])
                except DistutilsExecError as msg:
                    raise LinkError(msg)
        else:
            log.debug("skipping %s (up-to-date)", output_filename)
Beispiel #14
0
    def link(self,
             target_desc,
             objects,
             output_filename,
             output_dir=None,
             libraries=None,
             library_dirs=None,
             runtime_library_dirs=None,
             export_symbols=None,
             debug=0,
             extra_preargs=None,
             extra_postargs=None,
             build_temp=None,
             target_lang=None):

        if not self.initialized:
            self.initialize()
        (objects, output_dir) = self._fix_object_args(objects, output_dir)
        fixed_args = self._fix_lib_args(libraries, library_dirs,
                                        runtime_library_dirs)
        (libraries, library_dirs, runtime_library_dirs) = fixed_args

        if runtime_library_dirs:
            self.warn("I don't know what to do with 'runtime_library_dirs': " +
                      str(runtime_library_dirs))

        lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs,
                                   libraries)
        if output_dir is not None:
            output_filename = os.path.join(output_dir, output_filename)

        if self._need_link(objects, output_filename):
            if target_desc == CCompiler.EXECUTABLE:
                if debug:
                    ldflags = self.ldflags_shared_debug[1:]
                else:
                    ldflags = self.ldflags_shared[1:]
            else:
                if debug:
                    ldflags = self.ldflags_shared_debug
                else:
                    ldflags = self.ldflags_shared

            export_opts = []
            for sym in (export_symbols or []):
                export_opts.append("/EXPORT:" + sym)

            ld_args = (ldflags + lib_opts + export_opts + objects +
                       ['/OUT:' + output_filename])

            # The MSVC linker generates .lib and .exp files, which cannot be
            # suppressed by any linker switches. The .lib files may even be
            # needed! Make sure they are generated in the temporary build
            # directory. Since they have different names for debug and release
            # builds, they can go into the same directory.
            build_temp = os.path.dirname(objects[0])
            if export_symbols is not None:
                (dll_name,
                 dll_ext) = os.path.splitext(os.path.basename(output_filename))
                implib_file = os.path.join(build_temp,
                                           self.library_filename(dll_name))
                ld_args.append('/IMPLIB:' + implib_file)

            # Embedded manifests are recommended - see MSDN article titled
            # "How to: Embed a Manifest Inside a C/C++ Application"
            # (currently at http://msdn2.microsoft.com/en-us/library/ms235591(VS.80).aspx)
            # Ask the linker to generate the manifest in the temp dir, so
            # we can embed it later.
            temp_manifest = os.path.join(
                build_temp,
                os.path.basename(output_filename) + ".manifest")
            ld_args.append('/MANIFESTFILE:' + temp_manifest)

            if extra_preargs:
                ld_args[:0] = extra_preargs
            if extra_postargs:
                ld_args.extend(extra_postargs)

            self.mkpath(os.path.dirname(output_filename))
            try:
                self.spawn([self.linker] + ld_args)
            except DistutilsExecError as msg:
                raise LinkError(msg)

            # embed the manifest
            # XXX - this is somewhat fragile - if mt.exe fails, distutils
            # will still consider the DLL up-to-date, but it will not have a
            # manifest.  Maybe we should link to a temp file?  OTOH, that
            # implies a build environment error that shouldn't go undetected.
            if target_desc == CCompiler.EXECUTABLE:
                mfid = 1
            else:
                mfid = 2
                try:
                    # Remove references to the Visual C runtime, so they will
                    # fall through to the Visual C dependency of Python.exe.
                    # This way, when installed for a restricted user (e.g.
                    # runtimes are not in WinSxS folder, but in Python's own
                    # folder), the runtimes do not need to be in every folder
                    # with .pyd's.
                    manifest_f = open(temp_manifest, "rb")
                    manifest_buf = manifest_f.read()
                    manifest_f.close()
                    pattern = re.compile(
                        r"""<assemblyIdentity.*?name=("|')Microsoft\."""\
                        r"""VC\d{2}\.CRT("|').*?(/>|</assemblyIdentity>)""",
                        re.DOTALL)
                    manifest_buf = re.sub(pattern, "", manifest_buf)
                    pattern = "<dependentAssembly>\s*</dependentAssembly>"
                    manifest_buf = re.sub(pattern, "", manifest_buf)
                    manifest_f = open(temp_manifest, "wb")
                    manifest_f.write(manifest_buf)
                    manifest_f.close()
                except IOError:
                    pass
            out_arg = '-outputresource:%s;%s' % (output_filename, mfid)
            try:
                self.spawn(
                    ['mt.exe', '-nologo', '-manifest', temp_manifest, out_arg])
            except DistutilsExecError as msg:
                raise LinkError(msg)
        else:
            log.debug("skipping %s (up-to-date)", output_filename)
 def link(self,
          target_desc,
          objects,
          output_filename,
          output_dir=None,
          libraries=None,
          library_dirs=None,
          runtime_library_dirs=None,
          export_symbols=None,
          debug=0,
          extra_preargs=None,
          extra_postargs=None,
          build_temp=None,
          target_lang=None):
     objects, output_dir = self._fix_object_args(objects, output_dir)
     libraries, library_dirs, runtime_library_dirs = self._fix_lib_args(
         libraries, library_dirs, runtime_library_dirs)
     if runtime_library_dirs:
         log.warn("I don't know what to do with 'runtime_library_dirs': %s",
                  str(runtime_library_dirs))
     if output_dir is not None:
         output_filename = os.path.join(output_dir, output_filename)
     if self._need_link(objects, output_filename):
         if target_desc == CCompiler.EXECUTABLE:
             startup_obj = 'c0w32'
             if debug:
                 ld_args = self.ldflags_exe_debug[:]
             else:
                 ld_args = self.ldflags_exe[:]
         else:
             startup_obj = 'c0d32'
             if debug:
                 ld_args = self.ldflags_shared_debug[:]
             else:
                 ld_args = self.ldflags_shared[:]
         if export_symbols is None:
             def_file = ''
         else:
             head, tail = os.path.split(output_filename)
             modname, ext = os.path.splitext(tail)
             temp_dir = os.path.dirname(objects[0])
             def_file = os.path.join(temp_dir, '%s.def' % modname)
             contents = ['EXPORTS']
             for sym in (export_symbols or []):
                 contents.append('  %s=_%s' % (sym, sym))
             self.execute(write_file, (def_file, contents),
                          'writing %s' % def_file)
         objects2 = map(os.path.normpath, objects)
         objects = [startup_obj]
         resources = []
         for file in objects2:
             base, ext = os.path.splitext(os.path.normcase(file))
             if ext == '.res':
                 resources.append(file)
             else:
                 objects.append(file)
         for l in library_dirs:
             ld_args.append('/L%s' % os.path.normpath(l))
         ld_args.append('/L.')
         ld_args.extend(objects)
         ld_args.extend([',', output_filename])
         ld_args.append(',,')
         for lib in libraries:
             libfile = self.find_library_file(library_dirs, lib, debug)
             if libfile is None:
                 ld_args.append(lib)
             else:
                 ld_args.append(libfile)
         ld_args.append('import32')
         ld_args.append('cw32mt')
         ld_args.extend([',', def_file])
         ld_args.append(',')
         ld_args.extend(resources)
         if extra_preargs:
             ld_args[:0] = extra_preargs
         if extra_postargs:
             ld_args.extend(extra_postargs)
         self.mkpath(os.path.dirname(output_filename))
         try:
             self.spawn([self.linker] + ld_args)
         except DistutilsExecError as msg:
             raise LinkError(msg)
     else:
         log.debug('skipping %s (up-to-date)', output_filename)
Beispiel #16
0
    def run(self):
        global have_greenlet
        global have_good_greenlet
        if not have_stackless and not have_good_greenlet:
            if have_greenlet:
                log.info(
                    'no stackless found, but found old (unusable) greenlet')
            else:
                log.info('no stackless or greenlet found')
            log.info(
                'attempting to download and compile greenlet with easy_install'
            )
            install_purelib = self.get_finalized_command(
                'install').install_purelib
            # Not created yet:
            #so_ext = command_obj.get_finalized_command(
            #    'build_ext').compiler.shared_lib_extension
            from distutils.ccompiler import new_compiler
            so_ext = new_compiler().shared_lib_extension  # '.so'
            from distutils.file_util import copy_file
            from distutils.dir_util import remove_tree
            from distutils.dir_util import copy_tree

            # TODO(pts): Auto-detect pip (is it calling us, setup.py?) and try pip.
            try:
                from setuptools.command import easy_install
            except ImportError:
                easy_install = None
            if not easy_install:
                raise LinkError(
                    'neither stackless or greenlet found, '
                    'and easy_install was not found either to install them, '
                    'see the Installation section of README.txt')

            old_log_level = log._global_log.threshold
            mkpath('tmp')
            greenlet_file_pattern = 'tmp/greenlet-*.egg'
            for filename in glob.glob(greenlet_file_pattern):
                remove_tree(filename)
            if easy_install.main(
                ['-dtmp', '-m', '-U', '-Z', 'greenlet>=0.3.1']):
                # We usually won't reach this, easy_install calls sys.exit.
                raise DistutilsError('installation of greenlet failed')

            # Restore values overridden by easy_install.main.
            # See also setuptools.dist for overriding Distribution.
            log.set_threshold(old_log_level)
            for module in ('distutils.dist', 'distutils.core',
                           'distutils.cmd'):
                __import__(module, {}, {}, ('', )).Distribution = Distribution
            for module in ('distutils.core', 'distutils.extension',
                           'distutils.command.build_ext'):
                __import__(module, {}, {}, ('', )).Extension = Extension

            # Now extract greenlet.so from tmp/greenlet-*.egg
            log.info('extracting greenlet from its egg and installing it')
            greenlet_file_names = glob.glob(greenlet_file_pattern)
            if (len(greenlet_file_names) != 1
                    or not os.path.isdir(greenlet_file_names[0])):
                raise DistutilsError('could not find any of: %s' %
                                     greenlet_file_pattern)
            greenlet_so = 'greenlet' + so_ext
            copy_file(os.path.join(greenlet_file_names[0], greenlet_so),
                      install_purelib)
            egg_info_dir = (os.path.join(
                install_purelib, '-'.join(
                    os.path.basename(greenlet_file_names[0]).split('-')[:-2]))
                            + '.egg-info')
            if os.path.isfile(os.path.join(egg_info_dir, 'PKG-INFO')):
                remove_tree(egg_info_dir)
            copy_tree(os.path.join(greenlet_file_names[0], 'EGG-INFO'),
                      egg_info_dir)

            sys.modules.pop('greenlet', None)
            try:
                import greenlet
                have_greenlet = True
                have_good_greenlet = IsGoodGreenlet(greenlet)
            except ImportError:
                raise LinkError(
                    'neither stackless or greenlet found, '
                    'and could not import greenlet after easy_install, '
                    'see the Installation section of README.txt')
Beispiel #17
0
        def link(target_desc,
                 objects,
                 output_filename,
                 output_dir=None,
                 libraries=None,
                 library_dirs=None,
                 runtime_library_dirs=None,
                 export_symbols=None,
                 debug=0,
                 extra_preargs=None,
                 extra_postargs=None,
                 build_temp=None,
                 target_lang=None):

            if not self.initialized:
                self.initialize()
            objects, output_dir = self._fix_object_args(objects, output_dir)
            fixed_args = self._fix_lib_args(libraries, library_dirs,
                                            runtime_library_dirs)
            libraries, library_dirs, runtime_library_dirs = fixed_args

            if runtime_library_dirs:
                self.warn(
                    "I don't know what to do with 'runtime_library_dirs': " +
                    str(runtime_library_dirs))

            lib_opts = gen_lib_options(self, library_dirs,
                                       runtime_library_dirs, libraries)
            if output_dir is not None:
                output_filename = os.path.join(output_dir, output_filename)

            if self._need_link(objects, output_filename):
                ldflags = self._ldflags[target_desc, debug]

                export_opts = [
                    "/EXPORT:" + sym for sym in (export_symbols or [])
                ]

                ld_args = (ldflags + lib_opts + export_opts + objects +
                           ['/OUT:' + output_filename])

                # The MSVC linker generates .lib and .exp files, which cannot be
                # suppressed by any linker switches. The .lib files may even be
                # needed! Make sure they are generated in the temporary build
                # directory. Since they have different names for debug and release
                # builds, they can go into the same directory.
                build_temp = os.path.dirname(objects[0])
                if export_symbols is not None:
                    (dll_name, dll_ext) = os.path.splitext(
                        os.path.basename(output_filename))
                    implib_file = os.path.join(build_temp,
                                               self.library_filename(dll_name))
                    ld_args.append('/IMPLIB:' + implib_file)

                if extra_preargs:
                    ld_args[:0] = extra_preargs
                if extra_postargs:
                    ld_args.extend(extra_postargs)

                output_dir = os.path.dirname(os.path.abspath(output_filename))
                self.mkpath(output_dir)
                try:
                    ld_args.append("/NODEFAULTLIB:LIBCMT")
                    log.debug('Executing "%s" %s', self.linker,
                              ' '.join(ld_args))
                    self.spawn([self.linker] + ld_args)
                    self._copy_vcruntime(output_dir)
                except DistutilsExecError as msg:
                    print('-----', ld_args)
                    raise LinkError(msg)
            else:
                log.debug("skipping %s (up-to-date)", output_filename)
Beispiel #18
0
    def link(
        self,
        target_desc,
        objects,
        output_filename,
        output_dir=None,
        libraries=None,
        library_dirs=None,
        runtime_library_dirs=None,
        export_symbols=None,
        debug=0,
        extra_preargs=None,
        extra_postargs=None,
        build_temp=None,
        target_lang=None,
    ):
        objects, output_dir = self._fix_object_args(objects, output_dir)
        fixed_args = self._fix_lib_args(libraries, library_dirs,
                                        runtime_library_dirs)
        libraries, library_dirs, runtime_library_dirs = fixed_args

        lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs,
                                   libraries)
        if not isinstance(output_dir, (str, type(None))):
            raise TypeError("'output_dir' must be a string or None")
        if output_dir is not None:
            output_filename = os.path.join(output_dir, output_filename)

        if self._need_link(objects, output_filename):
            ld_args = objects + self.objects + lib_opts + [
                '-o', output_filename
            ]
            if debug:
                ld_args[:0] = ['-g']
            if extra_preargs:
                ld_args[:0] = extra_preargs
            if extra_postargs:
                ld_args.extend(extra_postargs)
            self.mkpath(os.path.dirname(output_filename))
            try:
                # Select a linker based on context: linker_exe when
                # building an executable or linker_so (with shared options)
                # when building a shared library.
                building_exe = target_desc == CCompiler.EXECUTABLE
                linker = (self.linker_exe
                          if building_exe else self.linker_so)[:]

                if target_lang == "c++" and self.compiler_cxx:
                    env, linker_ne = _split_env(linker)
                    aix, linker_na = _split_aix(linker_ne)
                    _, compiler_cxx_ne = _split_env(self.compiler_cxx)
                    _, linker_exe_ne = _split_env(self.linker_exe)

                    params = _linker_params(linker_na, linker_exe_ne)
                    linker = env + aix + compiler_cxx_ne + params

                linker = compiler_fixup(linker, ld_args)

                self.spawn(linker + ld_args)
            except DistutilsExecError as msg:
                raise LinkError(msg)
        else:
            log.debug("skipping %s (up-to-date)", output_filename)
Beispiel #19
0
def AutoDetect(command_obj):
    """Auto detect compilation information for a C extension.

  Args:
    command_obj: Any distutils.command object.
  """
    # We could add more directories (e.g. those in /etc/ld.so.conf), but that's
    # system-specific, see http://stackoverflow.com/questions/2230467 .
    # TODO(pts): Issue a fatal error if libev or libevhdns was not found.
    # TODO(pts): Find libevhdns separately.
    retval = {
        'include_dirs': [],
        'library_dirs': [],
        'libraries': [],
        'define_macros': [],
        'is_found': False,
        'sources': [],
        'depends': []
    }

    if have_stackless:
        retval['define_macros'].append(('COIO_USE_CO_STACKLESS', None))
    elif have_greenlet:
        if not have_good_greenlet:
            raise LinkError('detected old (unusable) version of greenlet, '
                            'see the Installation section of README.txt')
        retval['define_macros'].append(('COIO_USE_CO_GREENLET', None))
    else:
        raise LinkError('neither stackless or greenlet found, '
                        'see the Installation section of README.txt')

    compiler = GetCompiler(command_obj)
    prefixes = filter(
        bool,
        os.getenv('LD_LIBRARY_PATH', '').split(':') +
        [sys.prefix, '/usr/local', '/usr'])
    is_found = False

    is_asked = False
    event_driver = None
    if os.getenv('SYNCLESS_USE_LIBEV', ''):
        assert event_driver is None
        event_driver = 'libev'
    if os.getenv('SYNCLESS_USE_LIBEVENT1', ''):
        assert event_driver is None
        event_driver = 'libevent1'
    if os.getenv('SYNCLESS_USE_LIBEVENT2', ''):
        assert event_driver is None
        event_driver = 'libevent2'
    if os.getenv('SYNCLESS_USE_MINIEVENT', ''):
        assert event_driver is None
        event_driver = 'minievent'
    asked_for_libevhdns = bool(os.getenv('SYNCLESS_USE_LIBEVHDNS', ''))
    allowed_minievent = bool(os.getenv('SYNCLESS_ALLOW_MINIEVENT', '1'))

    if event_driver in (None, 'libev'):
        if FindLib(retval=retval,
                   compiler=compiler,
                   prefixes=prefixes,
                   includes=['ev.h'],
                   library='ev',
                   symbols=['ev_once']):
            if asked_for_libevhdns:
                if not FindLib(retval=retval,
                               compiler=compiler,
                               prefixes=prefixes,
                               includes=[()],
                               library='evhdns',
                               symbols=['evdns_resolve_ipv4'],
                               link_with_prev_libraries=['ev']):
                    raise LinkError('evhdns not found')
                retval['define_macros'].append(('COIO_USE_LIBEVHDNS', None))
                retval['libraries'].append('evhdns')
            else:
                retval['define_macros'].append(('COIO_USE_MINIHDNS', None))
                retval['sources'].append('coio_src/coio_minihdns.c')
            event_driver = 'libev'
            retval['is_found'] = True
            retval['libraries'].append('ev')
            retval['define_macros'].append(('COIO_USE_LIBEV', None))

    # TODO(pts): Add support for evhdns here.
    if event_driver in (None, 'libevent2'):
        if asked_for_libevhdns:
            # TODO(pts): Add support for evhdns here.
            raise LinkError('evhdns does not work yet with libevent2')
        # event2/event_compat.h in libevent-2.0.10 doesn't contain a prototype
        # for event_reinit() and event_add() (they are in event2/event.h), so we
        # don't check for those here.
        if (FindLib(retval=retval,
                    compiler=compiler,
                    prefixes=prefixes,
                    includes=['event2/event_compat.h'],
                    library='event',
                    symbols=['event_init', 'event_loop']) and FindLib(
                        retval=retval,
                        compiler=compiler,
                        prefixes=prefixes,
                        includes=['event2/dns.h', 'event2/dns_compat.h'],
                        library='event',
                        symbols=[
                            'evdns_resolve_ipv4', 'evdns_resolve_reverse_ipv6'
                        ])):
            event_driver = 'libevent2'
            retval['is_found'] = True
            # TODO(pts): Try to link something libevent1 doesn't have.
            retval['libraries'].extend(['event'])
            retval['define_macros'].append(('COIO_USE_LIBEVENT2', None))

    if event_driver in (None, 'libevent1'):
        if asked_for_libevhdns:
            # TODO(pts): Add support for evhdns here.
            raise LinkError('evhdns does not work yet with libevent1')
        lib_event = 'event'
        prefixes2 = list(prefixes)
        for prefix in prefixes:
            # Prefer libevent-1.4.so* because libevent.so might be libevent2 (sigh).
            lib_file = os.path.join(prefix, 'lib', 'libevent-1.4.so.2')
            if os.path.isfile(lib_file):
                lib_event = lib_file
                prefixes2 = [prefix]
                break
        if (FindLib(retval=retval,
                    compiler=compiler,
                    prefixes=prefixes2,
                    includes=['./coio_src/coio_event1_event.h'],
                    library=lib_event,
                    symbols=['event_init', 'event_loop', 'event_reinit']) and
                FindLib(retval=retval,
                        compiler=compiler,
                        prefixes=prefixes2,
                        includes=['evdns.h'],
                        library=lib_event,
                        symbols=[
                            'evdns_resolve_ipv4', 'evdns_resolve_reverse_ipv6'
                        ])):
            event_driver = 'libevent1'
            retval['is_found'] = True
            retval['libraries'].append(lib_event)
            retval['define_macros'].append(('COIO_USE_LIBEVENT1', None))

    if event_driver in ('minievent', None) and allowed_minievent:
        event_driver = 'minievent'
        retval['is_found'] = True
        retval['define_macros'].append(('COIO_USE_MINIEVENT', None))
        if asked_for_libevhdns:
            if not FindLib(retval=retval,
                           compiler=compiler,
                           prefixes=prefixes,
                           includes=[()],
                           library='evhdns',
                           symbols=['evdns_resolve_ipv4'],
                           link_with_prev_libraries=['ev']):
                raise LinkError('evhdns not found')
            retval['define_macros'].append(('COIO_USE_LIBEVHDNS', None))
            retval['libraries'].append('evhdns')
        else:
            retval['define_macros'].append(('COIO_USE_MINIHDNS', None))
            retval['sources'].append('coio_src/coio_minihdns.c')
        retval['sources'].append('coio_src/coio_minievent.c')
        retval['depends'].append('coio_src/coio_minievent.h')

    if not retval.pop('is_found'):
        raise LinkError('libevent/libev not found, '
                        'see the Installation section of README.txt')

    retval['python_version'] = sys.version
    repr_retval = repr(retval)
    if 'setuptools' in sys.modules and '-q' in sys.argv:
        log.error('using C env %s' % repr_retval)
    else:
        log.info('using C env %s' % repr_retval)
    try:
        old_repr_retval = open('setup.cenv').read()
    except IOError:
        old_repr_retval = None
    if repr_retval != old_repr_retval:
        open('setup.cenv', 'w').write(repr_retval)
    return retval
Beispiel #20
0
    def search_dependencies(self):

        # lib_checks = {}
        data_types = ['DOUBLE', 'SINGLE', 'LONG', 'QUAD']
        data_types_short = ['', 'f', 'l', 'q']
        lib_types = ['', 'THREADS', 'OMP']
        functions = ['plan_dft', 'init_threads', 'init_threads']
        if self.support_mpi:
            lib_types.append('MPI')
            functions.append('mpi_init')

        for d, s in zip(data_types, data_types_short):
            # first check for serial library...
            basic_lib = self.check('', 'plan_dft', d, s, True)
            self.add_library(basic_lib)

            # ...then multithreading: link check with threads requires
            # the serial library. Both omp and posix define the same
            # function names. Prefer openmp if linking dynamically,
            # else fall back to pthreads.  pthreads can be prioritized over
            # openmp by defining the environment variable PYFFTW_USE_PTHREADS
            if 'PYFFTW_USE_PTHREADS' not in os.environ:
                # openmp requires special linker treatment
                self.linker_flags.append(self.openmp_linker_flag())
                lib_omp = self.check(
                    'OMP', 'init_threads', d, s, basic_lib
                    and not hasattr(self, 'static_fftw_dir'))
                if lib_omp:
                    self.add_library(lib_omp)
                else:
                    self.linker_flags.pop()
            else:
                lib_omp = False
                self.compile_time_env[self.HAVE(d, 'OMP')] = False

            if lib_omp:
                self.compile_time_env[self.HAVE(d, 'THREADS')] = False

            if not lib_omp:
                # -pthread added for gcc/clang when checking for threads
                self.linker_flags.append(self.pthread_linker_flag())
                lib_pthread = self.check('THREADS', 'init_threads', d, s,
                                         basic_lib)
                if lib_pthread:
                    self.add_library(lib_pthread)
                else:
                    self.linker_flags.pop()

            # check MPI only if headers were found
            self.add_library(
                self.check('MPI', 'mpi_init', d, s, basic_lib
                           and self.support_mpi))

            # On windows, the serial and posix threading functions are
            # build into one library as released on fftw.org. mpi is
            # not supported in the releases
            if get_platform() in ('win32', 'win-amd64'):
                if basic_lib:
                    self.compile_time_env[self.HAVE(d, 'THREADS')] = True

        # optional packages summary: True if exists for any of the data types
        for l in lib_types[1:]:
            self.compile_time_env['HAVE_' + l] = False
            for d in data_types:
                self.compile_time_env['HAVE_' +
                                      l] |= self.compile_time_env[self.HAVE(
                                          d, l)]

        # compile only if mpi.h *and* one of the fftw mpi libraries are found
        if self.support_mpi:
            found_mpi_types = []
            for d in data_types:
                if self.compile_time_env['HAVE_' + d + '_MPI']:
                    found_mpi_types.append(d)
        else:
            self.compile_time_env['HAVE_MPI'] = False

        log.debug(repr(self.compile_time_env))

        # required package: FFTW itself
        have_fftw = False
        for d in data_types:
            have_fftw |= self.compile_time_env['HAVE_' + d]

        if not have_fftw:
            raise LinkError("Could not find any of the FFTW libraries")

        log.info('Discovered FFTW with')
        for d in data_types:
            if not self.compile_time_env[self.HAVE(d)]:
                continue
            s = d.lower() + ' precision'
            if self.compile_time_env[self.HAVE(d, 'OMP')]:
                s += ' + openMP'
            elif self.compile_time_env[self.HAVE(d, 'THREADS')]:
                s += ' + pthreads'
            if self.compile_time_env[self.HAVE(d, 'MPI')]:
                s += ' + MPI'
            log.info(s)
Beispiel #21
0
    def link(self,
             target_desc,
             objects,
             output_filename,
             output_dir=None,
             libraries=None,
             library_dirs=None,
             runtime_library_dirs=None,
             export_symbols=None,
             debug=0,
             extra_preargs=None,
             extra_postargs=None,
             build_temp=None,
             target_lang=None):

        # XXX this ignores 'build_temp'!  should follow the lead of
        # msvccompiler.py

        (objects, output_dir) = self._fix_object_args(objects, output_dir)
        (libraries, library_dirs, runtime_library_dirs) = \
            self._fix_lib_args (libraries, library_dirs, runtime_library_dirs)

        if runtime_library_dirs:
            log.warn("I don't know what to do with 'runtime_library_dirs': %s",
                     str(runtime_library_dirs))

        if output_dir is not None:
            output_filename = os.path.join(output_dir, output_filename)

        if self._need_link(objects, output_filename):

            # Figure out linker args based on type of target.
            if target_desc == CCompiler.EXECUTABLE:
                startup_obj = 'c0w32'
                if debug:
                    ld_args = self.ldflags_exe_debug[:]
                else:
                    ld_args = self.ldflags_exe[:]
            else:
                startup_obj = 'c0d32'
                if debug:
                    ld_args = self.ldflags_shared_debug[:]
                else:
                    ld_args = self.ldflags_shared[:]

            # Create a temporary exports file for use by the linker
            if export_symbols is None:
                def_file = ''
            else:
                head, tail = os.path.split(output_filename)
                modname, ext = os.path.splitext(tail)
                temp_dir = os.path.dirname(
                    objects[0])  # preserve tree structure
                def_file = os.path.join(temp_dir, '%s.def' % modname)
                contents = ['EXPORTS']
                for sym in (export_symbols or []):
                    contents.append('  %s=_%s' % (sym, sym))
                self.execute(write_file, (def_file, contents),
                             "writing %s" % def_file)

            # Borland C++ has problems with '/' in paths
            objects2 = map(os.path.normpath, objects)
            # split objects in .obj and .res files
            # Borland C++ needs them at different positions in the command line
            objects = [startup_obj]
            resources = []
            for file in objects2:
                (base, ext) = os.path.splitext(os.path.normcase(file))
                if ext == '.res':
                    resources.append(file)
                else:
                    objects.append(file)

            for l in library_dirs:
                ld_args.append("/L%s" % os.path.normpath(l))
            ld_args.append("/L.")  # we sometimes use relative paths

            # list of object files
            ld_args.extend(objects)

            # XXX the command-line syntax for Borland C++ is a bit wonky;
            # certain filenames are jammed together in one big string, but
            # comma-delimited.  This doesn't mesh too well with the
            # Unix-centric attitude (with a DOS/Windows quoting hack) of
            # 'spawn()', so constructing the argument list is a bit
            # awkward.  Note that doing the obvious thing and jamming all
            # the filenames and commas into one argument would be wrong,
            # because 'spawn()' would quote any filenames with spaces in
            # them.  Arghghh!.  Apparently it works fine as coded...

            # name of dll/exe file
            ld_args.extend([',', output_filename])
            # no map file and start libraries
            ld_args.append(',,')

            for lib in libraries:
                # see if we find it and if there is a bcpp specific lib
                # (xxx_bcpp.lib)
                libfile = self.find_library_file(library_dirs, lib, debug)
                if libfile is None:
                    ld_args.append(lib)
                    # probably a BCPP internal library -- don't warn
                else:
                    # full name which prefers bcpp_xxx.lib over xxx.lib
                    ld_args.append(libfile)

            # some default libraries
            ld_args.append('import32')
            ld_args.append('cw32mt')

            # def file for export symbols
            ld_args.extend([',', def_file])
            # add _resource files
            ld_args.append(',')
            ld_args.extend(resources)

            if extra_preargs:
                ld_args[:0] = extra_preargs
            if extra_postargs:
                ld_args.extend(extra_postargs)

            self.mkpath(os.path.dirname(output_filename))
            try:
                self.spawn([self.linker] + ld_args)
            except DistutilsExecError as msg:
                raise LinkError(msg)

        else:
            log.debug("skipping %s (up-to-date)", output_filename)
Beispiel #22
0
    def _link(self, output, sources):
        args = []
        libtool = utils.get_libtool_command(self._options)
        if libtool:
            # Note: MSVC Builds do not use libtool!
            # In the libtool case, put together the linker command, as we did before.
            # We aren't using distutils to link in this case.
            args.extend(libtool)
            args.append('--mode=link')
            args.append('--tag=CC')
            if self._options.quiet:
                args.append('--silent')

            args.extend(self._linker_cmd)

            args.extend(['-o', output])
            if os.name == 'nt':
                args.append('-Wl,--export-all-symbols')
            else:
                args.append('-export-dynamic')

        if not self._compiler.check_is_msvc():
            # These envvars are not used for MSVC Builds!
            # MSVC Builds use the INCLUDE, LIB envvars,
            # which are automatically picked up during
            # compilation and linking
            for cppflag in shlex.split(os.environ.get('CPPFLAGS', '')):
                args.append(cppflag)
            for cflag in shlex.split(os.environ.get('CFLAGS', '')):
                args.append(cflag)

        # Make sure to list the library to be introspected first since it's
        # likely to be uninstalled yet and we want the uninstalled RPATHs have
        # priority (or we might run with installed library that is older)
        for source in sources:
            if not os.path.exists(source):
                raise CompilerError(
                    "Could not find object file: %s" % (source, ))

        if libtool:
            args.extend(sources)

        pkg_config_libs = self._run_pkgconfig('--libs')

        if not self._options.external_library:
            self._compiler.get_internal_link_flags(args,
                                                   libtool,
                                                   self._options.libraries,
                                                   self._options.extra_libraries,
                                                   self._options.library_paths)
            args.extend(pkg_config_libs)

        else:
            args.extend(pkg_config_libs)
            self._compiler.get_external_link_flags(args,
                                                   libtool,
                                                   self._options.libraries)

        if not self._compiler.check_is_msvc():
            for ldflag in shlex.split(os.environ.get('LDFLAGS', '')):
                args.append(ldflag)

        if not libtool:
            # non-libtool: prepare distutils for linking the introspection
            # dumper program...
            try:
                self._compiler.link(output,
                                    sources,
                                    args)

            # Ignore failing to embed the manifest files, when the manifest
            # file does not exist, especially for MSVC 2010 and later builds.
            # If we are on Visual C++ 2005/2008, where
            # this embedding is required, the build will fail anyway, as
            # the dumper program will likely fail to run, and this means
            # something went wrong with the build.
            except LinkError as e:
                if self._compiler.check_is_msvc():
                    msg = str(e)

                    if msg[msg.rfind('mt.exe'):] == 'mt.exe\' failed with exit status 31':
                        if sys.version_info < (3, 0):
                            sys.exc_clear()
                        pass
                    else:
                        raise LinkError(e)
                else:
                    raise LinkError(e)
        else:
            # libtool: Run the assembled link command, we don't use distutils
            # for linking here.
            if not self._options.quiet:
                print("g-ir-scanner: link: %s" % (
                    subprocess.list2cmdline(args), ))
                sys.stdout.flush()
            msys = os.environ.get('MSYSTEM', None)
            if msys:
                shell = os.environ.get('SHELL', 'sh.exe')
                # Create a temporary script file that
                # runs the command we want
                tf, tf_name = tempfile.mkstemp()
                with os.fdopen(tf, 'wb') as f:
                    shellcontents = ' '.join([x.replace('\\', '/') for x in args])
                    fcontents = '#!/bin/sh\nunset PWD\n{}\n'.format(shellcontents)
                    f.write(fcontents)
                shell = utils.which(shell)
                args = [shell, tf_name.replace('\\', '/')]
            try:
                subprocess.check_call(args)
            except subprocess.CalledProcessError as e:
                raise LinkerError(e)
            finally:
                if msys:
                    os.remove(tf_name)
    def link(self,
             target_desc,
             objects,
             output_filename,
             output_dir=None,
             libraries=None,
             library_dirs=None,
             runtime_library_dirs=None,
             export_symbols=None,
             debug=0,
             extra_preargs=None,
             extra_postargs=None,
             build_temp=None,
             target_lang=None):
        objects, output_dir = self._fix_object_args(objects, output_dir)
        fixed_args = self._fix_lib_args(libraries, library_dirs,
                                        runtime_library_dirs)
        libraries, library_dirs, runtime_library_dirs = fixed_args

        # filter out standard library paths, which are not explicitely needed
        # for linking
        system_libdirs = ['/lib', '/lib64', '/usr/lib', '/usr/lib64']
        multiarch = sysconfig.get_config_var("MULTIARCH")
        if multiarch:
            system_libdirs.extend(
                ['/lib/%s' % multiarch,
                 '/usr/lib/%s' % multiarch])
        library_dirs = [
            dir for dir in library_dirs if not dir in system_libdirs
        ]
        runtime_library_dirs = [
            dir for dir in runtime_library_dirs if not dir in system_libdirs
        ]

        lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs,
                                   libraries)
        if not isinstance(output_dir, (str, type(None))):
            raise TypeError("'output_dir' must be a string or None")
        if output_dir is not None:
            output_filename = os.path.join(output_dir, output_filename)

        if self._need_link(objects, output_filename):
            ld_args = (objects + self.objects + lib_opts +
                       ['-o', output_filename])
            if debug:
                ld_args[:0] = ['-g']
            if extra_preargs:
                ld_args[:0] = extra_preargs
            if extra_postargs:
                ld_args.extend(extra_postargs)
            self.mkpath(os.path.dirname(output_filename))
            try:
                if target_desc == CCompiler.EXECUTABLE:
                    linker = self.linker_exe[:]
                else:
                    linker = self.linker_so[:]
                if target_lang == "c++" and self.compiler_cxx:
                    # skip over environment variable settings if /usr/bin/env
                    # is used to set up the linker's environment.
                    # This is needed on OSX. Note: this assumes that the
                    # normal and C++ compiler have the same environment
                    # settings.
                    i = 0
                    if os.path.basename(linker[0]) == "env":
                        i = 1
                        while '=' in linker[i]:
                            i += 1

                    if os.path.basename(linker[i]) == 'ld_so_aix':
                        # AIX platforms prefix the compiler with the ld_so_aix
                        # script, so we need to adjust our linker index
                        offset = 1
                    else:
                        offset = 0

                    linker[i + offset] = self.compiler_cxx[i]

                if sys.platform == 'darwin':
                    linker = _osx_support.compiler_fixup(linker, ld_args)

                self.spawn(linker + ld_args)
            except DistutilsExecError as msg:
                raise LinkError(msg)
        else:
            log.debug("skipping %s (up-to-date)", output_filename)
Beispiel #24
0
    def link(self,
             target_desc,
             objects,
             output_filename,
             output_dir=None,
             libraries=None,
             library_dirs=None,
             runtime_library_dirs=None,
             export_symbols=None,
             debug=0,
             extra_preargs=None,
             extra_postargs=None,
             build_temp=None,
             target_lang=None):

        if not self.initialized:
            self.initialize()
        (objects, output_dir) = self._fix_object_args(objects, output_dir)
        fixed_args = self._fix_lib_args(libraries, library_dirs,
                                        runtime_library_dirs)
        (libraries, library_dirs, runtime_library_dirs) = fixed_args

        if runtime_library_dirs:
            self.warn("I don't know what to do with 'runtime_library_dirs': " +
                      str(runtime_library_dirs))

        lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs,
                                   libraries)
        if output_dir is not None:
            output_filename = os.path.join(output_dir, output_filename)

        if self._need_link(objects, output_filename):
            if target_desc == CCompiler.EXECUTABLE:
                if debug:
                    ldflags = self.ldflags_shared_debug[1:]
                else:
                    ldflags = self.ldflags_shared[1:]
            else:
                if debug:
                    ldflags = self.ldflags_shared_debug
                else:
                    ldflags = self.ldflags_shared

            export_opts = []
            for sym in (export_symbols or []):
                export_opts.append("/EXPORT:" + sym)

            ld_args = (ldflags + lib_opts + export_opts + objects +
                       ['/OUT:' + output_filename])

            # The MSVC linker generates .lib and .exp files, which cannot be
            # suppressed by any linker switches. The .lib files may even be
            # needed! Make sure they are generated in the temporary build
            # directory. Since they have different names for debug and release
            # builds, they can go into the same directory.
            build_temp = os.path.dirname(objects[0])
            if export_symbols is not None:
                (dll_name,
                 dll_ext) = os.path.splitext(os.path.basename(output_filename))
                implib_file = os.path.join(build_temp,
                                           self.library_filename(dll_name))
                ld_args.append('/IMPLIB:' + implib_file)

            # Embedded manifests are recommended - see MSDN article titled
            # "How to: Embed a Manifest Inside a C/C++ Application"
            # (currently at http://msdn2.microsoft.com/en-us/library/ms235591(VS.80).aspx)
            # Ask the linker to generate the manifest in the temp dir, so
            # we can embed it later.
            temp_manifest = os.path.join(
                build_temp,
                os.path.basename(output_filename) + ".manifest")
            ld_args.append('/MANIFESTFILE:' + temp_manifest)

            if extra_preargs:
                ld_args[:0] = extra_preargs
            if extra_postargs:
                ld_args.extend(extra_postargs)

            self.mkpath(os.path.dirname(output_filename))
            try:
                self.spawn([self.linker] + ld_args)
            except DistutilsExecError as msg:
                raise LinkError(msg)

            # embed the manifest
            # XXX - this is somewhat fragile - if mt.exe fails, distutils
            # will still consider the DLL up-to-date, but it will not have a
            # manifest.  Maybe we should link to a temp file?  OTOH, that
            # implies a build environment error that shouldn't go undetected.
            mfid = 1 if target_desc == CCompiler.EXECUTABLE else 2
            out_arg = '-outputresource:%s;%s' % (output_filename, mfid)
            try:
                self.spawn(
                    ['mt.exe', '-nologo', '-manifest', temp_manifest, out_arg])
            except DistutilsExecError as msg:
                raise LinkError(msg)
        else:
            log.debug("skipping %s (up-to-date)", output_filename)
Beispiel #25
0
    def link(self,
             target_desc,
             objects,
             output_filename,
             output_dir=None,
             libraries=None,
             library_dirs=None,
             runtime_library_dirs=None,
             export_symbols=None,
             debug=0,
             extra_preargs=None,
             extra_postargs=None,
             build_temp=None,
             target_lang=None):
        # Distutils defaults to None for "unspecified option list"; we want
        # empty lists in that case (this substitution is done here in the body
        # rather than by changing the default parameters in case distutils
        # passes None explicitly).
        libraries = libraries or []
        library_dirs = library_dirs or []
        runtime_library_dirs = runtime_library_dirs or []
        export_symbols = export_symbols or []
        extra_preargs = extra_preargs or []
        extra_postargs = extra_postargs or []

        # On 64-bit Windows we just link to pythonXX.lib from the installation
        if _is_win64():
            library_dirs = list(set(_build_ext_library_dirs() + library_dirs))

        binpath = self._binpath
        if hasattr(self, '_linkOutputOpts'):
            outputOpts = self._linkOutputOpts[:]
        else:
            outputOpts = self._outputOpts[:]
        objectOpts = [_qp(fn) for fn in objects]

        (objects, output_dir) = self._fix_object_args(objects, output_dir)
        (libraries, library_dirs, runtime_library_dirs) = \
            self._fix_lib_args (libraries, library_dirs, runtime_library_dirs)
        if runtime_library_dirs:
            self.warn('This CCompiler implementation does nothing with'
                      ' "runtime_library_dirs": ' + str(runtime_library_dirs))

        if output_dir and os.path.basename(output_filename) == output_filename:
            output_filename = os.path.join(output_dir, output_filename)
        else:
            if not output_filename:
                raise DistutilsFileError( 'Neither output_dir nor' \
                    ' output_filename was specified.')
            output_dir = os.path.dirname(output_filename)
            if not output_dir:
                raise DistutilsFileError( 'Unable to guess output_dir on the'\
                    ' bases of output_filename "%s" alone.' % output_filename)

        # Format the output filename option
        # (-offilename in DMD, -o filename in GDC, -of=filename in LDC)
        outputOpts[-1] = outputOpts[-1] % _qp(
            winpath(output_filename, self.winonly))

        if not os.path.exists(output_dir):
            os.makedirs(output_dir)

        if not self._need_link(objects, output_filename):
            print("All binary output files are up to date.")
            return

        if self.build_exe:
            sharedOpts = []
            linkOpts = self._exeLinkOpts
            pythonLibOpt = []
            if target_desc != cc.CCompiler.EXECUTABLE:
                raise LinkError(
                    'This CCompiler implementation should be building'
                    ' an executable')
        else:
            # The .def file (on Windows) or -shared and -soname (on Linux)
            sharedOpts = self._def_file(build_temp, output_filename)
            if target_desc != cc.CCompiler.SHARED_OBJECT:
                raise LinkError(
                    'This CCompiler implementation should be building '
                    ' a shared object')
            linkOpts = self._linkOpts
        # The python .lib file, if needed
        pythonLibOpt = self._lib_file(libraries)
        if pythonLibOpt:
            pythonLibOpt = _qp(pythonLibOpt)

        # Library linkage options
        print("library_dirs: %s" % (library_dirs, ))
        print("runtime_library_dirs: %s" % (runtime_library_dirs, ))
        print("libraries: %s" % (libraries, ))
        libOpts = gen_lib_options(self, library_dirs, runtime_library_dirs,
                                  libraries)

        # Optimization opts
        if debug:
            optimizationOpts = self._debugOptimizeOpts
        elif self.optimize:
            optimizationOpts = self._releaseOptimizeOpts
        else:
            optimizationOpts = self._defaultOptimizeOpts

        cmdElements = ([binpath] + extra_preargs + linkOpts +
                       optimizationOpts + outputOpts + [pythonLibOpt] +
                       objectOpts + libOpts + sharedOpts + extra_postargs)
        cmdElements = [el for el in cmdElements if el]

        wrapped_spawn(self, cmdElements, 'pyd_link')
    def link(
        self,
        target_desc,
        objects,
        output_filename,
        output_dir=None,
        libraries=None,
        library_dirs=None,
        runtime_library_dirs=None,
        export_symbols=None,
        debug=0,
        extra_preargs=None,
        extra_postargs=None,
        build_temp=None,
        target_lang=None,
    ):

        if not self.initialized:
            self.initialize()
        (objects, output_dir) = self._fix_object_args(objects, output_dir)
        fixed_args = self._fix_lib_args(libraries, library_dirs,
                                        runtime_library_dirs)
        (libraries, library_dirs, runtime_library_dirs) = fixed_args

        if runtime_library_dirs:
            self.warn("I don't know what to do with 'runtime_library_dirs': " +
                      str(runtime_library_dirs))

        lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs,
                                   libraries)
        if output_dir is not None:
            output_filename = os.path.join(output_dir, output_filename)

        if self._need_link(objects, output_filename):
            if target_desc == CCompiler.EXECUTABLE:
                if debug:
                    ldflags = self.ldflags_shared_debug[1:]
                else:
                    ldflags = self.ldflags_shared[1:]
            else:
                if debug:
                    ldflags = self.ldflags_shared_debug
                else:
                    ldflags = self.ldflags_shared

            export_opts = []
            for sym in export_symbols or []:
                export_opts.append("/EXPORT:" + sym)

            ld_args = (ldflags + lib_opts + export_opts + objects +
                       ["/OUT:" + output_filename])

            # The MSVC linker generates .lib and .exp files, which cannot be
            # suppressed by any linker switches. The .lib files may even be
            # needed! Make sure they are generated in the temporary build
            # directory. Since they have different names for debug and release
            # builds, they can go into the same directory.
            if export_symbols is not None:
                (dll_name,
                 dll_ext) = os.path.splitext(os.path.basename(output_filename))
                implib_file = os.path.join(os.path.dirname(objects[0]),
                                           self.library_filename(dll_name))
                ld_args.append("/IMPLIB:" + implib_file)

            if extra_preargs:
                ld_args[:0] = extra_preargs
            if extra_postargs:
                ld_args.extend(extra_postargs)

            self.mkpath(os.path.dirname(output_filename))
            try:
                self.spawn([self.linker] + ld_args)
            except DistutilsExecError as msg:
                raise LinkError(msg)

        else:
            log.debug("skipping %s (up-to-date)", output_filename)
Beispiel #27
0
    def _link(self, output, sources):
        args = []
        libtool = utils.get_libtool_command(self._options)
        if libtool:
            # Note: MSVC Builds do not use libtool!
            # In the libtool case, put together the linker command, as we did before.
            # We aren't using distutils to link in this case.
            args.extend(libtool)
            args.append('--mode=link')
            args.append('--tag=CC')
            if self._options.quiet:
                args.append('--silent')

            args.extend(self._linker_cmd)

            args.extend(['-o', output])
            if os.name == 'nt':
                args.append('-Wl,--export-all-symbols')
            else:
                args.append('-export-dynamic')

        if not self._compiler.check_is_msvc():
            # These envvars are not used for MSVC Builds!
            # MSVC Builds use the INCLUDE, LIB envvars,
            # which are automatically picked up during
            # compilation and linking
            cppflags = os.environ.get('CPPFLAGS', '')
            for cppflag in cppflags.split():
                args.append(cppflag)
            cflags = os.environ.get('CFLAGS', '')
            for cflag in cflags.split():
                args.append(cflag)
            ldflags = os.environ.get('LDFLAGS', '')
            for ldflag in ldflags.split():
                args.append(ldflag)

        # Make sure to list the library to be introspected first since it's
        # likely to be uninstalled yet and we want the uninstalled RPATHs have
        # priority (or we might run with installed library that is older)
        for source in sources:
            if not os.path.exists(source):
                raise CompilerError(
                    "Could not find object file: %s" % (source, ))

        if libtool:
            args.extend(sources)

        pkg_config_libs = self._run_pkgconfig('--libs')

        if not self._options.external_library:
            self._compiler.get_internal_link_flags(args,
                                                   libtool,
                                                   self._options.libraries,
                                                   self._options.library_paths)
            args.extend(pkg_config_libs)

        else:
            args.extend(pkg_config_libs)
            self._compiler.get_external_link_flags(args,
                                                   libtool,
                                                   self._options.libraries)

        if not libtool:
            # non-libtool: prepare distutils for linking the introspection
            # dumper program...
            try:
                self._compiler.link(output,
                                    sources,
                                    args)

            # Ignore failing to embed the manifest files, when the manifest
            # file does not exist, especially for MSVC 2010 and later builds.
            # If we are on Visual C++ 2005/2008, where
            # this embedding is required, the build will fail anyway, as
            # the dumper program will likely fail to run, and this means
            # something went wrong with the build.
            except LinkError, e:
                if self._compiler.check_is_msvc():
                    msg = str(e)

                    if msg[msg.rfind('mt.exe'):] == 'mt.exe\' failed with exit status 31':
                        sys.exc_clear()
                        pass
                    else:
                        raise LinkError(e)
                else:
                    raise LinkError(e)