If subclass of codeexport.Generic_Code needs to have some of it
    sources compiled to objects and cached in a `prebuilt/` directory
    at invocation of `setup.py build_ext` this convenience function
    makes setting up a PCEExtension easier. Use together with
    cmdclass = {'build_ext': pce_build_ext}.

    files called ".metadata*" will be added to dist_files

def make_PCEExtension_for_prebuilding_Code(
        name, Code, prebuild_sources, srcdir,
        downloads=None, **kwargs):
    """
    If subclass of codeexport.Generic_Code needs to have some of it
    sources compiled to objects and cached in a `prebuilt/` directory
    at invocation of `setup.py build_ext` this convenience function
    makes setting up a PCEExtension easier. Use together with
    cmdclass = {'build_ext': pce_build_ext}.

    files called ".metadata*" will be added to dist_files
    """

    import glob
    from .dist import PCEExtension

    build_files = []
    dist_files = [(os.path.join(srcdir, x[0]), x[1]) for
                  x in getattr(Code, 'dist_files', [])]
    for attr in ('build_files', 'templates'):
        for cf in getattr(Code, attr, []) or []:
            if not cf.startswith('prebuilt'):
                build_files.append(os.path.join(srcdir, cf))
                dist_files.append((os.path.join(srcdir, cf), None))

    def prebuilder(build_temp, ext_fullpath, ext,
                   src_paths, **prebuilder_kwargs):
        build_temp = os.path.abspath(build_temp)
        if not os.path.isdir(build_temp):
            make_dirs(build_temp)

        if downloads:
            websrc, src_md5 = downloads
            download_dir = os.path.join(build_temp, srcdir)
            if not os.path.isdir(download_dir):
                make_dirs(download_dir)
            download_files(websrc, src_md5.keys(), src_md5,
                           cwd=download_dir, logger=ext.logger)

        for p in src_paths:
            if p not in build_files:
                copy(os.path.join(srcdir, p),
                     os.path.join(build_temp, srcdir),
                     dest_is_dir=True, create_dest_dirs=True,
                     only_update=ext.only_update,
                     logger=ext.logger)
        dst = os.path.abspath(os.path.join(
            os.path.dirname(ext_fullpath), 'prebuilt/'))
        make_dirs(dst, logger=ext.logger)
        objs = compile_sources(
            [os.path.join(srcdir, x) for x in src_paths], destdir=dst,
            cwd=build_temp, metadir=dst, only_update=True,
            logger=ext.logger, **prebuilder_kwargs)
        glb = os.path.join(ext_fullpath, '.metadata*')
        dist_files.extend(glob.glob(glb))
        for obj in objs:
            # Copy prebuilt objects into lib for distriubtion
            copy(os.path.join(build_temp, obj),
                 dst, dest_is_dir=True, create_dest_dirs=True,
                 only_update=ext.only_update,
                 logger=ext.logger)
        return objs

    compile_kwargs = Code.compile_kwargs.copy()
    logger = kwargs.pop('logger', True)
    compile_kwargs.update(kwargs)
    return PCEExtension(
        name,
        [],
        build_files=build_files,
        dist_files=dist_files,
        build_callbacks=[
            (
                prebuilder,
                (prebuild_sources,), compile_kwargs
            ),
        ],
        logger=logger,
        link_ext=False
    )