MySQL Improperly Configured Reason: unsafe use of relative path
Question:
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.
Answers:
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
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()
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.
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
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()