解决R语言找不到系统库导致的报错

1、基本需知

1.1、系统库

系统库(System library)是一组预先编写和编译好的软件模块集合,用于支持操作系统的基本功能和提供一些常见的服务。这些库通常由操作系统或第三方开发者提供,并且在系统安装过程中被预装或者用户可以额外安装。

常见的系统库包括标准C库(如libc)、图形用户界面库(如GTK+、Qt)、网络库(如libcurl)、数据库访问库(如libmysqlclient)、加密库(如OpenSSL)等。这些库在不同的操作系统上可能会有不同的实现和命名方式,但它们的作用都是为了简化开发者在特定操作系统上编写软件的任务,同时提供一定程度的抽象和封装。

1.2、conda 安装环境

conda 在安装环境时,会安装一个独立的、完整的开发环境,主要用于编译和运行各种软件和库。包括基础系统组件、图形和字体库、网络和安全类、其它工具和库以及语言支持。

大部分列出的包都是共享库(Shared Libraries),这些库通常用于在多个程序之间共享代码和资源,以提高效率和节省存储空间。共享库可以在程序运行时动态加载,而不是每个程序都包含完整的代码副本。

在你列出的包中,如 libgcc, libgfortran, libglib, libpng, libtiff, libxml2 等,它们通常是编译后的二进制文件,可以被多个程序同时使用。这些库通常被开发人员用来链接到他们的程序中,以便利用其提供的功能,如数学计算、图形渲染、文本处理等。

虽然大部分包是共享库,但也包括一些实用程序(如 make, curl)和编译工具(如 gcc, g++, gfortran),这些工具本身不是共享库,而是可执行程序,用于构建和管理软件项目。

(base) root@LAPTOP:~# conda create -n mytest r-base

Collecting package metadata (current_repodata.json): done

Solving environment: done

==> WARNING: A newer version of conda exists. <==

current version: 23.1.0

latest version: 24.5.0

Please update conda by running

$ conda update -n base -c defaults conda

Or to minimize the number of packages updated during conda update use

conda install conda=24.5.0

Package Plan

environment location: /root/anaconda3/envs/mytest

added / updated specs:

  • r-base

The following NEW packages will be INSTALLED:

_libgcc_mutex anaconda/pkgs/main/linux-64::_libgcc_mutex-0.1-main

_openmp_mutex anaconda/pkgs/main/linux-64::_openmp_mutex-5.1-1_gnu

bzip2 anaconda/pkgs/main/linux-64::bzip2-1.0.8-h5eee18b_6

cairo anaconda/pkgs/main/linux-64::cairo-1.16.0-hb05425b_5

curl anaconda/pkgs/free/linux-64::curl-7.26.0-1

expat anaconda/pkgs/main/linux-64::expat-2.6.2-h6a678d5_0

freetype anaconda/pkgs/main/linux-64::freetype-2.12.1-h4a9f257_0

fribidi anaconda/pkgs/main/linux-64::fribidi-1.0.10-h7b6447c_0

gcc_impl_linux-64 anaconda/pkgs/main/linux-64::gcc_impl_linux-64-11.2.0-h1234567_1

gcc_linux-64 anaconda/pkgs/main/linux-64::gcc_linux-64-11.2.0-h5c386dc_0

gfortran_linux-64 anaconda/pkgs/main/linux-64::gfortran_linux-64-11.2.0-hc2dff05_0

icu anaconda/pkgs/main/linux-64::icu-73.1-h6a678d5_0

jpeg anaconda/pkgs/main/linux-64::jpeg-9e-h5eee18b_1

libcurl anaconda/pkgs/main/linux-64::libcurl-8.7.1-h251f7ec_0

libopenblas anaconda/pkgs/main/linux-64::libopenblas-0.3.21-h043d6bf_0

libxml2 anaconda/pkgs/main/linux-64::libxml2-2.10.4-hfdd30dd_2

lz4-c anaconda/pkgs/main/linux-64::lz4-c-1.9.4-h6a678d5_1

