docs: def detect_version(basedir, compiler=None, **compiler_attrs):
      """Compile, link & execute a test program, in empty directory `basedir`.
  
      The C compiler will be updated with any keywords given via setattr.
  
      Parameters
      ----------
  
      basedir : path
          The location where the test program will be compiled and run
      compiler : str
          The distutils compiler key (e.g. 'unix', 'msvc', or 'mingw32')
      **compiler_attrs : dict
          Any extra compiler attributes, which will be set via ``setattr(cc)``.
  
      Returns
      -------
  
      A dict of properties for zmq compilation, with the following two keys:
  
      vers : tuple
          The ZMQ version as a tuple of ints, e.g. (2,2,0)
      settings : dict
          The compiler options used to compile the test function, e.g. `include_dirs`,
          `library_dirs`, `libs`, etc.
      """
      if compiler is None:
          compiler = get_default_compiler()
      cfile = pjoin(basedir, 'vers.cpp')
      shutil.copy(pjoin(os.path.dirname(__file__), 'vers.cpp'), cfile)
  
      # check if we need to link against Realtime Extensions library
      if sys.platform.startswith('linux'):
          cc = ccompiler.new_compiler(compiler=compiler)
          cc.output_dir = basedir
          if not cc.has_function('timer_create'):
              if 'libraries' not in compiler_attrs:
                  compiler_attrs['libraries'] = []
              compiler_attrs['libraries'].append('rt')
  
      cc = get_compiler(compiler=compiler, **compiler_attrs)
      efile = test_compilation(cfile, compiler=cc)
      patch_lib_paths(efile, cc.library_dirs)
  
      rc, so, se = get_output_error([efile])
      if rc:
          msg = "Error running version detection script:\n%s\n%s" % (so,se)
          logging.error(msg)
          raise IOError(msg)
  
      handlers = {'vers':  lambda val: tuple(int(v) for v in val.split('.'))}
  
      props = {}
      for line in (x for x in so.split('\n') if x):
          key, val = line.split(':')
          props[key] = handlers[key](val)
  
      return props