'Build a wheel from files in specified paths, and use any specified tags
when determining the name of the wheel.'

def build(self, paths, tags=None, wheel_version=None):

    if (tags is None):
        tags = {}
    libkey = list(filter((lambda o: (o in paths)), (u'purelib', u'platlib')))[0]
    if (libkey == u'platlib'):
        is_pure = u'false'
        default_pyver = [IMPVER]
        default_abi = [ABI]
        default_arch = [ARCH]
    else:
        is_pure = u'true'
        default_pyver = [PYVER]
        default_abi = [u'none']
        default_arch = [u'any']
    self.pyver = tags.get(u'pyver', default_pyver)
    self.abi = tags.get(u'abi', default_abi)
    self.arch = tags.get(u'arch', default_arch)
    libdir = paths[libkey]
    name_ver = (u'%s-%s' % (self.name, self.version))
    data_dir = (u'%s.data' % name_ver)
    info_dir = (u'%s.dist-info' % name_ver)
    archive_paths = []
    for key in (u'data', u'headers', u'scripts'):
        if (key not in paths):
            continue
        path = paths[key]
        if os.path.isdir(path):
            for (root, dirs, files) in os.walk(path):
                for fn in files:
                    p = fsdecode(os.path.join(root, fn))
                    rp = os.path.relpath(p, path)
                    ap = to_posix(os.path.join(data_dir, key, rp))
                    archive_paths.append((ap, p))
                    if ((key == u'scripts') and (not p.endswith(u'.exe'))):
                        with open(p, u'rb') as f:
                            data = f.read()
                        data = self.process_shebang(data)
                        with open(p, u'wb') as f:
                            f.write(data)
    path = libdir
    distinfo = None
    for (root, dirs, files) in os.walk(path):
        if (root == path):
            for (i, dn) in enumerate(dirs):
                dn = fsdecode(dn)
                if dn.endswith(u'.dist-info'):
                    distinfo = os.path.join(root, dn)
                    del dirs[i]
                    break
            assert distinfo, u'.dist-info    directory    expected,    not    found'
        for fn in files:
            if fsdecode(fn).endswith((u'.pyc', u'.pyo')):
                continue
            p = os.path.join(root, fn)
            rp = to_posix(os.path.relpath(p, path))
            archive_paths.append((rp, p))
    files = os.listdir(distinfo)
    for fn in files:
        if (fn not in (u'RECORD', u'INSTALLER', u'SHARED', u'WHEEL')):
            p = fsdecode(os.path.join(distinfo, fn))
            ap = to_posix(os.path.join(info_dir, fn))
            archive_paths.append((ap, p))
    wheel_metadata = [(u'Wheel-Version:    %d.%d' % (wheel_version or self.wheel_version)), (u'Generator:    distlib    %s' % __version__), (u'Root-Is-Purelib:    %s' % is_pure)]
    for (pyver, abi, arch) in self.tags:
        wheel_metadata.append((u'Tag:    %s-%s-%s' % (pyver, abi, arch)))
    p = os.path.join(distinfo, u'WHEEL')
    with open(p, u'w') as f:
        f.write(u'\n'.join(wheel_metadata))
    ap = to_posix(os.path.join(info_dir, u'WHEEL'))
    archive_paths.append((ap, p))
    self.write_records((distinfo, info_dir), libdir, archive_paths)
    pathname = os.path.join(self.dirname, self.filename)
    self.build_zip(pathname, archive_paths)
    return pathname