make anaconda/pkgs/main/linux-64::make-4.2.1-h1bed415_1

ncurses anaconda/pkgs/main/linux-64::ncurses-6.4-h6a678d5_0

openssl anaconda/pkgs/main/linux-64::openssl-3.0.14-h5eee18b_0

python anaconda/pkgs/free/linux-64::python-1.0.1-0

r-base anaconda/pkgs/r/linux-64::r-base-4.3.1-h1ae530e_0

readline anaconda/pkgs/main/linux-64::readline-8.2-h5eee18b_0

  • 基础系统组件:

    • _libgcc_mutex, _openmp_mutex, _r-mutex, _sysroot_linux-64_curr_repodata_hack: 这些是系统级别的支持包,用于处理多线程、库依赖和系统根目录相关问题。
    • binutils: 二进制工具集,用于创建、管理和操作二进制文件。
    • gcc, g++, gfortran: GNU编译器集合,用于编译C、C++和Fortran程序。
    • make: 编译工具,用于自动化构建程序。
    • ld: 链接器,将多个目标文件链接成一个可执行文件。
    • kernel-headers: 内核头文件,用于编译依赖于系统内核的软件。
    • ncurses: 控制台屏幕处理库,用于在终端上输出文本界面。
    • openssl: 加密库,提供安全套接字层(SSL)功能。
    • readline: 提供命令行编辑功能,如历史记录和命令补全。
    • zlib, bzip2, xz, lz4, zstd: 压缩和解压库,用于处理压缩文件。
  • 图形和字体库:

    • cairo, fontconfig, freetype, harfbuzz, libpng, libtiff, pango, pixman: 图形和字体处理库,用于渲染和处理文字和图像。
    • libjpeg, libwebp: 图像处理库,支持JPEG和WebP格式。
  • 网络和安全:

    • curl: URL传输工具,用于从各种网络协议下载数据。
    • libcurl, libnghttp2, libssh2: 网络通信库,支持HTTP/2和SSH协议。
  • 其他工具和库:

    • expat, libxml2: XML解析库。
    • libffi: 提供对外部函数接口的支持。
    • libev: 事件循环库,用于事件驱动程序设计。
    • libiconv: 字符集转换库。
    • libuuid: UUID生成库,用于唯一标识符的生成。
    • tk, tktable: Tcl/Tk图形库,用于构建图形用户界面(GUI)应用程序。
  • 语言支持:

    • python, r-base: Python和R编程语言的基础安装包。

1.3、以 libcurl系统库为例

libcurl 是一个广泛使用的开源库,用于支持各种网络协议的数据传输,如HTTP、FTP、SMTP等。它允许开发者通过简单的API调用来进行网络数据的发送和接收,无论是下载文件、上传数据还是与Web服务进行交互,都可以借助 libcurl 轻松实现。以下为 libcurl 库具象化(万物皆文件Everything is a file)。libcurl包括头文件(.h)和共享链接库(.so)。

(base) root@LAPTOP:~# tree /root/anaconda3/envs/mytest/include/curl

/root/anaconda3/envs/mytest/include/curl

├── curl.h

├── curlbuild.h

├── curlrules.h

├── curlver.h

├── easy.h

├── header.h

├── mprintf.h

├── multi.h

├── options.h

├── stdcheaders.h

├── system.h

├── typecheck-gcc.h

├── urlapi.h

└── websockets.h
(base) root@LAPTOP-D6CGI3Q6:~/anaconda3/envs/mytest/lib# ls|grep libcurl

libcurl.so

libcurl.so.4

libcurl.so.4.2.0

libcurl.so.4.8.0

其它应用可通过 libcurl 共享库的共享目标文件(shared object file, 即.so)实现所需功能。

1.4、R安装包的一般过程

以下为安装 ragg 包时输出内容的摘要,*代表一级标题,**代表二级标题,以此类推。可以看到R安装包过程如下:

① 通过url下载所需的包和该包的依赖

② 开始安装 ragg,解压缩以及MD5检查

