libcairo 未定義符號:在 Centos7 上從已編譯的 MATLAB 應用程序呼叫 R 時出現 FT_Get_Var_Design_Coordinates 錯誤
我發布這個問題是為了記錄一個問題的解決方案,這個問題讓我堅持了幾個星期,但在 StackExchange 或討論板上沒有找到答案。(答案待定)
我正在嘗試在 Centos7 作業系統上執行使用應用程序編譯器工具箱(Matlab 編譯器 6.4)編譯的已編譯 matlab 程序(MATLAB 2017a)。棘手的部分是我的 Matlab 程序使用“系統”命令來呼叫 R 並編織一個 rmarkdown 文件。
要讓獨立的 matlab 程序在 linux 作業系統上執行,有必要像這樣設置 LD_LIBRARY_PATH:
export LD_LIBRARY_PATH={$LD_LIBRARY_PATH}:/usr/local/MATLAB/MATLAB_Runtimev92/v92/runtime/glnxa64:/usr/local/MATLAB/MATLAB_Runtimev92/v92/bin/glnxa64:/usr/local/MATLAB/MATLAB_Runtimev92/v92/sys/os/glnxa64:/usr/local/MATLAB/MATLAB_Runtimev92/v92/sys/opengl/lib/glnxa64
問題是,這以下列方式破壞了 R:
In grDevices::png(f) : unable to load shared object '/usr/lib64/R/library/grDevices/libs//cairo.so': /lib64/libcairo.so.2: undefined symbol: FT_Get_Var_Design_Coordinates
獨立測試 R 程式碼我發現它在使用 sudo 權限執行時執行良好。這不起作用,因為 MATLAB 程序在以 sudo 權限執行時無法執行。
原來,sudo 特權清除 LD_LIBRARY_PATH: LD_LIBRARY_PATH 在 sudo 之後總是空白
我發現的一種解決方法是將我在 MATLAB 中的系統呼叫更改為使用 sudo 呼叫,但這是一個草率的修復,因為它要求使用者在程序執行的中途鍵入他們的 sudo 密碼。所以我正在尋找更好的解決方案。
因此,通過一些研究,我發現 libcairo 的問題實際上是 freetype 的問題。這個問題- https://stackoverflow.com/questions/60782074/r-issue-unable-to-load-shared-object-cairo-so-on-linux-centos-7 - 建議多個自由類型庫可能是問題,但是做 rpm 自由類型:
rpm -q freetype freetype-2.8-14.el7_9.1.x86_64 freetype-2.8-14.el7_9.1.i686
發現沒有重複的自由類型庫。
原來 LD_LIBRARY_PATH 在作業系統庫之前被搜尋:https ://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html
果然執行發現:
sudo find / -type f -iname 'libfreetype.so.*' /usr/lib/libfreetype.so.6.14.0 /usr/lib64/libfreetype.so.6.14.0 /usr/local/bin/glnxa64/libfreetype.so.6.11.1 /usr/local/MATLAB/MATLAB_Runtimev92/v92/bin/glnxa64/libfreetype.so.6.11.1 /usr/local/MATLAB/R2017a/bin/glnxa64/libfreetype.so.6.11.1
揭示了 rpm 不會 - MATLAB 有它自己的自由類型庫!哪個 LD_LIBRARY_PATH 覆蓋了 os freetype 庫(因此 R 在 sudo 時工作)。
最一致的修復是兩個部分:
- 確保 LD_LIBRARY_PATH 僅設置為對獨立 MATLAB 程序的原始呼叫的一部分,這可以通過編譯時創建的 run_MyProgram.sh 文件來完成。
- 在您的 MATLAB 程式碼中,確保所有“系統”呼叫在執行前清除 LD_LIBRARY_PATH。IE:
function [status,cmdout]=systemAlt(cmd) if isunix() [status,cmdout]=system(['export LD_LIBRARY_PATH="";',cmd]); else [status,cmdout]=system(cmd); end end
奇怪的是,我還需要下載新字型才能使其正常工作:
yum install xorg-x11-font*
所以那裡 - 如果有人像我一樣被困住,我希望能幫助你。