MacOSXでcl-mysqlを実行しようとするとlibmysqlclient_r.dylibがないと言われるのを回避する
最近,cl-mysqlを利用したライブラリを使おうとしたときに,以下のようなエラーを食らって困ったので備忘録
Unable to load foreign library (LIBMYSQLCLIENT). Error opening shared library libmysqlclient_r.dylib : dlopen(libmysqlclient_r.dylib, 10): image not found. [Condition of type CFFI:LOAD-FOREIGN-LIBRARY-ERROR] Restarts: 0: [RETRY] Try loading the foreign library again. 1: [USE-VALUE] Use another library instead. 2: [LOAD-SOURCE] Load "home:.emacs.d;bin;quicklisp;dists;quicklisp;software;cl-mysql-20150302-git;system.lisp" instead of "/Users/tomoki/.cache/common-lisp/ccl-1.10-f96-macosx-x64/Users/tomoki/.emacs.d/bin/quicklisp/dists/quicklisp/software/cl-mysql-20150302-git/system.dx64fsl" 3: [RECOMPILE] Compile "home:.emacs.d;bin;quicklisp;dists;quicklisp;software;cl-mysql-20150302-git;system.lisp" into "/Users/tomoki/.cache/common-lisp/ccl-1.10-f96-macosx-x64/Users/tomoki/.emacs.d/bin/quicklisp/dists/quicklisp/software/cl-mysql-20150302-git/system.dx64fsl" then load "/Users/tomoki/.cache/common-lisp/ccl-1.10-f96-macosx-x64/Users/tomoki/.emacs.d/bin/quicklisp/dists/quicklisp/software/cl-mysql-20150302-git/system.dx64fsl" again 4: [RETRY-LOAD] Retry loading #P"/Users/tomoki/.cache/common-lisp/ccl-1.10-f96-macosx-x64/Users/tomoki/.emacs.d/bin/quicklisp/dists/quicklisp/software/cl-mysql-20150302-git/system.dx64fsl" 5: [SKIP-LOAD] Skip loading #P"/Users/tomoki/.cache/common-lisp/ccl-1.10-f96-macosx-x64/Users/tomoki/.emacs.d/bin/quicklisp/dists/quicklisp/software/cl-mysql-20150302-git/system.dx64fsl" --more-- Backtrace: 0: (CFFI::FL-ERROR "Unable to load foreign library (~A).~% ~A" COM.HACKINGHAT.CL-MYSQL-SYSTEM::LIBMYSQLCLIENT "Error opening shared library libmysqlclient_r.dylib : dlopen(libmysqlclient_r.dylib, 10): i.. 1: ((:INTERNAL CFFI::%DO-LOAD CFFI::%DO-LOAD-FOREIGN-LIBRARY) #<FOREIGN-LIBRARY LIBMYSQLCLIENT> COM.HACKINGHAT.CL-MYSQL-SYSTEM::LIBMYSQLCLIENT (:DEFAULT "libmysqlclient_r")) 2: (CFFI:LOAD-FOREIGN-LIBRARY COM.HACKINGHAT.CL-MYSQL-SYSTEM::LIBMYSQLCLIENT :SEARCH-PATH NIL) 3: (CCL::$FASL-LFUNCALL #<CCL::FASLSTATE #x26F9BBED>) 4: (CCL::%FASLOAD "/Users/tomoki/.cache/common-lisp/ccl-1.10-f96-macosx-x64/Users/tomoki/.emacs.d/bin/quicklisp/dists/quicklisp/software/cl-mysql-20150302-git/system.dx64fsl" #(#<Compiled-function CCL::$.. 5: (CCL::%LOAD #P"/Users/tomoki/.cache/common-lisp/ccl-1.10-f96-macosx-x64/Users/tomoki/.emacs.d/bin/quicklisp/dists/quicklisp/software/cl-mysql-20150302-git/system.dx64fsl" NIL NIL :ERROR :DEFAULT NIL) 6: (LOAD #P"/Users/tomoki/.cache/common-lisp/ccl-1.10-f96-macosx-x64/Users/tomoki/.emacs.d/bin/quicklisp/dists/quicklisp/software/cl-mysql-20150302-git/system.dx64fsl" :VERBOSE NIL :PRINT NIL :IF-DOES-NO.. 7: (UIOP/UTILITY:CALL-WITH-MUFFLED-CONDITIONS #<COMPILED-LEXICAL-CLOSURE (:INTERNAL UIOP/LISP-BUILD:LOAD*) #x30200279676F> ("Overwriting already existing readtable ~S." ..)) 8: (CCL::%%BEFORE-AND-AFTER-COMBINED-METHOD-DCODE (NIL #<STANDARD-METHOD ASDF/ACTION:PERFORM (ASDF/LISP-ACTION:LOAD-OP ASDF/LISP-ACTION:CL-SOURCE-FILE)> . 81588985)) 9: (CCL::%%STANDARD-COMBINED-METHOD-DCODE ((#<STANDARD-METHOD ASDF/ACTION:PERFORM :BEFORE (ASDF/OPERATION:OPERATION ASDF/COMPONENT:COMPONENT)>) ..))) 81588985) 10: (NIL #<Unknown Arguments>) 11: (CCL::%CALL-NEXT-METHOD (NIL #<STANDARD-METHOD ASDF/ACTION:PERFORM-WITH-RESTARTS (T T)> . 81589056)) 12: (#<STANDARD-METHOD ASDF/ACTION:PERFORM-WITH-RESTARTS (ASDF/LISP-ACTION:LOAD-OP ASDF/LISP-ACTION:CL-SOURCE-FILE)> #<LOAD-OP :VERBOSE NIL> #<CL-SOURCE-FILE "cl-mysql" "system">) 13: (CCL::%CALL-NEXT-METHOD (NIL #<STANDARD-METHOD ASDF/ACTION:PERFORM-WITH-RESTARTS (T T)> . 81589056)) 14: (#<STANDARD-METHOD ASDF/ACTION:PERFORM-WITH-RESTARTS :AROUND (T T)> #<LOAD-OP :VERBOSE NIL> #<CL-SOURCE-FILE "cl-mysql" "system">) 15: (CCL::%%STANDARD-COMBINED-METHOD-DCODE (#<STANDARD-METHOD ASDF/ACTION:PERFORM-WITH-RESTARTS :AROUND (T T)> ..)) 81589056) 16: (NIL #<Unknown Arguments>) 17: (#<STANDARD-METHOD ASDF/PLAN:PERFORM-PLAN (LIST)> ((#<PREPARE-OP > . #<SYSTEM "uiop">) (#<COMPILE-OP > . #<SYSTEM "uiop">) (#<LOAD-OP > . #<SYSTEM "uiop">) ..))) :FORCE NIL) 18: (CCL::%CALL-NEXT-METHOD (NIL #<STANDARD-METHOD ASDF/PLAN:PERFORM-PLAN (LIST)> . 81589118)) 19: (CCL::CALL-WITH-COMPILATION-UNIT #<COMPILED-LEXICAL-CLOSURE (:INTERNAL CCL::WITH-COMPILATION-UNIT-BODY (ASDF/PLAN:PERFORM-PLAN :AROUND (T))) #x26F9C62F> :OVERRIDE NIL) --more--
結論から言えば,今回,この問題は,cl-mysql内のCFFIによるMySQL Clientライブラリの指定で問題が発生していた.
自分の場合,使用しているQuicklispのディレクトリは ~/.emacs.d/bin/quicklisp/ 以下にある.
そして,cl-mysqlのCFFI設定は以下のファイル内に記述されていた.
~/.emacs.d/bin/quicklisp/dists/quicklisp/software/cl-mysql-*********-git/system.lisp
元のファイルでは以下のような記述になっている.
(define-foreign-library libmysqlclient ((:not :windows) (:default "libmysqlclient_r")) (:windows (:default "libmysql")))
Windowsでなければlibmysqlclient_rというファイルを,Windowsならlibmysqlというファイルを使うという設定.
しかし,自分の環境(macOSX Sierra)のデフォルトMySQLのdylibファイルを調べてみると,
~ $ ls -la /usr/local/opt/mysql/lib/ total 22448 drwxr-xr-x 8 tomoki staff 272 6 29 01:42 . drwxr-xr-t 15 tomoki staff 510 10 21 13:53 .. -rw-r--r-- 1 tomoki staff 5424044 10 21 13:53 libmysqlclient.21.dylib -r--r--r-- 1 tomoki staff 6047688 6 29 01:42 libmysqlclient.a lrwxr-xr-x 1 tomoki staff 23 6 29 01:42 libmysqlclient.dylib -> libmysqlclient.21.dylib -r--r--r-- 1 tomoki staff 9624 6 29 01:42 libmysqlservices.a drwxr-xr-t 3 tomoki staff 102 10 21 13:53 pkgconfig drwxr-xr-x 91 tomoki staff 3094 6 29 01:42 plugin
となっており,libmysqlclient_rというファイルはない.
今回は対処療法的に,
(define-foreign-library libmysqlclient (:darwin (:or "libmysqlclient")) ((:not :windows) (:default "libmysqlclient_r")) (:windows (:default "libmysql")))
と書き換えて,正しく動作するようになった.
作者のGithubページを見に行くとすでに修正が入っているようだったので,昔インストールしたものやキャッシュを削除して入れ直せば治っていたのだろう.