docs: def checkCache(fnm, strip=0, upx=0):
      """
      Cache prevents preprocessing binary files again and again.
      """
      # On darwin a cache is required anyway to keep the libaries
      # with relative install names. Caching on darwin does not work
      # since we need to modify binary headers to use relative paths
      # to dll depencies and starting with '@executable_path'.
  
      if ((not strip and not upx and not is_darwin and not is_win)
          or fnm.lower().endswith(".manifest")):
          return fnm
      if strip:
          strip = 1
      else:
          strip = 0
      if upx:
          upx = 1
      else:
          upx = 0
  
      # Load cache index
      cachedir = os.path.join(CONFIGDIR, 'bincache%d%d' % (strip, upx))
      if not os.path.exists(cachedir):
          os.makedirs(cachedir)
      cacheindexfn = os.path.join(cachedir, "index.dat")
      if os.path.exists(cacheindexfn):
          cache_index = _load_data(cacheindexfn)
      else:
          cache_index = {}
  
      # Verify if the file we're looking for is present in the cache.
      basenm = os.path.normcase(os.path.basename(fnm))
      digest = cacheDigest(fnm)
      cachedfile = os.path.join(cachedir, basenm)
      cmd = None
      if basenm in cache_index:
          if digest != cache_index[basenm]:
              os.remove(cachedfile)
          else:
              # On Mac OS X we need relative paths to dll dependencies
              # starting with @executable_path
              if is_darwin:
                  dylib.mac_set_relative_dylib_deps(cachedfile)
              return cachedfile
      if upx:
          if strip:
              fnm = checkCache(fnm, 1, 0)
          bestopt = "--best"
          # FIXME: Linux builds of UPX do not seem to contain LZMA (they assert out)
          # A better configure-time check is due.
          if config["hasUPX"] >= (3,) and os.name == "nt":
              bestopt = "--lzma"
  
          upx_executable = "upx"
          if config.get('upx_dir'):
              upx_executable = os.path.join(config['upx_dir'], upx_executable)
          cmd = [upx_executable, bestopt, "-q", cachedfile]
      else:
          if strip:
              # -S = strip only debug symbols.
              # The default strip behaviour breaks some shared libraries
              # under Mac OSX
              cmd = ["strip", "-S", cachedfile]
      shutil.copy2(fnm, cachedfile)
      os.chmod(cachedfile, 0755)
  
      if pyasm and fnm.lower().endswith(".pyd"):
          # If python.exe has dependent assemblies, check for embedded manifest
          # of cached pyd file because we may need to 'fix it' for pyinstaller
          try:
              res = winmanifest.GetManifestResources(os.path.abspath(cachedfile))
          except winresource.pywintypes.error, e:
              if e.args[0] == winresource.ERROR_BAD_EXE_FORMAT:
                  # Not a win32 PE file
                  pass
              else:
                  logger.error(os.path.abspath(cachedfile))
                  raise
          else:
              if winmanifest.RT_MANIFEST in res and len(res[winmanifest.RT_MANIFEST]):
                  for name in res[winmanifest.RT_MANIFEST]:
                      for language in res[winmanifest.RT_MANIFEST][name]:
                          try:
                              manifest = winmanifest.Manifest()
                              manifest.filename = ":".join([cachedfile,
                                                            str(winmanifest.RT_MANIFEST),
                                                            str(name),
                                                            str(language)])
                              manifest.parse_string(res[winmanifest.RT_MANIFEST][name][language],
                                                    False)
                          except Exception, exc:
                              logger.error("Cannot parse manifest resource %s, "
                                           "%s from", name, language)
                              logger.error(cachedfile)
                              logger.exception(exc)
                          else:
                              # Fix the embedded manifest (if any):
                              # Extension modules built with Python 2.6.5 have
                              # an empty <dependency> element, we need to add
                              # dependentAssemblies from python.exe for
                              # pyinstaller
                              olen = len(manifest.dependentAssemblies)
                              _depNames = set([dep.name for dep in
                                               manifest.dependentAssemblies])
                              for pydep in pyasm:
                                  if not pydep.name in _depNames:
                                      logger.info("Adding %r to dependent "
                                                  "assemblies of %r",
                                                  pydep.name, cachedfile)
                                      manifest.dependentAssemblies.append(pydep)
                                      _depNames.update(pydep.name)
                              if len(manifest.dependentAssemblies) > olen:
                                  try:
                                      manifest.update_resources(os.path.abspath(cachedfile),
                                                                [name],
                                                                [language])
                                  except Exception, e:
                                      logger.error(os.path.abspath(cachedfile))
                                      raise
  
      if cmd:
          try:
              compat.exec_command(*cmd)
          except OSError, e:
              raise SystemExit("Execution failed: %s" % e)
  
      # update cache index
      cache_index[basenm] = digest
      _save_data(cacheindexfn, cache_index)
  
      # On Mac OS X we need relative paths to dll dependencies
      # starting with @executable_path
      if is_darwin:
          dylib.mac_set_relative_dylib_deps(cachedfile)
      return cachedfile