deploy-ng: fix failure to include libpython (particularly on macOS)

This commit is contained in:
rdb 2017-12-21 12:29:58 +01:00
parent f703fd51ed
commit 58917e6746
3 changed files with 38 additions and 19 deletions

View File

@ -1619,17 +1619,15 @@ class Freezer:
return target
def generateRuntimeFromStub(self, basename, stub_file, fields={}):
def generateRuntimeFromStub(self, target, stub_file, fields={}):
# We must have a __main__ module to make an exe file.
if not self.__writingModule('__main__'):
message = "Can't generate an executable without a __main__ module."
raise Exception(message)
if self.platform.startswith('win'):
target = basename + '.exe'
modext = '.pyd'
else:
target = basename
modext = '.so'
# First gather up the strings and code for all the module names, and

View File

@ -280,11 +280,16 @@ class build_apps(distutils.core.Command):
freezer.excludeModule(exmod)
freezer.done(addStartupModules=True)
target_path = os.path.join(builddir, appname)
stub_name = 'deploy-stub'
if platform.startswith('win'):
if not use_console:
stub_name = 'deploy-stubw'
if platform.startswith('win'):
stub_name += '.exe'
target_path += '.exe'
if use_wheels:
stub_file = p3dwhl.open('panda3d_tools/{0}'.format(stub_name))
@ -293,7 +298,7 @@ class build_apps(distutils.core.Command):
stub_path = os.path.join(os.path.dirname(dtool_path), '..', 'bin', stub_name)
stub_file = open(stub_path, 'rb')
freezer.generateRuntimeFromStub(os.path.join(builddir, appname), stub_file, {
freezer.generateRuntimeFromStub(target_path, stub_file, {
'prc_data': None,
'default_prc_dir': None,
'prc_dir_envvars': None,
@ -306,6 +311,12 @@ class build_apps(distutils.core.Command):
})
stub_file.close()
# Copy the dependencies.
search_path = [builddir]
if use_wheels:
search_path.append(os.path.join(p3dwhlfn, 'deploy_libs'))
self.copy_dependencies(open(target_path, 'rb'), builddir, search_path, stub_name)
freezer_extras.update(freezer.extras)
freezer_modules.update(freezer.getAllModuleNames())
@ -556,6 +567,13 @@ class build_apps(distutils.core.Command):
shutil.copyfile(source_path, target_path)
fp = open(target_path, 'rb')
target_dir = os.path.dirname(target_path)
base = os.path.basename(target_path)
self.copy_dependencies(fp, target_dir, search_path, base)
def copy_dependencies(self, fp, target_dir, search_path, referenced_by):
""" Copies the dependencies of the given open file. """
# What kind of magic does the file contain?
deps = []
magic = fp.read(4)
@ -589,11 +607,8 @@ class build_apps(distutils.core.Command):
deps = self._read_dependencies_fat(fp, True)
# If we discovered any dependencies, recursively add those.
if deps:
target_dir = os.path.dirname(target_path)
base = os.path.basename(target_path)
for dep in deps:
self.add_dependency(dep, target_dir, search_path, base)
for dep in deps:
self.add_dependency(dep, target_dir, search_path, referenced_by)
def _read_dependencies_elf(self, elf, origin, search_path):
""" Having read the first 4 bytes of the ELF file, fetches the

View File

@ -350,19 +350,25 @@ class WheelFile(object):
# Fix things like @loader_path/../lib references
if sys.platform == "darwin":
deps_path = '@loader_path'
loader_path = [os.path.dirname(source_path)]
for dep in deps:
if '@loader_path' not in dep:
continue
if dep.endswith('/Python'):
# If this references the Python framework, change it
# to reference libpython instead.
new_dep = deps_path + '/libpython{0}.{1}.dylib'.format(*sys.version_info)
else:
if '@loader_path' not in dep:
continue
dep_path = dep.replace('@loader_path', '.')
target_dep = os.path.dirname(target_path) + '/' + os.path.basename(dep)
target_dep = self.consider_add_dependency(target_dep, dep_path, loader_path)
if not target_dep:
# It won't be included, so no use adjusting the path.
continue
dep_path = dep.replace('@loader_path', '.')
target_dep = os.path.dirname(target_path) + '/' + os.path.basename(dep)
target_dep = self.consider_add_dependency(target_dep, dep_path, loader_path)
if not target_dep:
# It won't be included, so no use adjusting the path.
continue
new_dep = os.path.join(deps_path, os.path.relpath(target_dep, os.path.dirname(target_path)))
new_dep = os.path.join('@loader_path', os.path.relpath(target_dep, os.path.dirname(target_path)))
subprocess.call(["install_name_tool", "-change", dep, new_dep, temp.name])
else:
subprocess.call(["strip", "-s", temp.name])
@ -600,7 +606,7 @@ def makewheel(version, output_dir, platform=None):
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.write_file('deploy_libs/' + pylib_name, pylib_path)
whl.close()