③ 使用 pkg-config 检查安装此包所需的系统库 freetype2、libpng等系统库的头文件路径(PKG_CFLAGS),以及库文件路径(library path)

④ 建库:使用 gcc 编译器编译下载的R包,并编译和链接系统库,安装完成

> install.packages('ragg')

trying URL 'https://mirrors.tuna.tsinghua.edu.cn/CRAN/src/contrib/ragg_1.3.2.tar.gz'

Content type 'application/octet-stream' length 430366 bytes (420 KB)

==================================================

downloaded 420 KB

* installing *source* package 'ragg' ...

** package 'ragg' successfully unpacked and MD5 sums checked

** using staged installation

Found pkg-config cflags and libs!

Using PKG_CFLAGS=-I/root/anaconda3/envs/mytest/include/freetype2 -I/root/anaconda3/envs/mytest/include/libpng16 -I/root/anaconda3/envs/mytest/include -I/root/anaconda3/envs/mytest/include/webp -I/root/anaconda3/envs/mytest/include

Using PKG_LIBS=-L/root/anaconda3/envs/mytest/lib -lfreetype -lpng16 -ltiff -ljpeg

** libs

using C++ compiler: 'x86_64-conda-linux-gnu-c++ (Anaconda gcc) 11.2.0'

x86_64-conda-linux-gnu-c++ -std=gnu++17 -I"/root/anaconda3/envs/mytest/lib/R/include" -DNDEBUG -I./agg/include -I/root/anaconda3/envs/mytest/include/freetype2 -I/root/anaconda3/envs/mytest/include/libpng16 -I/root/anaconda3/envs/mytest/include -I/root/anaconda3/envs/mytest/include/webp -I/root/anaconda3/envs/mytest/include -I'/root/anaconda3/envs/mytest/lib/R/library/systemfonts/include' -I'/root/anaconda3/envs/mytest/lib/R/library/textshaping/include' -DNDEBUG -D_FORTIFY_SOURCE=2 -O2 -isystem /root/anaconda3/envs/mytest/include -I/root/anaconda3/envs/mytest/include -Wl,-rpath-link,/root/anaconda3/envs/mytest/lib -fpic -fvisibility-inlines-hidden -fmessage-length=0 -march=nocona -mtune=haswell -ftree-vectorize -fPIC -fstack-protector-strong -fno-plt -O2 -ffunction-sections -pipe -isystem /root/anaconda3/envs/mytest/include -fdebug-prefix-map=/workspace/croot/r-base_1695428141831/work=/usr/local/src/conda/r-base-4.3.1 -fdebug-prefix-map=/root/anaconda3/envs/mytest=/usr/local/src/conda-prefix -c capture_dev.cpp -o capture_dev.o

x86_64-conda-linux-gnu-ar rcs agg/libstatagg.a agg/src/agg_curves.o agg/src/agg_font_freetype.o agg/src/agg_image_filters.o agg/src/agg_trans_affine.o agg/src/agg_vcgen_dash.o agg/src/agg_vcgen_stroke.o

x86_64-conda-linux-gnu-c++ -std=gnu++17 -shared -L/root/anaconda3/envs/mytest/lib/R/lib -Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags -Wl,--gc-sections -Wl,-rpath,/root/anaconda3/envs/mytest/lib -Wl,-rpath-link,/root/anaconda3/envs/mytest/lib -L/root/anaconda3/envs/mytest/lib -o ragg.so capture_dev.o init.o jpeg_dev.o png_dev.o ppm_dev.o tiff_dev.o -Lagg -lstatagg -L/root/anaconda3/envs/mytest/lib -lfreetype -lpng16 -ltiff -ljpeg -L/root/anaconda3/envs/mytest/lib/R/lib -lR

installing to /root/anaconda3/envs/mytest/lib/R/library/00LOCK-ragg/00new/ragg/libs

** R

** byte-compile and prepare package for lazy loading

** help

*** installing help indices

*** copying figures

** building package indices

** testing if installed package can be loaded from temporary location

** checking absolute paths in shared objects and dynamic libraries

** testing if installed package can be loaded from final location

