Exemplo n.º 1
0
def makewheel(version, output_dir, platform=None):
    if sys.platform not in (
            "win32", "darwin") and not sys.platform.startswith("cygwin"):
        if not LocateBinary("patchelf"):
            raise Exception(
                "patchelf is required when building a Linux wheel.")

    if platform is None:
        # Determine the platform from the build.
        platform_dat = os.path.join(output_dir, 'tmp', 'platform.dat')
        if os.path.isfile(platform_dat):
            platform = open(platform_dat, 'r').read().strip()
        else:
            print("Could not find platform.dat in build directory")
            platform = get_platform()
            if platform.startswith("linux-"):
                # Is this manylinux1?
                if os.path.isfile("/lib/libc-2.5.so") and os.path.isdir(
                        "/opt/python"):
                    platform = platform.replace("linux", "manylinux1")

    platform = platform.replace('-', '_').replace('.', '_')

    # Global filepaths
    panda3d_dir = join(output_dir, "panda3d")
    pandac_dir = join(output_dir, "pandac")
    direct_dir = join(output_dir, "direct")
    models_dir = join(output_dir, "models")
    etc_dir = join(output_dir, "etc")
    bin_dir = join(output_dir, "bin")
    if sys.platform == "win32":
        libs_dir = join(output_dir, "bin")
    else:
        libs_dir = join(output_dir, "lib")
    license_src = "LICENSE"
    readme_src = "README.md"

    # Update relevant METADATA entries
    METADATA['version'] = version

    # Build out the metadata
    details = METADATA["extensions"]["python.details"]
    homepage = details["project_urls"]["Home"]
    author = details["contacts"][0]["name"]
    email = details["contacts"][0]["email"]
    metadata = ''.join([
        "Metadata-Version: {metadata_version}\n" \
        "Name: {name}\n" \
        "Version: {version}\n" \
        "Summary: {summary}\n" \
        "License: {license}\n".format(**METADATA),
        "Home-page: {0}\n".format(homepage),
    ] + ["Project-URL: {0}, {1}\n".format(*url) for url in PROJECT_URLS.items()] + [
        "Author: {0}\n".format(author),
        "Author-email: {0}\n".format(email),
        "Platform: {0}\n".format(platform),
    ] + ["Classifier: {0}\n".format(c) for c in METADATA['classifiers']])

    metadata += '\n' + DESCRIPTION.strip() + '\n'

    # Zip it up and name it the right thing
    whl = WheelFile('panda3d', version, platform)
    whl.lib_path = [libs_dir]

    if sys.platform == "win32":
        whl.lib_path.append(join(output_dir, "python", "DLLs"))

    if platform.startswith("manylinux"):
        # On manylinux1, we pick up all libraries except for the ones specified
        # by the manylinux1 ABI.
        whl.lib_path.append("/usr/local/lib")

        if platform.endswith("_x86_64"):
            whl.lib_path += ["/lib64", "/usr/lib64"]
        else:
            whl.lib_path += ["/lib", "/usr/lib"]

        whl.ignore_deps.update(MANYLINUX_LIBS)

    # Add the trees with Python modules.
    whl.write_directory('direct', direct_dir)

    # Write the panda3d tree.  We use a custom empty __init__ since the
    # default one adds the bin directory to the PATH, which we don't have.
    p3d_init = """"Python bindings for the Panda3D libraries"

__version__ = '{0}'
""".format(version)

    if '27' in ABI_TAG:
        p3d_init += """
if __debug__:
    import sys
    if sys.version_info < (3, 0):
        sys.stderr.write("WARNING: Python 2.7 will reach EOL after December 31, 2019.\\n")
        sys.stderr.write("To suppress this warning, upgrade to Python 3.\\n")
        sys.stderr.flush()
    del sys
"""

    whl.write_file_data('panda3d/__init__.py', p3d_init)

    # Copy the extension modules from the panda3d directory.
    ext_suffix = GetExtensionSuffix()

    for file in os.listdir(panda3d_dir):
        if file == '__init__.py':
            pass
        elif file.endswith('.py') or (file.endswith(ext_suffix)
                                      and '.' not in file[:-len(ext_suffix)]):
            source_path = os.path.join(panda3d_dir, file)

            if file.endswith('.pyd') and platform.startswith('cygwin'):
                # Rename it to .dll for cygwin Python to be able to load it.
                target_path = 'panda3d/' + os.path.splitext(file)[0] + '.dll'
            else:
                target_path = 'panda3d/' + file

            whl.write_file(target_path, source_path)

    # And copy the extension modules from the Python installation into the
    # deploy_libs directory, for use by deploy-ng.
    ext_suffix = '.pyd' if sys.platform in ('win32', 'cygwin') else '.so'
    ext_mod_dir = get_python_ext_module_dir()

    for file in os.listdir(ext_mod_dir):
        if file.endswith(ext_suffix):
            source_path = os.path.join(ext_mod_dir, file)

            if file.endswith('.pyd') and platform.startswith('cygwin'):
                # Rename it to .dll for cygwin Python to be able to load it.
                target_path = 'deploy_libs/' + os.path.splitext(
                    file)[0] + '.dll'
            else:
                target_path = 'deploy_libs/' + file

            whl.write_file(target_path, source_path)

    # Add plug-ins.
    for lib in PLUGIN_LIBS:
        plugin_name = 'lib' + lib
        if sys.platform in ('win32', 'cygwin'):
            plugin_name += '.dll'
        elif sys.platform == 'darwin':
            plugin_name += '.dylib'
        else:
            plugin_name += '.so'
        plugin_path = os.path.join(libs_dir, plugin_name)
        if os.path.isfile(plugin_path):
            whl.write_file('panda3d/' + plugin_name, plugin_path)

    # Add the .data directory, containing additional files.
    data_dir = 'panda3d-{0}.data'.format(version)
    #whl.write_directory(data_dir + '/data/etc', etc_dir)
    #whl.write_directory(data_dir + '/data/models', models_dir)

    # Actually, let's not.  That seems to install the files to the strangest
    # places in the user's filesystem.  Let's instead put them in panda3d.
    whl.write_directory('panda3d/etc', etc_dir)
    whl.write_directory('panda3d/models', models_dir)

    # Add the pandac tree for backward compatibility.
    for file in os.listdir(pandac_dir):
        if file.endswith('.py'):
            whl.write_file('pandac/' + file, os.path.join(pandac_dir, file))

    # Add a panda3d-tools directory containing the executables.
    entry_points = '[console_scripts]\n'
    entry_points += 'eggcacher = direct.directscripts.eggcacher:main\n'
    entry_points += 'pfreeze = direct.dist.pfreeze:main\n'
    tools_init = ''
    for file in os.listdir(bin_dir):
        basename = os.path.splitext(file)[0]
        if basename in ('eggcacher', 'packpanda'):
            continue

        source_path = os.path.join(bin_dir, file)

        if is_executable(source_path):
            # Put the .exe files inside the panda3d-tools directory.
            whl.write_file('panda3d_tools/' + file, source_path)

            # Tell pip to create a wrapper script.
            funcname = basename.replace('-', '_')
            entry_points += '{0} = panda3d_tools:{1}\n'.format(
                basename, funcname)
            tools_init += '{0} = lambda: _exec_tool({1!r})\n'.format(
                funcname, file)
    entry_points += '[distutils.commands]\n'
    entry_points += 'build_apps = direct.dist.commands:build_apps\n'
    entry_points += 'bdist_apps = direct.dist.commands:bdist_apps\n'

    whl.write_file_data('panda3d_tools/__init__.py',
                        PANDA3D_TOOLS_INIT.format(tools_init))

    # Add the dist-info directory last.
    info_dir = 'panda3d-{0}.dist-info'.format(version)
    whl.write_file_data(info_dir + '/entry_points.txt', entry_points)
    whl.write_file_data(info_dir + '/metadata.json',
                        json.dumps(METADATA, indent=4, separators=(',', ': ')))
    whl.write_file_data(info_dir + '/METADATA', metadata)
    whl.write_file_data(info_dir + '/WHEEL',
                        WHEEL_DATA.format(PY_VERSION, ABI_TAG, platform))
    whl.write_file(info_dir + '/LICENSE.txt', license_src)
    whl.write_file(info_dir + '/README.md', readme_src)
    whl.write_file_data(info_dir + '/top_level.txt',
                        'direct\npanda3d\npandac\npanda3d_tools\n')

    # Add libpython for deployment
    if sys.platform in ('win32', 'cygwin'):
        pylib_name = 'python{0}{1}.dll'.format(*sys.version_info)
        pylib_path = os.path.join(get_config_var('BINDIR'), pylib_name)
    elif sys.platform == 'darwin':
        pylib_name = 'libpython{0}.{1}.dylib'.format(*sys.version_info)
        pylib_path = os.path.join(get_config_var('LIBDIR'), pylib_name)
    else:
        pylib_name = get_config_var('LDLIBRARY')
        pylib_path = os.path.join(get_config_var('LIBDIR'), pylib_name)
    whl.write_file('deploy_libs/' + pylib_name, pylib_path)

    whl.close()
