libcairo 未定义符号:在 Centos7 上从编译的 MATLAB 应用程序调用 R 时出现 FT_Get_Var_Design_Cooperatives 错误

libcairo 未定义符号:在 Centos7 上从编译的 MATLAB 应用程序调用 R 时出现 FT_Get_Var_Design_Cooperatives 错误

我发布这个问题是为了记录一个问题的解决方案,这个问题困扰了我几个星期,但在 StackExchange 或讨论板上找不到答案。 (即将答复)

我正在尝试在 Centos7 操作系统上运行使用应用程序编译器工具箱(Matlab 编译器 6.4)编译的已编译 matlab 程序(MATLAB 2017a)。棘手的部分是我的Matlab程序使用“system”命令来调用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:sudo 之后 LD_LIBRARY_PATH 始终为空

我发现的一种解决方法是将 MATLAB 中的系统调用更改为使用 sudo 进行调用,但这是一个草率的修复,因为它要求用户在程序运行过程中输入 sudo 密码。所以我正在寻找更好的解决方案。

答案1

因此,通过一些研究,我发现 libcairo 的问题实际上是 freetype 的问题。这个问题-https://stackoverflow.com/questions/60782074/r-issue-unable-to-load-shared-object-cairo-so-on-linux-centos-7- 表明多个 freetype 库可能是问题所在,但是执行 rpm freetype:

rpm -q freetype
freetype-2.8-14.el7_9.1.x86_64
freetype-2.8-14.el7_9.1.i686

发现没有重复的freetype库。

结果是 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 有自己的 freetype 库!哪个 LD_LIBRARY_PATH 覆盖了 os freetype 库(这就是为什么 R 在 sudoed 时可以工作)。

最一致的修复是两个部分:

  1. 确保 LD_LIBRARY_PATH 仅设置为对独立 MATLAB 程序的原始调用的一部分,这可以通过编译时创建的 run_MyProgram.sh 文件来完成。
  2. 在您的 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*

所以,如果有人像我一样陷入困境,我希望这能帮助你。

相关内容