MySQL Improperly Configured Reason: unsafe use of relative path
Asked Answered
D

2

26

I'm using Django, and when I run python manage.py runserver I receive the following error:

ImproperlyConfigured: Error loading MySQLdb module: dlopen(/Library/Python/2.7/site-packages/_mysql.so, 2): Library not loaded: libmysqlclient.18.dylib
  Referenced from: /Library/Python/2.7/site-packages/_mysql.so
  Reason: unsafe use of relative rpath libmysqlclient.18.dylib in /Library/Python/2.7/site-packages/_mysql.so with restricted binary

I'm not entirely sure how to fix this. I have installed MySQL-python via pip. And I followed this step earlier.

I want to also point out this is with El Capitan Beta 3.

Dewey answered 10/7, 2015 at 14:26 Comment(2)
did you have any luck with fixing this? I am having the same issueBowel
I am currently on Beta 2. Upgraded yesterday but this is still an issue.Bowel
M
76

In OS X El Capitan (10.11), Apple added System Integrity Protection.

This prevents programs in protected locations like /usr from calling a shared library that uses a relative reference to another shared library. In the case of _mysql.so, it contains a relative reference to the shared library libmysqlclient.18.dylib.

In the future, the shared library _mysql.so may be updated. Until then, you can force it to use an absolute reference via the install_name_tool utility.

Assuming that libmysqlclient.18.dylib is in /usr/local/mysql/lib/, then run the command:

sudo install_name_tool -change libmysqlclient.18.dylib \
  /usr/local/mysql/lib/libmysqlclient.18.dylib \
  /Library/Python/2.7/site-packages/_mysql.so
Melanimelania answered 5/8, 2015 at 0:1 Comment(6)
This also let me fix an issue with the mysql2 gem in ruby. Just had to use my module instead of the _mysql.so. Thanks.Dickens
Can the original poster up vote this answer as the correct one?Jed
Just FYI, if you use a virtualenv, the site-packages path is inside the virtualenv folder.Mendelssohn
Well that saved my bacon after 4 very stressful days. What bothers me is that I didn't know how to find out what I didn't know--can anyone suggest how to prep for this kind of thing in the future? I had never heard of either install_name_tool or System Integrity Protection. What corners of the Web should I be browsing to prepare myself for things like this?Mitziemitzl
really great.It fixed my problem on my OS X system.Thank you!Westney
@Mitziemitzl you can't know EVERYTHING :) j/k I feel you on this one. In my case I just knew that googling for "unsafe use of relative rpath libmysqlclient.18.dylib" will give me the answer. You just need to look for the exact problem in the entire error trace.Conker
L
0

If there are lots of relative paths to be fixed for something (as happened with me for opencv library). You can use the following snippet:

Change the ABSPATH and LIBPATHS accordingly. It will create rPathChangeCmd.txt which you can paste in the terminal. It will also create rPathChangeErr.txt in case of any errors. I would suggest check error file (if created) before pasting the commands.

import glob
import subprocess
import os.path

ABSPATH = "/usr/local/lib/"  # absolute path to relative libraries
# libraries to correct
LIBPATHS = ['/usr/local/lib/python2.7/site-packages/cv2.so', '/usr/local/lib/libopencv*'] 

PREFIX = 'sudo install_name_tool -change '

assert(ABSPATH.startswith('/') and ABSPATH.endswith('/'), 
    'please provide absolute library path ending with /')

libs = []
for path in LIBPATHS:
  libs += glob.glob(path)

cmd =  []
err = []
for lib in libs:
  if not os.path.isfile(lib):
    err.append(lib+" library not found") # glob should take care
  datastr = subprocess.check_output(['otool','-l','-v', lib])
  data = datastr.split('\n') 
  for line in data:
    ll = line.split()
    if not ll: continue
    if (ll[0] == 'name' and ll[1].endswith('.dylib') and not ll[1].startswith('/')):
      libname = ll[1].split('/')[-1]
      if os.path.isfile(ABSPATH+libname):  
        cmd.append(PREFIX+ll[1]+" "+ABSPATH+libname+' '+lib)
      else:
        err.append(ABSPATH+libname+" does not exist, hence can't correct: "+ll[1]+" in: "+lib)

ohandle = open("rpathChangeCmd.txt", 'w')
for lib in cmd:
  ohandle.write(lib+'\n')
ohandle.close()

if err:
  ehandle = open("rpathChangeErr.txt", 'w')
  for e in err:
    ehandle.write(e+'\n')
  ehandle.close()
Litre answered 21/10, 2015 at 22:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.