Changeset 292 for pyyaml/trunk/setup.py


Ignore:
Timestamp:
10/01/08 20:24:42 (6 years ago)
Author:
xi
Message:

Check if libyaml is installed before attempting to compile the libyaml bindings.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pyyaml/trunk/setup.py

    r290 r292  
    3232 
    3333 
     34LIBYAML_CHECK = """ 
     35#include <yaml.h> 
     36 
     37int main(void) { 
     38    yaml_parser_t parser; 
     39    yaml_emitter_t emitter; 
     40 
     41    yaml_parser_initialize(&parser); 
     42    yaml_parser_delete(&parser); 
     43 
     44    yaml_emitter_initialize(&emitter); 
     45    yaml_emitter_delete(&emitter); 
     46 
     47    return 0; 
     48} 
     49""" 
     50 
     51 
     52from distutils import log 
    3453from distutils.core import setup, Command 
    3554from distutils.core import Distribution as _Distribution 
    3655from distutils.core import Extension as _Extension 
     56from distutils.dir_util import mkpath 
    3757from distutils.command.build_ext import build_ext as _build_ext 
     58from distutils.errors import CompileError, LinkError 
    3859 
    3960try: 
     
    5980            self.global_options = [ 
    6081                    (ext.option_name, None, 
    61                         "include %s" % ext.feature_description), 
     82                        "include %s (default if %s is available)" 
     83                        % (ext.feature_description, ext.feature_name)), 
    6284                    (ext.neg_option_name, None, 
    63                         "exclude %s (default)" % ext.feature_description), 
     85                        "exclude %s" % ext.feature_description), 
    6486            ] + self.global_options 
    6587            self.negative_opt = self.negative_opt.copy() 
     
    6991class Extension(_Extension): 
    7092 
    71     def __init__(self, name, sources, feature_name, feature_description, **kwds): 
     93    def __init__(self, name, sources, feature_name, feature_description, 
     94            feature_check, **kwds): 
    7295        if not with_pyrex: 
    7396            for filename in sources[:]: 
     
    78101        self.feature_name = feature_name 
    79102        self.feature_description = feature_description 
     103        self.feature_check = feature_check 
    80104        self.attr_name = 'with_' + feature_name.replace('-', '_') 
    81105        self.option_name = 'with-' + feature_name 
     
    104128        for ext in self.extensions: 
    105129            if isinstance(ext, Extension): 
    106                 if not getattr(self.distribution, ext.attr_name): 
     130                with_ext = getattr(self.distribution, ext.attr_name) 
     131                if with_ext is None: 
     132                    with_ext = self.check_extension_availability(ext) 
     133                if not with_ext: 
    107134                    continue 
    108135            if with_pyrex: 
    109136                ext.sources = self.pyrex_sources(ext.sources, ext) 
    110137            self.build_extension(ext) 
     138 
     139    def check_extension_availability(self, ext): 
     140        cache = os.path.join(self.build_temp, 'check_%s.out' % ext.feature_name) 
     141        if not self.force and os.path.isfile(cache): 
     142            data = open(cache).read().strip() 
     143            if data == '1': 
     144                return True 
     145            elif data == '0': 
     146                return False 
     147        mkpath(self.build_temp) 
     148        src = os.path.join(self.build_temp, 'check_%s.c' % ext.feature_name) 
     149        open(src, 'w').write(ext.feature_check) 
     150        log.info("checking if %s compiles" % ext.feature_name) 
     151        try: 
     152            [obj] = self.compiler.compile([src], 
     153                    macros=ext.define_macros+[(undef,) for undef in ext.undef_macros], 
     154                    include_dirs=ext.include_dirs, 
     155                    extra_postargs=(ext.extra_compile_args or []), 
     156                    depends=ext.depends) 
     157        except CompileError: 
     158            log.warn("%s appears not to be installed" % ext.feature_name) 
     159            log.warn("(if %s is installed, you may need to specify" 
     160                    % ext.feature_name) 
     161            log.warn(" the option --include-dirs or uncomment and modify") 
     162            log.warn(" the parameter include_dirs in setup.cfg)") 
     163            open(cache, 'w').write('0\n') 
     164            return False 
     165        prog = 'check_%s' % ext.feature_name 
     166        log.info("checking if %s links" % ext.feature_name) 
     167        try: 
     168            self.compiler.link_executable([obj], prog, 
     169                    output_dir=self.build_temp, 
     170                    libraries=ext.libraries, 
     171                    library_dirs=ext.library_dirs, 
     172                    runtime_library_dirs=ext.runtime_library_dirs, 
     173                    extra_postargs=(ext.extra_link_args or [])) 
     174        except LinkError: 
     175            log.warn("unable to link against %s" % ext.feature_name) 
     176            log.warn("(if %s is installed correctly, you may need to specify" 
     177                    % ext.feature_name) 
     178            log.warn(" the option --library-dirs or uncomment and modify") 
     179            log.warn(" the parameter library_dirs in setup.cfg)") 
     180            open(cache, 'w').write('0\n') 
     181            return False 
     182        open(cache, 'w').write('1\n') 
     183        return True 
    111184 
    112185 
     
    149222        ext_modules=[ 
    150223            Extension('yaml/_yaml', ['ext/_yaml.pyx'], 
    151                 'libyaml', "LibYAML bindings", 
     224                'libyaml', "LibYAML bindings", LIBYAML_CHECK, 
    152225                libraries=['yaml']), 
    153226        ], 
Note: See TracChangeset for help on using the changeset viewer.