Esempio n. 1
0
def compile_object(
      src_filename, 
      fn_name = None,  
      src_extension = None, 
      declarations = [],
      extra_objects = [], 
      extra_compile_flags = [], 
      print_commands = None, 
      compiler = None, 
      compiler_flag_prefix = None):
  
  
  if print_commands is None:  print_commands = config.print_commands
  if src_extension is None: src_extension = get_source_extension()
  if compiler is None: compiler = get_compiler()
    
  object_name = src_filename.replace(src_extension, object_extension)
  compiler_flags = get_compiler_flags(extra_compile_flags, compiler_flag_prefix)
  
  if isinstance(compiler, (list,tuple)):
    compiler_cmd = list(compiler)
  else:
    compiler_cmd = [compiler]
    
  compiler_cmd += compiler_flags 
  compiler_cmd += ['-c', src_filename, '-o', object_name]
  run_cmd(compiler_cmd, label = "Compile source")
  
  return CompiledObject(src_filename = src_filename, 
                        object_filename = object_name, 
                        fn_name = fn_name)
Esempio n. 2
0
def compile_module_from_source(
      partial_src, 
      fn_name,
      fn_signature = None,  
      src_filename = None,
      src_extension = None, 
      declarations = [],
      extra_function_sources = [], 
      extra_headers = [],  
      extra_objects = [],
      extra_compile_flags = [], 
      extra_link_flags = [], 
      print_source = None, 
      print_commands = None, 
      compiler = None, 
      compiler_flag_prefix = None, 
      linker_flag_prefix = None):
  
  if print_source is None: print_source = root_config.print_generated_code 
  if print_commands is None: print_commands = config.print_commands
  if src_extension is None: src_extension = get_source_extension()
  
  full_src = create_module_source(partial_src, fn_name, 
                                 extra_headers = python_headers + extra_headers, 
                                 declarations = declarations,  
                                 extra_function_sources = extra_function_sources, 
                                 print_source = print_source)


  digest = hashlib.sha224(full_src).hexdigest()
  
  if config.cache_dir:
    cached_name = os.path.join(config.cache_dir, fn_name + "_" + digest + shared_extension)
    have_cached_version = os.path.exists(cached_name)
  else:
    cached_name = None
    have_cached_version = False

  if have_cached_version:
    shared_name = cached_name
  else:
    src_file = create_source_file(full_src,
                                  fn_name = fn_name,
                                  src_filename = src_filename,
                                  src_extension = src_extension)
    src_filename = src_file.name

    if compiler is None: compiler = get_compiler()

    try:
      compiled_object = compile_object(src_filename,
                                       fn_name = fn_name,
                                       src_extension = src_extension,
                                       extra_objects = extra_objects,
                                       extra_compile_flags = extra_compile_flags,
                                       print_commands = print_commands,
                                       compiler = compiler,
                                       compiler_flag_prefix = compiler_flag_prefix)

      object_name = compiled_object.object_filename
      shared_name = src_filename.replace(src_extension, shared_extension)
      link_module(compiler, object_name, shared_name,
                  extra_objects = extra_objects,
                  extra_link_flags = extra_link_flags,
                  linker_flag_prefix = linker_flag_prefix)

      if config.delete_temp_files:
        os.remove(object_name)
    except CommandFailed:
      # if normal compilation fails, try distutils instead
      if not compiler_is_gnu(compiler):
        raise
      if compiler_flag_prefix or linker_flag_prefix:
        raise

      shared_name = compile_with_distutils(fn_name + "_" + digest,
                                           src_filename,
                                           extra_objects,
                                           extra_compile_flags,
                                           extra_link_flags,
                                           print_commands)

  # if we're caching generated modules, move our output
  # over to the cache directory before loading it up.
  if config.cache_dir and not have_cached_version:
    if print_commands:
      print 'Caching... %s -> %s' % (shared_name, cached_name)
    if not os.path.exists(config.cache_dir):
      os.makedirs(config.cache_dir)
    os.rename(shared_name, cached_name)
    shared_name = cached_name

  if print_commands:
    print "Loading newly compiled extension module %s..." % shared_name
  module =  imp.load_dynamic(fn_name, shared_name)
  #on a UNIX-style filesystem it should be OK to delete a file while it's open
  #since the inode will just float untethered from any name
  #If we ever support windows we should find some other way to delete the .dll 
  c_fn = getattr(module,fn_name)
  
  if config.delete_temp_files and src_filename is not None:
    os.remove(src_filename)
    if not config.cache_dir:
      # window's can't just untether inodes like a UNIX
      # ...have to eventually think of a plan to clean these things up
      if not windows: os.remove(shared_name)
    
  compiled_fn = CompiledPyFn(c_fn = c_fn, 
                             module = module, 
                             shared_filename =  shared_name,
                             src = full_src, 
                             src_filename = src_filename,
                             fn_name = fn_name, 
                             fn_signature = fn_signature)
  return compiled_fn