** testing if installed package keeps a record of temporary installation path

* DONE (ragg)

1.5、编译与链接

1.5.1、编译器

编译器是将高级编程语言(如C、C++、Java等)编写的源代码文件转换为机器语言或中间代码的工具。

1.5.2、链接器

链接器用于将编译器生成的目标文件(通常是二进制目标文件)链接成最终的可执行程序或库文件。

1.6、pkg-config 工具

pkg-config 是一个用于管理和查询软件包配置信息的工具。在编译和链接过程中,经常需要指定软件包的头文件路径(include path)和库文件路径(library path),以及其他编译和链接选项。而 pkg-config 则提供了一种标准化的方式来获取这些信息。

安装R包时,通过调用 pkg-config 工具获得安装某包所需系统库的头文件以及库文件的路径!

1.6.1、pkg-config 工具调用

在安装R包时,pkg-config 工具被调用的过程类似如下

which pkg-config

查看该工具的路径:/usr/bin/pkg-config

一般系统层面上会安装该工具

pkg-config --cflags libcurl

查看 libcurl 的头文件路径和编译选项:-I/root/anaconda3/envs/mytest/include

pkg-config --libs libcurl

查看 libcurl 的库文件路径和链接选项:-L/root/anaconda3/envs/mytest/lib -lcurl

1.6.2、pkg-config 的包 (库) 配置文件

pkg-config 是如何知道这些库文件的头文件和库文件路径,这些信息存储在哪呢?为什么我一用`pkg-config --cflags libcurl`这个命令就会输出 libcurl的头文件路径?

(base) root@LAPTOP:~/anaconda3/envs/mytest/lib/pkgconfig# ls|grep libcurl.pc

libcurl.pc

因为在环境的 lib/pkgconfig 路径下包含了 libcurl 这个包的包配置文件(package config,即.pc),pkg-config 可读取整个文件,然后输出这个包的头文件和库文件路径。让我们看一下 libcurl.pc文件是否存了这些信息

(base) root@LAPTOP:~/anaconda3/envs/mytest/lib/pkgconfig# cat libcurl.pc

#***************************************************************************

_ _ ____ _

Project ___| | | | _ \| |

/ __| | | | |_) | |

