Skip to content

Commit

Permalink
install_name_tool in OSX Framework builds pypa#168
Browse files Browse the repository at this point in the history
shouldfix:  creating a virtualenv from an OSX
Framework build should no longer require XCode to
run successfully.

implementaion:  if ``install_name_tool`` missing,
download binaries from macosxforge, and install
them to a temp directory

rejected:  download and compile .c source.

TODOS:

*   review for python2/3 issues
*   cleanup of tempfiles?  Assume the system will do it?
*   test for robustness
*   review implications of not having XCode for packages, if any
*   integrate with pypa#54 pull or its descendents.  (trivial)

Possible Test Code:

    #!/bin/sh

    deactivate # virtualenv on system (Framework) python

    # assuming I have XCode or ``install_name_tool`` in path.
    python virtualenv.py t_install_name_tool  # creates with no issue
    t_install_name_tool/bin/python -c ""

    # remove it from path
    sudo mv /usr/bin/install_name_tool{,2}

    # should create with no issue, using tmpfile
    python virtualenv.py t_tmp_install_name_tool
    t_tmp_install_name_tool/bin/python -c ""

    # clean up
    sudo mv /usr/bin/install_name_tool{2,}
    command rm -rf t_{,tmp_}install_name_tool
  • Loading branch information
gregglind committed Jan 2, 2012
1 parent 24b8e25 commit a614215
Showing 1 changed file with 55 additions and 1 deletion.
56 changes: 55 additions & 1 deletion virtualenv.py
Expand Up @@ -1318,9 +1318,11 @@ def install_python(home_dir, lib_dir, inc_dir, bin_dir, site_packages, clear):
virtual_lib)

# And then change the install_name of the copied python executable
install_name_tool = get_install_name_tool()

try:
call_subprocess(
["install_name_tool", "-change",
[install_name_tool, "-change",
os.path.join(prefix, 'Python'),
'@executable_path/../.Python',
py_executable])
Expand Down Expand Up @@ -1518,6 +1520,58 @@ def is_executable(exe):
"""Checks a file is executable"""
return os.access(exe, os.X_OK)


def get_install_name_tool():
"""
returns the command name of a working ``install_name_tool``, installing
one to a temp file, if necessary, or None on failure.
Returns:
string, name of tool to use by ``call_subprocess``
None: if it was unable to install or find one.
"""
## TODO: decide how robust this should be to various failure cases.
## is None the correct response on failure, or should it debug more?

## TODO: where/should this get 'cleaned up', if it's a temp install?
## perhaps this should return a tuple of (path,tempdir)?

import platform
import tarfile
import urllib

# default case... on path from Xcode or something.
try:
call_subprocess(['install_name_tool'])
return 'install_name_tool'
except OSError as exc:
logger.debug('%s',exc)

### couldn't find an installed one, so, let's get one.
urls = {
'5': "http://src.macosforge.org/Roots/9A581/cctools.root.tar.gz",
'6': "http://src.macosforge.org/Roots/10A432/cctools.root.tar.gz",
'7': "http://src.macosforge.org/Roots/11A511a/cctools.root.tar.gz",
}
try:
url = urls[platform.mac_ver()[0].split('.')[1]]
except KeyError:
raise ValueError("your version of OSX wasn't planned for. "
"File a bug against: https://github.com/pypa/virtualenv/issues/168")

d = tempfile.mkdtemp()
tarname = "cctools.root.tar.gz"
urllib.urlretrieve(url,join(d,tarname))
tarfile.open(join(d,tarname)).extractall(d)
os.listdir(d)
tool_bin = join(d,'usr','bin','install_name_tool')
if is_executable(tool_bin):
return tool_bin
else:
logger.debug('not executable: %s' % (tool_bin,))
return None


############################################################
## Relocating the environment:

Expand Down

0 comments on commit a614215

Please sign in to comment.