Exemplo n.º 2
0
def makewheel(version, output_dir, platform=default_platform):
    if sys.platform not in (
            "win32", "darwin") and not sys.platform.startswith("cygwin"):
        if not LocateBinary("patchelf"):
            raise Exception(
                "patchelf is required when building a Linux wheel.")

    platform = platform.replace('-', '_').replace('.', '_')

    # Global filepaths
    panda3d_dir = join(output_dir, "panda3d")
    pandac_dir = join(output_dir, "pandac")
    direct_dir = join(output_dir, "direct")
    models_dir = join(output_dir, "models")
    etc_dir = join(output_dir, "etc")
    bin_dir = join(output_dir, "bin")
    if sys.platform == "win32":
        libs_dir = join(output_dir, "bin")
    else:
        libs_dir = join(output_dir, "lib")
    license_src = "LICENSE"
    readme_src = "README.md"

    # Update relevant METADATA entries
    METADATA['version'] = version
    version_classifiers = [
        "Programming Language :: Python :: {0}".format(*sys.version_info),
        "Programming Language :: Python :: {0}.{1}".format(*sys.version_info),
    ]
    METADATA['classifiers'].extend(version_classifiers)

    # Build out the metadata
    details = METADATA["extensions"]["python.details"]
    homepage = details["project_urls"]["Home"]
    author = details["contacts"][0]["name"]
    email = details["contacts"][0]["email"]
    metadata = ''.join([
        "Metadata-Version: {metadata_version}\n" \
        "Name: {name}\n" \
        "Version: {version}\n" \
        "Summary: {summary}\n" \
        "License: {license}\n".format(**METADATA),
        "Home-page: {0}\n".format(homepage),
        "Author: {0}\n".format(author),
        "Author-email: {0}\n".format(email),
        "Platform: {0}\n".format(platform),
    ] + ["Classifier: {0}\n".format(c) for c in METADATA['classifiers']])

    # Zip it up and name it the right thing
    whl = WheelFile('panda3d', version, platform)
    whl.lib_path = [libs_dir]

    # Add the trees with Python modules.
    whl.write_directory('direct', direct_dir)

    # Write the panda3d tree.  We use a custom empty __init__ since the
    # default one adds the bin directory to the PATH, which we don't have.
    whl.write_file_data('panda3d/__init__.py', '')

    ext_suffix = GetExtensionSuffix()

    for file in os.listdir(panda3d_dir):
        if file == '__init__.py':
            pass
        elif file.endswith(ext_suffix) or file.endswith('.py'):
            source_path = os.path.join(panda3d_dir, file)

            if file.endswith('.pyd') and platform.startswith('cygwin'):
                # Rename it to .dll for cygwin Python to be able to load it.
                target_path = 'panda3d/' + os.path.splitext(file)[0] + '.dll'
            else:
                target_path = 'panda3d/' + file

            whl.write_file(target_path, source_path)

    # Add plug-ins.
    for lib in PLUGIN_LIBS:
        plugin_name = 'lib' + lib
        if sys.platform in ('win32', 'cygwin'):
            plugin_name += '.dll'
        elif sys.platform == 'darwin':
            plugin_name += '.dylib'
        else:
            plugin_name += '.so'
        plugin_path = os.path.join(libs_dir, plugin_name)
        if os.path.isfile(plugin_path):
            whl.write_file('panda3d/' + plugin_name, plugin_path)

    # Add the .data directory, containing additional files.
    data_dir = 'panda3d-{0}.data'.format(version)
    #whl.write_directory(data_dir + '/data/etc', etc_dir)
    #whl.write_directory(data_dir + '/data/models', models_dir)

    # Actually, let's not.  That seems to install the files to the strangest
    # places in the user's filesystem.  Let's instead put them in panda3d.
    whl.write_directory('panda3d/etc', etc_dir)
    whl.write_directory('panda3d/models', models_dir)

    # Add the pandac tree for backward compatibility.
    for file in os.listdir(pandac_dir):
        if file.endswith('.py'):
            whl.write_file('pandac/' + file, os.path.join(pandac_dir, file))

    # Add a panda3d-tools directory containing the executables.
    entry_points = '[console_scripts]\n'
    entry_points += 'eggcacher = direct.directscripts.eggcacher:main\n'
    entry_points += 'pfreeze = direct.showutil.pfreeze:main\n'
    tools_init = ''
    for file in os.listdir(bin_dir):
        basename = os.path.splitext(file)[0]
        if basename in ('eggcacher', 'packpanda'):
            continue

        source_path = os.path.join(bin_dir, file)

        if is_executable(source_path):
            # Put the .exe files inside the panda3d-tools directory.
            whl.write_file('panda3d_tools/' + file, source_path)

            # Tell pip to create a wrapper script.
            funcname = basename.replace('-', '_')
            entry_points += '{0} = panda3d_tools:{1}\n'.format(
                basename, funcname)
            tools_init += '{0} = lambda: _exec_tool({1!r})\n'.format(
                funcname, file)

    whl.write_file_data('panda3d_tools/__init__.py',
                        PANDA3D_TOOLS_INIT.format(tools_init))

    # Add the dist-info directory last.
    info_dir = 'panda3d-{0}.dist-info'.format(version)
    whl.write_file_data(info_dir + '/entry_points.txt', entry_points)
    whl.write_file_data(info_dir + '/metadata.json',
                        json.dumps(METADATA, indent=4, separators=(',', ': ')))
    whl.write_file_data(info_dir + '/METADATA', metadata)
    whl.write_file_data(info_dir + '/WHEEL',
                        WHEEL_DATA.format(PY_VERSION, ABI_TAG, platform))
    whl.write_file(info_dir + '/LICENSE.txt', license_src)
    whl.write_file(info_dir + '/README.md', readme_src)
    whl.write_file_data(info_dir + '/top_level.txt',
                        'direct\npanda3d\npandac\npanda3d_tools\n')

    whl.close()