太長不看版
- magick的安裝需要底層的imagemagick支持
- Ubuntu16.04由于版本老舊,安裝的舊版imagemagick無法使用
- 使用spack自己安裝新版,可以解決編譯問題。
果子老師向我求助,讓我幫忙安裝一個R包, magick。這個R包,我在自己的CentOS系統的服務器上安裝過,在我的Mac上裝過,我覺得應該不是個大問題。
然而,從最后我所花的時間來看,這確實是個大問題,因為這是果子老師提出的問題,但凡是他提出的問題,他肯定是前期花了點時間的,也就是常規的路子都走過了,實在沒法子才來找我出手。
這個信息的報錯消息如下
magick.so: undefined symbol: _ZNK6Magick8GeometrycvNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEv
我通過檢索,發現有人通過設置~/.R/Makevars
里的C++配置解決過
CXX11=/usr/bin/g++
但是,我測試過了這個方法,并不可行。不過,在這個思路下,我有兩個猜測
- R語言版本或許要最新版4.2.2,這是最簡單的思路。很大一部分問題都可以通過升級R來解決。
- GCC版本低,無法提供magick所要求的庫。
對于第一個猜想,我編譯了最新R4.2.2, 但是發現并不是原因。
對于第二個猜想,我得編譯一個gcc,這個我在2018年的【無root權限下解決編譯時的依賴問題】中介紹過,但是那個操作太復雜了,現如今可以考慮用spack(https://spack.io/)。
# 關于spack的安裝和使用,不在此文介紹
spack install gcc
spack load gcc
但是,基于最新的GCC去編譯R包依舊不行,甚至,基于最新的GCC編譯的最新的R也不行。此時,我的心態有點暴躁,于是,我想著要不要就不在這臺服務器上編譯了,用另一臺Ubuntu服務器編譯好,復制過來不就好了嗎?
但是,由于兩臺機子的Ubuntu版本不同,結果有依賴庫的問題
錯誤: package or namespace load failed for ‘magick’ in dyn.load(file, DLLpath = DLLpath, ...):
無法載入共享目標對象‘/home/xzg/R/x86_64-pc-linux-gnu-library/4.2/magick/libs/magick.so’::
libMagick++-6.Q16.so.8: cannot open shared object file: No such file or directory
這個情況,有一種偷懶的方式,就是用ln 做了軟連接
ln -s /usr/lib/x86_64-linux-gnu/libMagick++-6.Q16.so /usr/lib/x86_64-linux-gnu/libMagick++-6.Q16.so.8
然而,依舊報錯(好消息不是之前的錯誤)
/home/xzg/R/x86_64-pc-linux-gnu-library/4.2/magick/libs/magick.so:
undefined symbol: _ZN6Magick5Image10fontWeightEm
盡管失敗了,但是我有了一個新的猜想, 那就是系統自帶的Magick的版本低了。有沒有一種可能,在R里,我安裝舊版本的magick就可以避免這個問題呢?于是,我找到了它的歷史存檔 https://cran.r-project.org/src/contrib/Archive/magick/,從1.0測試到2.6 ,無一成功。
好吧,這條路也走不通,那我只能去編譯一個最新的imagemagick
spack install imagemagick
spack load imagemagick
# 動態庫,沒有這行命令,編譯過程最后一步還是失敗
export LD_LIBRARY_PATH=/home/xzg/spack/opt/spack/linux-ubuntu18.04-skylake_avx512/gcc-7.5.0/imagemagick-7.0.8-7-663acxuiasjhkjxymveygisoduukdmpa/lib:$LD_LIBRARY_PATH
然后安裝magick,終于這條路成功了!
終于,我可以斷定,果子老師之所以安裝不了magick是因為它的Ubuntu系統里沒有安裝最新的imagemagick底層庫。之所以,他沒法用下面的語句安裝最新的imagemagick底層庫,是因為它用的是16.04版本Ubuntu。
sudo apt-get update
sudo apt-get install -y libmagick++-dev
不過,問題還是沒有順利的解決,因為我們希望這個包是給所有人用的,而非自己用。
有兩種方法,一種是讓其他用戶添加一個環境變量,LD_LIBRARY_PATH。
另一種方式,當你是root用戶,你就可以在 /etc/ld.so.conf.d/
里加上一個配置文件,比如說我的是,imagemagick-7.0.8-7-663.conf,里面是lib路徑
/home/xzg/spack/opt/spack/linux-ubuntu18.04-skylake_avx512/gcc-7.5.0/imagemagick-7.0.8-7-663acxuiasjhkjxymveygisoduukdmpa/lib
然后調用ldconfig
讓配置生效,就可以讓我們自己編譯的動態庫變成系統級。
故事到這里基本就結束了,只有最后一個小插曲,那就是果子老師最終目標是安裝spatialLIBD
BiocManager::install("spatialLIBD")
但是安裝過程中,另一個R包textshaping出錯,提示信息如下
--------------------------- [ANTICONF] --------------------------------
Configuration failed to find the harfbuzz freetype2 fribidi library. Try installing:
* deb: libharfbuzz-dev libfribidi-dev (Debian, Ubuntu, etc)
* rpm: harfbuzz-devel fribidi-devel (Fedora, EPEL)
* csw: libharfbuzz_dev libfribidi_dev (Solaris)
* brew: harfbuzz fribidi (OSX)
If harfbuzz freetype2 fribidi is already installed, check that 'pkg-config' is in your
PATH and PKG_CONFIG_PATH contains a harfbuzz freetype2 fribidi.pc file. If pkg-config
is unavailable you can set INCLUDE_DIR and LIB_DIR manually via:
R CMD INSTALL --configure-vars='INCLUDE_DIR=... LIB_DIR=...'
-------------------------- [ERROR MESSAGE] ---------------------------
<stdin>:1:10: fatal error: hb-ft.h: No such file or directory
compilation terminated.
--------------------------------------------------------------------
ERROR: configuration failed for package ‘textshaping’
* removing ‘/opt/R-4.2.1/lib/R/library/textshaping’
其實解決思路很簡單,也就是用 apt install libharfbuzz-dev libfribidi-dev
去安裝這個依賴就好。然而,沒有那么順利
下列軟件包有未滿足的依賴關系:
libfribidi-dev : 依賴: libfribidi0 (= 0.19.7-1) 但是 0.19.7-2 正要被安裝
E: 無法修正錯誤,因為您要求某些軟件包保持現狀,就是它們破壞了軟件包間的依賴關系
不過,無所謂了,我直接用 spack自己裝一份fribidi就好了。
參考資料