| (| || | _ <| |

\|\/|| \\_____|

Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.

This software is licensed as described in the file COPYING, which

you should have received as part of this distribution. The terms

are also available at https://curl.se/docs/copyright.html.

You may opt to use, copy, modify, merge, publish, distribute and/or sell

copies of the Software, and permit persons to whom the Software is

furnished to do so, under the terms of the COPYING file.

This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY

KIND, either express or implied.

SPDX-License-Identifier: curl

###########################################################################

This should most probably benefit from getting a "Requires:" field added

dynamically by configure.

prefix=/root/anaconda3/envs/cellchat

exec_prefix={prefix} **libdir={exec_prefix}/lib**
includedir=${prefix}/include

supported_protocols="DICT FILE FTP FTPS GOPHER GOPHERS HTTP HTTPS IMAP IMAPS IPFS IPNS MQTT POP3 POP3S RTSP SCP SFTP SMB SMBS SMTP SMTPS TELNET TFTP"

supported_features="AsynchDNS GSS-API HSTS HTTP2 HTTPS-proxy IPv6 Kerberos Largefile NTLM SPNEGO SSL TLS-SRP UnixSockets alt-svc libz threadsafe"

Name: libcurl

URL: https://curl.se/

Description: Library to transfer files with ftp, http, etc.

Version: 8.7.1

Libs: -L${libdir} -lcurl

Libs.private: -lnghttp2 -lssh2 -lssh2 -lssl -lcrypto -lssl -lcrypto -L/root/anaconda3/envs/cellchat/lib -lgssapi_krb5 -lz -pthread

Cflags: -I${includedir}

1.6.3、pkg-config 的 pkgconfig 路径

pkg-config 工具为什么知道自己要去 pkgconfig 路径下找共享库的配置文件(.pc)?如上所述,pkg-config工具在系统上默认安装,它也会有默认设置的 pkgconfig 路径。当R安装包时就会使用默认 pkgconfig 文件下的共享库配置文件。使用 pkg-config --variable pc_path pkg-config 命令可知道该工具默认从哪个路径查找库的配置文件。

pkg-config --variable pc_path pkg-config

/usr/local/lib/x86_64-linux-gnu/pkgconfig:/usr/local/lib/pkgconfig:/usr/local/share/pkgconfig:/usr/lib/x86_64-linux-gnu/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig

2、问题

2.1、找不到系统库

Package libtiff-4 was not found in the pkg-config search path.

Perhaps you should add the directory containing `libtiff-4.pc'

to the PKG_CONFIG_PATH environment variable

No package 'libtiff-4' found
Package libjpeg was not found in the pkg-config search path.

Perhaps you should add the directory containing `libjpeg.pc'

to the PKG_CONFIG_PATH environment variable

No package 'libjpeg' found

Using PKG_CFLAGS=

Using PKG_LIBS=-lfreetype -lpng16 -ltiff -lz -ljpeg -lbz2

2.1、找到系统库,但不可使用

> install.packages('ragg')

trying URL 'https://mirrors.tuna.tsinghua.edu.cn/CRAN/src/contrib/ragg_1.3.2.tar.gz'

Content type 'application/octet-stream' length 430366 bytes (420 KB)

==================================================

downloaded 420 KB

* installing *source* package 'ragg' ...

** package 'ragg' successfully unpacked and MD5 sums checked

** using staged installation

Found pkg-config cflags and libs!

Using PKG_CFLAGS=-I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/x86_64-linux-gnu

Using PKG_LIBS=-lfreetype -lpng16 -lz -ltiff -ljpeg

-----------------------------[ ANTICONF ]-------------------------------

Configuration failed to find one of freetype2 libpng libtiff-4 libjpeg. Try installing:

* deb: libfreetype6-dev libpng-dev libtiff5-dev libjpeg-dev (Debian, Ubuntu, etc)

* rpm: freetype-devel libpng-devel libtiff-devel libjpeg-devel (Fedora, CentOS, RHEL)

* csw: libfreetype_dev libpng16_dev libtiff_dev libjpeg_dev (Solaris)

If freetype2 libpng libtiff-4 libjpeg is already installed, check that 'pkg-config' is in your

PATH and PKG_CONFIG_PATH contains a freetype2 libpng libtiff-4 libjpeg.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=...'

3、报错原因

报错原因可能出现在前面所述的前面所述的`R安装包的一般过程 `的任意一个环境,这里只针对第四步过程中产生报错的原因进行分析。

① 并未安装共享库

② pkg-config 工具未添加到 PATH 路径,导致在终端中不能直接键入pkg-config使用该工具

③ pkgconfig 路径错误: 如pkg-config工具默认的pkgconfig路径并包含某个库的配置文件 (.pc)

这对应报错中的提示

Configuration failed to find one of freetype2 libpng libtiff-4 libjpeg. Try installing:

* deb: libfreetype6-dev libpng-dev libtiff5-dev libjpeg-dev (Debian, Ubuntu, etc)

* rpm: freetype-devel libpng-devel libtiff-devel libjpeg-devel (Fedora, CentOS, RHEL)

* csw: libfreetype_dev libpng16_dev libtiff_dev libjpeg_dev (Solaris)

If freetype2 libpng libtiff-4 libjpeg is already installed, check that 'pkg-config' is in your

PATH and PKG_CONFIG_PATH contains a freetype2 libpng libtiff-4 libjpeg.pc file.

4、解决方法

4.1、安装所需的共享库

sudo apt install libcurl4-openssl-dev

使用系统的库管理工具apt安装,会默认安装到当前conda环境

conda install libcurl

使用conda 安装,同样安装到当前conda环境

4.2、安装pkg-config或将其添加到PATH

系统的base环境都会安装pkg-config工具,并已经添加到系统路径。如果想在conda环境安装pkg-config,如果直接在当前conda的虚拟环境下安装pkg-config,会立刻解决问题!!因为在当前环境安装pkg-config,当前环境中的pkg-config的pkgconfig路径就是当前虚拟环境的共享库路径!!

conda install pkg-config

sudo apt install pkg-config

一般安装完 pkg-config,就可直接使用,如果不行,需要将其添加到系统环境

export PATH="/path/to/pkg-config:$PATH"

这只会改变当前 shell,重新打开新shell 就会失效

echo 'export PATH="/path/to/pkg-config:$PATH"' >> ~/.bashrc

添加到.bashrc文件,之后都有效

soure ~/.bashrc

在当前shell立即生效

export LD_LIBRARY_PATH=/root/anaconda3/envs/test/lib:$LD_LIBRARY_PATH

export PKG_CONFIG_PATH=/root/anaconda3/envs/test/lib/pkgconfig:$PKG_CONFIG_PATH

export LDFLAGS="-L/root/anaconda3/envs/test/lib $LDFLAGS"

export CPPFLAGS="-I/root/anaconda3/envs/test/include $CPPFLAGS"

如果还是不行,可尝试

4.3、在shell中修改pkgconfig路径设置

pkg-config 工具并未提供直接修改 pkgconfig 路径的选项,不能像pkg-config --variable pc_path pkg-config 查看pkgconfig 路径一样修改。只能通过修改环境变量的方式修改。

export PKG_CONFIG_PATH=/root/anaconda3/envs/mytest/lib/pkgconfig:$PKG_CONFIG_PATH

这只会改变当前 shell,重新打开新shell 就会失效

echo 'PKG_CONFIG_PATH=/root/anaconda3/envs/mytest/lib/pkgconfig:$PKG_CONFIG_PATH' >> ~/.bashrc

添加到.bashrc文件,之后都有效

soure ~/.bashrc

在当前shell立即生效

4.5、在R语言中修改pkgconfig路径设置

Sys.getenv() # 获得当前环境的所有环境变量

Sys.setenv(PKG_CONFIG_PATH="/root/anaconda3/envs/mytest/lib/pkgconfig")

4.6、使用R 命令行工具手动安装

这种是最复杂的,如果实在不行可尝试自己指定系统库的头文件和库文件路径

R CMD INSTALL ragg --configure-vars='INCLUDE_DIR=/root/anaconda3/envs/test/include LIB_DIR=/root/anaconda3/envs/test/lib'

4.7、直接在R中指定所需系统库的路径

这种是最复杂的,如果实在不行可尝试自己指定系统库的头文件和库文件路径

install.packages('ragg', type = 'source', configure.vars = 'INCLUDE_DIR=/root/anaconda3/envs/test/include LIB_DIR=/root/anaconda3/envs/test/lib')

同在shell中

Rscript -e "install.packages('ragg', type = 'source', configure.vars = 'INCLUDE_DIR=/root/anaconda3/envs/test/include LIB_DIR=/root/anaconda3/envs/test/lib')"

相关推荐
萧鼎18 分钟前
Python并发编程库:Asyncio的异步编程实战
开发语言·数据库·python·异步
学地理的小胖砸19 分钟前
【一些关于Python的信息和帮助】
开发语言·python
疯一样的码农19 分钟前
Python 继承、多态、封装、抽象
开发语言·python
^velpro^20 分钟前
数据库连接池的创建
java·开发语言·数据库
秋の花28 分钟前
【JAVA基础】Java集合基础
java·开发语言·windows
小松学前端31 分钟前
第六章 7.0 LinkList
java·开发语言·网络
可峰科技40 分钟前
斗破QT编程入门系列之二:认识Qt:编写一个HelloWorld程序(四星斗师)
开发语言·qt
全栈开发圈44 分钟前
新书速览|Java网络爬虫精解与实践
java·开发语言·爬虫
面试鸭1 小时前
离谱!买个人信息买到网安公司头上???
java·开发语言·职场和发展
小白学大数据1 小时前
JavaScript重定向对网络爬虫的影响及处理
开发语言·javascript·数据库·爬虫